Repository: groovy
Updated Branches:
refs/heads/master 680317fc2 -> f8d4f1bec
GenericType name should use custom type rather than `String`(prepare to fix
GROOVY-8409)
e.g. The content of resolvedPlaceholders is:
{R=T, T=java.util.Date, U=java.net.URL}
the `T` of `R=T` is defined by user,
but the `T` of `T=java.util.Date` is defined in `BiFunction`.
As a result, R -> T -> Date
See the comment of GROOVY-8409, which is not resolved yet.
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/f8d4f1be
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/f8d4f1be
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/f8d4f1be
Branch: refs/heads/master
Commit: f8d4f1bec1dc8cd079e3db97bb2297ae448950af
Parents: 680317f
Author: Daniel Sun <[email protected]>
Authored: Sat Aug 18 20:31:02 2018 +0800
Committer: Daniel Sun <[email protected]>
Committed: Sat Aug 18 20:31:02 2018 +0800
----------------------------------------------------------------------
.../org/codehaus/groovy/ast/GenericsType.java | 46 ++++++--
.../groovy/ast/tools/GenericsUtils.java | 9 +-
.../groovy/ast/tools/WideningCategories.java | 8 +-
.../codehaus/groovy/control/ResolveVisitor.java | 30 ++---
.../stc/StaticTypeCheckingSupport.java | 110 +++++++++----------
.../stc/StaticTypeCheckingVisitor.java | 58 +++++-----
.../codehaus/groovy/ast/GenericsTypeTest.groovy | 16 +--
7 files changed, 153 insertions(+), 124 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/ast/GenericsType.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
index 57d4919..33d0b72 100644
--- a/src/main/java/org/codehaus/groovy/ast/GenericsType.java
+++ b/src/main/java/org/codehaus/groovy/ast/GenericsType.java
@@ -24,6 +24,7 @@ import org.codehaus.groovy.ast.tools.WideningCategories;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import static org.codehaus.groovy.ast.ClassHelper.GROOVY_OBJECT_TYPE;
@@ -371,18 +372,18 @@ public class GenericsType extends ASTNode {
return true;
}
GenericsType[] redirectBoundGenericTypes =
bound.redirect().getGenericsTypes();
- Map<String, GenericsType> classNodePlaceholders =
GenericsUtils.extractPlaceholders(classNode);
- Map<String, GenericsType> boundPlaceHolders =
GenericsUtils.extractPlaceholders(bound);
+ Map<GenericsType.GenericsTypeName, GenericsType>
classNodePlaceholders = GenericsUtils.extractPlaceholders(classNode);
+ Map<GenericsType.GenericsTypeName, GenericsType> boundPlaceHolders
= GenericsUtils.extractPlaceholders(bound);
boolean match = true;
for (int i = 0; redirectBoundGenericTypes!=null && i <
redirectBoundGenericTypes.length && match; i++) {
GenericsType redirectBoundType = redirectBoundGenericTypes[i];
GenericsType classNodeType = cnTypes[i];
if (classNodeType.isPlaceholder()) {
- String name = classNodeType.getName();
+ GenericsTypeName name = new
GenericsTypeName(classNodeType.getName());
if (redirectBoundType.isPlaceholder()) {
- match = name.equals(redirectBoundType.getName());
+ match = name.equals(new
GenericsTypeName(redirectBoundType.getName()));
if (!match) {
- GenericsType genericsType =
boundPlaceHolders.get(redirectBoundType.getName());
+ GenericsType genericsType =
boundPlaceHolders.get(new GenericsTypeName(redirectBoundType.getName()));
match = false;
if (genericsType!=null) {
if (genericsType.isPlaceholder()) {
@@ -408,7 +409,7 @@ public class GenericsType extends ASTNode {
if (classNodeType.isPlaceholder()) {
match =
classNodeType.getName().equals(redirectBoundType.getName());
} else {
- String name = redirectBoundType.getName();
+ GenericsTypeName name = new
GenericsTypeName(redirectBoundType.getName());
if (boundPlaceHolders.containsKey(name)) {
redirectBoundType =
boundPlaceHolders.get(name);
boolean wildcard =
redirectBoundType.isWildcard();
@@ -423,8 +424,8 @@ public class GenericsType extends ASTNode {
if (gt.isPlaceholder()) {
// check for recursive generic
typedef, like in
// <T extends Comparable<?
super T>>
- if
(classNodePlaceholders.containsKey(gt.getName())) {
- gt =
classNodePlaceholders.get(gt.getName());
+ if
(classNodePlaceholders.containsKey(new GenericsTypeName(gt.getName()))) {
+ gt =
classNodePlaceholders.get(new GenericsTypeName(gt.getName()));
}
}
match =
implementsInterfaceOrIsSubclassOf(gt.getType(), classNodeType.getType());
@@ -435,8 +436,8 @@ public class GenericsType extends ASTNode {
if (gt.isPlaceholder()) {
// check for recursive
generic typedef, like in
// <T extends Comparable<?
super T>>
- if
(classNodePlaceholders.containsKey(gt.getName())) {
- gt =
classNodePlaceholders.get(gt.getName());
+ if
(classNodePlaceholders.containsKey(new GenericsTypeName(gt.getName()))) {
+ gt =
classNodePlaceholders.get(new GenericsTypeName(gt.getName()));
}
}
match =
implementsInterfaceOrIsSubclassOf(classNodeType.getType(), gt.getType())
@@ -497,4 +498,29 @@ public class GenericsType extends ASTNode {
}
return superClass;
}
+
+ public static class GenericsTypeName {
+ private String name;
+
+ public GenericsTypeName(String name) {
+ this.name = name;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ GenericsTypeName that = (GenericsTypeName) o;
+ return Objects.equals(name, that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(name);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
index 188ce59..06c8d84 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GenericsUtils.java
@@ -54,6 +54,7 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
+import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.getCorrectedClassNode;
import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf;
@@ -140,8 +141,8 @@ public class GenericsUtils {
return gt;
}
- public static Map<String, GenericsType> extractPlaceholders(ClassNode cn) {
- Map<String, GenericsType> ret = new HashMap<String, GenericsType>();
+ public static Map<GenericsTypeName, GenericsType>
extractPlaceholders(ClassNode cn) {
+ Map<GenericsTypeName, GenericsType> ret = new
HashMap<GenericsTypeName, GenericsType>();
extractPlaceholders(cn, ret);
return ret;
}
@@ -153,7 +154,7 @@ public class GenericsUtils {
* @param node the class node to check
* @param map the generics type information collector
*/
- public static void extractPlaceholders(ClassNode node, Map<String,
GenericsType> map) {
+ public static void extractPlaceholders(ClassNode node,
Map<GenericsTypeName, GenericsType> map) {
if (node == null) return;
if (node.isArray()) {
@@ -179,7 +180,7 @@ public class GenericsUtils {
for (int i = 0; i < redirectGenericsTypes.length; i++) {
GenericsType redirectType = redirectGenericsTypes[i];
if (redirectType.isPlaceholder()) {
- String name = redirectType.getName();
+ GenericsTypeName name = new
GenericsTypeName(redirectType.getName());
if (!map.containsKey(name)) {
GenericsType value = parameterized[i];
map.put(name, value);
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
----------------------------------------------------------------------
diff --git
a/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
b/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
index 3f6efbb..68b67b3 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/WideningCategories.java
@@ -52,7 +52,7 @@ import static
org.codehaus.groovy.ast.ClassHelper.isNumberType;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
import static org.codehaus.groovy.ast.ClassHelper.long_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.short_TYPE;
-
+import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
/**
* This class provides helper methods to determine the type from a widening
* operation for example for a plus operation.
@@ -303,14 +303,14 @@ public class WideningCategories {
ClassNode superClass = source.getUnresolvedSuperClass();
// copy generic type information if available
if (superClass!=null && superClass.isUsingGenerics()) {
- Map<String, GenericsType> genericsTypeMap =
GenericsUtils.extractPlaceholders(source);
+ Map<GenericsTypeName, GenericsType> genericsTypeMap =
GenericsUtils.extractPlaceholders(source);
GenericsType[] genericsTypes = superClass.getGenericsTypes();
if (genericsTypes!=null) {
GenericsType[] copyTypes = new
GenericsType[genericsTypes.length];
for (int i = 0; i < genericsTypes.length; i++) {
GenericsType genericsType = genericsTypes[i];
- if (genericsType.isPlaceholder() &&
genericsTypeMap.containsKey(genericsType.getName())) {
- copyTypes[i] =
genericsTypeMap.get(genericsType.getName());
+ if (genericsType.isPlaceholder() &&
genericsTypeMap.containsKey(new GenericsTypeName(genericsType.getName()))) {
+ copyTypes[i] = genericsTypeMap.get(new
GenericsTypeName(genericsType.getName()));
} else {
copyTypes[i] = genericsType;
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index 3950745..b51aff3 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -77,9 +77,9 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName;
import static org.codehaus.groovy.ast.tools.GeneralUtils.inSamePackage;
import static org.codehaus.groovy.ast.tools.GeneralUtils.isDefaultVisibility;
-
/**
* Visitor to resolve Types and convert VariableExpression to
* ClassExpressions if needed. The ResolveVisitor will try to
@@ -106,7 +106,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
private boolean inPropertyExpression = false;
private boolean inClosure = false;
- private Map<String, GenericsType> genericParameterNames = new
HashMap<String, GenericsType>();
+ private Map<GenericsTypeName, GenericsType> genericParameterNames = new
HashMap<GenericsTypeName, GenericsType>();
private final Set<FieldNode> fieldTypesChecked = new HashSet<FieldNode>();
private boolean checkingVariableTypeInDeclaration = false;
private ImportNode currImportNode = null;
@@ -228,10 +228,10 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
protected void visitConstructorOrMethod(MethodNode node, boolean
isConstructor) {
VariableScope oldScope = currentScope;
currentScope = node.getVariableScope();
- Map<String, GenericsType> oldPNames = genericParameterNames;
+ Map<GenericsTypeName, GenericsType> oldPNames = genericParameterNames;
genericParameterNames = node.isStatic()
- ? new HashMap<String, GenericsType>()
- : new HashMap<String, GenericsType>(genericParameterNames);
+ ? new HashMap<GenericsTypeName, GenericsType>()
+ : new HashMap<GenericsTypeName,
GenericsType>(genericParameterNames);
resolveGenericsHeader(node.getGenericsTypes());
@@ -265,9 +265,9 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
}
public void visitProperty(PropertyNode node) {
- Map<String, GenericsType> oldPNames = genericParameterNames;
+ Map<GenericsTypeName, GenericsType> oldPNames = genericParameterNames;
if (node.isStatic()) {
- genericParameterNames = new HashMap<String, GenericsType>();
+ genericParameterNames = new HashMap<GenericsTypeName,
GenericsType>();
}
ClassNode t = node.getType();
@@ -372,7 +372,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
String typeName = type.getName();
- GenericsType genericsType = genericParameterNames.get(typeName);
+ GenericsType genericsType = genericParameterNames.get(new
GenericsTypeName(typeName));
if (genericsType != null) {
type.setRedirect(genericsType.getType());
type.setGenericsTypes(new GenericsType[]{ genericsType });
@@ -1332,7 +1332,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
if (node instanceof InnerClassNode) {
if (Modifier.isStatic(node.getModifiers())) {
- genericParameterNames = new HashMap<String, GenericsType>();
+ genericParameterNames = new HashMap<GenericsTypeName,
GenericsType>();
}
InnerClassNode innerClassNode = (InnerClassNode) node;
@@ -1343,7 +1343,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
}
}
} else {
- genericParameterNames = new HashMap<String, GenericsType>();
+ genericParameterNames = new HashMap<GenericsTypeName,
GenericsType>();
}
resolveGenericsHeader(node.getGenericsTypes());
@@ -1488,7 +1488,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
String name = type.getName();
ClassNode[] bounds = type.getUpperBounds();
boolean isWild = QUESTION_MARK.equals(name);
- boolean toDealWithGenerics = 0 == level || (level > 0 && null !=
genericParameterNames.get(name));
+ boolean toDealWithGenerics = 0 == level || (level > 0 && null !=
genericParameterNames.get(new GenericsTypeName(name)));
if (bounds != null) {
boolean nameAdded = false;
@@ -1496,7 +1496,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
if (!isWild) {
if (!nameAdded && upperBound != null ||
!resolve(classNode)) {
if (toDealWithGenerics) {
- genericParameterNames.put(name, type);
+ genericParameterNames.put(new
GenericsTypeName(name), type);
type.setPlaceholder(true);
classNode.setRedirect(upperBound);
nameAdded = true;
@@ -1513,8 +1513,8 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
} else {
if (!isWild) {
if (toDealWithGenerics) {
- GenericsType originalGt =
genericParameterNames.get(name);
- genericParameterNames.put(name, type);
+ GenericsType originalGt =
genericParameterNames.get(new GenericsTypeName(name));
+ genericParameterNames.put(new GenericsTypeName(name),
type);
type.setPlaceholder(true);
if (null == originalGt) {
@@ -1545,7 +1545,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
currentClass.setUsingGenerics(true);
ClassNode type = genericsType.getType();
// save name before redirect
- String name = type.getName();
+ GenericsTypeName name = new GenericsTypeName(type.getName());
ClassNode[] bounds = genericsType.getUpperBounds();
if (!genericParameterNames.containsKey(name)) {
if (bounds != null) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
----------------------------------------------------------------------
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 a195ed7..56f64e3 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -108,6 +108,7 @@ 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.syntax.Types.ASSIGN;
import static org.codehaus.groovy.syntax.Types.BITWISE_AND;
@@ -155,7 +156,6 @@ import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT;
import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_EQUAL;
import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED;
import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED_EQUAL;
-
/**
* Static support methods for {@link StaticTypeCheckingVisitor}.
*/
@@ -1301,8 +1301,8 @@ public abstract class StaticTypeCheckingSupport {
* @return the parameterized arguments
*/
public static Parameter[] parameterizeArguments(final ClassNode receiver,
final MethodNode m) {
- Map<String, GenericsType> genericFromReceiver =
GenericsUtils.extractPlaceholders(receiver);
- Map<String, GenericsType> contextPlaceholders =
extractGenericsParameterMapOfThis(m);
+ Map<GenericsTypeName, GenericsType> genericFromReceiver =
GenericsUtils.extractPlaceholders(receiver);
+ Map<GenericsTypeName, GenericsType> contextPlaceholders =
extractGenericsParameterMapOfThis(m);
Parameter[] methodParameters = m.getParameters();
Parameter[] params = new Parameter[methodParameters.length];
for (int i = 0; i < methodParameters.length; i++) {
@@ -1322,7 +1322,7 @@ public abstract class StaticTypeCheckingSupport {
* @param paramType the (unresolved) type of the method
parameter
* @return a new parameter with the same name and type as the original
one, but with resolved generic types
*/
- private static Parameter buildParameter(final Map<String, GenericsType>
genericFromReceiver, final Map<String, GenericsType> placeholdersFromContext,
final Parameter methodParameter, final ClassNode paramType) {
+ private static Parameter buildParameter(final Map<GenericsTypeName,
GenericsType> genericFromReceiver, final Map<GenericsTypeName, GenericsType>
placeholdersFromContext, final Parameter methodParameter, final ClassNode
paramType) {
if (genericFromReceiver.isEmpty() && (placeholdersFromContext == null
|| placeholdersFromContext.isEmpty())) {
return methodParameter;
}
@@ -1355,8 +1355,8 @@ public abstract class StaticTypeCheckingSupport {
* Given a generics type representing SomeClass<T,V> and a resolved
placeholder map, returns a new generics type
* for which placeholders are resolved recursively.
*/
- protected static GenericsType fullyResolve(GenericsType gt, Map<String,
GenericsType> placeholders) {
- GenericsType fromMap = placeholders.get(gt.getName());
+ protected static GenericsType fullyResolve(GenericsType gt,
Map<GenericsTypeName, GenericsType> placeholders) {
+ GenericsType fromMap = placeholders.get(new
GenericsTypeName(gt.getName()));
if (gt.isPlaceholder() && fromMap != null) {
gt = fromMap;
}
@@ -1378,15 +1378,15 @@ public abstract class StaticTypeCheckingSupport {
return genericsType;
}
- protected static ClassNode fullyResolveType(final ClassNode type, final
Map<String, GenericsType> placeholders) {
+ protected static ClassNode fullyResolveType(final ClassNode type, final
Map<GenericsTypeName, GenericsType> placeholders) {
if (type.isUsingGenerics() && !type.isGenericsPlaceHolder()) {
GenericsType[] gts = type.getGenericsTypes();
if (gts != null) {
GenericsType[] copy = new GenericsType[gts.length];
for (int i = 0; i < gts.length; i++) {
GenericsType genericsType = gts[i];
- if (genericsType.isPlaceholder() &&
placeholders.containsKey(genericsType.getName())) {
- copy[i] = placeholders.get(genericsType.getName());
+ if (genericsType.isPlaceholder() &&
placeholders.containsKey(new GenericsTypeName(genericsType.getName()))) {
+ copy[i] = placeholders.get(new
GenericsTypeName(genericsType.getName()));
} else {
copy[i] = fullyResolve(genericsType, placeholders);
}
@@ -1398,7 +1398,7 @@ public abstract class StaticTypeCheckingSupport {
return result;
} else if (type.isUsingGenerics() && OBJECT_TYPE.equals(type) &&
type.getGenericsTypes() != null) {
// Object<T>
- GenericsType genericsType =
placeholders.get(type.getGenericsTypes()[0].getName());
+ GenericsType genericsType = placeholders.get(new
GenericsTypeName(type.getGenericsTypes()[0].getName()));
if (genericsType != null) {
return genericsType.getType();
}
@@ -1450,7 +1450,7 @@ public abstract class StaticTypeCheckingSupport {
return true;
}
- static void addMethodLevelDeclaredGenerics(MethodNode method, Map<String,
GenericsType> resolvedPlaceholders) {
+ static void addMethodLevelDeclaredGenerics(MethodNode method,
Map<GenericsTypeName, GenericsType> resolvedPlaceholders) {
ClassNode dummy = OBJECT_TYPE.getPlainNodeReference();
dummy.setGenericsTypes(method.getGenericsTypes());
GenericsUtils.extractPlaceholders(dummy, resolvedPlaceholders);
@@ -1492,7 +1492,7 @@ public abstract class StaticTypeCheckingSupport {
boolean skipBecauseOfInnerClassNotReceiver = isOuterClassOf(receiver,
candidateMethod.getDeclaringClass());
Parameter[] parameters = candidateMethod.getParameters();
- Map<String, GenericsType> classGTs;
+ Map<GenericsTypeName, GenericsType> classGTs;
if (skipBecauseOfInnerClassNotReceiver) {
classGTs = Collections.EMPTY_MAP;
} else {
@@ -1508,12 +1508,12 @@ public abstract class StaticTypeCheckingSupport {
// There is firstly the context given through the class, and the
method.
// The method context may hide generics given through the class, but
use
// the non-hidden ones.
- Map<String, GenericsType> resolvedMethodGenerics = new HashMap<String,
GenericsType>();
+ Map<GenericsTypeName, GenericsType> resolvedMethodGenerics = new
HashMap<GenericsTypeName, GenericsType>();
if (!skipBecauseOfInnerClassNotReceiver) {
addMethodLevelDeclaredGenerics(candidateMethod,
resolvedMethodGenerics);
}
// so first we remove hidden generics
- for (String key : resolvedMethodGenerics.keySet())
classGTs.remove(key);
+ for (GenericsTypeName key : resolvedMethodGenerics.keySet())
classGTs.remove(key);
// then we use the remaining information to refine the given generics
applyGenericsConnections(classGTs, resolvedMethodGenerics);
// and then start our checks with the receiver
@@ -1525,7 +1525,7 @@ public abstract class StaticTypeCheckingSupport {
// extension methods are special, since they set the receiver as
// first parameter. While we normally allow generalization for the
first
// parameter, in case of an extension method we must not.
- Set<String> fixedGenericsPlaceHolders =
extractResolvedPlaceHolders(resolvedMethodGenerics);
+ Set<GenericsTypeName> fixedGenericsPlaceHolders =
extractResolvedPlaceHolders(resolvedMethodGenerics);
for (int i = 0; i < arguments.length; i++) {
int pindex = min(i, parameters.length - 1);
@@ -1546,10 +1546,10 @@ public abstract class StaticTypeCheckingSupport {
return true;
}
- private static Set<String> extractResolvedPlaceHolders(Map<String,
GenericsType> resolvedMethodGenerics) {
+ private static Set<GenericsTypeName>
extractResolvedPlaceHolders(Map<GenericsTypeName, GenericsType>
resolvedMethodGenerics) {
if (resolvedMethodGenerics.isEmpty()) return Collections.EMPTY_SET;
- Set<String> result = new HashSet<String>();
- for (Entry<String, GenericsType> entry :
resolvedMethodGenerics.entrySet()) {
+ Set<GenericsTypeName> result = new HashSet<GenericsTypeName>();
+ for (Entry<GenericsTypeName, GenericsType> entry :
resolvedMethodGenerics.entrySet()) {
GenericsType value = entry.getValue();
if (value.isPlaceholder()) continue;
result.add(entry.getKey());
@@ -1557,8 +1557,8 @@ public abstract class StaticTypeCheckingSupport {
return result;
}
- private static boolean inferenceCheck(Set<String>
fixedGenericsPlaceHolders, Map<String, GenericsType> resolvedMethodGenerics,
ClassNode type, ClassNode wrappedArgument, boolean lastArg) {
- Map<String, GenericsType> connections = new HashMap<String,
GenericsType>();
+ private static boolean inferenceCheck(Set<GenericsTypeName>
fixedGenericsPlaceHolders, Map<GenericsTypeName, GenericsType>
resolvedMethodGenerics, ClassNode type, ClassNode wrappedArgument, boolean
lastArg) {
+ Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
if (isPrimitiveType(wrappedArgument)) wrappedArgument =
getWrapper(wrappedArgument);
// the context we compare with in the end is the one of the callsite
// so far we specified the context of the method declaration only
@@ -1593,8 +1593,8 @@ public abstract class StaticTypeCheckingSupport {
return gt;
}
- private static boolean compatibleConnections(Map<String, GenericsType>
connections, Map<String, GenericsType> resolvedMethodGenerics, Set<String>
fixedGenericsPlaceHolders) {
- for (Entry<String, GenericsType> entry : connections.entrySet()) {
+ private static boolean compatibleConnections(Map<GenericsTypeName,
GenericsType> connections, Map<GenericsTypeName, GenericsType>
resolvedMethodGenerics, Set<GenericsTypeName> fixedGenericsPlaceHolders) {
+ for (Entry<GenericsTypeName, GenericsType> entry :
connections.entrySet()) {
GenericsType resolved = resolvedMethodGenerics.get(entry.getKey());
if (resolved == null) continue;
GenericsType connection = entry.getValue();
@@ -1640,8 +1640,8 @@ public abstract class StaticTypeCheckingSupport {
return gt.isCompatibleWith(compareNode);
}
- private static void addMissingEntries(Map<String, GenericsType>
connections, Map<String, GenericsType> resolved) {
- for (Entry<String, GenericsType> entry : connections.entrySet()) {
+ private static void addMissingEntries(Map<GenericsTypeName, GenericsType>
connections, Map<GenericsTypeName, GenericsType> resolved) {
+ for (Entry<GenericsTypeName, GenericsType> entry :
connections.entrySet()) {
if (resolved.containsKey(entry.getKey())) continue;
GenericsType gt = entry.getValue();
ClassNode cn = gt.getType();
@@ -1650,12 +1650,12 @@ public abstract class StaticTypeCheckingSupport {
}
}
- public static ClassNode resolveClassNodeGenerics(Map<String, GenericsType>
resolvedPlaceholders, final Map<String, GenericsType> placeholdersFromContext,
ClassNode currentType) {
+ public static ClassNode resolveClassNodeGenerics(Map<GenericsTypeName,
GenericsType> resolvedPlaceholders, final Map<GenericsTypeName, GenericsType>
placeholdersFromContext, ClassNode currentType) {
ClassNode target = currentType.redirect();
- resolvedPlaceholders = new HashMap<String,
GenericsType>(resolvedPlaceholders);
+ resolvedPlaceholders = new HashMap<GenericsTypeName,
GenericsType>(resolvedPlaceholders);
applyContextGenerics(resolvedPlaceholders, placeholdersFromContext);
- Map<String, GenericsType> connections = new HashMap<String,
GenericsType>();
+ Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
extractGenericsConnections(connections, currentType, target);
applyGenericsConnections(connections, resolvedPlaceholders);
currentType = applyGenericsContext(resolvedPlaceholders, currentType);
@@ -1663,16 +1663,16 @@ public abstract class StaticTypeCheckingSupport {
}
static void applyGenericsConnections(
- Map<String, GenericsType> connections,
- Map<String, GenericsType> resolvedPlaceholders
+ Map<GenericsTypeName, GenericsType> connections,
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders
) {
if (connections == null) return;
int count = 0;
while (count < 10000) {
count++;
boolean checkForMorePlaceHolders = false;
- for (Entry<String, GenericsType> entry :
resolvedPlaceholders.entrySet()) {
- String name = entry.getKey();
+ for (Entry<GenericsTypeName, GenericsType> entry :
resolvedPlaceholders.entrySet()) {
+ GenericsTypeName name = entry.getKey();
GenericsType replacement = connections.get(name);
if (replacement == null) {
GenericsType value = entry.getValue();
@@ -1687,7 +1687,7 @@ public abstract class StaticTypeCheckingSupport {
}
boolean placeholderReplacement = replacement.isPlaceholder();
if (placeholderReplacement) {
- GenericsType connectedType =
resolvedPlaceholders.get(replacement.getName());
+ GenericsType connectedType = resolvedPlaceholders.get(new
GenericsTypeName(replacement.getName()));
if (replacement == connectedType) continue;
}
// GROOVY-6787: Don't override the original if the replacement
placeholder doesn't respect the bounds,
@@ -1777,7 +1777,7 @@ public abstract class StaticTypeCheckingSupport {
* to get E=Integer, since IntRange is an AbstractList<Integer>)
* Should the target not have any generics this method does nothing.
*/
- static void extractGenericsConnections(Map<String, GenericsType>
connections, ClassNode type, ClassNode target) {
+ static void extractGenericsConnections(Map<GenericsTypeName, GenericsType>
connections, ClassNode type, ClassNode target) {
if (target == null || type == target ||
!isUsingGenericsOrIsArrayUsingGenerics(target)) return;
if (type == null || type == UNKNOWN_PARAMETER_TYPE) return;
if (type.isArray() && target.isArray()) {
@@ -1785,7 +1785,7 @@ public abstract class StaticTypeCheckingSupport {
} else if (target.isGenericsPlaceHolder() || type.equals(target) ||
!implementsInterfaceOrIsSubclassOf(type, target)) {
// structural match route
if (target.isGenericsPlaceHolder()) {
- connections.put(target.getGenericsTypes()[0].getName(), new
GenericsType(type));
+ connections.put(new
GenericsTypeName(target.getGenericsTypes()[0].getName()), new
GenericsType(type));
} else {
extractGenericsConnections(connections,
type.getGenericsTypes(), target.getGenericsTypes());
}
@@ -1813,7 +1813,7 @@ public abstract class StaticTypeCheckingSupport {
return corrected;
}
- private static void extractGenericsConnections(Map<String, GenericsType>
connections, GenericsType[] usage, GenericsType[] declaration) {
+ private static void extractGenericsConnections(Map<GenericsTypeName,
GenericsType> connections, GenericsType[] usage, GenericsType[] declaration) {
// if declaration does not provide generics, there is no connection to
make
if (usage == null || declaration == null || declaration.length == 0)
return;
if (usage.length != declaration.length) return;
@@ -1823,7 +1823,7 @@ public abstract class StaticTypeCheckingSupport {
GenericsType ui = usage[i];
GenericsType di = declaration[i];
if (di.isPlaceholder()) {
- connections.put(di.getName(), ui);
+ connections.put(new GenericsTypeName(di.getName()), ui);
} else if (di.isWildcard()) {
if (ui.isWildcard()) {
extractGenericsConnections(connections,
ui.getLowerBound(), di.getLowerBound());
@@ -1844,7 +1844,7 @@ public abstract class StaticTypeCheckingSupport {
}
}
- private static void extractGenericsConnections(Map<String, GenericsType>
connections, ClassNode[] usage, ClassNode[] declaration) {
+ private static void extractGenericsConnections(Map<GenericsTypeName,
GenericsType> connections, ClassNode[] usage, ClassNode[] declaration) {
if (usage == null || declaration == null || declaration.length == 0)
return;
// both have generics
for (int i = 0; i < usage.length; i++) {
@@ -1853,7 +1853,7 @@ public abstract class StaticTypeCheckingSupport {
if (di.isGenericsPlaceHolder()) {
GenericsType gt = new GenericsType(di);
gt.setPlaceholder(di.isGenericsPlaceHolder());
- connections.put(di.getGenericsTypes()[0].getName(), gt);
+ connections.put(new
GenericsTypeName(di.getGenericsTypes()[0].getName()), gt);
} else if (di.isUsingGenerics()) {
extractGenericsConnections(connections, ui.getGenericsTypes(),
di.getGenericsTypes());
}
@@ -1865,8 +1865,8 @@ public abstract class StaticTypeCheckingSupport {
return type.getGenericsTypes();
}
- static Map<String, GenericsType> applyGenericsContextToParameterClass(
- Map<String, GenericsType> spec, ClassNode parameterUsage
+ static Map<GenericsTypeName, GenericsType>
applyGenericsContextToParameterClass(
+ Map<GenericsTypeName, GenericsType> spec, ClassNode parameterUsage
) {
GenericsType[] gts = parameterUsage.getGenericsTypes();
if (gts == null) return Collections.EMPTY_MAP;
@@ -1878,7 +1878,7 @@ public abstract class StaticTypeCheckingSupport {
}
private static GenericsType[] applyGenericsContext(
- Map<String, GenericsType> spec, GenericsType[] gts
+ Map<GenericsTypeName, GenericsType> spec, GenericsType[] gts
) {
if (gts == null) return null;
GenericsType[] newGTs = new GenericsType[gts.length];
@@ -1889,9 +1889,9 @@ public abstract class StaticTypeCheckingSupport {
return newGTs;
}
- private static GenericsType applyGenericsContext(Map<String, GenericsType>
spec, GenericsType gt) {
+ private static GenericsType applyGenericsContext(Map<GenericsTypeName,
GenericsType> spec, GenericsType gt) {
if (gt.isPlaceholder()) {
- String name = gt.getName();
+ GenericsTypeName name = new GenericsTypeName(gt.getName());
GenericsType specType = spec.get(name);
if (specType != null) return specType;
if (hasNonTrivialBounds(gt)) {
@@ -1924,7 +1924,7 @@ public abstract class StaticTypeCheckingSupport {
}
private static ClassNode[] applyGenericsContext(
- Map<String, GenericsType> spec, ClassNode[] bounds
+ Map<GenericsTypeName, GenericsType> spec, ClassNode[] bounds
) {
if (bounds == null) return null;
ClassNode[] newBounds = new ClassNode[bounds.length];
@@ -1935,7 +1935,7 @@ public abstract class StaticTypeCheckingSupport {
}
static ClassNode applyGenericsContext(
- Map<String, GenericsType> spec, ClassNode bound
+ Map<GenericsTypeName, GenericsType> spec, ClassNode bound
) {
if (bound == null) return null;
if (bound.isArray()) {
@@ -1972,12 +1972,12 @@ public abstract class StaticTypeCheckingSupport {
return genericsType.getType();
}
- private static void applyContextGenerics(Map<String, GenericsType>
resolvedPlaceholders, Map<String, GenericsType> placeholdersFromContext) {
+ private static void applyContextGenerics(Map<GenericsTypeName,
GenericsType> resolvedPlaceholders, Map<GenericsTypeName, GenericsType>
placeholdersFromContext) {
if (placeholdersFromContext == null) return;
- for (Entry<String, GenericsType> entry :
resolvedPlaceholders.entrySet()) {
+ for (Entry<GenericsTypeName, GenericsType> entry :
resolvedPlaceholders.entrySet()) {
GenericsType gt = entry.getValue();
if (gt.isPlaceholder()) {
- String name = gt.getName();
+ GenericsTypeName name = new GenericsTypeName(gt.getName());
GenericsType outer = placeholdersFromContext.get(name);
if (outer == null) continue;
entry.setValue(outer);
@@ -1985,9 +1985,9 @@ public abstract class StaticTypeCheckingSupport {
}
}
- private static Map<String, GenericsType>
getGenericsParameterMapOfThis(ClassNode cn) {
+ private static Map<GenericsTypeName, GenericsType>
getGenericsParameterMapOfThis(ClassNode cn) {
if (cn == null) return null;
- Map<String, GenericsType> map = null;
+ Map<GenericsTypeName, GenericsType> map = null;
if (cn.getEnclosingMethod() != null) {
map = extractGenericsParameterMapOfThis(cn.getEnclosingMethod());
} else if (cn.getOuterClass() != null) {
@@ -2045,10 +2045,10 @@ public abstract class StaticTypeCheckingSupport {
return false;
}
- static Map<String, GenericsType>
extractGenericsParameterMapOfThis(MethodNode mn) {
+ static Map<GenericsTypeName, GenericsType>
extractGenericsParameterMapOfThis(MethodNode mn) {
if (mn == null) return null;
- Map<String, GenericsType> map;
+ Map<GenericsTypeName, GenericsType> map;
if (mn.isStatic()) {
map = new HashMap<>();
} else {
@@ -2058,12 +2058,12 @@ public abstract class StaticTypeCheckingSupport {
return mergeGenerics(map, mn.getGenericsTypes());
}
- private static Map<String, GenericsType> mergeGenerics(Map<String,
GenericsType> current, GenericsType[] newGenerics) {
+ private static Map<GenericsTypeName, GenericsType>
mergeGenerics(Map<GenericsTypeName, GenericsType> current, GenericsType[]
newGenerics) {
if (newGenerics == null || newGenerics.length == 0) return current;
- if (current == null) current = new HashMap<String, GenericsType>();
+ if (current == null) current = new HashMap<GenericsTypeName,
GenericsType>();
for (GenericsType gt : newGenerics) {
if (!gt.isPlaceholder()) continue;
- String name = gt.getName();
+ GenericsTypeName name = new GenericsTypeName(gt.getName());
if (!current.containsKey(name)) current.put(name, gt);
}
return current;
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
----------------------------------------------------------------------
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 6d1f21c..a80f27c 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -167,6 +167,7 @@ import static org.codehaus.groovy.ast.ClassHelper.long_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.make;
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.GeneralUtils.args;
import static org.codehaus.groovy.ast.tools.GeneralUtils.binX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
@@ -256,7 +257,6 @@ import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.resolv
import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.toMethodParametersString;
import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.typeCheckMethodArgumentWithGenerics;
import static
org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.typeCheckMethodsWithGenerics;
-
//import static org.codehaus.groovy.syntax.Types.COMPARE_NOT_INSTANCEOF;
/**
@@ -1706,7 +1706,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
private void storeWithResolve(ClassNode typeToResolve, ClassNode receiver,
ClassNode declaringClass, boolean isStatic, PropertyExpression
expressionToStoreOn) {
ClassNode type = typeToResolve;
if (getGenericsWithoutArray(type) != null) {
- Map<String, GenericsType> resolvedPlaceholders =
resolvePlaceHoldersFromDeclaration(receiver, declaringClass, null, isStatic);
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders =
resolvePlaceHoldersFromDeclaration(receiver, declaringClass, null, isStatic);
type = resolveGenericsWithContext(resolvedPlaceholders, type);
}
storeInferredTypeForPropertyExpression(expressionToStoreOn, type);
@@ -2655,7 +2655,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// First we try to get as much information about the declaration
// class through the receiver
- Map<String, GenericsType> targetMethodDeclarationClassConnections =
new HashMap<String, GenericsType>();
+ Map<GenericsTypeName, GenericsType>
targetMethodDeclarationClassConnections = new HashMap<GenericsTypeName,
GenericsType>();
extractGenericsConnections(targetMethodDeclarationClassConnections,
receiver, receiver.redirect());
// then we use the method with the SAM parameter to get more
information about the declaration
Parameter[] parametersOfMethodContainingSAM =
methodWithSAMParameter.getParameters();
@@ -2676,7 +2676,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// to replace the generics in the SAM type parameter of the target
// method and than that to make the connections to the SAM type
generics
ClassNode paramTypeWithReceiverInformation =
applyGenericsContext(targetMethodDeclarationClassConnections,
param.getOriginType());
- Map<String, GenericsType> SAMTypeConnections = new HashMap<String,
GenericsType>();
+ Map<GenericsTypeName, GenericsType> SAMTypeConnections = new
HashMap<GenericsTypeName, GenericsType>();
ClassNode classForSAM = paramTypeWithReceiverInformation.redirect();
extractGenericsConnections(SAMTypeConnections,
paramTypeWithReceiverInformation, classForSAM);
@@ -4155,7 +4155,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (samGt == null || closureGt == null) return samUsage;
// extract the generics from the return type
- Map<String, GenericsType> connections = new HashMap<String,
GenericsType>();
+ Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
extractGenericsConnections(connections,
getInferredReturnType(closureExpression), sam.getReturnType());
// next we get the block parameter types and set the generics
@@ -4766,7 +4766,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
*/
private ClassNode getGenericsResolvedTypeOfFieldOrProperty(AnnotatedNode
an, ClassNode type) {
if (!type.isUsingGenerics()) return type;
- Map<String, GenericsType> connections = new HashMap<String,
GenericsType>();
+ Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
//TODO: inner classes mean a different this-type. This is ignored here!
extractGenericsConnections(connections,
typeCheckingContext.getEnclosingClassNode(), an.getDeclaringClass());
type = applyGenericsContext(connections, type);
@@ -4951,7 +4951,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
if (!isUsingGenericsOrIsArrayUsingGenerics(returnType)) return
returnType;
if (getGenericsWithoutArray(returnType) == null) return returnType;
- Map<String, GenericsType> resolvedPlaceholders =
resolvePlaceHoldersFromDeclaration(receiver, getDeclaringClass(method,
arguments), method, method.isStatic());
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders =
resolvePlaceHoldersFromDeclaration(receiver, getDeclaringClass(method,
arguments), method, method.isStatic());
if (!receiver.isGenericsPlaceHolder()) {
GenericsUtils.extractPlaceholders(receiver, resolvedPlaceholders);
}
@@ -4959,7 +4959,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (resolvedPlaceholders.isEmpty()) {
return boundUnboundedWildcards(returnType);
}
- Map<String, GenericsType> placeholdersFromContext =
extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+ Map<GenericsTypeName, GenericsType> placeholdersFromContext =
extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
applyGenericsConnections(placeholdersFromContext,
resolvedPlaceholders);
// then resolve receivers from method arguments
@@ -4981,7 +4981,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (implementsInterfaceOrIsSubclassOf(actualType,
CLOSURE_TYPE) &&
isSAMType(type)) {
// implicit closure coercion in action!
- Map<String, GenericsType> pholders =
applyGenericsContextToParameterClass(resolvedPlaceholders, type);
+ Map<GenericsTypeName, GenericsType> pholders =
applyGenericsContextToParameterClass(resolvedPlaceholders, type);
actualType =
convertClosureTypeToSAMType(expressions.get(i), actualType, type, pholders);
}
if (isVargs && lastArg && actualType.isArray()) {
@@ -4992,7 +4992,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
actualType = wrapTypeIfNecessary(actualType);
- Map<String, GenericsType> connections = new
HashMap<String, GenericsType>();
+ Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
extractGenericsConnections(connections, actualType, type);
extractGenericsConnectionsForSuperClassAndInterfaces(resolvedPlaceholders,
connections);
applyGenericsConnections(connections,
resolvedPlaceholders);
@@ -5003,20 +5003,20 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return applyGenericsContext(resolvedPlaceholders, returnType);
}
- private static void resolvePlaceholdersFromExplicitTypeHints(final
MethodNode method, final GenericsType[] explicitTypeHints, final Map<String,
GenericsType> resolvedPlaceholders) {
+ private static void resolvePlaceholdersFromExplicitTypeHints(final
MethodNode method, final GenericsType[] explicitTypeHints, final
Map<GenericsTypeName, GenericsType> resolvedPlaceholders) {
if (explicitTypeHints != null) {
GenericsType[] methodGenericTypes = method.getGenericsTypes();
if (methodGenericTypes != null && methodGenericTypes.length ==
explicitTypeHints.length) {
for (int i = 0; i < explicitTypeHints.length; i++) {
GenericsType methodGenericType = methodGenericTypes[i];
GenericsType explicitTypeHint = explicitTypeHints[i];
- resolvedPlaceholders.put(methodGenericType.getName(),
explicitTypeHint);
+ resolvedPlaceholders.put(new
GenericsTypeName(methodGenericType.getName()), explicitTypeHint);
}
}
}
}
- private static void
extractGenericsConnectionsForSuperClassAndInterfaces(final Map<String,
GenericsType> resolvedPlaceholders, final Map<String, GenericsType>
connections) {
+ private static void
extractGenericsConnectionsForSuperClassAndInterfaces(final
Map<GenericsTypeName, GenericsType> resolvedPlaceholders, final
Map<GenericsTypeName, GenericsType> connections) {
for (GenericsType value : new
HashSet<GenericsType>(connections.values())) {
if (!value.isPlaceholder() && !value.isWildcard()) {
ClassNode valueType = value.getType();
@@ -5064,7 +5064,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
* @param samType the type into which the closure is coerced into
* @return same SAM type, but completed with information from the closure
node
*/
- private static ClassNode convertClosureTypeToSAMType(final Expression
expression, final ClassNode closureType, final ClassNode samType, final
Map<String, GenericsType> placeholders) {
+ private static ClassNode convertClosureTypeToSAMType(final Expression
expression, final ClassNode closureType, final ClassNode samType, final
Map<GenericsTypeName, GenericsType> placeholders) {
if (!samType.isUsingGenerics()) return samType;
// use the generics information from the Closure to further specify
the type
@@ -5080,7 +5080,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
ClassNode unwrapped =
closureReturnType.getGenericsTypes()[0].getType();
extractGenericsConnections(placeholders, unwrapped,
samReturnType);
} else if (samReturnType.isGenericsPlaceHolder()) {
-
placeholders.put(samReturnType.getGenericsTypes()[0].getName(),
closureType.getGenericsTypes()[0]);
+ placeholders.put(new
GenericsTypeName(samReturnType.getGenericsTypes()[0].getName()),
closureType.getGenericsTypes()[0]);
}
// now repeat the same for each parameter given in the
ClosureExpression
@@ -5111,7 +5111,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
generifiedType = generifiedType.getComponentType();
}
if (expected.isGenericsPlaceHolder()) {
-
placeholders.put(expected.getGenericsTypes()[0].getName(), new
GenericsType(generifiedType));
+ placeholders.put(new
GenericsTypeName(expected.getGenericsTypes()[0].getName()), new
GenericsType(generifiedType));
} else {
GenericsType[] expectedGenericsTypes =
expected.getGenericsTypes();
GenericsType[] foundGenericsTypes =
generifiedType.getGenericsTypes();
@@ -5120,7 +5120,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
final GenericsType type = expectedGenericsTypes[i];
if (type.isPlaceholder()) {
String name = type.getName();
- placeholders.put(name, foundGenericsTypes[i]);
+ placeholders.put(new GenericsTypeName(name),
foundGenericsTypes[i]);
}
}
}
@@ -5131,8 +5131,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return result;
}
- private ClassNode resolveGenericsWithContext(Map<String, GenericsType>
resolvedPlaceholders, ClassNode currentType) {
- Map<String, GenericsType> placeholdersFromContext =
extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
+ private ClassNode resolveGenericsWithContext(Map<GenericsTypeName,
GenericsType> resolvedPlaceholders, ClassNode currentType) {
+ Map<GenericsTypeName, GenericsType> placeholdersFromContext =
extractGenericsParameterMapOfThis(typeCheckingContext.getEnclosingMethod());
return resolveClassNodeGenerics(resolvedPlaceholders,
placeholdersFromContext, currentType);
}
@@ -5151,8 +5151,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return declaringClass;
}
- private Map<String, GenericsType>
resolvePlaceHoldersFromDeclaration(ClassNode receiver, ClassNode declaration,
MethodNode method, boolean isStaticTarget) {
- Map<String, GenericsType> resolvedPlaceholders;
+ private Map<GenericsTypeName, GenericsType>
resolvePlaceHoldersFromDeclaration(ClassNode receiver, ClassNode declaration,
MethodNode method, boolean isStaticTarget) {
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders;
if (isStaticTarget && CLASS_Type.equals(receiver) &&
receiver.isUsingGenerics() &&
receiver.getGenericsTypes().length > 0 &&
@@ -5170,14 +5170,14 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
- private static Map<String, GenericsType> extractPlaceHolders(MethodNode
method, ClassNode receiver, ClassNode declaringClass) {
+ private static Map<GenericsTypeName, GenericsType>
extractPlaceHolders(MethodNode method, ClassNode receiver, ClassNode
declaringClass) {
if (declaringClass.equals(OBJECT_TYPE)) {
- Map<String, GenericsType> resolvedPlaceholders = new
HashMap<String, GenericsType>();
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders = new
HashMap<GenericsTypeName, GenericsType>();
if (method != null) addMethodLevelDeclaredGenerics(method,
resolvedPlaceholders);
return resolvedPlaceholders;
}
- Map<String, GenericsType> resolvedPlaceholders = null;
+ Map<GenericsTypeName, GenericsType> resolvedPlaceholders = null;
if (isPrimitiveType(receiver) && !isPrimitiveType(declaringClass)) {
receiver = getWrapper(receiver);
}
@@ -5192,7 +5192,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
while (current != null) {
boolean continueLoop = true;
//extract the place holders
- Map<String, GenericsType> currentPlaceHolders = new
HashMap<String, GenericsType>();
+ Map<GenericsTypeName, GenericsType> currentPlaceHolders = new
HashMap<GenericsTypeName, GenericsType>();
if (isGenericsPlaceHolderOrArrayOf(declaringClass) ||
declaringClass.equals(current)) {
extractGenericsConnections(currentPlaceHolders, current,
declaringClass);
if (method != null) addMethodLevelDeclaredGenerics(method,
currentPlaceHolders);
@@ -5203,11 +5203,11 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (resolvedPlaceholders != null) {
// merge maps
- Set<Map.Entry<String, GenericsType>> entries =
currentPlaceHolders.entrySet();
- for (Map.Entry<String, GenericsType> entry : entries) {
+ Set<Map.Entry<GenericsTypeName, GenericsType>> entries =
currentPlaceHolders.entrySet();
+ for (Map.Entry<GenericsTypeName, GenericsType> entry :
entries) {
GenericsType gt = entry.getValue();
if (!gt.isPlaceholder()) continue;
- GenericsType referenced =
resolvedPlaceholders.get(gt.getName());
+ GenericsType referenced = resolvedPlaceholders.get(new
GenericsTypeName(gt.getName()));
if (referenced == null) continue;
entry.setValue(referenced);
}
@@ -5239,7 +5239,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
protected boolean typeCheckMethodsWithGenericsOrFail(ClassNode receiver,
ClassNode[] arguments, MethodNode candidateMethod, Expression location) {
if (!typeCheckMethodsWithGenerics(receiver, arguments,
candidateMethod)) {
- Map<String, GenericsType> classGTs =
GenericsUtils.extractPlaceholders(receiver);
+ Map<GenericsTypeName, GenericsType> classGTs =
GenericsUtils.extractPlaceholders(receiver);
ClassNode[] ptypes = new
ClassNode[candidateMethod.getParameters().length];
final Parameter[] parameters = candidateMethod.getParameters();
for (int i = 0; i < parameters.length; i++) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/f8d4f1be/src/test/org/codehaus/groovy/ast/GenericsTypeTest.groovy
----------------------------------------------------------------------
diff --git a/src/test/org/codehaus/groovy/ast/GenericsTypeTest.groovy
b/src/test/org/codehaus/groovy/ast/GenericsTypeTest.groovy
index 7a72d66..858cdff 100644
--- a/src/test/org/codehaus/groovy/ast/GenericsTypeTest.groovy
+++ b/src/test/org/codehaus/groovy/ast/GenericsTypeTest.groovy
@@ -20,6 +20,8 @@ package org.codehaus.groovy.ast
import org.codehaus.groovy.ast.tools.GenericsUtils
+import static org.codehaus.groovy.ast.GenericsType.GenericsTypeName
+
/**
* Various tests aimed at testing the {@link GenericsType} class.
*/
@@ -135,23 +137,23 @@ public class GenericsTypeTest extends GenericsTestCase {
void testPlaceholderExtract() {
def type = extractTypesFromCode("List<String> type").type
def placeholders = GenericsUtils.extractPlaceholders(type)
- assert placeholders.E?.type == ClassHelper.STRING_TYPE
+ assert placeholders[new GenericsTypeName('E')]?.type ==
ClassHelper.STRING_TYPE
}
void testPlaceholderExtract2() {
def type = extractTypesFromCode("Map<String,Integer> type").type
def placeholders = GenericsUtils.extractPlaceholders(type)
- assert placeholders.K?.type == ClassHelper.STRING_TYPE
- assert placeholders.V?.type == ClassHelper.Integer_TYPE
+ assert placeholders[new GenericsTypeName('K')]?.type ==
ClassHelper.STRING_TYPE
+ assert placeholders[new GenericsTypeName('V')]?.type ==
ClassHelper.Integer_TYPE
}
void testPlaceholderExtract3() {
def type = extractTypesFromCode("List<Map<String,Integer>> type").type
def placeholders = GenericsUtils.extractPlaceholders(type)
- assert placeholders.E?.type == ClassHelper.MAP_TYPE
- placeholders = GenericsUtils.extractPlaceholders(placeholders.E.type)
- assert placeholders.K?.type == ClassHelper.STRING_TYPE
- assert placeholders.V?.type == ClassHelper.Integer_TYPE
+ assert placeholders[new GenericsTypeName('E')]?.type ==
ClassHelper.MAP_TYPE
+ placeholders = GenericsUtils.extractPlaceholders(placeholders[new
GenericsTypeName('E')].type)
+ assert placeholders[new GenericsTypeName('K')]?.type ==
ClassHelper.STRING_TYPE
+ assert placeholders[new GenericsTypeName('V')]?.type ==
ClassHelper.Integer_TYPE
}
// ------------------ Support methods -------------------------