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 <[email protected]> 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'])
