This is an automated email from the ASF dual-hosted git repository. emilles pushed a commit to branch GROOVY_3_0_X in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 1cf87b6a2055d809c0cea7c57804df53b26d716d Author: Eric Milles <[email protected]> AuthorDate: Mon Apr 5 14:13:34 2021 -0500 GROOVY-10010: check GString element vs String collection for method call --- .../java/org/codehaus/groovy/ast/GenericsType.java | 2 +- .../transform/stc/StaticTypeCheckingVisitor.java | 4 ++ .../groovy/transform/stc/GenericsSTCTest.groovy | 80 +++++++++++++++------- 3 files changed, 61 insertions(+), 25 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java b/src/main/java/org/codehaus/groovy/ast/GenericsType.java index a1da7a6..ba8dc5d 100644 --- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java +++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java @@ -445,7 +445,7 @@ public class GenericsType extends ASTNode { if (!match) break; } } - return match; + continue; } } match = redirectBoundType.isCompatibleWith(classNodeType.getType()); 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 4172126..41256b3 100644 --- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java +++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java @@ -5567,6 +5567,10 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport { ClassNode[] paramTypes = new ClassNode[parameters.length]; for (int i = 0, n = parameters.length; i < n; i += 1) { paramTypes[i] = fullyResolveType(parameters[i].getType(), classGTs); + // GROOVY-10010: check for List<String> parameter and ["foo","$bar"] argument + if (i < arguments.length && hasGStringStringError(paramTypes[i], arguments[i], location)) { + return false; + } } addStaticTypeError("Cannot call " + toMethodGenericTypesString(candidateMethod) + receiver.toString(false) + "#" + toMethodParametersString(candidateMethod.getName(), paramTypes) + " with arguments " + formatArgumentList(arguments), location); diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy index 3d47868..800ea5f 100644 --- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy +++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy @@ -45,6 +45,13 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { ''', 'Incompatible generic argument types. Cannot assign java.util.HashMap <String, Integer> to: java.util.Map <String, String>' } + void testDeclaration4() { + // no generics checked after first wildcard + shouldFailWithMessages ''' + Map<? extends CharSequence,String> obj = new HashMap<String,Integer>() + ''', 'Incompatible generic argument types. Cannot assign java.util.HashMap <String, Integer> to: java.util.Map <? extends java.lang.CharSequence, String>' + } + void testAddOnList() { shouldFailWithMessages ''' List<String> list = [] @@ -816,34 +823,59 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase { ''' } - // GROOVY-5559 + // GROOVY-5559, GROOVY-10010 void testGStringInListShouldNotBeConsideredAsAString() { - assertScript '''import org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode as LUB - def bar = 1 - @ASTTest(phase=INSTRUCTION_SELECTION, value={ - assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE - assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type instanceof LUB - }) - def list = ["foo", "$bar"] + String base = '''import org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode as LUB + def bar = 1 ''' - shouldFailWithMessages '''import org.codehaus.groovy.ast.tools.WideningCategories.LowestUpperBoundClassNode as LUB - def bar = 1 - @ASTTest(phase=INSTRUCTION_SELECTION, value={ - assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE - assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type instanceof LUB - }) - List<String> list = ["foo", "$bar"] - ''', 'You are trying to use a GString' + assertScript base + ''' + @ASTTest(phase=INSTRUCTION_SELECTION, value={ + assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE + assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type instanceof LUB + }) + def list = ["foo", "$bar"] + ''' - shouldFailWithMessages ''' - def bar = 1 - @ASTTest(phase=INSTRUCTION_SELECTION, value={ - assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE - assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type == GSTRING_TYPE - }) - List<String> list = ["$bar"] // single element means no LUB - ''', 'You are trying to use a GString' + shouldFailWithMessages base + ''' + @ASTTest(phase=INSTRUCTION_SELECTION, value={ + assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE + assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type instanceof LUB + }) + List<String> list = ["foo", "$bar"] + ''', 'You are trying to use a GString in place of a String' + + shouldFailWithMessages base + ''' + @ASTTest(phase=INSTRUCTION_SELECTION, value={ + assert node.getNodeMetaData(INFERRED_TYPE) == LIST_TYPE + assert node.getNodeMetaData(INFERRED_TYPE).genericsTypes[0].type == GSTRING_TYPE // single element means no LUB + }) + List<String> list = ["$bar"] + ''', 'You are trying to use a GString in place of a String' + + shouldFailWithMessages base + ''' + void m(List<String> list) {} + m(["foo", "$bar"]) + ''', 'You are trying to use a GString in place of a String' + } + + // GROOVY-5559, GROOVY-10010 + void testGStringInMapShouldNotBeConsideredAsAString() { + String base = 'def bar = 123' + + shouldFailWithMessages base + ''' + Map<String,String> map = [x:"foo", y:"$bar"] + ''', 'You are trying to use a GString in place of a String' + + shouldFailWithMessages base + ''' + void m(Map<?,String> map) {} + m([x:"foo", y:"$bar"]) + ''', 'You are trying to use a GString in place of a String' + + shouldFailWithMessages base + ''' + void m(Map<?,String> map) {} + m(x:"foo", y:"$bar") + ''', 'You are trying to use a GString in place of a String' } // GROOVY-5559: related behaviour
