From 62910e52072126af8f96fe344e508e44e3d6470c Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Sat, 23 Oct 2021 13:23:05 -0500 Subject: [PATCH] GROOVY-10327 --- .../core/tests/xform/TypeCheckedTests.java | 31 ++++++++++++++++--- .../stc/StaticTypeCheckingSupport.java | 12 ++++--- .../stc/StaticTypeCheckingVisitor.java | 18 +++++++---- .../stc/StaticTypeCheckingSupport.java | 12 ++++--- .../stc/StaticTypeCheckingVisitor.java | 13 +++++++- .../stc/StaticTypeCheckingSupport.java | 6 ++-- .../stc/StaticTypeCheckingVisitor.java | 29 ++--------------- 7 files changed, 70 insertions(+), 51 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 1631780b17..b4f8ef243c 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 @@ -1780,10 +1780,13 @@ public void testTypeChecked9074d() { }; //@formatter:on - runConformTest(sources); - /* - runNegativeTest(sources, "cannot convert from capture#1-of ? super Type to Type"); - */ + runNegativeTest(sources, + "----------\n" + + "1. ERROR in Main.groovy (at line 7)\n" + + "\tType bean = fact.make(rule.type)\n" + + "\t ^^^^^^^^^^^^^^^^^^^^\n" + + "Groovy:[Static type checking] - Cannot assign value of type java.lang.Object to variable of type Type\n" + + "----------\n"); } @Test @@ -4228,4 +4231,24 @@ public void testTypeChecked10326() { "Groovy:[Static type checking] - Cannot set read-only property: key\n" + "----------\n"); } + + @Test + public void testTypeChecked10327() { + //@formatter:off + String[] sources = { + "Main.groovy", + "@groovy.transform.TypeChecked\n" + + "void test(Map map) {\n" + + " @groovy.transform.ASTTest(phase=INSTRUCTION_SELECTION, value={\n" + + " def type = node.getNodeMetaData(org.codehaus.groovy.transform.stc.StaticTypesMarker.INFERRED_TYPE)\n" + + " assert type == org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE\n" + + " })\n" + + " def foo = map.foo\n" + + "}\n" + + "test(foo:'bar')\n", + }; + //@formatter:on + + runConformTest(sources); + } } diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index 1113c493bb..95f8c704ca 100644 --- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -2030,8 +2030,8 @@ private static void extractGenericsConnections(Map" and ui like "List" extractGenericsConnections(connections, ui.getType(), boundType); } - // GRECLIPSE end } + // GRECLIPSE end } else { extractGenericsConnections(connections, ui.getType(), di.getType()); } @@ -2205,7 +2207,7 @@ static ClassNode getCombinedBoundType(GenericsType genericsType) { // representing the combination of all bounds. The code here, just picks // something out to be able to proceed and is not actually correct if (hasNonTrivialBounds(genericsType)) { - if (genericsType.getLowerBound() != null) return genericsType.getLowerBound(); + if (genericsType.getLowerBound() != null) return OBJECT_TYPE; // GROOVY-10327 if (genericsType.getUpperBounds() != null) return genericsType.getUpperBounds()[0]; } return genericsType.getType(); 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 1e911532c1..f787dd2059 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 @@ -3850,12 +3850,21 @@ private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final dummyMN.setGenericsTypes(orig.getGenericsTypes()); } ClassNode classNode = inferReturnTypeGenerics(receiver, dummyMN, arguments); + /* GRECLIPSE edit -- GROOVY-10327 ClassNode[] inferred = new ClassNode[classNode.getGenericsTypes().length]; for (int i = 0; i < classNode.getGenericsTypes().length; i++) { GenericsType genericsType = classNode.getGenericsTypes()[i]; ClassNode value = createUsableClassNodeFromGenericsType(genericsType); inferred[i] = value; } + */ + GenericsType[] returnTypeGenerics = classNode.getGenericsTypes(); + ClassNode[] inferred = new ClassNode[returnTypeGenerics.length]; + for (int i = 0, n = returnTypeGenerics.length; i < n; i += 1) { + GenericsType genericsType = returnTypeGenerics[i]; + inferred[i] = getCombinedBoundType(genericsType); + } + // GRECLIPSE end return inferred; } @@ -3865,14 +3874,10 @@ private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final * @param genericsType a {@link org.codehaus.groovy.ast.GenericsType} representing either a type, a placeholder or a wildcard * @return a class node usable as an inferred type */ + /* GRECLIPSE edit private static ClassNode createUsableClassNodeFromGenericsType(final GenericsType genericsType) { ClassNode value = genericsType.getType(); if (genericsType.isPlaceholder()) { - // GRECLIPSE add -- GROOVY-9968 - if (value.isRedirectNode()) - value = value.redirect(); - else - // GRECLIPSE end value = OBJECT_TYPE; } ClassNode lowerBound = genericsType.getLowerBound(); @@ -3886,6 +3891,7 @@ private static ClassNode createUsableClassNodeFromGenericsType(final GenericsTyp } return value; } + */ private static String[] convertToStringArray(final Expression options) { if (options == null) { @@ -4159,7 +4165,7 @@ public void visitMethodCallExpression(MethodCallExpression call) { */ if (genericsTypes != null && genericsTypes.length == 1 && genericsTypes[0].getLowerBound() == null) { - type = getCombinedBoundType(genericsTypes[0]); + type = genericsTypes[0].getType(); } else { type = OBJECT_TYPE; } diff --git a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index a3c1b3845a..76749aa5e3 100644 --- a/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy30/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1896,8 +1896,8 @@ private static void extractGenericsConnections(final Map" and ui like "List" extractGenericsConnections(connections, ui.getType(), boundType); } - // GRECLIPSE end } + // GRECLIPSE end } else { extractGenericsConnections(connections, ui.getType(), di.getType()); } @@ -2080,7 +2082,7 @@ static ClassNode getCombinedBoundType(final GenericsType genericsType) { // representing the combination of all bounds. The code here, just picks // something out to be able to proceed and is not actually correct if (hasNonTrivialBounds(genericsType)) { - if (genericsType.getLowerBound() != null) return genericsType.getLowerBound(); + if (genericsType.getLowerBound() != null) return OBJECT_TYPE; // GROOVY-10327 if (genericsType.getUpperBounds() != null) return genericsType.getUpperBounds()[0]; } return genericsType.getType(); 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 465cdefeaf..2beb679412 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 @@ -3534,12 +3534,21 @@ private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final dummyMN.setGenericsTypes(orig.getGenericsTypes()); } ClassNode classNode = inferReturnTypeGenerics(receiver, dummyMN, arguments); + /* GRECLIPSE edit -- GROOVY-10327 ClassNode[] inferred = new ClassNode[classNode.getGenericsTypes().length]; for (int i = 0; i < classNode.getGenericsTypes().length; i++) { GenericsType genericsType = classNode.getGenericsTypes()[i]; ClassNode value = createUsableClassNodeFromGenericsType(genericsType); inferred[i] = value; } + */ + GenericsType[] returnTypeGenerics = classNode.getGenericsTypes(); + ClassNode[] inferred = new ClassNode[returnTypeGenerics.length]; + for (int i = 0, n = returnTypeGenerics.length; i < n; i += 1) { + GenericsType genericsType = returnTypeGenerics[i]; + inferred[i] = getCombinedBoundType(genericsType); + } + // GRECLIPSE end return inferred; } @@ -3549,6 +3558,7 @@ private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final * @param genericsType a {@link org.codehaus.groovy.ast.GenericsType} representing either a type, a placeholder or a wildcard * @return a class node usable as an inferred type */ + /* GRECLIPSE edit private static ClassNode createUsableClassNodeFromGenericsType(final GenericsType genericsType) { ClassNode value = genericsType.getType(); if (genericsType.isPlaceholder()) { @@ -3565,6 +3575,7 @@ private static ClassNode createUsableClassNodeFromGenericsType(final GenericsTyp } return value; } + */ private static String[] convertToStringArray(final Expression options) { if (options == null) { @@ -3807,7 +3818,7 @@ public void visitMethodCallExpression(final MethodCallExpression call) { GenericsType[] genericsTypes = type.getGenericsTypes(); if (genericsTypes != null && genericsTypes.length == 1 && genericsTypes[0].getLowerBound() == null) { - type = getCombinedBoundType(genericsTypes[0]); + type = genericsTypes[0].getType(); } else { type = OBJECT_TYPE; } diff --git a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java index b2800c41b2..56ddcc5e46 100644 --- a/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java +++ b/base/org.codehaus.groovy40/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java @@ -1774,8 +1774,8 @@ private static void extractGenericsConnections(final Map