entry : genericsPlaceholderAndTypeMap.entrySet()) {
if (placeholderName.equals(entry.getKey().getName())) {
GenericsType gt = entry.getValue();
@@ -1066,6 +956,44 @@ public static ClassNode findActualTypeByGenericsPlaceholderName(String placehold
return null;
}
+ //--------------------------------------------------------------------------
+
+ /**
+ * Clears the parameterized type cache.
+ *
+ * It is useful to IDE as the type being compiled are continuously being edited/altered, see GROOVY-8675
+ */
+ public static void clearParameterizedTypeCache() {
+ PARAMETERIZED_TYPE_CACHE.clearAll();
+ }
+
+ /**
+ * Try to get the parameterized type from the cache. If no cached item found,
+ * cache and return the result of {@link #findParameterizedType(ClassNode, ClassNode)}
+ */
+ public static ClassNode findParameterizedTypeFromCache(final ClassNode genericsClass, final ClassNode actualType) {
+ return findParameterizedType(genericsClass, actualType, false);
+ }
+
+ private static ClassNode findParameterizedTypeFromCache(final ClassNode genericsClass, final ClassNode actualType, final boolean tryToFindExactType) {
+ if (!PARAMETERIZED_TYPE_CACHE_ENABLED) {
+ return findParameterizedType(genericsClass, actualType, tryToFindExactType);
+ }
+
+ SoftReference sr = PARAMETERIZED_TYPE_CACHE.getAndPut(new ParameterizedTypeCacheKey(genericsClass, actualType), new EvictableCache.ValueProvider>() {
+ @Override
+ public SoftReference provide(ParameterizedTypeCacheKey key) {
+ return new SoftReference<>(findParameterizedType(key.getGenericsClass(), key.getActualType(), tryToFindExactType));
+ }
+ });
+
+ return sr == null ? null : sr.get();
+ }
+
+ private static final EvictableCache> PARAMETERIZED_TYPE_CACHE = new ConcurrentSoftCache<>(64);
+
+ private static final boolean PARAMETERIZED_TYPE_CACHE_ENABLED = Boolean.getBoolean("groovy.enable.parameterized.type.cache");
+
private static class ParameterizedTypeCacheKey {
private ClassNode genericsClass;
private ClassNode actualType;
diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
index b80a78f3a7..a838b790d6 100644
--- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -21,7 +21,6 @@
import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.ConstructorNode;
import org.codehaus.groovy.ast.FieldNode;
@@ -36,7 +35,6 @@
import org.codehaus.groovy.ast.expr.ListExpression;
import org.codehaus.groovy.ast.stmt.ReturnStatement;
import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.ParameterUtils;
import org.codehaus.groovy.control.AnnotationConstantsVisitor;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.ErrorCollector;
@@ -44,15 +42,15 @@
import groovyjarjarasm.asm.Opcodes;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getInterfacesAndSuperInterfaces;
import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
+import static org.codehaus.groovy.ast.tools.ParameterUtils.parametersEqual;
/**
* A specialized Groovy AST visitor meant to perform additional verifications upon the
@@ -272,32 +270,25 @@ private void visitOverride(AnnotatedNode node, AnnotationNode visited) {
}
}
- private static boolean isOverrideMethod(MethodNode method) {
- ClassNode cNode = method.getDeclaringClass();
- ClassNode next = cNode;
+ private static boolean isOverrideMethod(final MethodNode method) {
+ ClassNode declaringClass = method.getDeclaringClass();
+ ClassNode next = declaringClass;
outer:
while (next != null) {
- Map genericsSpec = createGenericsSpec(next);
- MethodNode mn = correctToGenericsSpec(genericsSpec, method);
- if (next != cNode) {
- ClassNode correctedNext = correctToGenericsSpecRecurse(genericsSpec, next);
- MethodNode found = getDeclaredMethodCorrected(genericsSpec, mn, correctedNext);
- if (found != null) break;
+ Map nextSpec = createGenericsSpec(next);
+ MethodNode mn = correctToGenericsSpec(nextSpec, method);
+ if (next != declaringClass) {
+ if (getDeclaredMethodCorrected(nextSpec, mn, next) != null) break;
}
- List ifaces = new ArrayList(Arrays.asList(next.getInterfaces()));
- while (!ifaces.isEmpty()) {
- ClassNode origInterface = ifaces.remove(0);
- if (!origInterface.equals(ClassHelper.OBJECT_TYPE)) {
- genericsSpec = createGenericsSpec(origInterface, genericsSpec);
- ClassNode iNode = correctToGenericsSpecRecurse(genericsSpec, origInterface);
- MethodNode found2 = getDeclaredMethodCorrected(genericsSpec, mn, iNode);
- if (found2 != null) break outer;
- Collections.addAll(ifaces, iNode.getInterfaces());
- }
+
+ for (ClassNode face : getInterfacesAndSuperInterfaces(next)) {
+ Map faceSpec = createGenericsSpec(face, nextSpec);
+ if (getDeclaredMethodCorrected(faceSpec, mn, face) != null) break outer;
}
+
ClassNode superClass = next.getUnresolvedSuperClass();
if (superClass != null) {
- next = correctToGenericsSpecRecurse(genericsSpec, superClass);
+ next = correctToGenericsSpecRecurse(nextSpec, superClass);
} else {
next = null;
}
@@ -305,10 +296,10 @@ private static boolean isOverrideMethod(MethodNode method) {
return next != null;
}
- private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
- for (MethodNode declared : correctedNext.getDeclaredMethods(mn.getName())) {
+ private static MethodNode getDeclaredMethodCorrected(final Map genericsSpec, final MethodNode mn, final ClassNode cn) {
+ for (MethodNode declared : cn.getDeclaredMethods(mn.getName())) {
MethodNode corrected = correctToGenericsSpec(genericsSpec, declared);
- if (ParameterUtils.parametersEqual(corrected.getParameters(), mn.getParameters())) {
+ if (parametersEqual(corrected.getParameters(), mn.getParameters())) {
return corrected;
}
}
diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java
index f052b5fd3e..8960b98085 100644
--- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java
+++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/classgen/Verifier.java
@@ -120,12 +120,12 @@
import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorThisX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.declS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getInterfacesAndSuperInterfaces;
import static org.codehaus.groovy.ast.tools.GeneralUtils.localVarX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
import static org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
-import static org.codehaus.groovy.ast.tools.GenericsUtils.parameterizeType;
import static org.codehaus.groovy.ast.tools.PropertyNodeUtils.adjustPropertyModifiersForMethod;
/**
@@ -320,23 +320,8 @@ public void variableNotAlwaysInitialized(final VariableExpression var) {
}
// GRECLIPSE add
- private static void addAllInterfaces(final Set result, final ClassNode source) {
- for (ClassNode in : source.getInterfaces()) {
- in = parameterizeType(source, in);
- if (result.add(in))
- addAllInterfaces(result, in);
- }
- ClassNode sc = source.redirect().getUnresolvedSuperClass(false);
- if (sc != null && !sc.equals(ClassHelper.OBJECT_TYPE)) {
- addAllInterfaces(result, parameterizeType(source, sc));
- }
- }
-
private static Set getAllInterfaces(final ClassNode cn) {
- Set result = new HashSet<>();
- if (cn.isInterface()) result.add(cn);
- addAllInterfaces(result, cn);
- return result;
+ return getInterfacesAndSuperInterfaces(cn);
}
private static void checkForDuplicateInterfaces(final ClassNode cn) {
diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilerConfiguration.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilerConfiguration.java
index 0e49024b0e..76c6894694 100644
--- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilerConfiguration.java
+++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/control/CompilerConfiguration.java
@@ -107,11 +107,17 @@ public class CompilerConfiguration {
JDK15, Opcodes.V15
);
- /** The valid targetBytecode values. */
+ /**
+ * The valid targetBytecode values.
+ */
public static final String[] ALLOWED_JDKS = JDK_TO_BYTECODE_VERSION_MAP.keySet().toArray(new String[JDK_TO_BYTECODE_VERSION_MAP.size()]);
+
+ /**
+ * The ASM API version used when loading/parsing classes and generating proxy adapter classes.
+ */
+ public static final int ASM_API_VERSION = Opcodes.ASM9;
+
/* GRECLIPSE edit
- public static final int ASM_API_VERSION = Opcodes.ASM8;
- @Deprecated
public static final String CURRENT_JVM_VERSION = JDK7;
*/
public static final String DEFAULT_SOURCE_ENCODING = "UTF-8";
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 3fe690db07..e5ddf7bba6 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
@@ -69,7 +69,6 @@
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;
@@ -163,13 +162,15 @@
import static org.codehaus.groovy.syntax.Types.RIGHT_SHIFT_UNSIGNED_EQUAL;
/**
- * Static support methods for {@link StaticTypeCheckingVisitor}.
+ * Support methods for {@link StaticTypeCheckingVisitor}.
*/
public abstract class StaticTypeCheckingSupport {
- protected static final ClassNode Collection_TYPE = makeWithoutCaching(Collection.class);
- protected static final ClassNode Deprecated_TYPE = makeWithoutCaching(Deprecated.class);
+
protected static final ClassNode Matcher_TYPE = makeWithoutCaching(Matcher.class);
protected static final ClassNode ArrayList_TYPE = makeWithoutCaching(ArrayList.class);
+ protected static final ClassNode Collection_TYPE = makeWithoutCaching(Collection.class);
+ protected static final ClassNode Deprecated_TYPE = makeWithoutCaching(Deprecated.class);
+
protected static final ExtensionMethodCache EXTENSION_METHOD_CACHE = new ExtensionMethodCache();
protected static final Map NUMBER_TYPES = Collections.unmodifiableMap(
new HashMap() {
@@ -1625,7 +1626,7 @@ private static boolean isOuterClassOf(ClassNode receiver, ClassNode type) {
private static Set extractResolvedPlaceHolders(Map resolvedMethodGenerics) {
if (resolvedMethodGenerics.isEmpty()) return Collections.EMPTY_SET;
Set result = new HashSet();
- for (Entry entry : resolvedMethodGenerics.entrySet()) {
+ for (Map.Entry entry : resolvedMethodGenerics.entrySet()) {
GenericsType value = entry.getValue();
if (value.isPlaceholder()) continue;
result.add(entry.getKey());
@@ -1681,7 +1682,7 @@ private static GenericsType buildWildcardType(GenericsType origin) {
}
private static boolean compatibleConnections(Map connections, Map resolvedMethodGenerics, Set fixedGenericsPlaceHolders) {
- for (Entry entry : connections.entrySet()) {
+ for (Map.Entry entry : connections.entrySet()) {
GenericsType resolved = resolvedMethodGenerics.get(entry.getKey());
if (resolved == null) continue;
GenericsType connection = entry.getValue();
@@ -1745,7 +1746,7 @@ private static boolean compatibleConnection(GenericsType resolved, GenericsType
}
private static void addMissingEntries(Map connections, Map resolved) {
- for (Entry entry : connections.entrySet()) {
+ for (Map.Entry entry : connections.entrySet()) {
if (resolved.containsKey(entry.getKey())) continue;
GenericsType gt = entry.getValue();
ClassNode cn = gt.getType();
@@ -2149,21 +2150,6 @@ static ClassNode getCombinedBoundType(GenericsType genericsType) {
return genericsType.getType();
}
- /* GRECLIPSE edit
- private static void applyContextGenerics(Map resolvedPlaceholders, Map placeholdersFromContext) {
- if (placeholdersFromContext == null) return;
- for (Entry entry : resolvedPlaceholders.entrySet()) {
- GenericsType gt = entry.getValue();
- if (gt.isPlaceholder()) {
- GenericsTypeName name = new GenericsTypeName(gt.getName());
- GenericsType outer = placeholdersFromContext.get(name);
- if (outer == null) continue;
- entry.setValue(outer);
- }
- }
- }
- */
-
private static Map getGenericsParameterMapOfThis(ClassNode cn) {
if (cn == null) return null;
Map map = null;
diff --git a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index e65649c993..f515408ba5 100644
--- a/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/base/org.codehaus.groovy25/src/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -99,6 +99,7 @@
import org.codehaus.groovy.classgen.asm.InvocationWriter;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.ResolveVisitor;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
import org.codehaus.groovy.runtime.DefaultGroovyMethods;
@@ -181,7 +182,6 @@
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
import static org.codehaus.groovy.ast.ClassHelper.isSAMType;
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.tools.ClosureUtils.getParametersSafe;
@@ -304,11 +304,11 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
protected static final MethodNode GET_THISOBJECT = CLOSURE_TYPE.getGetterMethod("getThisObject");
protected static final ClassNode DELEGATES_TO = ClassHelper.make(DelegatesTo.class);
protected static final ClassNode DELEGATES_TO_TARGET = ClassHelper.make(DelegatesTo.Target.class);
- protected static final ClassNode LINKEDHASHMAP_CLASSNODE = make(LinkedHashMap.class);
- protected static final ClassNode CLOSUREPARAMS_CLASSNODE = make(ClosureParams.class);
- protected static final ClassNode NAMED_PARAMS_CLASSNODE = make(NamedParams.class);
- protected static final ClassNode MAP_ENTRY_TYPE = make(Map.Entry.class);
- protected static final ClassNode ENUMERATION_TYPE = make(Enumeration.class);
+ protected static final ClassNode LINKEDHASHMAP_CLASSNODE = ClassHelper.make(LinkedHashMap.class);
+ protected static final ClassNode CLOSUREPARAMS_CLASSNODE = ClassHelper.make(ClosureParams.class);
+ protected static final ClassNode NAMED_PARAMS_CLASSNODE = ClassHelper.make(NamedParams.class);
+ protected static final ClassNode MAP_ENTRY_TYPE = ClassHelper.make(Map.Entry.class);
+ protected static final ClassNode ENUMERATION_TYPE = ClassHelper.make(Enumeration.class);
// GRECLIPSE add
private static final ClassNode STREAM_TYPE = ClassHelper.make(Stream.class);
private static final ClassNode SET_TYPE = ClassHelper.makeWithoutCaching(Set.class);
@@ -317,61 +317,44 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
public static final Statement GENERATED_EMPTY_STATEMENT = new EmptyStatement();
- public static final MethodNode CLOSURE_CALL_NO_ARG;
- public static final MethodNode CLOSURE_CALL_ONE_ARG;
- public static final MethodNode CLOSURE_CALL_VARGS;
-
- static {
- // Cache closure call methods
- CLOSURE_CALL_NO_ARG = CLOSURE_TYPE.getDeclaredMethod("call", Parameter.EMPTY_ARRAY);
- CLOSURE_CALL_ONE_ARG = CLOSURE_TYPE.getDeclaredMethod("call", new Parameter[]{
- new Parameter(OBJECT_TYPE, "arg")
- });
- CLOSURE_CALL_VARGS = CLOSURE_TYPE.getDeclaredMethod("call", new Parameter[]{
- new Parameter(OBJECT_TYPE.makeArray(), "args")
- });
- }
-
- private static final String[] EMPTY_STRING_ARRAY = new String[0];
+ // Cache closure call methods
+ public static final MethodNode CLOSURE_CALL_NO_ARG = CLOSURE_TYPE.getDeclaredMethod("call", Parameter.EMPTY_ARRAY);
+ public static final MethodNode CLOSURE_CALL_ONE_ARG = CLOSURE_TYPE.getDeclaredMethod("call", new Parameter[]{new Parameter(OBJECT_TYPE, "arg")});
+ public static final MethodNode CLOSURE_CALL_VARGS = CLOSURE_TYPE.getDeclaredMethod("call", new Parameter[]{new Parameter(OBJECT_TYPE.makeArray(), "args")});
protected final ReturnAdder.ReturnStatementListener returnListener = new ReturnAdder.ReturnStatementListener() {
@Override
public void returnStatementAdded(final ReturnStatement returnStatement) {
- if (!isNullConstant(returnStatement.getExpression())) {
- ClassNode returnType = checkReturnType(returnStatement);
- if (typeCheckingContext.getEnclosingClosure() != null) {
- addClosureReturnType(returnType);
- } else if (typeCheckingContext.getEnclosingMethod() != null) {
- // TODO
- } else {
- throw new GroovyBugError("Unexpected return statement at " + returnStatement.getLineNumber() + ":" + returnStatement.getColumnNumber() + " " + returnStatement.getText());
- }
+ if (isNullConstant(returnStatement.getExpression())) return;
+ ClassNode returnType = checkReturnType(returnStatement);
+ if (typeCheckingContext.getEnclosingClosure() != null) {
+ addClosureReturnType(returnType);
+ } else if (typeCheckingContext.getEnclosingMethod() == null) {
+ throw new GroovyBugError("Unexpected return statement at " + returnStatement.getLineNumber() + ":" + returnStatement.getColumnNumber() + " " + returnStatement.getText());
}
}
};
protected final ReturnAdder returnAdder = new ReturnAdder(returnListener);
- protected TypeCheckingContext typeCheckingContext;
- protected DefaultTypeCheckingExtension extension;
protected FieldNode currentField;
protected PropertyNode currentProperty;
+ protected DefaultTypeCheckingExtension extension;
+ protected TypeCheckingContext typeCheckingContext;
- public StaticTypeCheckingVisitor(SourceUnit source, ClassNode cn) {
+ public StaticTypeCheckingVisitor(final SourceUnit source, final ClassNode classNode) {
this.typeCheckingContext = new TypeCheckingContext(this);
- this.extension = createDefaultTypeCheckingExtension();
- this.typeCheckingContext.source = source;
- this.typeCheckingContext.pushEnclosingClassNode(cn);
- this.typeCheckingContext.pushErrorCollector(source.getErrorCollector());
+ this.typeCheckingContext.pushEnclosingClassNode(classNode);
this.typeCheckingContext.pushTemporaryTypeInfo();
- }
+ this.typeCheckingContext.pushErrorCollector(
+ source.getErrorCollector());
+ this.typeCheckingContext.source = source;
- private DefaultTypeCheckingExtension createDefaultTypeCheckingExtension() {
- DefaultTypeCheckingExtension ext = new DefaultTypeCheckingExtension(this);
- ext.addHandler(new TraitTypeCheckingExtension(this));
- return ext;
+ this.extension = new DefaultTypeCheckingExtension(this);
+ this.extension.addHandler(new TraitTypeCheckingExtension(this));
}
+ @Override
protected SourceUnit getSourceUnit() {
return typeCheckingContext.getSource();
}
@@ -697,21 +680,21 @@ public void visitVariableExpression(VariableExpression vexp) {
if (!(accessedVariable instanceof DynamicVariable)) {
/* GRECLIPSE edit -- GROOVY-9907
- if (typeCheckingContext.getEnclosingClosure() == null) {
+ if (enclosingClosure == null) {
*/
{
// GRECLIPSE end
VariableExpression variable = null;
if (accessedVariable instanceof Parameter) {
- variable = new ParameterVariableExpression((Parameter) accessedVariable);
+ Parameter parameter = (Parameter) accessedVariable;
+ variable = new ParameterVariableExpression(parameter);
} else if (accessedVariable instanceof VariableExpression) {
variable = (VariableExpression) accessedVariable;
}
-
if (variable != null) {
ClassNode inferredType = getInferredTypeFromTempInfo(variable, (ClassNode) variable.getNodeMetaData(StaticTypesMarker.INFERRED_TYPE));
/* GRECLIPSE edit -- GROOVY-10102, GROOVY-10179, GROOVY-10217, GROOVY-10308, et al.
- if (inferredType != null && !inferredType.getName().equals("java.lang.Object")) {
+ if (inferredType != null && !inferredType.getName().equals(ClassHelper.OBJECT)) {
vexp.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, inferredType);
}
*/
@@ -1044,8 +1027,9 @@ && isAssignment(enclosingBinaryExpression.getOperation().getType())) {
}
/**
- * Given a binary expression corresponding to an assignment, will check that the type of the RHS matches one
- * of the possible setters and if not, throw a type checking error.
+ * Given a binary expression corresponding to an assignment, will check that
+ * the type of the RHS matches one of the possible setters and if not, throw
+ * a type checking error.
*
* @param expression the assignment expression
* @param leftExpression left expression of the assignment
@@ -1186,48 +1170,45 @@ protected void inferDiamondType(final ConstructorCallExpression cce, final Class
ClassNode cceType = cce.getType(), inferredType = lType;
// check if constructor call expression makes use of the diamond operator
if (cceType.getGenericsTypes() != null && cceType.getGenericsTypes().length == 0) {
- ArgumentListExpression argumentListExpression = InvocationWriter.makeArgumentList(cce.getArguments());
- /* GRECLIPSE edit -- GROOVY-9948, GROOVY-9983, GROOVY-10291, GROOVY-10367, GROOVY-10368, et al.
- if (argumentListExpression.getExpressions().isEmpty()) {
- adjustGenerics(lType, cceType);
- } else {
- ClassNode type = getType(argumentListExpression.getExpression(0));
- if (type.isUsingGenerics()) {
- adjustGenerics(type, cceType);
- }
- }
- // store inferred type on CCE
- storeType(cce, cceType);
- */
+ ArgumentListExpression argumentList = InvocationWriter.makeArgumentList(cce.getArguments());
ConstructorNode constructor = cce.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
- if (!argumentListExpression.getExpressions().isEmpty() && constructor != null) {
+ if (constructor != null && !argumentList.getExpressions().isEmpty()) {
ClassNode type = GenericsUtils.parameterizeType(cceType, cceType);
- type = inferReturnTypeGenerics(type, constructor, argumentListExpression);
+ type = inferReturnTypeGenerics(type, constructor, argumentList);
+ /* GRECLIPSE edit
+ if (type.isUsingGenerics()) {
+ // GROOVY-6232, GROOVY-9956: if cce not assignment compatible, process target as additional type witness
+ if (checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type)) {
+ */
// process target as additional type witness, if ...
if (lType.getGenericsTypes() != null // has generics
&& (type.toString(false).indexOf('#') > 0 // unresolved generics
// GROOVY-6232, GROOVY-9956, etc.: cce not assignment compatible
|| checkCompatibleAssignmentTypes(lType, type, cce) && !GenericsUtils.buildWildcardType(lType).isCompatibleWith(type))) {
- // allow covariance of each type parameter, but maintain semantics for nested generics
+ // GRECLIPSE end
+ // allow covariance of each type parameter, but maintain semantics for nested generics
- ClassNode pType = GenericsUtils.parameterizeType(lType, type);
- GenericsType[] lhs = pType.getGenericsTypes(), rhs = type.getGenericsTypes();
- if (lhs == null || rhs == null || lhs.length != rhs.length) throw new GroovyBugError(
- "Parameterization failed: " + prettyPrintType(pType) + " ~ " + prettyPrintType(type));
+ ClassNode pType = GenericsUtils.parameterizeType(lType, type);
+ GenericsType[] lhs = pType.getGenericsTypes(), rhs = type.getGenericsTypes();
+ if (lhs == null || rhs == null || lhs.length != rhs.length) throw new GroovyBugError(
+ "Parameterization failed: " + prettyPrintType(pType) + " ~ " + prettyPrintType(type));
- if (IntStream.range(0, lhs.length).allMatch(i ->
- GenericsUtils.buildWildcardType(getCombinedBoundType(lhs[i])).isCompatibleWith(rhs[i].getType()))) {
- type = pType; // lType proved to be a viable type witness
+ boolean allMatch = true;
+ for (int i = 0, n = lhs.length; i < n && allMatch; i += 1) {
+ if (!GenericsUtils.buildWildcardType(getCombinedBoundType(lhs[i])).isCompatibleWith(rhs[i].getType())) { // GROOVY-10368
+ allMatch = false;
+ }
+ }
+ if (allMatch) type = pType; // lType proved to be a viable type witness
}
- }
- inferredType = type;
+ inferredType = type;
+ //}
}
if (inferredType.isGenericsPlaceHolder()) // GROOVY-10344: "T t = new C<>()"
inferredType = getCombinedBoundType(inferredType.getGenericsTypes()[0]);
adjustGenerics(inferredType, cceType);
storeType(cce, cceType);
- // GRECLIPSE end
}
}
@@ -1273,7 +1254,7 @@ private void adjustGenerics(final ClassNode source, final ClassNode target) {
}
/**
- * Stores information about types when [objectOfInstanceof instanceof typeExpression] is visited
+ * Stores information about types when [objectOfInstanceof instanceof typeExpression] is visited.
*
* @param objectOfInstanceOf the expression which must be checked against instanceof
* @param typeExpression the expression which represents the target type
@@ -1387,7 +1368,7 @@ private static ClassNode adjustTypeForSpreading(ClassNode inferredRightExpressio
if (leftExpression instanceof PropertyExpression && ((PropertyExpression) leftExpression).isSpreadSafe()) {
wrappedRHS = LIST_TYPE.getPlainNodeReference();
wrappedRHS.setGenericsTypes(new GenericsType[]{
- new GenericsType(getWrapper(inferredRightExpressionType))
+ new GenericsType(wrapTypeIfNecessary(inferredRightExpressionType))
});
}
return wrappedRHS;
@@ -1640,7 +1621,8 @@ protected static boolean hasRHSIncompleteGenericTypeInfo(final ClassNode inferre
}
/**
- * Checks that a constructor style expression is valid regarding the number of arguments and the argument types.
+ * Checks that a constructor style expression is valid regarding the number
+ * of arguments and the argument types.
*
* @param node the class node for which we will try to find a matching constructor
* @param arguments the constructor arguments
@@ -1652,7 +1634,8 @@ protected void checkGroovyStyleConstructor(final ClassNode node, final ClassNode
}
/**
- * Checks that a constructor style expression is valid regarding the number of arguments and the argument types.
+ * Checks that a constructor style expression is valid regarding the number
+ * of arguments and the argument types.
*
* @param node the class node for which we will try to find a matching constructor
* @param arguments the constructor arguments
@@ -1686,8 +1669,9 @@ protected MethodNode checkGroovyStyleConstructor(final ClassNode node, final Cla
}
/**
- * When instanceof checks are found in the code, we store temporary type information data in the {@link
- * TypeCheckingContext#temporaryIfBranchTypeInformation} table. This method computes the key which must be used to store this type
+ * When instanceof checks are found in the code, we store temporary type
+ * information data in the {@link TypeCheckingContext#temporaryIfBranchTypeInformation}
+ * table. This method computes the key which must be used to store this type
* info.
*
* @param expression the expression for which to compute the key
@@ -1708,7 +1692,7 @@ protected Object extractTemporaryTypeInfoKey(final Expression expression) {
* otherwise falls back to the provided type class.
*/
protected ClassNode findCurrentInstanceOfClass(final Expression expr, final ClassNode type) {
- if (!typeCheckingContext.temporaryIfBranchTypeInformation.empty()) {
+ if (!typeCheckingContext.temporaryIfBranchTypeInformation.isEmpty()) {
List nodes = getTemporaryTypesForExpression(expr);
if (nodes != null && nodes.size() == 1) return nodes.get(0);
}
@@ -1841,7 +1825,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
// skip property/accessor checks for "x.@field"
if (storeField(field, isAttributeExpression, pexp, receiverType, visitor, receiver.getData(), !readMode)) {
/* GRECLIPSE edit -- GROOVY-5450
- pexp.removeNodeMetaData(READONLY_PROPERTY);
+ pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
*/
return true;
} else if (isAttributeExpression) {
@@ -1851,7 +1835,7 @@ protected boolean existsProperty(final PropertyExpression pexp, final boolean re
// skip property/accessor checks for "field", "this.field", "this.with { field }", etc. in declaring class of field
if (storeField(field, enclosingTypes.contains(current), pexp, receiverType, visitor, receiver.getData(), !readMode)) {
/* GRECLIPSE edit -- GROOVY-5450
- pexp.removeNodeMetaData(READONLY_PROPERTY);
+ pexp.removeNodeMetaData(StaticTypesMarker.READONLY_PROPERTY);
*/
return true;
}
@@ -3462,9 +3446,9 @@ protected void inferClosureParameterTypes(final ClassNode receiver, final Expres
if (annotations != null && !annotations.isEmpty()) {
for (AnnotationNode annotation : annotations) {
Expression hintClass = annotation.getMember("value");
- Expression options = annotation.getMember("options");
- Expression resolverClass = annotation.getMember("conflictResolutionStrategy");
if (hintClass instanceof ClassExpression) {
+ Expression options = annotation.getMember("options");
+ Expression resolverClass = annotation.getMember("conflictResolutionStrategy");
doInferClosureParameterTypes(receiver, arguments, expression, selectedMethod, hintClass, resolverClass, options);
}
}
@@ -3788,57 +3772,27 @@ private ClassNode[] resolveGenericsFromTypeHint(final ClassNode receiver, final
dummyMN.setDeclaringClass(orig.getDeclaringClass());
dummyMN.setGenericsTypes(orig.getGenericsTypes());
}
- ClassNode classNode = inferReturnTypeGenerics(receiver, dummyMN, arguments);
- /* GRECLIPSE edit -- GROOVY-9968, GROOVY-10327, GROOVY-10528
- ClassNode[] inferred = new ClassNode[classNode.getGenericsTypes().length];
- for (int i = 0; i < classNode.getGenericsTypes().length; i++) {
- GenericsType genericsType = classNode.getGenericsTypes()[i];
- ClassNode value = createUsableClassNodeFromGenericsType(genericsType);
- inferred[i] = value;
- }
- */
- GenericsType[] returnTypeGenerics = classNode.getGenericsTypes();
+ ClassNode returnType = inferReturnTypeGenerics(receiver, dummyMN, arguments);
+ GenericsType[] returnTypeGenerics = returnType.getGenericsTypes();
ClassNode[] inferred = new ClassNode[returnTypeGenerics.length];
for (int i = 0, n = returnTypeGenerics.length; i < n; i += 1) {
+ /* GRECLIPSE edit -- GROOVY-9968, GROOVY-10327, GROOVY-10528
+ inferred[i] = getCombinedBoundType(returnTypeGenerics[i]);
+ */
GenericsType gt = returnTypeGenerics[i];
if (!gt.isPlaceholder()) {
inferred[i] = getCombinedBoundType(gt);
} else {
inferred[i] = gt.getUpperBounds() != null ? gt.getUpperBounds()[0] : gt.getType().redirect();
}
+ // GRECLIPSE end
}
- // GRECLIPSE end
return inferred;
}
- /**
- * Given a GenericsType instance, returns a ClassNode which can be used as an inferred type.
- *
- * @param genericsType a {@link org.codehaus.groovy.ast.GenericsType} representing either a type, a placeholder or a wildcard
- * @return a class node usable as an inferred type
- */
- /* GRECLIPSE edit
- private static ClassNode createUsableClassNodeFromGenericsType(final GenericsType genericsType) {
- ClassNode value = genericsType.getType();
- if (genericsType.isPlaceholder()) {
- value = value.isRedirectNode() ? value.redirect() : OBJECT_TYPE; // GROOVY-9968
- }
- ClassNode lowerBound = genericsType.getLowerBound();
- if (lowerBound != null) {
- value = lowerBound;
- } else {
- ClassNode[] upperBounds = genericsType.getUpperBounds();
- if (upperBounds != null) {
- value = lowestUpperBound(Arrays.asList(upperBounds));
- }
- }
- return value;
- }
- */
-
private static String[] convertToStringArray(final Expression options) {
if (options == null) {
- return EMPTY_STRING_ARRAY;
+ return ResolveVisitor.EMPTY_STRING_ARRAY;
}
if (options instanceof ConstantExpression) {
return new String[]{options.getText()};
@@ -6324,27 +6278,8 @@ private Map extractGenericsConnectionsFromArgume
* method target of "m", {@code T} could be resolved.
*/
private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals, final ArgumentListExpression argumentList, final Parameter[] parameterArray) {
- /* GRECLIPSE edit
- for (int i = 0, n = actuals.length; i < n; i += 1) {
- Expression a = argumentList.getExpression(i);
- // check for method call without type arguments, with a known target
- if (!(a instanceof MethodCall) || (a instanceof MethodCallExpression
- && ((MethodCallExpression) a).isUsingGenerics())) continue;
- MethodNode aNode = a.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
- if (aNode == null || aNode.getGenericsTypes() == null) continue;
-
- // and unknown generics
- ClassNode at = actuals[i];
- if (!GenericsUtils.hasUnresolvedGenerics(at)) continue;
-
- int np = parameterArray.length;
- Parameter p = parameterArray[Math.min(i, np - 1)];
-
- ClassNode pt = p.getOriginType();
- if (i >= (np - 1) && pt.isArray() && !at.isArray()) pt = pt.getComponentType();
- */
int np = parameterArray.length;
- for (int i = 0, n = actuals.length; np > 0 && i < n; i += 1) {
+ for (int i = 0, n = actuals.length; i < n && np > 0; i += 1) {
Expression a = argumentList.getExpression(i);
Parameter p = parameterArray[Math.min(i, np - 1)];
@@ -6352,12 +6287,14 @@ private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals,
if (!isUsingGenericsOrIsArrayUsingGenerics(pt)) continue;
if (i >= (np - 1) && pt.isArray() && !at.isArray()) pt = pt.getComponentType();
- if (a instanceof ListExpression) {
+ if (a instanceof ConstructorCallExpression) {
+ inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-10086, GROOVY-10316
+ }
+ // GRECLIPSE add
+ else if (a instanceof ListExpression) {
actuals[i] = getLiteralResultType(pt, at, ArrayList_TYPE);
} else if (a instanceof MapExpression) {
actuals[i] = getLiteralResultType(pt, at, LINKEDHASHMAP_CLASSNODE);
- } else if (a instanceof ConstructorCallExpression) {
- inferDiamondType((ConstructorCallExpression) a, pt); // GROOVY-10086
} else if (a instanceof TernaryExpression && at.getGenericsTypes() != null && at.getGenericsTypes().length == 0) {
// GROOVY-9983: double diamond scenario -- "m(flag ? new Type<>(...) : new Type<>(...))"
typeCheckingContext.pushEnclosingBinaryExpression(assignX(varX(p), a, a));
@@ -6365,6 +6302,7 @@ private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals,
typeCheckingContext.popEnclosingBinaryExpression();
actuals[i] = getType(a);
}
+ // GRECLIPSE end
// check for method call without type arguments, with a known target
if (!(a instanceof MethodCall) || (a instanceof MethodCallExpression
@@ -6379,7 +6317,6 @@ private void resolvePlaceholdersFromImplicitTypeHints(final ClassNode[] actuals,
ClassNode sc = GenericsUtils.getSuperClass(at, pt);
at = applyGenericsContext(GenericsUtils.extractPlaceholders(at), sc);
}
- // GRECLIPSE end
// try to resolve placeholder(s) in argument type using parameter type
@@ -6943,7 +6880,6 @@ protected static ClassNode[] extractTypesFromParameters(final Parameter[] parame
* This method differs from {@link ClassHelper#getWrapper(org.codehaus.groovy.ast.ClassNode)} as it will
* return the same instance if the provided type is not a generic type.
*
- * @param type
* @return the wrapped type
*/
protected static ClassNode wrapTypeIfNecessary(ClassNode type) {
@@ -6959,6 +6895,7 @@ protected static boolean isClassInnerClassOrEqualTo(ClassNode toBeChecked, Class
return false;
}
+ //--------------------------------------------------------------------------
protected class VariableExpressionTypeMemoizer extends ClassCodeVisitorSupport {
private final boolean onlySharedVariables;
@@ -6991,7 +6928,7 @@ public void visitVariableExpression(final VariableExpression expression) {
}
}
- // ------------------- codecs for method return type signatures ------------------------------
+ //--------------------------------------------------------------------------
public static class SignatureCodecFactory {
public static SignatureCodec getCodec(int version, final ClassLoader classLoader) {
@@ -7018,7 +6955,6 @@ private SetterInfo(final ClassNode receiverType, final String name, final List T getNodeMetaData(Object key) {
+ public T getNodeMetaData(final Object key) {
return parameter.getNodeMetaData(key);
}
-
+ // GRECLIPSE add
@Override
- /* GRECLIPSE edit
- public void setNodeMetaData(Object key, Object value) {
- parameter.setNodeMetaData(key, value);
- */
- public T getNodeMetaData(Object key, Function, ? extends T> valFn) {
+ public T getNodeMetaData(final Object key, final Function, ? extends T> valFn) {
return parameter.getNodeMetaData(key, valFn);
+ }
// GRECLIPSE end
+
+ @Override
+ public Object putNodeMetaData(final Object key, final Object value) {
+ return parameter.putNodeMetaData(key, value);
}
}
}
diff --git a/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF b/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF
index 3719a27315..6acee5a51a 100644
--- a/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF
+++ b/base/org.eclipse.jdt.groovy.core/META-INF/MANIFEST.MF
@@ -15,7 +15,7 @@ Export-Package: org.codehaus.jdt.groovy.ast,
org.eclipse.jdt.groovy.core.util,
org.eclipse.jdt.groovy.search
Import-Package: org.eclipse.jdt.launching
-Require-Bundle: org.codehaus.groovy;bundle-version="[2.5.17,5)";visibility:=reexport,
+Require-Bundle: org.codehaus.groovy;bundle-version="[2.5.18,5)";visibility:=reexport,
org.eclipse.core.expressions;visibility:=reexport,
org.eclipse.core.filesystem;visibility:=reexport,
org.eclipse.core.resources;visibility:=reexport,
diff --git a/docs/Manual-Setup.md b/docs/Manual-Setup.md
index 72688444d0..250df692c1 100644
--- a/docs/Manual-Setup.md
+++ b/docs/Manual-Setup.md
@@ -12,7 +12,7 @@ On the Eclipse menu bar, select *Help -> Install New Software...*. In the *Inst
### Setup Groovy Compiler
-If you installed extra Groovy compiler versions, then you must activate Groovy 2.5 compiler for Groovy-Eclipse. On the Eclipse menu bar, select *Window -> Preferences*. In the *Preferences* window, go to *Groovy -> Compiler*. Click the *Switch to 2.5.17* button, and let Eclipse restart.
+If you installed extra Groovy compiler versions, then you must activate Groovy 2.5 compiler for Groovy-Eclipse. On the Eclipse menu bar, select *Window -> Preferences*. In the *Preferences* window, go to *Groovy -> Compiler*. Click the *Switch to 2.5.18* button, and let Eclipse restart.
### Install Execution Environment Descriptions
diff --git a/extras/Feature-org.codehaus.groovy.m2eclipse/feature.xml b/extras/Feature-org.codehaus.groovy.m2eclipse/feature.xml
index 7ac5fc8b3d..ecb7d14b0e 100644
--- a/extras/Feature-org.codehaus.groovy.m2eclipse/feature.xml
+++ b/extras/Feature-org.codehaus.groovy.m2eclipse/feature.xml
@@ -19,7 +19,7 @@
-
+
diff --git a/extras/groovy-eclipse-batch-builder/build.properties b/extras/groovy-eclipse-batch-builder/build.properties
index 32a80da620..3e4c28e79b 100644
--- a/extras/groovy-eclipse-batch-builder/build.properties
+++ b/extras/groovy-eclipse-batch-builder/build.properties
@@ -1,5 +1,5 @@
# version numbers
-version2.5=2.5.17-02
+version2.5=2.5.18-01
version3.0=3.0.11-03
version4.0=4.0.3-02
diff --git a/extras/groovy-eclipse-maven-tests/pom.xml b/extras/groovy-eclipse-maven-tests/pom.xml
index b696bf4fd0..ea522129d9 100644
--- a/extras/groovy-eclipse-maven-tests/pom.xml
+++ b/extras/groovy-eclipse-maven-tests/pom.xml
@@ -37,7 +37,7 @@
org.codehaus.groovy
groovy
indy
- 2.5.17
+ 2.5.18
@@ -72,7 +72,7 @@
org.codehaus.groovy
groovy-eclipse-batch
- 2.5.17-02
+ 2.5.18-01
diff --git a/extras/groovy-eclipse-quickstart/src/main/resources/archetype-resources/pom.xml b/extras/groovy-eclipse-quickstart/src/main/resources/archetype-resources/pom.xml
index 9eb5f09cbe..c4995b246e 100755
--- a/extras/groovy-eclipse-quickstart/src/main/resources/archetype-resources/pom.xml
+++ b/extras/groovy-eclipse-quickstart/src/main/resources/archetype-resources/pom.xml
@@ -19,13 +19,13 @@
org.codehaus.groovy
groovy
- 2.5.17
+ 2.5.18
indy
org.codehaus.groovy
groovy-test
- 2.5.17
+ 2.5.18
indy
@@ -64,7 +64,7 @@
org.codehaus.groovy
groovy-eclipse-batch
- 2.5.17-02
+ 2.5.18-01
diff --git a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/testResources/DSLD_meta_script.dsld b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/testResources/DSLD_meta_script.dsld
index ca587ba21f..66c1bad882 100644
--- a/ide-test/org.codehaus.groovy.eclipse.dsl.tests/testResources/DSLD_meta_script.dsld
+++ b/ide-test/org.codehaus.groovy.eclipse.dsl.tests/testResources/DSLD_meta_script.dsld
@@ -25,7 +25,7 @@ import org.codehaus.groovy.eclipse.dsl.script.PointcutFactory
// first thing to do is to check that versions are correct
// for this script to be evaluated any further, all conditions must be met
// also supports grailsTooling and sts, which are synonyms and correspond to the STS version eg- 2.6.0
-assertVersion(groovy: '2.5.17', groovyEclipse: '3.0.0')
+assertVersion(groovy: '2.5.18', groovyEclipse: '3.0.0')
// You can store shared pointcuts in a variable
// This particular pointcut matches all join points that are inside of a
diff --git a/ide/Feature-org.codehaus.groovy25.feature/feature.xml b/ide/Feature-org.codehaus.groovy25.feature/feature.xml
index 5fde14eb5c..cff7dd93f8 100644
--- a/ide/Feature-org.codehaus.groovy25.feature/feature.xml
+++ b/ide/Feature-org.codehaus.groovy25.feature/feature.xml
@@ -22,7 +22,7 @@
id="org.codehaus.groovy"
download-size="0"
install-size="0"
- version="2.5.17.qualifier"
+ version="2.5.18.qualifier"
/>