From df1d8f913cba400bb14088107cc52549989c7620 Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Sun, 24 Jul 2022 12:08:59 -0500 Subject: [PATCH] GROOVY-10698 --- .../core/tests/xform/TypeCheckedTests.java | 22 +++++++++++++++++++ .../stc/StaticTypeCheckingVisitor.java | 9 +++++++- .../stc/StaticTypeCheckingVisitor.java | 9 +++++++- .../stc/StaticTypeCheckingVisitor.java | 9 +++++++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java index f4070ef4ef..f8ad5ffbc7 100644 --- a/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java +++ b/base-test/org.eclipse.jdt.groovy.core.tests.compiler/src/org/eclipse/jdt/groovy/core/tests/xform/TypeCheckedTests.java @@ -6022,6 +6022,28 @@ public void testTypeChecked10673() { runConformTest(sources, "1"); } + @Test + public void testTypeChecked10698() { + //@formatter:off + String[] sources = { + "Main.groovy", + "class A {\n" + + " A(T t, B b_of_t) {\n" + + " }\n" + + "}\n" + + "class B {\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "void test() {\n" + + " new A<>('string', new B<>())\n" + + "}\n" + + "test()\n", + }; + //@formatter:on + + runConformTest(sources); + } + @Test public void testTypeChecked10699() { for (String type : new String[] {"java.util.function.Function", "java.util.function.UnaryOperator"}) { diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index ada034c465..3ab46f0cef 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -2788,11 +2788,18 @@ && findMethod(receiver, "", init(argumentTypes)).size() == 1) { && parameters.length == argumentTypes.length - 1) { ctor = typeCheckMapConstructor(call, receiver, arguments); } else { + /* GRECLIPSE edit -- GROOVY-10698 if (parameters.length > 0 && asBoolean(receiver.getGenericsTypes())) { // GROOVY-10283, GROOVY-10316, GROOVY-10482, GROOVY-10624, et al. Map context = extractPlaceHolders(null, receiver, ctor.getDeclaringClass()); parameters = parameters.clone(); for (int i = 0; i < parameters.length; i += 1) parameters[i] = new Parameter(applyGenericsContext(context, parameters[i].getType()), parameters[i].getName()); } + */ + GenericsType[] typeParameters = ctor.getDeclaringClass().getGenericsTypes(); if (typeParameters != null && typeParameters.length > 0) { + Map context = extractGenericsConnectionsFromArguments(typeParameters, parameters, argumentList, receiver.getGenericsTypes()); + if (!context.isEmpty()) parameters = Arrays.stream(parameters).map(p -> new Parameter(applyGenericsContext(context, p.getType()), p.getName())).toArray(Parameter[]::new); + } + // GRECLIPSE end resolvePlaceholdersFromImplicitTypeHints(argumentTypes, argumentList, parameters); typeCheckMethodsWithGenericsOrFail(receiver, argumentTypes, ctor, call); visitMethodCallArguments(receiver, argumentList, true, ctor); @@ -6203,7 +6210,7 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth private Map extractGenericsConnectionsFromArguments(final GenericsType[] methodGenericTypes, final Parameter[] parameters, final Expression arguments, final GenericsType[] explicitTypeHints) { Map resolvedPlaceholders = new HashMap<>(); - if (explicitTypeHints != null) { // resolve type parameters from type arguments + if (asBoolean(explicitTypeHints)) { // resolve type parameters from type arguments int n = methodGenericTypes.length; if (n == explicitTypeHints.length) { for (int i = 0; i < n; i += 1) { diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index b3ae2ee2c5..1beec8906f 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -2615,10 +2615,17 @@ && findMethod(receiver, "", init(argumentTypes)).size() == 1) { && parameters.length == argumentTypes.length - 1) { ctor = typeCheckMapConstructor(call, receiver, arguments); } else { + /* GRECLIPSE edit -- GROOVY-10698 if (asBoolean(receiver.getGenericsTypes())) { // GROOVY-10283, GROOVY-10316, GROOVY-10482, GROOVY-10624, et al. Map context = extractPlaceHolders(null, receiver, ctor.getDeclaringClass()); parameters = Arrays.stream(parameters).map(p -> new Parameter(applyGenericsContext(context, p.getType()), p.getName())).toArray(Parameter[]::new); } + */ + GenericsType[] typeParameters = ctor.getDeclaringClass().getGenericsTypes(); if (typeParameters != null && typeParameters.length > 0) { + Map context = extractGenericsConnectionsFromArguments(typeParameters, parameters, argumentList, receiver.getGenericsTypes()); + if (!context.isEmpty()) parameters = Arrays.stream(parameters).map(p -> new Parameter(applyGenericsContext(context, p.getType()), p.getName())).toArray(Parameter[]::new); + } + // GRECLIPSE end resolvePlaceholdersFromImplicitTypeHints(argumentTypes, argumentList, parameters); typeCheckMethodsWithGenericsOrFail(receiver, argumentTypes, ctor, call); visitMethodCallArguments(receiver, argumentList, true, ctor); @@ -5891,7 +5898,7 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth private Map extractGenericsConnectionsFromArguments(final GenericsType[] methodGenericTypes, final Parameter[] parameters, final Expression arguments, final GenericsType[] explicitTypeHints) { Map resolvedPlaceholders = new HashMap<>(); - if (explicitTypeHints != null) { // resolve type parameters from type arguments + if (asBoolean(explicitTypeHints)) { // resolve type parameters from type arguments int n = methodGenericTypes.length; if (n == explicitTypeHints.length) { for (int i = 0; i < n; i += 1) { diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java index 4749adc664..06823f7a66 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -2314,10 +2314,17 @@ && findMethod(receiver, "", init(argumentTypes)).size() == 1) { && parameters.length == argumentTypes.length - 1) { ctor = typeCheckMapConstructor(call, receiver, arguments); } else { + /* GRECLIPSE edit -- GROOVY-10698 if (asBoolean(receiver.getGenericsTypes())) { // GROOVY-10283, GROOVY-10316, GROOVY-10482, GROOVY-10624 Map context = extractPlaceHolders(receiver, ctor.getDeclaringClass()); parameters = Arrays.stream(parameters).map(p -> new Parameter(applyGenericsContext(context, p.getType()), p.getName())).toArray(Parameter[]::new); } + */ + GenericsType[] typeParameters = ctor.getDeclaringClass().getGenericsTypes(); if (typeParameters != null && typeParameters.length > 0) { + Map context = extractGenericsConnectionsFromArguments(typeParameters, parameters, argumentList, receiver.getGenericsTypes()); + if (!context.isEmpty()) parameters = Arrays.stream(parameters).map(p -> new Parameter(applyGenericsContext(context, p.getType()), p.getName())).toArray(Parameter[]::new); + } + // GRECLIPSE end resolvePlaceholdersFromImplicitTypeHints(argumentTypes, argumentList, parameters); typeCheckMethodsWithGenericsOrFail(receiver, argumentTypes, ctor, call); visitMethodCallArguments(receiver, argumentList, true, ctor); @@ -5384,7 +5391,7 @@ protected ClassNode inferReturnTypeGenerics(final ClassNode receiver, final Meth private Map extractGenericsConnectionsFromArguments(final GenericsType[] methodGenericTypes, final Parameter[] parameters, final Expression arguments, final GenericsType[] explicitTypeHints) { Map resolvedPlaceholders = new HashMap<>(); - if (explicitTypeHints != null) { // resolve type parameters from type arguments + if (asBoolean(explicitTypeHints)) { // resolve type parameters from type arguments int n = methodGenericTypes.length; if (n == explicitTypeHints.length) { for (int i = 0; i < n; i += 1) {