You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/02/27 17:19:26 UTC
[groovy] branch master updated: checking generics of super used raw
type instead of parameterized type
This is an automated email from the ASF dual-hosted git repository.
emilles 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 b86f738 checking generics of super used raw type instead of parameterized type
b86f738 is described below
commit b86f738b3ac9e0e77e641f0b307fd51701ede430
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Feb 27 11:19:16 2021 -0600
checking generics of super used raw type instead of parameterized type
abstarct class A<X> {}
class C<Y> extends A<Y> {}
A<Z> a = new C<Z>() // was checking C<Z> compatible with A (raw)
---
.../java/org/codehaus/groovy/ast/GenericsType.java | 72 ++++++----------------
.../groovy/transform/stc/GenericsSTCTest.groovy | 11 ++--
2 files changed, 26 insertions(+), 57 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
index 64d1287..75ba049 100644
--- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
+++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
@@ -22,6 +22,7 @@ import org.codehaus.groovy.ast.tools.GenericsUtils;
import org.codehaus.groovy.ast.tools.WideningCategories;
import java.lang.reflect.Modifier;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
@@ -333,24 +334,31 @@ public class GenericsType extends ASTNode {
// class node are not parameterized. This means that we must create a
// new class node with the parameterized types that the current class node
// has defined.
- ClassNode node = GenericsUtils.parameterizeType(classNode, face);
- return compareGenericsWithBound(node, bound);
+ if (face.getGenericsTypes() != null) {
+ face = GenericsUtils.parameterizeType(classNode, face);
+ }
+ return compareGenericsWithBound(face, bound);
}
}
}
if (bound instanceof WideningCategories.LowestUpperBoundClassNode) {
// another special case here, where the bound is a "virtual" type
// we must then check the superclass and the interfaces
- boolean success = compareGenericsWithBound(classNode, bound.getSuperClass());
- if (success) {
- for (ClassNode face : bound.getInterfaces()) {
- success &= compareGenericsWithBound(classNode, face);
- if (!success) break;
- }
- if (success) return true;
+ if (compareGenericsWithBound(classNode, bound.getSuperClass())
+ && Arrays.stream(bound.getInterfaces()).allMatch(face -> compareGenericsWithBound(classNode, face))) {
+ return true;
}
}
- return compareGenericsWithBound(getParameterizedSuperClass(classNode), bound);
+ if (classNode.equals(ClassHelper.OBJECT_TYPE)) {
+ return false;
+ }
+ ClassNode superClass = classNode.getUnresolvedSuperClass();
+ if (superClass == null) {
+ superClass = ClassHelper.OBJECT_TYPE;
+ } else if (superClass.getGenericsTypes() != null) {
+ superClass = GenericsUtils.parameterizeType(classNode, superClass);
+ }
+ return compareGenericsWithBound(superClass, bound);
}
GenericsType[] cnTypes = classNode.getGenericsTypes();
@@ -358,7 +366,7 @@ public class GenericsType extends ASTNode {
cnTypes = classNode.redirect().getGenericsTypes();
}
if (cnTypes == null) {
- // may happen if generic type is Foo<T extends Foo> and classnode is Foo -> Foo
+ // may happen if generic type is Foo<T extends Foo> and ClassNode is Foo -> Foo
return true;
}
@@ -461,46 +469,6 @@ public class GenericsType extends ASTNode {
}
/**
- * If you have a class which extends a class using generics, returns the superclass with parameterized types. For
- * example, if you have:
- * <code>class MyList<T> extends LinkedList<T>
- * def list = new MyList<String>
- * </code>
- * then the parameterized superclass for MyList<String> is LinkedList<String>
- * @param classNode the class for which we want to return the parameterized superclass
- * @return the parameterized superclass
- */
- private static ClassNode getParameterizedSuperClass(final ClassNode classNode) {
- if (ClassHelper.OBJECT_TYPE.equals(classNode)) return null;
- ClassNode superClass = classNode.getUnresolvedSuperClass();
- if (superClass == null) return ClassHelper.OBJECT_TYPE;
-
- if (!classNode.isUsingGenerics() || !superClass.isUsingGenerics()) {
- return superClass;
- }
-
- GenericsType[] genericsTypes = classNode.getGenericsTypes();
- GenericsType[] redirectGenericTypes = classNode.redirect().getGenericsTypes();
- superClass = superClass.getPlainNodeReference();
- if (genericsTypes == null || redirectGenericTypes == null || superClass.getGenericsTypes() == null) {
- return superClass;
- }
- for (int i = 0, genericsTypesLength = genericsTypes.length; i < genericsTypesLength; i += 1) {
- if (redirectGenericTypes[i].isPlaceholder()) {
- GenericsType genericsType = genericsTypes[i];
- GenericsType[] superGenericTypes = superClass.getGenericsTypes();
- for (int j = 0, superGenericTypesLength = superGenericTypes.length; j < superGenericTypesLength; j += 1) {
- final GenericsType superGenericType = superGenericTypes[j];
- if (superGenericType.isPlaceholder() && superGenericType.getName().equals(redirectGenericTypes[i].getName())) {
- superGenericTypes[j] = genericsType;
- }
- }
- }
- }
- return superClass;
- }
-
- /**
* Represents GenericsType name
* TODO In order to distinguish GenericsType with same name(See GROOVY-8409), we should add a property to keep the declaring class.
*
@@ -513,7 +481,7 @@ public class GenericsType extends ASTNode {
* We should find a way to set declaring class for `GenericsType` first, it can be completed at the resolving phase.
*/
public static class GenericsTypeName {
- private String name;
+ private final String name;
public GenericsTypeName(final String name) {
this.name = Objects.requireNonNull(name);
diff --git a/src/test/groovy/transform/stc/GenericsSTCTest.groovy b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
index d840fe3..12b5e70 100644
--- a/src/test/groovy/transform/stc/GenericsSTCTest.groovy
+++ b/src/test/groovy/transform/stc/GenericsSTCTest.groovy
@@ -311,16 +311,16 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
@NotYetImplemented
void testDiamondInferrenceFromConstructor9() {
assertScript '''
+ abstract class A<X> { }
@groovy.transform.TupleConstructor
- class C<T> {
+ class C<T> extends A<T> {
T p
}
interface I { }
class D implements I { }
- class E extends C<I> { }
void test() {
- E e = new C<>(new D())
+ A<I> ai = new C<>(new D())
}
test()
'''
@@ -941,8 +941,9 @@ class GenericsSTCTest extends StaticTypeCheckingTestCase {
// GROOVY-5528
void testAssignmentToInterfaceFromUserClassWithGenerics() {
- assertScript '''class UserList<T> extends LinkedList<T> {}
- List<String> list = new UserList<String>()
+ assertScript '''
+ class UserList<T> extends LinkedList<T> {}
+ List<String> list = new UserList<String>()
'''
}