This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 5eeb6b15473280dc78df1b574bfc444751ab379f
Author: Eric Milles <[email protected]>
AuthorDate: Wed May 14 11:06:45 2025 -0500

    GROOVY-11663: STC: resolve `$self.pack_Type__name` to a static access
---
 .../transform/stc/TraitTypeCheckingExtension.java  | 32 ++++++++++++++++++++++
 .../traitx/TraitASTTransformationTest.groovy       | 10 +++----
 2 files changed, 37 insertions(+), 5 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
index f0b2b9157e..926582a967 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java
@@ -25,6 +25,8 @@ import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.MethodCall;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.transform.trait.TraitASTTransformation;
 import org.codehaus.groovy.transform.trait.Traits;
 
@@ -93,4 +95,34 @@ public class TraitTypeCheckingExtension extends 
AbstractTypeCheckingExtension {
 
         return Collections.emptyList();
     }
+
+    @Override
+    public boolean handleUnresolvedProperty(final PropertyExpression pexp) {
+        var objectExpression = pexp.getObjectExpression();
+        if (objectExpression instanceof VariableExpression
+                && objectExpression.getText().endsWith(Traits.THIS_OBJECT)) {
+            String propertyName = pexp.getPropertyAsString();
+            if (propertyName != null) {
+                ClassNode objectExpressionType = getType(objectExpression);
+                if 
(isClassClassNodeWrappingConcreteType(objectExpressionType)) {
+                    objectExpressionType = 
objectExpressionType.getGenericsTypes()[0].getType();
+                }
+                for (ClassNode trait : 
Traits.findTraits(objectExpressionType)) {
+                    if (propertyName.startsWith(trait.getName().replace('.', 
'_') + "__")) {
+                        ClassNode staticFieldHelper = 
Traits.findStaticFieldHelper(trait);
+                        if (staticFieldHelper != null) {
+                            MethodNode getter = 
staticFieldHelper.getDeclaredMethod(propertyName + "$get", 
Parameter.EMPTY_ARRAY);
+                            if (getter != null) { // GROOVY-11663: resolve 
"$self.pack_Type__name" to a static field access method
+                                ClassNode returnType = 
typeCheckingVisitor.inferReturnTypeGenerics(objectExpressionType, getter, 
ArgumentListExpression.EMPTY_ARGUMENTS);
+                                
pexp.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, returnType);
+                                storeType(pexp, returnType);
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        return false;
+    }
 }
diff --git 
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
 
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index 7caea44797..32a21c5cdb 100644
--- 
a/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ 
b/src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -3787,20 +3787,20 @@ final class TraitASTTransformationTest {
             $mode
             trait B extends A {
                 static one(String string) {
-                    string// + A__BANG
+                    string + A__BANG
                 }
                 Object two(String string) {
-                    string// + A__BANG
+                    string + A__BANG
                 }
             }
             $mode
             class C implements B {
                 static test1() {
-                    assert A__BANG + one('works') == '!works'
+                    assert A__BANG + one('works') == '!works!'
                 }
                 void test2() {
-                    assert A__BANG + one('works') == '!works'
-                    assert A__BANG + two('works') == '!works'
+                    assert A__BANG + one('works') == '!works!'
+                    assert A__BANG + two('works') == '!works!'
                 }
             }
 

Reply via email to