You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2019/08/13 15:21:50 UTC
[groovy] branch master updated: Allow chooseBestMethod to match "?
super T"
This is an automated email from the ASF dual-hosted git repository.
sunlan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new 62ab65a Allow chooseBestMethod to match "? super T"
62ab65a is described below
commit 62ab65a7fcc4a63e9d8fdf920fe20b81afaf7138
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Thu May 30 12:38:34 2019 -0500
Allow chooseBestMethod to match "? super T"
See comment in GROOVY-9074 for next step(s)
---
.../transform/stc/StaticTypeCheckingSupport.java | 22 +--
src/test/groovy/bugs/Groovy8609Bug.groovy | 14 +-
src/test/groovy/bugs/Groovy9074.groovy | 157 +++++++++++++++++++++
3 files changed, 175 insertions(+), 18 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
index ef043d5..84728cd 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -23,6 +23,7 @@ import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
@@ -50,6 +51,7 @@ import org.objectweb.asm.Opcodes;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -60,6 +62,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
+import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
@@ -102,7 +105,6 @@ import static org.codehaus.groovy.ast.ClassHelper.make;
import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.void_WRAPPER_TYPE;
-import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
import static org.codehaus.groovy.ast.tools.GenericsUtils.getSuperClass;
import static org.codehaus.groovy.runtime.DefaultGroovyMethods.asBoolean;
import static org.codehaus.groovy.syntax.Types.ASSIGN;
@@ -1186,16 +1188,14 @@ public abstract class StaticTypeCheckingSupport {
}
private static Parameter[] makeRawTypes(Parameter[] params, Map<GenericsType, GenericsType> genericsPlaceholderAndTypeMap) {
-
- Parameter[] newParam = new Parameter[params.length];
- for (int i = 0; i < params.length; i++) {
- Parameter oldP = params[i];
-
- ClassNode actualType = GenericsUtils.findActualTypeByGenericsPlaceholderName(oldP.getType().getUnresolvedName(), genericsPlaceholderAndTypeMap);
- Parameter newP = new Parameter(makeRawType(null == actualType ? oldP.getType() : actualType), oldP.getName());
- newParam[i] = newP;
- }
- return newParam;
+ return Arrays.stream(params).map(param -> {
+ String name = param.getType().getUnresolvedName();
+ Optional<GenericsType> value = genericsPlaceholderAndTypeMap.entrySet().stream()
+ .filter(e -> e.getKey().getName().equals(name)).findFirst().map(e -> e.getValue());
+ ClassNode type = value.map(GenericsType::getType).orElseGet(() -> makeRawType(param.getType()));
+
+ return new Parameter(type, param.getName());
+ }).toArray(Parameter[]::new);
}
private static ClassNode makeRawType(final ClassNode receiver) {
diff --git a/src/test/groovy/bugs/Groovy8609Bug.groovy b/src/test/groovy/bugs/Groovy8609Bug.groovy
index bfc021f..2ada73c 100644
--- a/src/test/groovy/bugs/Groovy8609Bug.groovy
+++ b/src/test/groovy/bugs/Groovy8609Bug.groovy
@@ -18,9 +18,11 @@
*/
package groovy.bugs
-import gls.CompilableTestSupport
+import groovy.transform.CompileStatic
+
+@CompileStatic
+final class Groovy8609Bug extends GroovyTestCase {
-class Groovy8609Bug extends CompilableTestSupport {
void testUpperBoundWithGenerics() {
assertScript '''
@groovy.transform.CompileStatic
@@ -96,7 +98,7 @@ class Groovy8609Bug extends CompilableTestSupport {
}
'''
- assert errMsg.contains('[Static type checking] - Cannot call A <ArrayList, HashMap>#getFirstRecord(T) with arguments [java.util.ArrayList <TreeMap>]')
+ assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList <TreeMap>)')
}
void testUpperBoundWithGenericsThroughWrongType2() {
@@ -117,8 +119,7 @@ class Groovy8609Bug extends CompilableTestSupport {
}
'''
- // TODO we should print generics details, e.g. [Static type checking] - Cannot call A <ArrayList, HashMap<String, Integer>>#getFirstRecord(T) with arguments [java.util.ArrayList <HashMap<String, Long>>]
- assert errMsg.contains('[Static type checking] - Cannot call A <ArrayList, HashMap>#getFirstRecord(T) with arguments [java.util.ArrayList <HashMap>]')
+ assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList <HashMap>)')
}
void testUpperBoundWithGenericsThroughWrongType3() {
@@ -139,7 +140,6 @@ class Groovy8609Bug extends CompilableTestSupport {
}
'''
- // TODO we should print generics details, e.g. [Static type checking] - Cannot call A <ArrayList, HashMap<String, Integer>>#getFirstRecord(T) with arguments [java.util.ArrayList <HashMap<StringBuffer, Integer>>]
- assert errMsg.contains('[Static type checking] - Cannot call A <ArrayList, HashMap>#getFirstRecord(T) with arguments [java.util.ArrayList <HashMap>]')
+ assert errMsg.contains('[Static type checking] - Cannot find matching method A#getFirstRecord(java.util.ArrayList <HashMap>)')
}
}
diff --git a/src/test/groovy/bugs/Groovy9074.groovy b/src/test/groovy/bugs/Groovy9074.groovy
new file mode 100644
index 0000000..b3ebf16
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy9074.groovy
@@ -0,0 +1,157 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package groovy.bugs
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.control.CompilationUnit
+
+import static org.codehaus.groovy.control.Phases.CLASS_GENERATION
+
+@CompileStatic
+final class Groovy9074 extends GroovyTestCase {
+
+ void _FIXME_testWildcardCapture() {
+ def err = shouldFail '''
+ @groovy.transform.CompileStatic
+ class Main {
+ private static Collection<?> c = new ArrayList<String>()
+ static main(args) {
+ c.add(new Object())
+ }
+ }
+ '''
+
+ // TODO: This is just a sample message; Java produces this for the equivalent code.
+ assert err =~ / The method add\(capture#1-of \?\) in the type Collection<capture#1-of \?> is not applicable for the arguments \(Object\)/
+ }
+
+ void _FIXME_testWildcardExtends() {
+ def err = shouldFail '''
+ import java.awt.Canvas
+ abstract class Shape {
+ abstract void draw(Canvas c)
+ }
+ class Circle extends Shape {
+ private int x, y, radius
+ @Override void draw(Canvas c) {}
+ }
+ class Rectangle extends Shape {
+ private int x, y, width, height
+ @Override void draw(Canvas c) {}
+ }
+
+ @groovy.transform.CompileStatic
+ void addRectangle(List<? extends Shape> shapes) {
+ shapes.add(0, new Rectangle()) // TODO: compile-time error!
+ }
+ '''
+
+ // TODO: This is just a sample message; Java produces this for the equivalent code.
+ assert err =~ / The method add(capture#1-of \?) in the type List<capture#1-of \?> is not applicable for the arguments \(Rectangle\)/
+ }
+
+ void testWildcardSuper() {
+ assertScript '''
+ import java.awt.Canvas
+ abstract class Shape {
+ abstract void draw(Canvas c)
+ }
+ class Circle extends Shape {
+ private int x, y, radius
+ @Override void draw(Canvas c) {}
+ }
+ class Rectangle extends Shape {
+ private int x, y, width, height
+ @Override void draw(Canvas c) {}
+ }
+
+ @groovy.transform.CompileStatic
+ void addRectangle(List<? super Shape> shapes) {
+ shapes.add(0, new Rectangle())
+ }
+
+ List<Shape> list = []
+ addRectangle(list)
+
+ assert list.size() == 1
+ assert list.get(0) instanceof Rectangle
+ '''
+ }
+
+ void testWildcardExtends2() {
+ new CompilationUnit().with {
+ addSource 'Main.groovy', '''
+ class Factory {
+ def <T> T make(Class<T> type, ... args) {}
+ }
+
+ @groovy.transform.CompileStatic
+ void test(Factory fact, Rule rule) {
+ Type bean = fact.make(rule.type)
+ }
+ '''
+
+ addSource 'Rule.groovy', '''
+ class Rule {
+ Class<? extends Type> getType() {
+ }
+ }
+ '''
+
+ addSource 'Type.groovy', '''
+ interface Type {
+ }
+ '''
+
+ compile CLASS_GENERATION
+ }
+ }
+
+ void _FIXME_testWildcardSuper2() {
+ new CompilationUnit().with {
+ addSource 'Main.groovy', '''
+ class Factory {
+ def <T> T make(Class<T> type, ... args) {}
+ }
+
+ @groovy.transform.CompileStatic
+ void test(Factory fact, Rule rule) {
+ Type bean = fact.make(rule.type) // can't assign "? super Type" to "Type"
+ }
+ '''
+
+ addSource 'Rule.groovy', '''
+ class Rule {
+ Class<? super Type> getType() {
+ }
+ }
+ '''
+
+ addSource 'Type.groovy', '''
+ interface Type {
+ }
+ '''
+
+ def err = shouldFail {
+ compile CLASS_GENERATION
+ }
+ assert err =~ "cannot convert from capture#1-of ? super Type to Type"
+ }
+ }
+}