[ https://issues.apache.org/jira/browse/GROOVY-9902?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Paul King updated GROOVY-9902: ------------------------------ Fix Version/s: 3.0.8 > Generic typecheck in @DelegatesTo doesn't work > ---------------------------------------------- > > Key: GROOVY-9902 > URL: https://issues.apache.org/jira/browse/GROOVY-9902 > Project: Groovy > Issue Type: Bug > Components: Static compilation > Affects Versions: 2.5.6, 3.0.7 > Reporter: Felix Scheinost > Assignee: Eric Milles > Priority: Major > Fix For: 3.0.8, 4.0.0-alpha-3 > > Time Spent: 1h > Remaining Estimate: 0h > > I found an edge case where @CompileStatic doesn't raise an error when calling > a method with incompatible types. > Example code that reproduces the problem: > [https://groovyconsole.appspot.com/script/5098548152500224] > {code:java} > import groovy.transform.CompileStatic > /** > * For the bug to be visible this class has to have a generic type > * Even if in this case the generic seems pointless. > */ > @CompileStatic > class Holder<D> { > TypedProperty<String, D> stringProperty = prop(String) > TypedProperty<Long, D> longProperty = prop(Long) > def <T> TypedProperty<T, D> prop(Class<T> clazz) { > return new TypedProperty<T, D>(clazz: clazz) > } > /** > * This method is also necessary to trigger the bug. > * Seems like because of the missing <D> in the @DelegatesTo the > typechecker is tripped up? > * In the original method in our codebase the signature contains <D> as > well. > */ > def <T> T of(@DelegatesTo(value = Holder, strategy = > Closure.DELEGATE_FIRST) Closure<T> c) { > c.delegate = this > c.resolveStrategy = Closure.DELEGATE_FIRST > c() > } > } > @CompileStatic > class TypedProperty<T, D> { > Class<T> clazz > void eq(T t) { > // The code fails here, expected String but got GString > // This should have been catched by the typechecker > // And/Or the typechecker should have automatically converted GString to > String > assert t.class == clazz, "t.class is ${t.class} not ${clazz}" > } > } > @CompileStatic > class Test { > static void test() { > Holder<Object> q = new Holder<Object>() > // Works: > // Typechecker catches this: Cannot call TypedProperty <String, > Object>#eq(java.lang.String) with arguments [groovy.lang.GString] > // q.stringProperty.eq("${0}") > > // Doesn't work because of delegation > q.of { > // Typechecker should be able to catch this as well > // But instead it yields a runtime problem because TypedProperty is > called with GString and assert fails > stringProperty.eq("${0}") > > // Doesn't get catched by the typecherk as well - completely different > types Long and String > longProperty.eq("foo") > } > } > } > Test.test() > {code} > -- This message was sent by Atlassian Jira (v8.3.4#803005)