[
https://issues.apache.org/jira/browse/GROOVY-12593?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18135555#comment-18135555
]
ASF GitHub Bot commented on GROOVY-12593:
-----------------------------------------
codeconsole opened a new pull request, #3120:
URL: https://github.com/apache/groovy/pull/3120
A static trait property cannot be assigned from a static trait method when
its name matches a declared field of `java.lang.Class`: `name`, `module`,
`componentType` or `packageName`.
```groovy
trait T {
static String name = 'x'
static void w() { name = 'y' } // or this.name = 'y', name += 'y', in
a closure or lambda
}
class C implements T {}
C.w()
```
Dynamic Groovy throws `MissingMethodException: No signature of static
method: java_lang_Object__name$set for class: C`. @TypeChecked and
@CompileStatic reject the code with `Cannot find matching method
java.lang.Class#java_lang_Object__name$set(java.lang.String)`. 4.0.33, 5.0.8
and 6.0.0 fail the same way.
In a static trait method the receiver is typed `Class<T>`.
`TraitReceiverTransformer.tryGetFieldNode` asked that type for the field before
it asked the trait, so it found Class's own private field, and the generated
setter call was named after `Object`. For a `Class<T>` receiver it now looks
only in the trait. Instance trait methods, whose receiver is the trait itself,
are unchanged.
## Tests
`TraitASTTransformationTest.testTraitStaticPropertyNamedLikeFieldOfClass`
fails without the change in all three modes (@CompileDynamic, @TypeChecked,
@CompileStatic). It covers each of the four names with plain, `this.`,
compound, closure and lambda assignment from static methods, plain and `this.`
assignment from instance methods, and assignment from a sub-trait. The
`groovy.transform.stc.*`, `org.codehaus.groovy.classgen.asm.sc.*`,
`org.codehaus.groovy.transform.traitx.*`, `gls.*` and `groovy.bugs.*` tests and
`groovy.ThisAndSuperTest` pass. The Checkstyle and CodeNarc gates pass.
> Assigning a static trait property named name, module, componentType or
> packageName from a static trait method fails
> -------------------------------------------------------------------------------------------------------------------
>
> Key: GROOVY-12593
> URL: https://issues.apache.org/jira/browse/GROOVY-12593
> Project: Groovy
> Issue Type: Bug
> Affects Versions: 4.0.33, 5.0.8, 6.0.0
> Reporter: Scott Murphy Heiberg
> Priority: Major
>
> {code:groovy}
> trait T {
> static String name = 'x'
> static void w() { name = 'y' } // same with this.name = 'y', name += 'y',
> or inside a closure or lambda
> }
> class C implements T {}
> C.w()
> assert C.name == 'y'
> {code}
> Actual (dynamic):
> {noformat}
> groovy.lang.MissingMethodException: No signature of static method:
> java_lang_Object__name$set for class: C is applicable for argument types:
> (String) values: [y]
> {noformat}
> Actual (@TypeChecked or @CompileStatic):
> {noformat}
> [Static type checking] - Cannot find matching method
> java.lang.Class#java_lang_Object__name$set(java.lang.String) or static method
> T#java_lang_Object__name$set(java.lang.String). Please check if the declared
> type is correct and if the method exists.
> {noformat}
> Expected: the assignment sets the static property, as it does for any other
> property name. The same happens for {{module}}, {{componentType}} and
> {{packageName}}. Reads, and assignments from instance trait methods, work.
> Cause: in a static trait method the receiver is typed as Class of T, and
> {{TraitReceiverTransformer.tryGetFieldNode}} looked the field up on that type
> before the trait. It found the private field of {{java.lang.Class}} with that
> name, so the transformer generated a call to a setter named after {{Object}}.
> Seen in 4.0.33, 5.0.8 and 6.0.0 (dynamic).
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)