This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/GROOVY_2_5_X by this push:
new 9444a8a minor edits
9444a8a is described below
commit 9444a8a0fa76250dbd1b1f7e667e97afc955e553
Author: Eric Milles <[email protected]>
AuthorDate: Wed Feb 23 06:20:34 2022 -0600
minor edits
---
.../org/codehaus/groovy/ast/AnnotatedNode.java | 6 +-
.../java/org/codehaus/groovy/ast/ClassHelper.java | 10 +-
.../java/org/codehaus/groovy/ast/MethodNode.java | 3 +-
.../org/codehaus/groovy/classgen/Verifier.java | 9 +-
.../groovy/classgen/asm/BytecodeHelper.java | 10 +-
.../codehaus/groovy/control/ResolveVisitor.java | 4 +-
.../transform/stc/StaticTypeCheckingSupport.java | 44 +++--
.../transform/stc/StaticTypeCheckingVisitor.java | 190 +++++++++------------
8 files changed, 134 insertions(+), 142 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/ast/AnnotatedNode.java
b/src/main/java/org/codehaus/groovy/ast/AnnotatedNode.java
index 1d9b795..0b45da3 100644
--- a/src/main/java/org/codehaus/groovy/ast/AnnotatedNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/AnnotatedNode.java
@@ -48,8 +48,10 @@ public class AnnotatedNode extends ASTNode {
}
public void addAnnotation(AnnotationNode value) {
- checkInit();
- annotations.add(value);
+ if (value != null) {
+ checkInit();
+ annotations.add(value);
+ }
}
private void checkInit() {
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index f4876f8..3a09d4e 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -325,7 +325,8 @@ public class ClassHelper {
* @see #make(String)
*/
public static boolean isStaticConstantInitializerType(ClassNode cn) {
- return cn == int_TYPE ||
+ cn = cn.redirect();
+ return (cn == int_TYPE ||
cn == float_TYPE ||
cn == long_TYPE ||
cn == double_TYPE ||
@@ -333,11 +334,12 @@ public class ClassHelper {
// the next items require conversion to int when initializing
cn == byte_TYPE ||
cn == char_TYPE ||
- cn == short_TYPE;
+ cn == short_TYPE);
}
public static boolean isNumberType(ClassNode cn) {
- return cn == Byte_TYPE ||
+ cn = cn.redirect();
+ return (cn == Byte_TYPE ||
cn == Short_TYPE ||
cn == Integer_TYPE ||
cn == Long_TYPE ||
@@ -348,7 +350,7 @@ public class ClassHelper {
cn == int_TYPE ||
cn == long_TYPE ||
cn == float_TYPE ||
- cn == double_TYPE;
+ cn == double_TYPE);
}
public static ClassNode makeReference() {
diff --git a/src/main/java/org/codehaus/groovy/ast/MethodNode.java
b/src/main/java/org/codehaus/groovy/ast/MethodNode.java
index aa844b5..bf0db57 100644
--- a/src/main/java/org/codehaus/groovy/ast/MethodNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/MethodNode.java
@@ -32,6 +32,7 @@ import java.util.List;
public class MethodNode extends AnnotatedNode implements Opcodes {
public static final String SCRIPT_BODY_METHOD_KEY =
"org.codehaus.groovy.ast.MethodNode.isScriptBody";
+
private String name;
private int modifiers;
private boolean syntheticPublic;
@@ -190,7 +191,7 @@ public class MethodNode extends AnnotatedNode implements
Opcodes {
/**
* Set the metadata flag for this method to indicate that it is a script
body implementation.
- * @see ModuleNode createStatementsClass().
+ * @see ModuleNode#createStatementsClass()
*/
public void setIsScriptBody() {
setNodeMetaData(SCRIPT_BODY_METHOD_KEY, Boolean.TRUE);
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 915380e..5c648a2 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -901,6 +901,7 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
localVariable = localVarX(p.getName(),
p.getType());
localVariable.setModifiers(p.getModifiers());
blockScope.putDeclaredVariable(localVariable);
+
localVariable.setInStaticContext(blockScope.isInStaticContext());
code.addStatement(declS(localVariable,
p.getInitialExpression()));
}
if (!localVariable.isClosureSharedVariable()) {
@@ -967,7 +968,7 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
public void call(ArgumentListExpression arguments, Parameter[]
newParams, MethodNode method) {
// delegate to original constructor using arguments derived
from defaults
Statement code = new ExpressionStatement(ctorThisX(arguments));
- addConstructor(newParams, (ConstructorNode) method, code,
node);
+ addConstructor(newParams, (ConstructorNode)method, code, node);
}
});
}
@@ -1429,13 +1430,13 @@ public class Verifier implements GroovyClassVisitor,
Opcodes {
if ((oldMethod.getModifiers() & ACC_BRIDGE) != 0) return null;
if (oldMethod.isPrivate()) return null;
+ if (oldMethod.getGenericsTypes() != null) // GROOVY-9059
+ genericsSpec = addMethodGenerics(oldMethod, genericsSpec);
+
// parameters
boolean equalParameters = equalParametersNormal(overridingMethod,
oldMethod);
if (!equalParameters && !equalParametersWithGenerics(overridingMethod,
oldMethod, genericsSpec)) return null;
- // correct to method level generics for the overriding method
- genericsSpec = addMethodGenerics(overridingMethod, genericsSpec);
-
// return type
ClassNode mr = overridingMethod.getReturnType();
ClassNode omr = oldMethod.getReturnType();
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
index 29a88b5..13d53a5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/BytecodeHelper.java
@@ -24,7 +24,6 @@ import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.GenericsType;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.decompiled.DecompiledClassNode;
import org.codehaus.groovy.classgen.asm.util.TypeUtil;
import org.codehaus.groovy.reflection.ReflectionCache;
import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
@@ -49,14 +48,13 @@ import static
org.codehaus.groovy.ast.ClassHelper.short_TYPE;
*/
public class BytecodeHelper implements Opcodes {
- private static String DTT_CLASSNAME =
BytecodeHelper.getClassInternalName(DefaultTypeTransformation.class.getName());
+ private static String DTT_CLASSNAME =
getClassInternalName(DefaultTypeTransformation.class.getName());
public static String getClassInternalName(ClassNode t) {
- if (t.isPrimaryClassNode() || t instanceof DecompiledClassNode) {
- if (t.isArray()) return
"[L"+getClassInternalName(t.getComponentType())+";";
- return getClassInternalName(t.getName());
+ if (t.isArray()) {
+ return TypeUtil.getDescriptionByType(t);
}
- return getClassInternalName(t.getTypeClass());
+ return getClassInternalName(t.getName());
}
public static String getClassInternalName(Class t) {
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index cce4f72..00ebd63 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -786,7 +786,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
// check package this class is defined in. The usage of
ConstructedClassWithPackage here
// means, that the module package will not be involved when the
// compiler tries to find an inner class.
- ConstructedClassWithPackage tmp = new
ConstructedClassWithPackage(module.getPackageName(), name);
+ ConstructedClassWithPackage tmp = new
ConstructedClassWithPackage(module.getPackageName(), name);
if (resolve(tmp, false, false, false)) {
ambiguousClass(type, tmp, name);
type.setRedirect(tmp.redirect());
@@ -1016,7 +1016,7 @@ public class ResolveVisitor extends
ClassCodeExpressionTransformer {
if (className != null) {
ClassNode type = ClassHelper.make(className);
if (resolve(type)) {
- Expression ret = new ClassExpression(type);
+ Expression ret = new ClassExpression(type);
ret.setSourcePosition(pe);
return ret;
}
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 ce6ef54..bfc702b 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -158,6 +158,7 @@ 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}.
*/
@@ -691,11 +692,11 @@ public abstract class StaticTypeCheckingSupport {
}
if (isNumberType(rightRedirect) ||
WideningCategories.isNumberCategory(rightRedirect)) {
- if (BigDecimal_TYPE == leftRedirect || Number_TYPE ==
leftRedirect) {
+ if (leftRedirect.equals(BigDecimal_TYPE) ||
leftRedirect.equals(Number_TYPE)) {
// any number can be assigned to BigDecimal or Number
return true;
}
- if (BigInteger_TYPE == leftRedirect) {
+ if (leftRedirect.equals(BigInteger_TYPE)) {
return
WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) ||
rightRedirect.isDerivedFrom(BigInteger_TYPE);
}
@@ -712,7 +713,7 @@ public abstract class StaticTypeCheckingSupport {
// anything can be assigned to an Object, String, Boolean
// or Class typed variable
if (isWildcardLeftHandSide(leftRedirect)
- && !(boolean_TYPE.equals(left) && rightExpressionIsNull))
return true;
+ && !(left.equals(boolean_TYPE) && rightExpressionIsNull))
return true;
// char as left expression
if (leftRedirect == char_TYPE && rightRedirect == STRING_TYPE) {
@@ -727,7 +728,7 @@ public abstract class StaticTypeCheckingSupport {
// if left is Enum and right is String or GString we do valueOf
if (leftRedirect.isDerivedFrom(Enum_Type) &&
- (rightRedirect == GSTRING_TYPE || rightRedirect ==
STRING_TYPE)) {
+ (rightRedirect.equals(STRING_TYPE) ||
rightRedirect.equals(GSTRING_TYPE))) {
return true;
}
@@ -755,7 +756,7 @@ public abstract class StaticTypeCheckingSupport {
return true;
}
- if (GROOVY_OBJECT_TYPE.equals(leftRedirect) && isBeingCompiled(right))
{
+ if (leftRedirect.equals(GROOVY_OBJECT_TYPE) && isBeingCompiled(right))
{
return true;
}
@@ -888,11 +889,23 @@ public abstract class StaticTypeCheckingSupport {
return sb.toString();
}
- static String prettyPrintType(ClassNode type) {
+ /**
+ * Returns string representation of type with generics. Arrays are
indicated
+ * with trailing "[]".
+ */
+ static String prettyPrintType(final ClassNode type) {
+ return type.toString(false);
+ }
+
+ /**
+ * Returns string representation of type *no* generics. Arrays are
indicated
+ * with trailing "[]".
+ */
+ static String prettyPrintTypeName(final ClassNode type) {
if (type.isArray()) {
- return prettyPrintType(type.getComponentType()) + "[]";
+ return prettyPrintTypeName(type.getComponentType()) + "[]";
}
- return type.toString(false);
+ return type.isGenericsPlaceHolder() ? type.getUnresolvedName() :
type.getText();
}
public static boolean implementsInterfaceOrIsSubclassOf(ClassNode type,
ClassNode superOrInterface) {
@@ -959,7 +972,7 @@ public abstract class StaticTypeCheckingSupport {
return dist;
}
- ClassNode ref = isPrimitiveType(receiver) && !isPrimitiveType(compare)
? ClassHelper.getWrapper(receiver) : receiver;
+ ClassNode ref = isPrimitiveType(receiver) && !isPrimitiveType(compare)
? getWrapper(receiver) : receiver;
while (ref != null) {
if (compare.equals(ref)) {
break;
@@ -1564,9 +1577,8 @@ public abstract class StaticTypeCheckingSupport {
// we use the provided information to transform the parameter
// into something that can exist in the callsite context
type = applyGenericsContext(resolvedMethodGenerics, type);
- // there of course transformed parameter type and argument must fit
- failure |= !typeCheckMethodArgumentWithGenerics(type, wrappedArgument,
lastArg);
- return failure;
+ // then of course transformed parameter type and argument must fit
+ return failure || !typeCheckMethodArgumentWithGenerics(type,
wrappedArgument, lastArg);
}
private static GenericsType buildWildcardType(GenericsType origin) {
@@ -1872,12 +1884,10 @@ public abstract class StaticTypeCheckingSupport {
return GenericsUtils.extractPlaceholders(newTarget);
}
- private static GenericsType[] applyGenericsContext(
- Map<GenericsTypeName, GenericsType> spec, GenericsType[] gts
- ) {
- if (gts == null) return null;
+ static GenericsType[] applyGenericsContext(final Map<GenericsTypeName,
GenericsType> spec, final GenericsType[] gts) {
+ if (gts == null || spec == null || spec.isEmpty()) return gts;
GenericsType[] newGTs = new GenericsType[gts.length];
- for (int i = 0; i < gts.length; i++) {
+ for (int i = 0, n = gts.length; i < n; i += 1) {
GenericsType gt = gts[i];
newGTs[i] = applyGenericsContext(spec, gt);
}
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 c8b4e19..e9b25ea 100644
---
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -129,6 +129,7 @@ import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static org.apache.groovy.ast.tools.ClassNodeUtils.samePackageName;
+import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
import static org.codehaus.groovy.ast.ClassHelper.BigDecimal_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.BigInteger_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.Boolean_TYPE;
@@ -542,21 +543,17 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
private void checkSuperCallFromClosure(Expression call, MethodNode
directCallTarget) {
- if (call instanceof MethodCallExpression &&
typeCheckingContext.getEnclosingClosure() != null) {
- Expression objectExpression = ((MethodCallExpression)
call).getObjectExpression();
- if (objectExpression instanceof VariableExpression) {
- VariableExpression var = (VariableExpression) objectExpression;
- if (var.isSuperExpression()) {
- ClassNode current =
typeCheckingContext.getEnclosingClassNode();
- LinkedList<MethodNode> list =
current.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED);
- if (list == null) {
- list = new LinkedList<MethodNode>();
-
current.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, list);
- }
- list.add(directCallTarget);
-
call.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, current);
- }
+ if (call instanceof MethodCallExpression
+ && typeCheckingContext.getEnclosingClosure() != null
+ && isSuperExpression(((MethodCallExpression)
call).getObjectExpression())) {
+ ClassNode current = typeCheckingContext.getEnclosingClassNode();
+ LinkedList<MethodNode> list =
current.getNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED);
+ if (list == null) {
+ list = new LinkedList<MethodNode>();
+
current.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED, list);
}
+ list.add(directCallTarget);
+ call.putNodeMetaData(StaticTypesMarker.SUPER_MOP_METHOD_REQUIRED,
current);
}
}
@@ -849,14 +846,13 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
ClassNode completedType =
GenericsUtils.parameterizeType(lType, resultType.getPlainNodeReference());
resultType = completedType;
-
}
+
if (isArrayOp(op)
&& !lType.isArray()
&& enclosingBinaryExpression != null
&& enclosingBinaryExpression.getLeftExpression() ==
expression
- &&
isAssignment(enclosingBinaryExpression.getOperation().getType())
- ) {
+ &&
isAssignment(enclosingBinaryExpression.getOperation().getType())) {
// left hand side of an assignment : map['foo'] = ...
Expression enclosingBE_rightExpr =
enclosingBinaryExpression.getRightExpression();
if (!(enclosingBE_rightExpr instanceof ClosureExpression)) {
@@ -1032,28 +1028,28 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
protected void inferDiamondType(final ConstructorCallExpression cce, final
ClassNode lType) {
+ ClassNode cceType = cce.getType();
// check if constructor call expression makes use of the diamond
operator
- ClassNode node = cce.getType();
- if (node.isUsingGenerics() && node.getGenericsTypes() != null &&
node.getGenericsTypes().length == 0) {
+ if (cceType.getGenericsTypes() != null &&
cceType.getGenericsTypes().length == 0) {
ArgumentListExpression argumentListExpression =
InvocationWriter.makeArgumentList(cce.getArguments());
if (argumentListExpression.getExpressions().isEmpty()) {
- adjustGenerics(lType, node);
+ adjustGenerics(lType, cceType);
} else {
ClassNode type =
getType(argumentListExpression.getExpression(0));
if (type.isUsingGenerics()) {
- adjustGenerics(type, node);
+ adjustGenerics(type, cceType);
}
}
// store inferred type on CCE
- storeType(cce, node);
+ storeType(cce, cceType);
}
}
- private void adjustGenerics(ClassNode from, ClassNode to) {
- GenericsType[] genericsTypes = from.getGenericsTypes();
+ private void adjustGenerics(final ClassNode source, final ClassNode
target) {
+ GenericsType[] genericsTypes = source.getGenericsTypes();
if (genericsTypes == null) {
// case of: def foo = new HashMap<>()
- genericsTypes = to.redirect().getGenericsTypes();
+ genericsTypes = target.redirect().getGenericsTypes();
}
GenericsType[] copy = new GenericsType[genericsTypes.length];
for (int i = 0; i < genericsTypes.length; i++) {
@@ -1064,7 +1060,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
genericsType.getLowerBound()
);
}
- to.setGenericsTypes(copy);
+ target.setGenericsTypes(copy);
}
/**
@@ -1237,8 +1233,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
final Expression leftExpression,
final ClassNode leftExpressionType,
final Expression rightExpression,
- final ClassNode inferredRightExpressionTypeOrig) {
- ClassNode inferredRightExpressionType =
inferredRightExpressionTypeOrig;
+ final ClassNode rightExpressionType) {
+ ClassNode inferredRightExpressionType = rightExpressionType;
if (!typeCheckMultipleAssignmentAndContinue(leftExpression,
rightExpression)) return;
// TODO: need errors for write-only too!
@@ -1571,10 +1567,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
// GROOVY-5568: the property may be defined by DGM
- List<ClassNode> dgmReceivers = new ArrayList<ClassNode>(2);
- dgmReceivers.add(receiverType);
- if (isPrimitiveType(receiverType))
dgmReceivers.add(getWrapper(receiverType));
- for (ClassNode dgmReceiver : dgmReceivers) {
+ for (ClassNode dgmReceiver : isPrimitiveType(receiverType) ? new
ClassNode[]{receiverType, getWrapper(receiverType)} : new
ClassNode[]{receiverType}) {
List<MethodNode> methods =
findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver,
"get" + capName, ClassNode.EMPTY_ARRAY);
for (MethodNode m :
findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver,
"is" + capName, ClassNode.EMPTY_ARRAY)) {
if (Boolean_TYPE.equals(getWrapper(m.getReturnType())))
methods.add(m);
@@ -1618,8 +1611,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
for (Receiver<String> receiver : receivers) {
ClassNode receiverType = receiver.getType();
ClassNode propertyType =
getTypeForMapPropertyExpression(receiverType, objectExpressionType, pexp);
- if (propertyType == null)
- propertyType = getTypeForListPropertyExpression(receiverType,
objectExpressionType, pexp);
+ if (propertyType == null) propertyType =
getTypeForListPropertyExpression(receiverType, objectExpressionType, pexp);
if (propertyType == null) propertyType =
getTypeForSpreadExpression(receiverType, objectExpressionType, pexp);
if (propertyType == null) continue;
if (visitor != null) {
@@ -1690,8 +1682,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
AtomicReference<ClassNode> result = new AtomicReference<ClassNode>();
if (existsProperty(subExp, true, new PropertyLookupVisitor(result))) {
intf = LIST_TYPE.getPlainNodeReference();
- ClassNode itemType = result.get();
- intf.setGenericsTypes(new GenericsType[]{new
GenericsType(wrapTypeIfNecessary(itemType))});
+ intf.setGenericsTypes(new GenericsType[]{new
GenericsType(wrapTypeIfNecessary(result.get()))});
return intf;
}
return null;
@@ -2040,7 +2031,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
visitPrefixOrPostifExpression(expression, inner, type);
}
- private static ClassNode getMathWideningClassNode(ClassNode type) {
+ private static ClassNode getMathWideningClassNode(final ClassNode type) {
if (byte_TYPE.equals(type) || short_TYPE.equals(type) ||
int_TYPE.equals(type)) {
return int_TYPE;
}
@@ -2159,16 +2150,16 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
type =
expression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
}
MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
- if (enclosingMethod != null &&
typeCheckingContext.getEnclosingClosure() == null) {
- if (!enclosingMethod.isVoidMethod()
- && !type.equals(void_WRAPPER_TYPE)
+ if (enclosingMethod != null && !enclosingMethod.isVoidMethod()) {
+ ClassNode returnType = enclosingMethod.getReturnType();
+ if (!isNullConstant(expression)
&& !type.equals(VOID_TYPE)
- &&
!checkCompatibleAssignmentTypes(enclosingMethod.getReturnType(), type, null,
false)
- && !(isNullConstant(expression))) {
+ && !type.equals(void_WRAPPER_TYPE)
+ && !checkCompatibleAssignmentTypes(returnType, type, null,
false)) {
if (!extension.handleIncompatibleReturnType(statement, type)) {
- addStaticTypeError("Cannot return value of type " +
type.toString(false) + " on method returning type " +
enclosingMethod.getReturnType().toString(false), expression);
+ addStaticTypeError("Cannot return value of type " +
type.toString(false) + " on method returning type " +
returnType.toString(false), expression);
}
- } else if (!enclosingMethod.isVoidMethod()) {
+ } else {
ClassNode previousType =
getInferredReturnType(enclosingMethod);
ClassNode inferred = previousType == null ? type :
lowestUpperBound(type, previousType);
if (implementsInterfaceOrIsSubclassOf(inferred,
enclosingMethod.getReturnType())) {
@@ -2191,8 +2182,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
protected void addClosureReturnType(ClassNode returnType) {
- if (VOID_TYPE.equals(returnType)) return; // GROOVY-8202
- typeCheckingContext.getEnclosingClosure().addReturnType(returnType);
+ if (returnType != null && !returnType.equals(VOID_TYPE)) // GROOVY-8202
+
typeCheckingContext.getEnclosingClosure().addReturnType(returnType);
}
@Override
@@ -2203,10 +2194,13 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
extension.afterMethodCall(call);
return;
}
- ClassNode receiver = call.isThisCall() ?
typeCheckingContext.getEnclosingClassNode() :
- call.isSuperCall() ?
typeCheckingContext.getEnclosingClassNode().getSuperClass() : call.getType();
+ ClassNode receiver = call.getType();
+ if (call.isThisCall()) {
+ receiver = typeCheckingContext.getEnclosingClassNode();
+ } else if (call.isSuperCall()) {
+ receiver =
typeCheckingContext.getEnclosingClassNode().getSuperClass();
+ }
Expression arguments = call.getArguments();
-
ArgumentListExpression argumentList =
InvocationWriter.makeArgumentList(arguments);
checkForbiddenSpreadArgument(argumentList);
@@ -2623,8 +2617,9 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
for (Receiver<String> currentReceiver : receivers) {
mn = findMethod(currentReceiver.getType(), name, args);
if (!mn.isEmpty()) {
- if (mn.size() == 1)
+ if (mn.size() == 1) {
typeCheckMethodsWithGenericsOrFail(currentReceiver.getType(), args, mn.get(0),
call);
+ }
chosenReceiver = currentReceiver;
break;
}
@@ -2662,8 +2657,6 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
/**
- * @param callArguments
- * @param receiver
* @deprecated this method is unused, replaced with {@link DelegatesTo}
inference.
*/
@Deprecated
@@ -2698,37 +2691,35 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
startMethodInference(directMethodCallCandidate, collector);
}
- protected void visitMethodCallArguments(final ClassNode receiver,
ArgumentListExpression arguments, boolean visitClosures, final MethodNode
selectedMethod) {
+ protected void visitMethodCallArguments(final ClassNode receiver, final
ArgumentListExpression arguments, final boolean visitClosures, final MethodNode
selectedMethod) {
Parameter[] params = selectedMethod != null ?
selectedMethod.getParameters() : Parameter.EMPTY_ARRAY;
List<Expression> expressions = new
LinkedList<Expression>(arguments.getExpressions());
if (selectedMethod instanceof ExtensionMethodNode) {
params = ((ExtensionMethodNode)
selectedMethod).getExtensionMethodNode().getParameters();
expressions.add(0, varX("$self", receiver));
}
- ArgumentListExpression newArgs = args(expressions);
+ if (expressions.isEmpty()) return;
- for (int i = 0, expressionsSize = expressions.size(); i <
expressionsSize; i++) {
+ for (int i = 0, n = expressions.size(); i < n; i++) {
final Expression expression = expressions.get(i);
if (visitClosures && expression instanceof ClosureExpression
|| !visitClosures && !(expression instanceof
ClosureExpression)) {
if (i < params.length && visitClosures) {
Parameter param = params[i];
- checkClosureWithDelegatesTo(receiver, selectedMethod,
newArgs, params, expression, param);
+ checkClosureWithDelegatesTo(receiver, selectedMethod,
args(expressions), params, expression, param);
if (selectedMethod instanceof ExtensionMethodNode) {
if (i > 0) {
inferClosureParameterTypes(receiver, arguments,
(ClosureExpression) expression, param, selectedMethod);
}
} else {
- inferClosureParameterTypes(receiver, newArgs,
(ClosureExpression) expression, param, selectedMethod);
+ inferClosureParameterTypes(receiver, arguments,
(ClosureExpression) expression, param, selectedMethod);
}
}
expression.visit(this);
- if
(expression.getNodeMetaData(StaticTypesMarker.DELEGATION_METADATA) != null) {
-
expression.removeNodeMetaData(StaticTypesMarker.DELEGATION_METADATA);
- }
+
expression.removeNodeMetaData(StaticTypesMarker.DELEGATION_METADATA);
}
}
- if (expressions.size() > 0 && expressions.get(0) instanceof
MapExpression && params.length > 0) {
+ if (params.length > 0 && expressions.get(0) instanceof MapExpression) {
checkNamedParamsAnnotation(params[0], (MapExpression)
expressions.get(0));
}
}
@@ -2805,7 +2796,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
}
- private ClassNode getDeclaredOrInferredType(Expression expression) {
+ private ClassNode getDeclaredOrInferredType(final Expression expression) {
ClassNode declaredOrInferred;
// in case of "T t = new ExtendsOrImplementsT()", return T for the
expression type
if (expression instanceof Variable && !((Variable)
expression).isDynamicTyped()) {
@@ -3384,7 +3375,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
} else if (objectExpression instanceof ClosureExpression) {
// we can get actual parameters directly
Parameter[] parameters = ((ClosureExpression)
objectExpression).getParameters();
- typeCheckClosureCall(callArguments, args, parameters);
+ if (parameters != null)
typeCheckClosureCall(callArguments, args, parameters);
ClassNode data = getInferredReturnType(objectExpression);
if (data != null) {
storeType(call, data);
@@ -3422,7 +3413,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// if we are not in a static context but the current
receiver is a static class, we must
// ensure that all methods are either static or declared
by the current receiver or a superclass
if (!mn.isEmpty()
- && (typeCheckingContext.isInStaticContext ||
(receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)
+ && (typeCheckingContext.isInStaticContext ||
Modifier.isStatic(receiverType.getModifiers()))
&& (call.isImplicitThis() || (objectExpression
instanceof VariableExpression && ((VariableExpression)
objectExpression).isThisExpression()))) {
// we create separate method lists just to be able to
print out
// a nice error message to the user
@@ -3941,6 +3932,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
for (ClassNode value : allValues) {
if (value != null) nonNullValues.add(value);
}
+ if (nonNullValues.isEmpty()) continue;
+
ClassNode cn = lowestUpperBound(nonNullValues);
storeType(key, cn);
assignments.put(key, cn);
@@ -3996,9 +3989,9 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// char c = (char) ...
} else if (sourceIsNull && isPrimitiveType(targetType) &&
!boolean_TYPE.equals(targetType)) {
return false;
- } else if ((expressionType.getModifiers() & Opcodes.ACC_FINAL) == 0 &&
targetType.isInterface()) {
+ } else if (!Modifier.isFinal(expressionType.getModifiers()) &&
targetType.isInterface()) {
return true;
- } else if ((targetType.getModifiers() & Opcodes.ACC_FINAL) == 0 &&
expressionType.isInterface()) {
+ } else if (!Modifier.isFinal(targetType.getModifiers()) &&
expressionType.isInterface()) {
return true;
} else if (!isAssignableTo(targetType, expressionType) &&
!implementsInterfaceOrIsSubclassOf(expressionType, targetType)) {
return false;
@@ -4025,13 +4018,11 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
ClassNode typeOfFalse = getType(falseExpression);
// handle instanceof cases
if (hasInferredReturnType(falseExpression)) {
- typeOfFalse =
falseExpression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
+ typeOfFalse = getInferredReturnType(falseExpression);
}
if (hasInferredReturnType(trueExpression)) {
- typeOfTrue =
trueExpression.getNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE);
+ typeOfTrue = getInferredReturnType(trueExpression);
}
- // TODO consider moving next two statements "up a level", i.e. have
just one more widely invoked
- // check but determine no -ve consequences first
typeOfFalse = checkForTargetType(falseExpression, typeOfFalse);
typeOfTrue = checkForTargetType(trueExpression, typeOfTrue);
if (isNullConstant(trueExpression) || isNullConstant(falseExpression))
{
@@ -4088,8 +4079,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
private static boolean isEmptyCollection(Expression expr) {
- return (expr instanceof ListExpression && ((ListExpression)
expr).getExpressions().size() == 0) ||
- (expr instanceof MapExpression && ((MapExpression)
expr).getMapEntryExpressions().size() == 0);
+ return (expr instanceof ListExpression && ((ListExpression)
expr).getExpressions().isEmpty())
+ || (expr instanceof MapExpression && ((MapExpression)
expr).getMapEntryExpressions().isEmpty());
}
private static boolean hasInferredReturnType(Expression expression) {
@@ -4181,6 +4172,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
Expression leftExpression = expr.getLeftExpression();
Expression rightExpression = expr.getRightExpression();
+
if (op == ASSIGN || op == ASSIGNMENT_OPERATOR) {
if (leftRedirect.isArray() &&
implementsInterfaceOrIsSubclassOf(rightRedirect, Collection_TYPE))
return leftRedirect;
@@ -4198,12 +4190,13 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// ex : def foos = ['a','b','c']
return right;
}
- if (rightRedirect.isDerivedFrom(CLOSURE_TYPE) &&
isSAMType(leftRedirect) && rightExpression instanceof ClosureExpression) {
+ if (rightExpression instanceof ClosureExpression &&
rightRedirect.isDerivedFrom(CLOSURE_TYPE) && isSAMType(leftRedirect)) {
return inferSAMTypeGenericsInAssignment(left, findSAM(left),
right, (ClosureExpression) rightExpression);
}
if (leftExpression instanceof VariableExpression) {
ClassNode initialType =
getOriginalDeclarationType(leftExpression).redirect();
+
if (isPrimitiveType(right) &&
initialType.isDerivedFrom(Number_TYPE)) {
return getWrapper(right);
}
@@ -4212,7 +4205,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return getUnwrapper(right);
}
- // as anything can be assigned to a String, Class or boolean,
return the left type instead
+ // as anything can be assigned to a String, Class or
[Bb]oolean, return the left type instead
if (STRING_TYPE.equals(initialType)
|| CLASS_Type.equals(initialType)
|| Boolean_TYPE.equals(initialType)
@@ -4329,7 +4322,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
// extract the generics from the return type
Map<GenericsTypeName, GenericsType> connections = new
HashMap<GenericsTypeName, GenericsType>();
- extractGenericsConnections(connections,
getInferredReturnType(closureExpression), sam.getReturnType());
+ extractGenericsConnections(connections,
wrapTypeIfNecessary(getInferredReturnType(closureExpression)),
sam.getReturnType());
// next we get the block parameter types and set the generics
// information just like before
@@ -4337,7 +4330,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (closureExpression.isParameterSpecified()) {
Parameter[] closureParams = closureExpression.getParameters();
Parameter[] methodParams = sam.getParameters();
- for (int i = 0; i < closureParams.length; i++) {
+ for (int i = 0, n = Math.min(closureParams.length,
methodParams.length); i < n; i += 1) {
ClassNode fromClosure = closureParams[i].getType();
ClassNode fromMethod = methodParams[i].getType();
extractGenericsConnections(connections, fromClosure,
fromMethod);
@@ -4372,10 +4365,9 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
protected ClassNode inferComponentType(final ClassNode containerType,
final ClassNode indexType) {
- final ClassNode componentType = containerType.getComponentType();
+ ClassNode componentType = containerType.getComponentType();
if (componentType == null) {
- // GROOVY-5521
- // try to identify a getAt method
+ // GROOVY-5521: check for a suitable "getAt(T)" method
typeCheckingContext.pushErrorCollector();
MethodCallExpression vcall = callX(localVarX("_hash_",
containerType), "getAt", varX("_index_", indexType));
vcall.setImplicitThis(false); // GROOVY-8943
@@ -4385,9 +4377,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
typeCheckingContext.popErrorCollector();
}
return getType(vcall);
- } else {
- return componentType;
}
+ return componentType;
}
protected MethodNode findMethodOrFail(
@@ -4549,8 +4540,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return result;
}
- protected List<MethodNode> findMethod(
- ClassNode receiver, String name, ClassNode... args) {
+ protected List<MethodNode> findMethod(ClassNode receiver, final String
name, final ClassNode... args) {
if (isPrimitiveType(receiver)) receiver = getWrapper(receiver);
List<MethodNode> methods;
if (!receiver.isInterface() && "<init>".equals(name)) {
@@ -4651,16 +4641,15 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
}
}
- if (receiver.equals(CLASS_Type) && receiver.getGenericsTypes() !=
null) {
- List<MethodNode> result =
findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
- if (!result.isEmpty()) return result;
+ if (isClassClassNodeWrappingConcreteType(receiver)) {
+ chosen = findMethod(receiver.getGenericsTypes()[0].getType(),
name, args);
+ if (!chosen.isEmpty()) return chosen;
+ }
+ if (receiver.equals(GSTRING_TYPE)) {
+ return findMethod(STRING_TYPE, name, args);
}
-
- if (ClassHelper.GSTRING_TYPE.equals(receiver)) return
findMethod(ClassHelper.STRING_TYPE, name, args);
-
if (isBeingCompiled(receiver)) {
- chosen = findMethod(GROOVY_OBJECT_TYPE, name, args);
- if (!chosen.isEmpty()) return chosen;
+ return findMethod(GROOVY_OBJECT_TYPE, name, args);
}
return EMPTY_METHODNODE_LIST;
@@ -4781,7 +4770,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
if (variable instanceof FieldNode) {
ClassNode fieldType = variable.getOriginType();
if (isUsingGenericsOrIsArrayUsingGenerics(fieldType)) {
- boolean isStatic = (variable.getModifiers() &
Opcodes.ACC_STATIC) != 0;
+ boolean isStatic =
Modifier.isStatic(variable.getModifiers());
ClassNode thisType =
typeCheckingContext.getEnclosingClassNode(), declType = ((FieldNode)
variable).getDeclaringClass();
Map<GenericsTypeName, GenericsType> placeholders =
resolvePlaceHoldersFromDeclaration(thisType, declType, null, isStatic);
@@ -5080,8 +5069,8 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
List<Expression> expressions = argList.getExpressions();
int paramLength = parameters.length;
if (expressions.size() >= paramLength) {
- for (int i = 0; i < paramLength; i++) {
- boolean lastArg = i == paramLength - 1;
+ for (int i = 0; i < paramLength; i += 1) {
+ boolean lastArg = (i == paramLength - 1);
ClassNode type = parameters[i].getType();
ClassNode actualType = getType(expressions.get(i));
while (!type.isUsingGenerics() && type.isArray() &&
actualType.isArray()) {
@@ -5328,7 +5317,6 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
return cn.isGenericsPlaceHolder();
}
-
private static Map<GenericsTypeName, GenericsType>
extractPlaceHolders(MethodNode method, ClassNode receiver, ClassNode
declaringClass) {
if (declaringClass.equals(OBJECT_TYPE)) {
Map<GenericsTypeName, GenericsType> resolvedPlaceholders = new
HashMap<GenericsTypeName, GenericsType>();
@@ -5350,7 +5338,7 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
ClassNode current = item;
while (current != null) {
boolean continueLoop = true;
- //extract the place holders
+ // extract the place holders
Map<GenericsTypeName, GenericsType> currentPlaceHolders = new
HashMap<GenericsTypeName, GenericsType>();
if (isGenericsPlaceHolderOrArrayOf(declaringClass) ||
declaringClass.equals(current)) {
extractGenericsConnections(currentPlaceHolders, current,
declaringClass);
@@ -5701,16 +5689,6 @@ public class StaticTypeCheckingVisitor extends
ClassCodeVisitorSupport {
public void setNodeMetaData(Object key, Object value) {
parameter.setNodeMetaData(key, value);
}
-
- @Override
- public int hashCode() {
- return parameter.hashCode();
- }
-
- @Override
- public boolean equals(Object other) {
- return parameter.equals(other);
- }
}
private static ClassNode infer(Variable variable) {