From a8c2423872308ff6176bc8b94f28aa918615468d Mon Sep 17 00:00:00 2001 From: Eric Milles Date: Tue, 9 Mar 2021 19:14:06 -0600 Subject: [PATCH] GROOVY-9974 --- .../core/tests/xform/TypeCheckedTests.java | 19 +++++++++++++++++++ .../stc/StaticTypeCheckingSupport.java | 11 ++++++++++- .../stc/StaticTypeCheckingSupport.java | 11 ++++++++++- .../stc/StaticTypeCheckingSupport.java | 11 ++++++++++- 4 files changed, 49 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 d178563079..5814d96832 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 @@ -1243,4 +1243,23 @@ public void testTypeChecked9972c() { runConformTest(sources, ""); } + + @Test + public void testTypeChecked9974() { + //@formatter:off + String[] sources = { + "Main.groovy", + "boolean isBlank(String s) {\n" + + " s.isAllWhitespace()\n" + + "}\n" + + "@groovy.transform.TypeChecked\n" + + "void test() {\n" + + " print([''].removeIf(this.&isBlank))\n" + + "}\n" + + "test()\n", + }; + //@formatter:on + + runConformTest(sources, "true"); + } } 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 eb1d18d8b5..d3d1046c37 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 @@ -1790,12 +1790,21 @@ private static boolean equalIncludingGenerics(ClassNode orig, ClassNode copy) { static void extractGenericsConnections(Map connections, ClassNode type, ClassNode target) { if (target == null || type == target || !isUsingGenericsOrIsArrayUsingGenerics(target)) return; if (type == null || type == UNKNOWN_PARAMETER_TYPE) return; + + MethodNode sam; + if (type.isArray() && target.isArray()) { extractGenericsConnections(connections, type.getComponentType(), target.getComponentType()); + // GRECLIPSE add + } else if (type.equals(CLOSURE_TYPE) && (sam = findSAM(target)) != null) { + // GROOVY-9974: Lambda, Closure, Pointer or Reference for SAM-type receiver + ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(sam.getReturnType()); + extractGenericsConnections(connections, type.getGenericsTypes(), new GenericsType[] {new GenericsType(returnType)}); + // GRECLIPSE end } else if (target.isGenericsPlaceHolder() || type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) { // structural match route if (target.isGenericsPlaceHolder()) { - connections.put(new GenericsTypeName(target.getGenericsTypes()[0].getName()), new GenericsType(type)); + connections.put(new GenericsTypeName(target.getUnresolvedName()), new GenericsType(type)); } else { extractGenericsConnections(connections, type.getGenericsTypes(), target.getGenericsTypes()); } 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 1919c2e805..0d4e728fbb 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 @@ -1715,12 +1715,21 @@ static void extractGenericsConnections(final Map if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return; if (type == null || type == UNKNOWN_PARAMETER_TYPE) return; + MethodNode sam; + if (target.isGenericsPlaceHolder()) { - connections.put(new GenericsTypeName(target.getGenericsTypes()[0].getName()), new GenericsType(type)); + connections.put(new GenericsTypeName(target.getUnresolvedName()), new GenericsType(type)); } else if (type.isArray() && target.isArray()) { extractGenericsConnections(connections, type.getComponentType(), target.getComponentType()); + // GRECLIPSE add + } else if (type.equals(CLOSURE_TYPE) && (sam = findSAM(target)) != null) { + // GROOVY-9974: Lambda, Closure, Pointer or Reference for SAM-type receiver + ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(sam.getReturnType()); + extractGenericsConnections(connections, type.getGenericsTypes(), new GenericsType[] {new GenericsType(returnType)}); + // GRECLIPSE end + } else if (type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) { extractGenericsConnections(connections, type.getGenericsTypes(), target.getGenericsTypes()); 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 096a77063f..7bd3239336 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 @@ -1713,12 +1713,21 @@ static void extractGenericsConnections(final Map if (target == null || target == type || !isUsingGenericsOrIsArrayUsingGenerics(target)) return; if (type == null || type == UNKNOWN_PARAMETER_TYPE) return; + MethodNode sam; + if (target.isGenericsPlaceHolder()) { - connections.put(new GenericsTypeName(target.getGenericsTypes()[0].getName()), new GenericsType(type)); + connections.put(new GenericsTypeName(target.getUnresolvedName()), new GenericsType(type)); } else if (type.isArray() && target.isArray()) { extractGenericsConnections(connections, type.getComponentType(), target.getComponentType()); + // GRECLIPSE add + } else if (type.equals(CLOSURE_TYPE) && (sam = findSAM(target)) != null) { + // GROOVY-9974: Lambda, Closure, Pointer or Reference for SAM-type receiver + ClassNode returnType = StaticTypeCheckingVisitor.wrapTypeIfNecessary(sam.getReturnType()); + extractGenericsConnections(connections, type.getGenericsTypes(), new GenericsType[] {new GenericsType(returnType)}); + // GRECLIPSE end + } else if (type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) { extractGenericsConnections(connections, type.getGenericsTypes(), target.getGenericsTypes());