You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/05/13 17:07:50 UTC
[groovy] branch master updated: GROOVY-8409,
GROOVY-9902: STC: retain generics for setter receiver
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
The following commit(s) were added to refs/heads/master by this push:
new 7109f64 GROOVY-8409, GROOVY-9902: STC: retain generics for setter receiver
7109f64 is described below
commit 7109f64f17601016e41cb989ec1ee78f764c6a81
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 13 12:07:37 2021 -0500
GROOVY-8409, GROOVY-9902: STC: retain generics for setter receiver
---
.../groovy/ast/expr/VariableExpression.java | 26 ++++++------
.../transform/stc/StaticTypeCheckingSupport.java | 3 --
.../transform/stc/StaticTypeCheckingVisitor.java | 11 ++---
.../groovy/transform/stc/GenericsSTCTest.groovy | 49 +++++++++++++++++++++-
4 files changed, 66 insertions(+), 23 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
index 04e9bdb..7a83054 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/VariableExpression.java
@@ -50,16 +50,16 @@ public class VariableExpression extends Expression implements Variable {
this.accessedVariable = origin;
}
- public VariableExpression(String variable, ClassNode type) {
- this.variable = variable;
+ public VariableExpression(final String name, final ClassNode type) {
+ variable = name;
originType = type;
- setType(ClassHelper.getWrapper(type));
+ setType(ClassHelper.isPrimitiveType(type) ? ClassHelper.getWrapper(type) : type);
}
-
+
public VariableExpression(String variable) {
this(variable, ClassHelper.DYNAMIC_TYPE);
}
-
+
public VariableExpression(Variable variable) {
this(variable.getName(), variable.getOriginType());
setAccessedVariable(variable);
@@ -80,7 +80,7 @@ public class VariableExpression extends Expression implements Variable {
public String getText() {
return variable;
}
-
+
@Override
public String getName() {
return variable;
@@ -100,13 +100,13 @@ public class VariableExpression extends Expression implements Variable {
public boolean hasInitialExpression() {
return false;
}
-
+
@Override
public boolean isInStaticContext() {
if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isInStaticContext();
return inStaticContext;
}
-
+
public void setInStaticContext(boolean inStaticContext) {
this.inStaticContext = inStaticContext;
}
@@ -123,7 +123,7 @@ public class VariableExpression extends Expression implements Variable {
super.setType(cn);
isDynamicTyped |= ClassHelper.DYNAMIC_TYPE==cn;
}
-
+
@Override
public boolean isDynamicTyped() {
if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.isDynamicTyped();
@@ -156,7 +156,7 @@ public class VariableExpression extends Expression implements Variable {
*/
@Override
public void setClosureSharedVariable(boolean inClosure) {
- closureShare = inClosure;
+ closureShare = inClosure;
}
@Override
@@ -170,9 +170,9 @@ public class VariableExpression extends Expression implements Variable {
* @param useRef
*/
public void setUseReferenceDirectly(boolean useRef) {
- this.useRef = useRef;
+ this.useRef = useRef;
}
-
+
/**
* For internal use only. This flag is used by compiler internals and should probably
* be converted to a node metadata in future.
@@ -180,7 +180,7 @@ public class VariableExpression extends Expression implements Variable {
public boolean isUseReferenceDirectly() {
return useRef;
}
-
+
@Override
public ClassNode getType() {
if (accessedVariable!=null && accessedVariable!=this) return accessedVariable.getType();
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index b06fda3..b7bafd5 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -1031,9 +1031,6 @@ public abstract class StaticTypeCheckingSupport {
if (!asBoolean(methods)) {
return Collections.emptyList();
}
- if (isUsingUncheckedGenerics(receiver)) {
- return chooseBestMethod(makeRawType(receiver), methods, argumentTypes);
- }
int bestDist = Integer.MAX_VALUE;
List<MethodNode> bestChoices = new LinkedList<>();
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 5a0fb9a..588532e 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -805,7 +805,8 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// the inferred type of the binary expression is the type of the RHS
// "completed" with generics type information available from the LHS
- resultType = GenericsUtils.parameterizeType(lType, resultType.getPlainNodeReference());
+ if (!resultType.isGenericsPlaceHolder()) // plain reference drops placeholder
+ resultType = GenericsUtils.parameterizeType(lType, resultType.getPlainNodeReference());
} else if (lType.equals(OBJECT_TYPE) && GenericsUtils.hasUnresolvedGenerics(resultType)) { // def list = []
Map<GenericsTypeName, GenericsType> placeholders = extractGenericsParameterMapOfThis(typeCheckingContext);
resultType = fullyResolveType(resultType, Optional.ofNullable(placeholders).orElseGet(Collections::emptyMap));
@@ -4888,11 +4889,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
if (!result.isEmpty()) return result;
}
- if (GSTRING_TYPE.equals(receiver)) return findMethod(STRING_TYPE, name, args);
-
+ if (GSTRING_TYPE.equals(receiver)) {
+ return findMethod(STRING_TYPE, name, args);
+ }
if (isBeingCompiled(receiver)) {
- chosen = findMethod(GROOVY_OBJECT_TYPE, name, args);
- if (!chosen.isEmpty()) return chosen;
+ return findMethod(GROOVY_OBJECT_TYPE, name, args);
}
return EMPTY_METHODNODE_LIST;
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index cd2a4ba..d65b991 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -1521,6 +1521,51 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-8409, GROOVY-9902
+ void testShouldUseMethodGenericType11() {
+ config.with {
+ targetDirectory = File.createTempDir()
+ jointCompilationOptions = [stubDir: File.createTempDir()]
+ }
+ File parentDir = File.createTempDir()
+ try {
+ def a = new File(parentDir, 'Main.groovy')
+ a.write '''
+ def obj = new Pojo()
+ Foo raw = obj.getFoo('')
+ raw.bar = raw.baz // Cannot assign value of type Object to variable of type R
+ '''
+ def b = new File(parentDir, 'Pojo.java')
+ b.write '''
+ public class Pojo {
+ public <R extends I> Foo<R> getFoo(String key) {
+ return new Foo<>();
+ }
+ }
+ '''
+ def c = new File(parentDir, 'Types.groovy')
+ c.write '''
+ interface I {
+ }
+ class Foo<T extends I> {
+ T bar
+ T baz
+ }
+ '''
+
+ def loader = new GroovyClassLoader(this.class.classLoader)
+ def cu = new JavaAwareCompilationUnit(config, loader)
+ cu.addSources(a, b, c)
+ cu.compile()
+
+ loader.loadClass('Main').main()
+ } finally {
+ parentDir.deleteDir()
+ config.targetDirectory.deleteDir()
+ config.jointCompilationOptions.stubDir.deleteDir()
+ }
+ }
+
// GROOVY-5516
void testAddAllWithCollectionShouldBeAllowed() {
assertScript '''import org.codehaus.groovy.transform.stc.ExtensionMethodNode
@@ -2039,8 +2084,8 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
test(new Holder<Object>())
''',
'Cannot call TypedProperty#eq(java.lang.String) with arguments [groovy.lang.GString]',
- 'Cannot call TypedProperty#eq(java.lang.String) with arguments [int]',
- 'Cannot call TypedProperty#eq(java.lang.Number) with arguments [java.lang.String]'
+ 'Cannot find matching method TypedProperty#eq(int)', // chooseBestMethod removes "eq"
+ 'Cannot find matching method TypedProperty#eq(java.lang.String)'
}
// GROOVY-5748