You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2021/04/10 23:37:27 UTC
[groovy] 01/02: GROOVY-9996: infer return type generics using
declared type of variables (port to 3_0_X)
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit e538c6f6a9edfae2e1651361d2652943b7467b23
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Tue Mar 23 10:20:45 2021 -0500
GROOVY-9996: infer return type generics using declared type of variables (port to 3_0_X)
---
.../groovy/transform/stc/StaticTypeCheckingVisitor.java | 10 +++++++++-
src/test/groovy/transform/stc/GenericsSTCTest.groovy | 17 +++++++++++++++++
2 files changed, 26 insertions(+), 1 deletion(-)
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 5d4bc3f..e025180 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -5183,7 +5183,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
for (int i = 0; i < paramLength; i += 1) {
boolean lastArg = (i == paramLength - 1);
ClassNode paramType = parameters[i].getType();
- ClassNode argumentType = getType(expressions.get(i));
+ ClassNode argumentType = getDeclaredOrInferredType(expressions.get(i));
while (paramType.isArray() && argumentType.isArray()) {
paramType = paramType.getComponentType();
argumentType = argumentType.getComponentType();
@@ -5446,6 +5446,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return resolveClassNodeGenerics(resolvedPlaceholders, placeholdersFromContext, currentType);
}
+ private ClassNode getDeclaredOrInferredType(final Expression expression) {
+ // in case of "T t = new ExtendsOrImplementsT()", return T for the expression type
+ if (expression instanceof Variable && !((Variable) expression).isDynamicTyped()) {
+ return getOriginalDeclarationType(expression); // GROOVY-9996
+ }
+ return getInferredTypeFromTempInfo(expression, getType(expression));
+ }
+
private static ClassNode getDeclaringClass(final MethodNode method, final Expression arguments) {
ClassNode declaringClass = method.getDeclaringClass();
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index 2c0b7bd..b5020e3 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -196,6 +196,23 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
'''
}
+ // GROOVY-9996
+ void testDiamondInferrenceFromConstructor8a() {
+ assertScript '''
+ @groovy.transform.TupleConstructor(defaults=false)
+ class C<T> {
+ T p
+ }
+ interface I { }
+ class D implements I { }
+ void test(C<I> c) { assert c.p instanceof D }
+
+ I i = new D() // infers D for "i"
+ def ci = new C<>(i) // infers C<D> for "ci"
+ test(ci)
+ '''
+ }
+
void testLinkedListWithListArgument() {
assertScript '''
List<String> list = new LinkedList<String>(['1','2','3'])