Skip to content

Commit 5eeb6b1

Browse files
committed
GROOVY-11663: STC: resolve $self.pack_Type__name to a static access
1 parent 7851400 commit 5eeb6b1

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

src/main/java/org/codehaus/groovy/transform/stc/TraitTypeCheckingExtension.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
import org.codehaus.groovy.ast.expr.ArgumentListExpression;
2626
import org.codehaus.groovy.ast.expr.MethodCall;
2727
import org.codehaus.groovy.ast.expr.MethodCallExpression;
28+
import org.codehaus.groovy.ast.expr.PropertyExpression;
29+
import org.codehaus.groovy.ast.expr.VariableExpression;
2830
import org.codehaus.groovy.transform.trait.TraitASTTransformation;
2931
import org.codehaus.groovy.transform.trait.Traits;
3032

@@ -93,4 +95,34 @@ public List<MethodNode> handleMissingMethod(final ClassNode receiver, final Stri
9395

9496
return Collections.emptyList();
9597
}
98+
99+
@Override
100+
public boolean handleUnresolvedProperty(final PropertyExpression pexp) {
101+
var objectExpression = pexp.getObjectExpression();
102+
if (objectExpression instanceof VariableExpression
103+
&& objectExpression.getText().endsWith(Traits.THIS_OBJECT)) {
104+
String propertyName = pexp.getPropertyAsString();
105+
if (propertyName != null) {
106+
ClassNode objectExpressionType = getType(objectExpression);
107+
if (isClassClassNodeWrappingConcreteType(objectExpressionType)) {
108+
objectExpressionType = objectExpressionType.getGenericsTypes()[0].getType();
109+
}
110+
for (ClassNode trait : Traits.findTraits(objectExpressionType)) {
111+
if (propertyName.startsWith(trait.getName().replace('.', '_') + "__")) {
112+
ClassNode staticFieldHelper = Traits.findStaticFieldHelper(trait);
113+
if (staticFieldHelper != null) {
114+
MethodNode getter = staticFieldHelper.getDeclaredMethod(propertyName + "$get", Parameter.EMPTY_ARRAY);
115+
if (getter != null) { // GROOVY-11663: resolve "$self.pack_Type__name" to a static field access method
116+
ClassNode returnType = typeCheckingVisitor.inferReturnTypeGenerics(objectExpressionType, getter, ArgumentListExpression.EMPTY_ARGUMENTS);
117+
pexp.putNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION, returnType);
118+
storeType(pexp, returnType);
119+
return true;
120+
}
121+
}
122+
}
123+
}
124+
}
125+
}
126+
return false;
127+
}
96128
}

src/test/groovy/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3787,20 +3787,20 @@ final class TraitASTTransformationTest {
37873787
$mode
37883788
trait B extends A {
37893789
static one(String string) {
3790-
string// + A__BANG
3790+
string + A__BANG
37913791
}
37923792
Object two(String string) {
3793-
string// + A__BANG
3793+
string + A__BANG
37943794
}
37953795
}
37963796
$mode
37973797
class C implements B {
37983798
static test1() {
3799-
assert A__BANG + one('works') == '!works'
3799+
assert A__BANG + one('works') == '!works!'
38003800
}
38013801
void test2() {
3802-
assert A__BANG + one('works') == '!works'
3803-
assert A__BANG + two('works') == '!works'
3802+
assert A__BANG + one('works') == '!works!'
3803+
assert A__BANG + two('works') == '!works!'
38043804
}
38053805
}
38063806

0 commit comments

Comments
 (0)