Repository navigation
GROOVY-12605: resolve a static accessor method of a trait as a property in a static scope of the implementing class - #3132
Conversation
…ty in a static scope of the implementing class
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #3132 +/- ##
==================================================
+ Coverage 74.1016% 74.1021% +0.0005%
- Complexity 43596 43608 +12
==================================================
Files 1692 1692
Lines 149245 149263 +18
Branches 28284 28291 +7
==================================================
+ Hits 110593 110607 +14
- Misses 28475 28477 +2
- Partials 10177 10179 +2
🚀 New features to boost your workflow:
|
✅ All tests passed ✅🏷️ Commit: 3ff2f13 Learn more about TestLens at testlens.app/docs. |
daniellansun
left a comment
There was a problem hiding this comment.
LGTM for GROOVY-12605.
VariableScopeVisitor.findClassMember already synthesised pseudo-properties for superclass accessors, but for traits it only considered fields/properties and did not walk a still-unmoved extends clause. Matching non-private static trait accessors (same-CU method or precompiled public forwarder) and following unresolved super-traits fixes vr / label / setter assignment from a static method of the implementing class in every mode — including precompiled traits and private-static negative cases.
@CompileModesTest matrix is appropriate. CI green.
A static accessor method of a trait could not be referenced as a property from a static method of the implementing class:
trait T { static boolean isVr() { true } } class C implements T { static m() { vr } } assert C.m()This failed to compile in every mode, dynamic included, with "Apparent variable 'vr' was found in a static scope but doesn't refer to a local variable, static field or class", in 4.0.33, 5.0.8 and 6.0.0 too. The same method declared in a superclass works, and so does the same reference from an instance method of
C. Static getters, static setters used as assignment targets, and statics inherited through a super trait (trait U extends T) failed the same way.VariableScopeVisitor.findClassMembercreates a pseudo-property for accessor methods of the class and its superclasses. For traits it looked only at fields and properties, and it did not follow a super trait that is still in theextendsclause beforeTraitASTTransformationmoves it to the interfaces. It now also matches a trait's non-private static accessor methods: the method itself for a trait in the same compilation unit, the public static forwarder for a precompiled trait. It also queues a trait's super trait. Private static trait methods and static methods of plain interfaces are still not resolved, since neither becomes a member of the implementing class. The pseudo-property construction moved into a shared helper.Tests
TraitASTTransformationTest.testTraitStaticAccessorFromStaticMethod,testSuperTraitStaticAccessorFromStaticMethodandtestPrecompiledTraitStaticAccessorFromStaticMethodfail without the change in dynamic,@TypeCheckedand@CompileStaticmode.testTraitPrivateStaticAccessorFromStaticMethodchecks that a private static trait accessor stays rejected.groovy.transform.stc.*,org.codehaus.groovy.classgen.*(includingasm.sc.*),org.codehaus.groovy.transform.traitx.*,gls.*,bugs.*,groovy.ThisAndSuperTestandgroovy.StaticImportTestpass. The Checkstyle and CodeNarc gates pass.