You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2022/02/27 19:23:56 UTC
[groovy] 01/01: sync with 2_5_X
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 4d45668fe870c12c14cc7582c426e105532c0b49
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sun Feb 27 11:59:11 2022 -0600
sync with 2_5_X
---
.../groovy/antlr/UnicodeEscapingReader.java | 11 ++-
.../java/org/codehaus/groovy/ast/ClassHelper.java | 10 +--
.../java/org/codehaus/groovy/ast/ClassNode.java | 16 ++---
.../java/org/codehaus/groovy/ast/CompileUnit.java | 52 +++++++-------
.../org/codehaus/groovy/ast/GroovyCodeVisitor.java | 8 ++-
.../java/org/codehaus/groovy/ast/ImportNode.java | 2 +-
.../codehaus/groovy/ast/expr/RangeExpression.java | 14 ++--
.../codehaus/groovy/ast/tools/GeneralUtils.java | 8 +++
.../groovy/ast/tools/WideningCategories.java | 11 ++-
.../groovy/classgen/AsmClassGenerator.java | 21 +++---
.../org/codehaus/groovy/classgen/EnumVisitor.java | 8 +--
.../groovy/classgen/VariableScopeVisitor.java | 5 +-
.../org/codehaus/groovy/classgen/Verifier.java | 9 ++-
.../codehaus/groovy/classgen/asm/CompileStack.java | 2 +-
.../classgen/asm/sc/StaticTypesCallSiteWriter.java | 32 ++++-----
...StaticTypesMethodReferenceExpressionWriter.java | 2 +-
.../asm/sc/StaticTypesStatementWriter.java | 2 -
.../codehaus/groovy/control/CompilationUnit.java | 6 +-
.../groovy/control/CompilerConfiguration.java | 81 ++++++++--------------
.../codehaus/groovy/control/ErrorCollector.java | 13 ++--
.../codehaus/groovy/control/ResolveVisitor.java | 21 +++---
.../org/codehaus/groovy/control/SourceUnit.java | 12 ++--
.../groovy/control/StaticImportVisitor.java | 8 ++-
.../groovy/transform/ASTTransformationVisitor.java | 7 +-
.../groovy/transform/FieldASTTransformation.java | 18 ++---
.../transform/sc/TemporaryVariableExpression.java | 19 ++---
.../transformers/BinaryExpressionTransformer.java | 2 +-
.../transform/stc/StaticTypeCheckingSupport.java | 39 +++++++----
.../transform/stc/StaticTypeCheckingVisitor.java | 69 ++++++++----------
.../groovy/transform/trait/TraitComposer.java | 2 +-
.../transform/trait/TraitReceiverTransformer.java | 8 +--
.../codehaus/groovy/transform/trait/Traits.java | 3 +-
32 files changed, 250 insertions(+), 271 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/antlr/UnicodeEscapingReader.java b/src/main/java/org/codehaus/groovy/antlr/UnicodeEscapingReader.java
index 107dd5b..055ce86 100644
--- a/src/main/java/org/codehaus/groovy/antlr/UnicodeEscapingReader.java
+++ b/src/main/java/org/codehaus/groovy/antlr/UnicodeEscapingReader.java
@@ -45,6 +45,7 @@ public class UnicodeEscapingReader extends Reader {
private static class DummyLexer extends CharScanner {
private final Token t = new Token();
+ @Override
public Token nextToken() throws TokenStreamException {
return t;
}
@@ -57,7 +58,7 @@ public class UnicodeEscapingReader extends Reader {
return 0;
}
}
-
+
/**
* Constructor.
* @param reader The reader that this reader will filter over.
@@ -80,6 +81,7 @@ public class UnicodeEscapingReader extends Reader {
* Reads characters from the underlying reader.
* @see java.io.Reader#read(char[],int,int)
*/
+ @Override
public int read(char cbuf[], int off, int len) throws IOException {
int c = 0;
int count = 0;
@@ -95,6 +97,7 @@ public class UnicodeEscapingReader extends Reader {
* translating escapes as required.
* @see java.io.Reader#close()
*/
+ @Override
public int read() throws IOException {
if (hasNextChar) {
hasNextChar = false;
@@ -107,7 +110,7 @@ public class UnicodeEscapingReader extends Reader {
numUnicodeEscapesFoundOnCurrentLine = 0;
previousLine = lexer.getLine();
}
-
+
int c = reader.read();
if (c != '\\') {
write(c);
@@ -143,12 +146,13 @@ public class UnicodeEscapingReader extends Reader {
}
int rv = Integer.parseInt(charNum.toString(), 16);
write(rv);
-
+
numUnicodeEscapesFound += 4 + numberOfUChars;
numUnicodeEscapesFoundOnCurrentLine += 4 + numberOfUChars;
return rv;
}
+
private void write(int c) {
if (sourceBuffer != null) {sourceBuffer.write(c);}
}
@@ -185,6 +189,7 @@ public class UnicodeEscapingReader extends Reader {
*
* @see java.io.Reader#close()
*/
+ @Override
public void close() throws IOException {
reader.close();
}
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
index 413ac68..6045883f 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassHelper.java
@@ -176,8 +176,8 @@ public class ClassHelper {
public static final String OBJECT = "java.lang.Object";
public static ClassNode makeCached(Class c) {
- final SoftReference<ClassNode> classNodeSoftReference = ClassHelperCache.classCache.get(c);
ClassNode classNode;
+ final SoftReference<ClassNode> classNodeSoftReference = ClassHelperCache.classCache.get(c);
if (classNodeSoftReference == null || (classNode = classNodeSoftReference.get()) == null) {
classNode = new ClassNode(c);
ClassHelperCache.classCache.put(c, new SoftReference<ClassNode>(classNode));
@@ -369,7 +369,7 @@ public class ClassHelper {
*/
public static boolean isStaticConstantInitializerType(ClassNode cn) {
cn = cn.redirect();
- return cn == int_TYPE ||
+ return (cn == int_TYPE ||
cn == float_TYPE ||
cn == long_TYPE ||
cn == double_TYPE ||
@@ -377,12 +377,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) {
cn = cn.redirect();
- return cn == Byte_TYPE ||
+ return (cn == Byte_TYPE ||
cn == Short_TYPE ||
cn == Integer_TYPE ||
cn == Long_TYPE ||
@@ -393,7 +393,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/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 4769125..4e09342 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -47,9 +47,9 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
-import java.util.stream.Collectors;
import static java.util.Arrays.stream;
+import static java.util.stream.Collectors.toList;
import static java.util.stream.Collectors.joining;
import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
@@ -401,7 +401,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
*/
public List<MethodNode> getAbstractMethods() {
return getDeclaredMethodsMap().values().stream()
- .filter(MethodNode::isAbstract).collect(Collectors.toList());
+ .filter(MethodNode::isAbstract).collect(toList());
}
public List<MethodNode> getAllDeclaredMethods() {
@@ -683,7 +683,8 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
if (that == this) return true;
if (!(that instanceof ClassNode)) return false;
if (redirect != null) return redirect.equals(that);
- return (((ClassNode) that).getText().equals(getText()));
+ if (componentType != null) return componentType.equals(((ClassNode) that).componentType);
+ return ((ClassNode) that).getText().equals(getText()); // arrays could be "T[]" or "[LT;"
}
public int hashCode() {
@@ -1122,8 +1123,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
boolean booleanReturnOnly = getterName.startsWith("is");
for (MethodNode method : getDeclaredMethods(getterName)) {
if (getterName.equals(method.getName())
- && ClassHelper.VOID_TYPE != method.getReturnType()
- && method.getParameters().length == 0
+ && method.getParameters().length == 0 && !method.isVoidMethod()
&& (!booleanReturnOnly || ClassHelper.Boolean_TYPE.equals(ClassHelper.getWrapper(method.getReturnType())))) {
// GROOVY-7363: There can be multiple matches for a getter returning a generic parameter type, due to
// the generation of a bridge method. The real getter is really the non-bridge, non-synthetic one as it
@@ -1153,8 +1153,8 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
public MethodNode getSetterMethod(String setterName, boolean voidOnly) {
for (MethodNode method : getDeclaredMethods(setterName)) {
if (setterName.equals(method.getName())
- && (!voidOnly || ClassHelper.VOID_TYPE == method.getReturnType())
- && method.getParameters().length == 1) {
+ && method.getParameters().length == 1
+ && (!voidOnly || method.isVoidMethod())) {
return method;
}
}
@@ -1212,7 +1212,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
ret.append(">");
}
if (showRedirect && redirect != null) {
- ret.append(" -> ").append(redirect.toString());
+ ret.append(" -> ").append(redirect);
}
return ret.toString();
}
diff --git a/src/main/java/org/codehaus/groovy/ast/CompileUnit.java b/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
index c6e92ac..2d2a972 100644
--- a/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
+++ b/src/main/java/org/codehaus/groovy/ast/CompileUnit.java
@@ -52,7 +52,7 @@ public class CompileUnit implements NodeMetaDataHandler {
private final Map<String, ClassNode> classesToCompile = new LinkedHashMap<>();
private final Map<String, SourceUnit> classNameToSource = new LinkedHashMap<>();
private final Map<String, InnerClassNode> generatedInnerClasses = new LinkedHashMap<>();
- private final Map<String, ConstructedOuterNestedClassNode> classesToResolve = new LinkedHashMap<>();
+
private Map metaDataMap;
public CompileUnit(GroovyClassLoader classLoader, CompilerConfiguration config) {
@@ -61,8 +61,8 @@ public class CompileUnit implements NodeMetaDataHandler {
public CompileUnit(GroovyClassLoader classLoader, CodeSource codeSource, CompilerConfiguration config) {
this.classLoader = classLoader;
- this.config = config;
this.codeSource = codeSource;
+ this.config = config;
}
public List<ModuleNode> getModules() {
@@ -153,7 +153,7 @@ public class CompileUnit implements NodeMetaDataHandler {
classes.put(name, node);
ClassNode cn = classesToCompile.get(name);
- if (null != cn) {
+ if (cn != null) {
cn.setRedirect(node);
classesToCompile.remove(name);
}
@@ -170,39 +170,48 @@ public class CompileUnit implements NodeMetaDataHandler {
classNameToSource.put(nodeName, location);
}
- public SourceUnit getScriptSourceLocation(String className) {
- return classNameToSource.get(className);
- }
-
- public boolean hasClassNodeToCompile() {
- return !classesToCompile.isEmpty();
+ public Map<String, ClassNode> getClassesToCompile() {
+ return classesToCompile;
}
public Iterator<String> iterateClassNodeToCompile() {
return classesToCompile.keySet().iterator();
}
- public InnerClassNode getGeneratedInnerClass(String name) {
- return generatedInnerClasses.get(name);
+ public boolean hasClassNodeToCompile() {
+ return !classesToCompile.isEmpty();
}
public void addGeneratedInnerClass(InnerClassNode icn) {
generatedInnerClasses.put(icn.getName(), icn);
}
+ public InnerClassNode getGeneratedInnerClass(String name) {
+ return generatedInnerClasses.get(name);
+ }
+
public Map<String, InnerClassNode> getGeneratedInnerClasses() {
return Collections.unmodifiableMap(generatedInnerClasses);
}
- public Map<String, ClassNode> getClassesToCompile() {
- return classesToCompile;
+ public SourceUnit getScriptSourceLocation(String scriptClassName) {
+ return classNameToSource.get(scriptClassName);
}
- @Deprecated
- public Map<String, ConstructedOuterNestedClassNode> getClassesToResolve() {
- return classesToResolve;
+ @Override
+ public Map<?, ?> getMetaDataMap() {
+ return metaDataMap;
}
+ @Override
+ public void setMetaDataMap(Map<?, ?> metaDataMap) {
+ this.metaDataMap = metaDataMap;
+ }
+
+ //--------------------------------------------------------------------------
+
+ private final Map<String, ConstructedOuterNestedClassNode> classesToResolve = new LinkedHashMap<>();
+
/**
* Add a constructed class node as a placeholder to resolve outer nested class further.
*
@@ -213,14 +222,9 @@ public class CompileUnit implements NodeMetaDataHandler {
classesToResolve.put(cn.getUnresolvedName(), cn);
}
- @Override
- public Map<?, ?> getMetaDataMap() {
- return metaDataMap;
- }
-
- @Override
- public void setMetaDataMap(Map<?, ?> metaDataMap) {
- this.metaDataMap = metaDataMap;
+ @Deprecated
+ public Map<String, ConstructedOuterNestedClassNode> getClassesToResolve() {
+ return classesToResolve;
}
/**
diff --git a/src/main/java/org/codehaus/groovy/ast/GroovyCodeVisitor.java b/src/main/java/org/codehaus/groovy/ast/GroovyCodeVisitor.java
index be45610..56ec5b9 100644
--- a/src/main/java/org/codehaus/groovy/ast/GroovyCodeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/ast/GroovyCodeVisitor.java
@@ -117,7 +117,8 @@ public interface GroovyCodeVisitor {
void visitCatchStatement(CatchStatement statement);
- default void visitEmptyStatement(EmptyStatement statement) {}
+ default void visitEmptyStatement(EmptyStatement statement) {
+ }
//--------------------------------------------------------------------------
// expressions
@@ -196,9 +197,10 @@ public interface GroovyCodeVisitor {
void visitBytecodeExpression(BytecodeExpression expression);
- default void visitEmptyExpression(EmptyExpression expression) {}
+ default void visitEmptyExpression(EmptyExpression expression) {
+ }
- default void visitListOfExpressions(List<? extends Expression> list) {
+ default void visitListOfExpressions(final List<? extends Expression> list) {
if (list != null) list.forEach(expr -> expr.visit(this));
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/ImportNode.java b/src/main/java/org/codehaus/groovy/ast/ImportNode.java
index 406788f..e6665aa 100644
--- a/src/main/java/org/codehaus/groovy/ast/ImportNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ImportNode.java
@@ -144,7 +144,7 @@ public class ImportNode extends AnnotatedNode {
}
public void setType(final ClassNode type) {
- this.type = type;
+ this.type = requireNonNull(type);
}
@Override
diff --git a/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java b/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
index 983b69e..9ef8252 100644
--- a/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
+++ b/src/main/java/org/codehaus/groovy/ast/expr/RangeExpression.java
@@ -32,19 +32,19 @@ public class RangeExpression extends Expression {
private final Expression to;
private final boolean inclusive;
- public RangeExpression(Expression from, Expression to, boolean inclusive) {
+ public RangeExpression(final Expression from, final Expression to, final boolean inclusive) {
this.from = from;
this.to = to;
this.inclusive = inclusive;
- setType(ClassHelper.RANGE_TYPE);
+ setType(ClassHelper.RANGE_TYPE.getPlainNodeReference());
}
- public void visit(GroovyCodeVisitor visitor) {
+ public void visit(final GroovyCodeVisitor visitor) {
visitor.visitRangeExpression(this);
}
- public Expression transformExpression(ExpressionTransformer transformer) {
- Expression ret = new RangeExpression(transformer.transform(from), transformer.transform(to), inclusive);
+ public Expression transformExpression(final ExpressionTransformer transformer) {
+ Expression ret = new RangeExpression(transformer.transform(getFrom()), transformer.transform(getTo()), isInclusive());
ret.setSourcePosition(this);
ret.copyNodeMetaData(this);
return ret;
@@ -63,8 +63,6 @@ public class RangeExpression extends Expression {
}
public String getText() {
- return "(" + from.getText() +
- (!isInclusive()? "..<" : ".." ) +
- to.getText() + ")";
+ return "(" + getFrom().getText() + (isInclusive() ? ".." : "..<") + getTo().getText() + ")";
}
}
diff --git a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
index 9390a16..41e6efe 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -781,6 +781,14 @@ public class GeneralUtils {
return new TryCatchStatement(tryStatement, finallyStatement);
}
+ public static TryCatchStatement tryCatchS(final Statement tryStatement, final Statement finallyStatement, final CatchStatement... catchStatements) {
+ TryCatchStatement result = new TryCatchStatement(tryStatement, finallyStatement);
+ for (CatchStatement catchStatement : catchStatements) {
+ result.addCatch(catchStatement);
+ }
+ return result;
+ }
+
public static VariableExpression varX(final String name) {
return new VariableExpression(name);
}
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 2682581..b82db72 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.
@@ -298,13 +298,13 @@ public class WideningCategories {
ClassNode superClass = source.getUnresolvedSuperClass();
// copy generic type information if available
if (superClass!=null && superClass.isUsingGenerics()) {
- Map<GenericsTypeName, GenericsType> genericsTypeMap = GenericsUtils.extractPlaceholders(source);
+ Map<GenericsType.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];
- GenericsTypeName gtn = new GenericsTypeName(genericsType.getName());
+ GenericsType.GenericsTypeName gtn = new GenericsType.GenericsTypeName(genericsType.getName());
if (genericsType.isPlaceholder() && genericsTypeMap.containsKey(gtn)) {
copyTypes[i] = genericsTypeMap.get(gtn);
} else {
@@ -658,10 +658,7 @@ public class WideningCategories {
@Override
public int hashCode() {
- int result = super.hashCode();
-// result = 31 * result + (compileTimeClassNode != null ? compileTimeClassNode.hashCode() : 0);
- result = 31 * result + (name != null ? name.hashCode() : 0);
- return result;
+ return 31 * super.hashCode() + (name != null ? name.hashCode() : 0);
}
@Override
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index ae7e188..36602e8 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -373,35 +373,34 @@ public class AsmClassGenerator extends ClassGenerator {
@Override
protected void visitConstructorOrMethod(final MethodNode node, final boolean isConstructor) {
- controller.resetLineNumber();
Parameter[] parameters = node.getParameters();
- String methodType = BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters);
- String signature = BytecodeHelper.getGenericsMethodSignature(node);
- int modifiers = node.getModifiers();
- if (isVargs(node.getParameters())) modifiers |= ACC_VARARGS;
- MethodVisitor mv = classVisitor.visitMethod(modifiers, node.getName(), methodType, signature, buildExceptions(node.getExceptions()));
+ MethodVisitor mv = classVisitor.visitMethod(
+ node.getModifiers() | (isVargs(parameters) ? ACC_VARARGS : 0), node.getName(),
+ BytecodeHelper.getMethodDescriptor(node.getReturnType(), parameters),
+ BytecodeHelper.getGenericsMethodSignature(node),
+ buildExceptions(node.getExceptions()));
controller.setMethodVisitor(mv);
+ controller.resetLineNumber();
visitAnnotations(node, mv);
for (int i = 0, n = parameters.length; i < n; i += 1) {
visitParameterAnnotations(parameters[i], i, mv);
}
- // add parameter names to the MethodVisitor (jdk8+ only)
+ // add parameter names to the MethodVisitor (JDK8+)
if (Optional.ofNullable(controller.getClassNode().getCompileUnit())
.orElseGet(context::getCompileUnit).getConfig().getParameters()) {
for (Parameter parameter : parameters) {
- // TODO: handle ACC_SYNTHETIC for enum method parameters?
- mv.visitParameter(parameter.getName(), 0);
+ mv.visitParameter(parameter.getName(), parameter.getModifiers());
}
}
if (controller.getClassNode().isAnnotationDefinition() && !node.isStaticConstructor()) {
visitAnnotationDefault(node, mv);
} else if (!node.isAbstract()) {
- Statement code = node.getCode();
mv.visitCode();
+ Statement code = node.getCode();
BytecodeInstruction instruction; // fast path for getters, setters, etc.
if (code instanceof BytecodeSequence && (instruction = ((BytecodeSequence) code).getBytecodeInstruction()) != null) {
instruction.visit(mv);
@@ -452,7 +451,7 @@ public class AsmClassGenerator extends ClassGenerator {
}
}
if (!hasCallToSuper) {
- // invokes the super class constructor
+ // add call to "super()"
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, controller.getInternalBaseClassName(), "<init>", "()V", false);
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java b/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
index ef7e6de..aa7e969 100644
--- a/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/EnumVisitor.java
@@ -95,8 +95,8 @@ public class EnumVisitor extends ClassCodeVisitorSupport {
boolean isAic = isAnonymousInnerClass(enumClass);
if (!isAic) {
ClassNode enumRef = enumClass.getPlainNodeReference();
-
- // create $VALUES field
+ minValue = new FieldNode("MIN_VALUE", ACC_FINAL | ACC_PUBLIC | ACC_STATIC, enumRef, enumClass, null);
+ maxValue = new FieldNode("MAX_VALUE", ACC_FINAL | ACC_PUBLIC | ACC_STATIC, enumRef, enumClass, null);
values = new FieldNode("$VALUES", ACC_FINAL | ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, enumRef.makeArray(), enumClass, null);
values.setSynthetic(true);
@@ -111,10 +111,6 @@ public class EnumVisitor extends ClassCodeVisitorSupport {
addMethods(enumClass, values);
checkForAbstractMethods(enumClass);
-
- // create MIN_VALUE and MAX_VALUE fields
- minValue = new FieldNode("MIN_VALUE", ACC_FINAL | ACC_PUBLIC | ACC_STATIC, enumRef, enumClass, null);
- maxValue = new FieldNode("MAX_VALUE", ACC_FINAL | ACC_PUBLIC | ACC_STATIC, enumRef, enumClass, null);
}
addInit(enumClass, minValue, maxValue, values, isAic);
diff --git a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
index ac358dc..a68cda1 100644
--- a/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/VariableScopeVisitor.java
@@ -199,6 +199,8 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
for (ClassNode in : cn.getAllInterfaces()) {
FieldNode fn = in.getDeclaredField(name);
if (fn != null) return fn;
+ PropertyNode pn = in.getProperty(name);
+ if (pn != null) return pn;
}
}
@@ -505,13 +507,12 @@ public class VariableScopeVisitor extends ClassCodeVisitorSupport {
visitAnnotations(field); // GROOVY-7033
Expression initExpression = field.getInitialExpression();
if (initExpression != null) {
- pushState(field.isStatic());
if (initExpression.isSynthetic() && initExpression instanceof VariableExpression
&& ((VariableExpression) initExpression).getAccessedVariable() instanceof Parameter) {
// GROOVY-6834: accessing a parameter which is not yet seen in scope
- popState();
continue;
}
+ pushState(field.isStatic());
initExpression.visit(this);
popState();
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 2458d12..603fcef 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -206,8 +206,8 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
public void visitClass(final ClassNode node) {
this.classNode = node;
- if (Traits.isTrait(node) // maybe possible to have this true in joint compilation mode
- || classNode.isInterface()) {
+ if (classNode.isInterface()
+ || Traits.isTrait(node)) { // maybe possible to have this true in joint compilation mode
//interfaces have no constructors, but this code expects one,
//so create a dummy and don't add it to the class node
ConstructorNode dummy = new ConstructorNode(0, null);
@@ -681,9 +681,8 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
Statement getterBlock = node.getGetterBlock();
if (getterBlock == null) {
MethodNode getter = classNode.getGetterMethod(getterName, !node.isStatic());
- if (getter == null && ClassHelper.boolean_TYPE == node.getType()) {
- String secondGetterName = "is" + capitalize(name);
- getter = classNode.getGetterMethod(secondGetterName);
+ if (getter == null && node.getType().equals(ClassHelper.boolean_TYPE)) {
+ getter = classNode.getGetterMethod("is" + capitalize(name));
}
if (!node.isPrivate() && methodNeedsReplacement(getter)) {
getterBlock = createGetterBlock(node, field);
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java b/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
index 5d8d056..a4bb1c5 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/CompileStack.java
@@ -417,7 +417,7 @@ public class CompileStack implements Opcodes {
clear = false;
pushVariableScope(scope);
defineMethodVariables(parameters, scope.isInStaticContext());
- this.className = BytecodeHelper.getTypeDescription(controller.getClassNode());
+ className = BytecodeHelper.getTypeDescription(controller.getClassNode());
}
/**
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
index 1c651f5..9e5abd0 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesCallSiteWriter.java
@@ -439,7 +439,6 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
}
private boolean makeGetPropertyWithGetter(final Expression receiver, final ClassNode receiverType, final String propertyName, final boolean safe, final boolean implicitThis) {
- // does a getter exist?
String getterName = "get" + capitalize(propertyName);
MethodNode getterNode = receiverType.getGetterMethod(getterName);
if (getterNode == null) {
@@ -450,12 +449,11 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
return false;
}
- // GROOVY-5561: if two files are compiled in the same source unit
- // and that one references the other, the getters for properties have not been
+ // GROOVY-5561: if two files are compiled in the same source unit and
+ // one references the other, the getters for properties have not been
// generated by the compiler yet (generated by the Verifier)
PropertyNode propertyNode = receiverType.getProperty(propertyName);
if (getterNode == null && propertyNode != null) {
- // it is possible to use a getter
String prefix = "get";
if (boolean_TYPE.equals(propertyNode.getOriginType())) {
prefix = "is";
@@ -463,13 +461,12 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
getterName = prefix + capitalize(propertyName);
getterNode = new MethodNode(
getterName,
- ACC_PUBLIC,
+ ACC_PUBLIC | (propertyNode.isStatic() ? ACC_STATIC : 0),
propertyNode.getOriginType(),
Parameter.EMPTY_ARRAY,
ClassNode.EMPTY_ARRAY,
EmptyStatement.INSTANCE);
getterNode.setDeclaringClass(receiverType);
- if (propertyNode.isStatic()) getterNode.setModifiers(ACC_PUBLIC + ACC_STATIC);
}
if (getterNode != null) {
MethodCallExpression call = callX(receiver, getterName);
@@ -487,7 +484,7 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
}
}
- // check direct interfaces (GROOVY-7149)
+ // GROOVY-7149: check direct interfaces
for (ClassNode node : receiverType.getInterfaces()) {
if (makeGetPropertyWithGetter(receiver, node, propertyName, safe, implicitThis)) {
return true;
@@ -764,11 +761,15 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
@Override
public void fallbackAttributeOrPropertySite(final PropertyExpression expression, final Expression objectExpression, final String name, final MethodCallerMultiAdapter adapter) {
- if (name != null && controller.getCompileStack().isLHS()) {
+ CompileStack compileStack = controller.getCompileStack();
+ OperandStack operandStack = controller.getOperandStack();
+
+ if (name != null && compileStack.isLHS()) {
ClassNode receiverType = getPropertyOwnerType(objectExpression);
if (adapter == AsmClassGenerator.setField || adapter == AsmClassGenerator.setGroovyObjectField) {
if (setField(expression, objectExpression, receiverType, name)) return;
- } else if (isThisExpression(objectExpression)) {
+ }
+ if (isThisExpression(objectExpression)) {
ClassNode classNode = controller.getClassNode();
FieldNode fieldNode = receiverType.getField(name);
if (fieldNode != null && fieldNode.isPrivate() && !receiverType.equals(classNode)
@@ -777,9 +778,9 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
if (mutators != null) {
MethodNode methodNode = mutators.get(name);
if (methodNode != null) {
- ClassNode rhsType = controller.getOperandStack().getTopOperand();
- int i = controller.getCompileStack().defineTemporaryVariable("$rhsValue", rhsType, true);
- VariableSlotLoader rhsValue = new VariableSlotLoader(rhsType, i, controller.getOperandStack());
+ ClassNode rhsType = operandStack.getTopOperand();
+ int i = compileStack.defineTemporaryVariable("$rhsValue", rhsType, true);
+ VariableSlotLoader rhsValue = new VariableSlotLoader(rhsType, i, operandStack);
MethodCallExpression call = callX(objectExpression, methodNode.getName(), args(fieldNode.isStatic() ? nullX() : objectExpression, rhsValue));
call.setImplicitThis(expression.isImplicitThis());
@@ -788,11 +789,8 @@ public class StaticTypesCallSiteWriter extends CallSiteWriter implements Opcodes
call.setMethodTarget(methodNode);
call.visit(controller.getAcg());
- // GROOVY-9892: assuming that the mutator method has a return value, make sure the operand
- // stack is not polluted with the result of the method call
- controller.getOperandStack().pop();
-
- controller.getCompileStack().removeVar(i);
+ compileStack.removeVar(i);
+ operandStack.pop(); //9892
return;
}
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
index a56631c..eefac9c 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesMethodReferenceExpressionWriter.java
@@ -302,7 +302,7 @@ public class StaticTypesMethodReferenceExpressionWriter extends MethodReferenceE
}
private static Parameter[] removeFirstParameter(final Parameter[] parameters) {
- return Arrays.stream(parameters).skip(1).toArray(Parameter[]::new);
+ return Arrays.copyOfRange(parameters, 1, parameters.length);
}
/**
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
index 56a59b9..e5e4e15 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesStatementWriter.java
@@ -261,7 +261,5 @@ public class StaticTypesStatementWriter extends StatementWriter {
mv.visitJumpInsn(GOTO, continueLabel);
mv.visitLabel(breakLabel);
-
}
-
}
diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
index fdfce7f..27e377c 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
@@ -114,12 +114,12 @@ public class CompilationUnit extends ProcessingUnit {
}
}
- /** Controls behavior of {@link #classgen} and other routines. */
+ /** Controls behavior of {@link #classgen()} and other routines. */
protected boolean debug;
/** True after the first {@link #configure(CompilerConfiguration)} operation. */
protected boolean configured;
- /** A callback for use during {@link #classgen} */
+ /** A callback for use during {@link #classgen()} */
protected ClassgenCallback classgenCallback;
/** A callback for use during {@link #compile()} */
protected ProgressCallback progressCallback;
@@ -740,7 +740,7 @@ public class CompilationUnit extends ProcessingUnit {
};
/**
- * Runs class generation on a single {@code ClassNode}.
+ * Runs {@link #classgen()} on a single {@code ClassNode}.
*/
private final IPrimaryClassNodeOperation classgen = new IPrimaryClassNodeOperation() {
@Override
diff --git a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
index 8e767ef..d059634 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
@@ -132,13 +132,10 @@ public class CompilerConfiguration {
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 to use when loading/parsing classes, and generating proxy adapter classes.
- */
+ * The ASM API version used when loading/parsing classes and generating proxy adapter classes.
+ */
public static final int ASM_API_VERSION = Opcodes.ASM9;
- /**
- * The default source encoding.
- */
public static final String DEFAULT_SOURCE_ENCODING = "UTF-8";
/**
@@ -446,21 +443,10 @@ public class CompilerConfiguration {
defaultScriptExtension = getSystemPropertySafe("groovy.default.scriptExtension", ".groovy");
optimizationOptions = new HashMap<>(4);
- handleOptimizationOption(optimizationOptions, INVOKEDYNAMIC, "groovy.target.indy");
- handleOptimizationOption(optimizationOptions, GROOVYDOC, "groovy.attach.groovydoc");
- handleOptimizationOption(optimizationOptions, RUNTIME_GROOVYDOC, "groovy.attach.runtime.groovydoc");
- handleOptimizationOption(optimizationOptions, PARALLEL_PARSE, "groovy.parallel.parse");
- }
-
- private void handleOptimizationOption(final Map<String, Boolean> options, final String optionName, final String sysOptionName) {
- String propValue = getSystemPropertySafe(sysOptionName);
- boolean optionEnabled = propValue == null
- ? (DEFAULT != null && Boolean.TRUE.equals(DEFAULT.getOptimizationOptions().get(optionName)))
- : Boolean.parseBoolean(propValue);
-
- if (optionEnabled) {
- options.put(optionName, Boolean.TRUE);
- }
+ if (getBooleanSafe("groovy.target.indy" )) optimizationOptions.put(INVOKEDYNAMIC , Boolean.TRUE);
+ if (getBooleanSafe("groovy.attach.groovydoc" )) optimizationOptions.put(GROOVYDOC , Boolean.TRUE);
+ if (getBooleanSafe("groovy.attach.runtime.groovydoc")) optimizationOptions.put(RUNTIME_GROOVYDOC, Boolean.TRUE);
+ if (getBooleanSafe("groovy.parallel.parse" )) optimizationOptions.put(PARALLEL_PARSE , Boolean.TRUE);
}
/**
@@ -482,7 +468,7 @@ public class CompilerConfiguration {
public CompilerConfiguration(final CompilerConfiguration configuration) {
setWarningLevel(configuration.getWarningLevel());
setTargetDirectory(configuration.getTargetDirectory());
- setClasspathList(new LinkedList<String>(configuration.getClasspath()));
+ setClasspathList(configuration.getClasspath());
setVerbose(configuration.getVerbose());
setDebug(configuration.getDebug());
setParameters(configuration.getParameters());
@@ -746,11 +732,7 @@ public class CompilerConfiguration {
*/
@Deprecated
public void setOutput(final PrintWriter output) {
- if (output == null) {
- this.output = new PrintWriter(NullWriter.DEFAULT);
- } else {
- this.output = output;
- }
+ this.output = (output != null ? output : new PrintWriter(NullWriter.DEFAULT));
}
/**
@@ -763,6 +745,13 @@ public class CompilerConfiguration {
/**
* Sets the target directory.
*/
+ public void setTargetDirectory(final File directory) {
+ this.targetDirectory = directory;
+ }
+
+ /**
+ * Sets the target directory.
+ */
public void setTargetDirectory(final String directory) {
setTargetDirectorySafe(directory);
}
@@ -776,13 +765,6 @@ public class CompilerConfiguration {
}
/**
- * Sets the target directory.
- */
- public void setTargetDirectory(final File directory) {
- this.targetDirectory = directory;
- }
-
- /**
* @return the classpath
*/
public List<String> getClasspath() {
@@ -936,8 +918,18 @@ public class CompilerConfiguration {
}
/**
- * Sets the bytecode compatibility level. The parameter can take one of the values
- * in {@link #ALLOWED_JDKS}.
+ * Returns the compiler bytecode compatibility level. Defaults to the minimum
+ * officially supported bytecode version for any particular Groovy version.
+ *
+ * @return bytecode compatibility level
+ */
+ public String getTargetBytecode() {
+ return targetBytecode;
+ }
+
+ /**
+ * Sets the bytecode compatibility level. The parameter can take one of the
+ * values in {@link #ALLOWED_JDKS}.
*
* @param version the bytecode compatibility level
*/
@@ -952,16 +944,6 @@ public class CompilerConfiguration {
}
/**
- * Retrieves the compiler bytecode compatibility level. Defaults to the minimum
- * officially supported bytecode version for any particular Groovy version.
- *
- * @return bytecode compatibility level
- */
- public String getTargetBytecode() {
- return this.targetBytecode;
- }
-
- /**
* Whether the bytecode version has preview features enabled (JEP 12)
*
* @return preview features
@@ -1075,23 +1057,20 @@ public class CompilerConfiguration {
* Checks if invoke dynamic is enabled.
*/
public boolean isIndyEnabled() {
- Boolean indyEnabled = getOptimizationOptions().get(INVOKEDYNAMIC);
- return Optional.ofNullable(indyEnabled).orElse(Boolean.FALSE);
+ return Boolean.TRUE.equals(getOptimizationOptions().get(INVOKEDYNAMIC));
}
/**
* Checks if groovydoc is enabled.
*/
public boolean isGroovydocEnabled() {
- Boolean groovydocEnabled = getOptimizationOptions().get(GROOVYDOC);
- return Optional.ofNullable(groovydocEnabled).orElse(Boolean.FALSE);
+ return Boolean.TRUE.equals(getOptimizationOptions().get(GROOVYDOC));
}
/**
* Checks if runtime groovydoc is enabled.
*/
public boolean isRuntimeGroovydocEnabled() {
- Boolean runtimeGroovydocEnabled = getOptimizationOptions().get(RUNTIME_GROOVYDOC);
- return Optional.ofNullable(runtimeGroovydocEnabled).orElse(Boolean.FALSE);
+ return Boolean.TRUE.equals(getOptimizationOptions().get(RUNTIME_GROOVYDOC));
}
}
diff --git a/src/main/java/org/codehaus/groovy/control/ErrorCollector.java b/src/main/java/org/codehaus/groovy/control/ErrorCollector.java
index 85bb723..94668b2 100644
--- a/src/main/java/org/codehaus/groovy/control/ErrorCollector.java
+++ b/src/main/java/org/codehaus/groovy/control/ErrorCollector.java
@@ -80,7 +80,11 @@ public class ErrorCollector implements Serializable {
}
}
- public void addErrorAndContinue(final SyntaxException error, final SourceUnit source) throws CompilationFailedException {
+ public void addErrorAndContinue(final String error, final ASTNode node, final SourceUnit source) {
+ addErrorAndContinue(Message.create(new SyntaxException(error, node), source));
+ }
+
+ public void addErrorAndContinue(final SyntaxException error, final SourceUnit source) {
addErrorAndContinue(Message.create(error, source));
}
@@ -95,13 +99,6 @@ public class ErrorCollector implements Serializable {
errors.add(message);
}
- public void addErrorAndContinue(String error, ASTNode node, SourceUnit source) {
- addErrorAndContinue(new SyntaxErrorMessage(
- new SyntaxException(error,
- node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()),
- source));
- }
-
/**
* Adds a non-fatal error to the message set, which may cause a failure if the error threshold is exceeded.
* The message is not required to have a source line and column specified, but it is best practice to try
diff --git a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
index e66657d..3d101b7 100644
--- a/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/ResolveVisitor.java
@@ -113,8 +113,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
private VariableScope currentScope;
private boolean isTopLevelProperty = true;
- private boolean inPropertyExpression = false;
- private boolean inClosure = false;
+ private boolean inPropertyExpression;
+ private boolean inClosure;
private final Map<ClassNode, ClassNode> possibleOuterClassNodeMap = new HashMap<>();
private Map<GenericsTypeName, GenericsType> genericParameterNames = new HashMap<>();
@@ -603,8 +603,7 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
tmp.className = savedName;
} else {
String savedName = type.getName();
- String replacedPointType = replaceLastPointWithDollar(savedName);
- type.setName(replacedPointType);
+ type.setName(replaceLastPointWithDollar(savedName));
if (resolve(type, false, true, true)) return true;
type.setName(savedName);
}
@@ -914,9 +913,8 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
private static String lookupClassName(final PropertyExpression pe) {
boolean doInitialClassTest = true;
StringBuilder name = new StringBuilder(32);
- // this loop builds a name from right to left each name part
- // separated by "."
- for (Expression expr = pe; expr != null; expr = ((PropertyExpression) expr).getObjectExpression()) {
+ // this loop builds a name from right to left each name part separated by "."
+ for (Expression expr = pe; expr != null && name != null; expr = ((PropertyExpression) expr).getObjectExpression()) {
if (expr instanceof VariableExpression) {
VariableExpression ve = (VariableExpression) expr;
// stop at super and this
@@ -944,7 +942,6 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
}
Tuple2<StringBuilder, Boolean> classNameInfo = makeClassName(doInitialClassTest, name, property);
name = classNameInfo.getV1();
- if (name == null) return null;
doInitialClassTest = classNameInfo.getV2();
}
@@ -1450,13 +1447,13 @@ public class ResolveVisitor extends ClassCodeExpressionTransformer {
}
for (ImportNode importNode : module.getStaticImports().values()) {
ClassNode type = importNode.getType();
- if (resolve(type, true, true, true)) continue;
- addError("unable to resolve class " + type.getName(), type);
+ if (!resolve(type, true, true, true))
+ addError("unable to resolve class " + type.getName(), type);
}
for (ImportNode importNode : module.getStaticStarImports().values()) {
ClassNode type = importNode.getType();
- if (resolve(type, true, true, true)) continue;
- addError("unable to resolve class " + type.getName(), type);
+ if (!resolve(type, true, true, true))
+ addError("unable to resolve class " + type.getName(), type);
}
module.setImportsResolved(true);
}
diff --git a/src/main/java/org/codehaus/groovy/control/SourceUnit.java b/src/main/java/org/codehaus/groovy/control/SourceUnit.java
index 56879c2..f57c570 100644
--- a/src/main/java/org/codehaus/groovy/control/SourceUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/SourceUnit.java
@@ -238,8 +238,6 @@ public class SourceUnit extends ProcessingUnit {
throw new GroovyBugError("SourceUnit not ready for convert()");
}
- //
- // Build the AST
buildAST();
String property = (String) AccessController.doPrivileged((PrivilegedAction) () -> System.getProperty("groovy.ast"));
@@ -249,17 +247,17 @@ public class SourceUnit extends ProcessingUnit {
}
}
+ /**
+ * Builds the AST.
+ */
public ModuleNode buildAST() {
- if (null != this.ast) {
- return this.ast;
- }
-
+ if (this.ast == null)
try {
this.ast = parserPlugin.buildAST(this, this.classLoader, this.cst);
this.ast.setDescription(this.name);
} catch (SyntaxException e) {
if (this.ast == null) {
- // Create a dummy ModuleNode to represent a failed parse - in case a later phase attempts to use the ast
+ // create an empty ModuleNode to represent a failed parse, in case a later phase attempts to use the AST
this.ast = new ModuleNode(this);
}
getErrorCollector().addError(new SyntaxErrorMessage(e, this));
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index e8bbea1..c47311a 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -257,16 +257,18 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
if (mce.isImplicitThis()) {
String name = mce.getMethodAsString();
boolean thisOrSuperMethod = staticWrtCurrent ? hasPossibleStaticMethod(currentClass, name, args, true) : currentClass.tryFindPossibleMethod(name, args) != null;
- if (!thisOrSuperMethod && currentClass.getOuterClasses().stream().noneMatch(oc -> oc.tryFindPossibleMethod(name, args) != null)) {
+ if (!thisOrSuperMethod && currentClass.getOuterClasses().stream().noneMatch(oc -> oc.tryFindPossibleMethod(name, args) != null)) { // GROOVY-5239
Expression result = findStaticMethodImportFromModule(method, args);
if (result != null) {
- setSourcePosition(result, mce);
+ result.setSourcePosition(mce);
return result;
}
if (name != null && !inLeftExpression) { // maybe a closure field
result = findStaticFieldOrPropAccessorImportFromModule(name);
if (result != null) {
+ setSourcePosition(result, method);
result = new MethodCallExpression(result, "call", args);
+ ((MethodCallExpression) result).setImplicitThis(false);
result.setSourcePosition(mce);
return result;
}
@@ -319,7 +321,7 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
}
MethodCallExpression result = new MethodCallExpression(object, method, args);
- result.setGenericsTypes(mce.getGenericsTypes());
+ result.setGenericsTypes(mce.getGenericsTypes()); // GROOVY-6757
result.setMethodTarget(mce.getMethodTarget());
result.setImplicitThis(mce.isImplicitThis());
result.setSpreadSafe(mce.isSpreadSafe());
diff --git a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
index 48249d3..dcea1ce 100644
--- a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
@@ -205,6 +205,7 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(source, compilationUnit.getTransformLoader());
visitor.visitClass(classNode);
}, Phases.SEMANTIC_ANALYSIS);
+
for (CompilePhase phase : CompilePhase.values()) {
switch (phase) {
case INITIALIZATION:
@@ -241,8 +242,8 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
Enumeration<URL> globalServices = transformLoader.getResources("META-INF/services/org.codehaus.groovy.transform.ASTTransformation");
while (globalServices.hasMoreElements()) {
URL service = globalServices.nextElement();
- String className;
try (BufferedReader svcIn = new BufferedReader(new InputStreamReader(URLStreams.openUncachedStream(service), StandardCharsets.UTF_8))) {
+ String className;
try {
className = svcIn.readLine();
} catch (IOException ioe) {
@@ -346,10 +347,10 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
+ entry.getValue().toExternalForm() + " is not an ASTTransformation.", null));
}
} catch (Exception e) {
- Throwable effectiveException = e instanceof InvocationTargetException ? e.getCause() : e;
+ Throwable t = e instanceof InvocationTargetException ? e.getCause() : e;
compilationUnit.getErrorCollector().addError(new SimpleMessage(
"Could not instantiate global transform class " + entry.getKey() + " specified at "
- + entry.getValue().toExternalForm() + " because of exception " + effectiveException.toString(), null));
+ + entry.getValue().toExternalForm() + " because of exception " + t.toString(), null));
}
}
}
diff --git a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
index 5df75e5..38c4f87 100644
--- a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
@@ -125,26 +125,22 @@ public class FieldASTTransformation extends ClassCodeExpressionTransformer imple
));
}
- // GROOVY-4833 : annotations that are not Groovy transforms should be transferred to the generated field
- // GROOVY-6112 : also copy acceptable Groovy transforms
- final List<AnnotationNode> annotations = de.getAnnotations();
- for (AnnotationNode annotation : annotations) {
- // GROOVY-6337 HACK: in case newly created field is @Lazy
+ for (AnnotationNode annotation : de.getAnnotations()) {
+ // GROOVY-6337: in case newly created field is @Lazy
if (annotation.getClassNode().equals(LAZY_TYPE)) {
LazyASTTransformation.visitField(this, annotation, fieldNode);
}
- final ClassNode annotationClassNode = annotation.getClassNode();
- if (notTransform(annotationClassNode) || acceptableTransform(annotation)) {
+ // GROOVY-4833: copy annotations that are not Groovy transforms; GROOVY-6112: also copy acceptable Groovy transforms
+ if (notTransform(annotation.getClassNode()) || acceptableTransform(annotation)) {
fieldNode.addAnnotation(annotation);
}
}
super.visitClass(cNode);
- // GROOVY-5207 So that Closures can see newly added fields
+ // GROOVY-5207: So that Closures can see newly added fields
// (not super efficient for a very large class with many @Fields but we chose simplicity
- // and understandability of this solution over more complex but efficient alternatives)
- VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
- scopeVisitor.visitClass(cNode);
+ // and understandability of this solution over more complex but efficient alternatives)
+ new VariableScopeVisitor(source).visitClass(cNode);
}
}
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/TemporaryVariableExpression.java b/src/main/java/org/codehaus/groovy/transform/sc/TemporaryVariableExpression.java
index ef41205..515cbf8 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/TemporaryVariableExpression.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/TemporaryVariableExpression.java
@@ -26,6 +26,8 @@ import org.codehaus.groovy.classgen.AsmClassGenerator;
import org.codehaus.groovy.classgen.asm.ExpressionAsVariableSlot;
import org.codehaus.groovy.classgen.asm.WriterController;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.INFERRED_TYPE;
+
/**
* A front-end class for {@link org.codehaus.groovy.classgen.asm.ExpressionAsVariableSlot} which
* allows defining temporary variables loaded from variable slots directly at the AST level,
@@ -37,36 +39,37 @@ public class TemporaryVariableExpression extends Expression {
private final Expression expression;
- private ExpressionAsVariableSlot variable;
+ private ExpressionAsVariableSlot[] variable = {null};
public TemporaryVariableExpression(final Expression expression) {
this.expression = expression;
+ putNodeMetaData(INFERRED_TYPE, expression.getNodeMetaData(INFERRED_TYPE));
}
@Override
public Expression transformExpression(final ExpressionTransformer transformer) {
TemporaryVariableExpression result = new TemporaryVariableExpression(transformer.transform(expression));
result.copyNodeMetaData(this);
+ result.variable = variable;
return result;
}
@Override
public void visit(final GroovyCodeVisitor visitor) {
if (visitor instanceof AsmClassGenerator) {
- if (variable == null) {
- AsmClassGenerator acg = (AsmClassGenerator) visitor;
- WriterController controller = acg.getController();
- variable = new ExpressionAsVariableSlot(controller, expression);
+ if (variable[0] == null) {
+ WriterController controller = ((AsmClassGenerator) visitor).getController();
+ variable[0] = new ExpressionAsVariableSlot(controller, expression);
}
- variable.visit(visitor);
+ variable[0].visit(visitor);
} else {
expression.visit(visitor);
}
}
public void remove(final WriterController controller) {
- controller.getCompileStack().removeVar(variable.getIndex());
- variable = null;
+ controller.getCompileStack().removeVar(variable[0].getIndex());
+ variable[0] = null;
}
@Override
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java b/src/main/java/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java
index 86261aa..04994f7 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/transformers/BinaryExpressionTransformer.java
@@ -197,7 +197,7 @@ public class BinaryExpressionTransformer {
MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
if (adapter != null) {
Expression sba = classX(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
- call = callX(sba, "compareEquals", args(expr, right));
+ call = callX(sba, adapter.getName(), args(expr, right));
call.setMethodTarget(adapter);
} else {
call = callX(expr, name, args(right));
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 6b8916d..f2ec272 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingSupport.java
@@ -241,6 +241,10 @@ public abstract class StaticTypeCheckingSupport {
EXTENSION_METHOD_CACHE.cache.clearAll();
}
+ public static void clearExtensionMethodCache(final ClassLoader loader) {
+ EXTENSION_METHOD_CACHE.cache.remove(loader);
+ }
+
/**
* Returns true for expressions of the form x[...]
*
@@ -659,17 +663,17 @@ public abstract class StaticTypeCheckingSupport {
}
if (isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect)) {
- if (BigDecimal_TYPE == leftRedirect || Number_TYPE == leftRedirect) {
+ if (BigDecimal_TYPE.equals(leftRedirect) || Number_TYPE.equals(leftRedirect)) {
// any number can be assigned to BigDecimal or Number
return true;
}
- if (BigInteger_TYPE == leftRedirect) {
+ if (BigInteger_TYPE.equals(leftRedirect)) {
return WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE);
}
}
// anything can be assigned to an Object, String, [Bb]oolean or Class receiver; except null to boolean
- if (isWildcardLeftHandSide(leftRedirect) && !(boolean_TYPE.equals(left) && isNullConstant(rightExpression))) return true;
+ if (isWildcardLeftHandSide(left) && !(leftRedirect == boolean_TYPE && isNullConstant(rightExpression))) return true;
if (leftRedirect == char_TYPE && rightRedirect == Character_TYPE) return true;
if (leftRedirect == Character_TYPE && rightRedirect == char_TYPE) return true;
@@ -678,7 +682,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)) {
+ if (leftRedirect.isDerivedFrom(Enum_Type) && (rightRedirect.equals(STRING_TYPE) || rightRedirect.equals(GSTRING_TYPE))) {
return true;
}
@@ -830,11 +834,23 @@ public abstract class StaticTypeCheckingSupport {
return joiner.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(final ClassNode type, final ClassNode superOrInterface) {
@@ -1476,9 +1492,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 = 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(final GenericsType origin) {
@@ -1560,7 +1575,7 @@ public abstract class StaticTypeCheckingSupport {
}
static void applyGenericsConnections(final Map<GenericsTypeName, GenericsType> connections, final Map<GenericsTypeName, GenericsType> resolvedPlaceholders) {
- if (connections == null) return;
+ if (connections == null || connections.isEmpty()) return;
int count = 0;
while (count++ < 10000) {
boolean checkForMorePlaceholders = false;
@@ -1777,7 +1792,7 @@ public abstract class StaticTypeCheckingSupport {
}
private static GenericsType[] applyGenericsContext(final Map<GenericsTypeName, GenericsType> spec, final GenericsType[] gts) {
- if (gts == null) return null;
+ if (gts == null || spec == null || spec.isEmpty()) return gts;
GenericsType[] newGTs = new GenericsType[gts.length];
for (int i = 0, n = gts.length; i < n; i += 1) {
GenericsType gt = gts[i];
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 7bc2ccc..370b8ae 100644
--- a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -279,6 +279,7 @@ import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isWild
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.lastArgMatchesVarg;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.missesGenericsTypes;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.prettyPrintType;
+import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.prettyPrintTypeName;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.resolveClassNodeGenerics;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.toMethodParametersString;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.typeCheckMethodArgumentWithGenerics;
@@ -751,7 +752,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
lType = getType(leftExpression);
} else {
- if (op != ASSIGN && op != ELVIS_EQUAL) {
+ if (op != EQUAL && op != ELVIS_EQUAL) {
lType = getType(leftExpression);
} else {
lType = getOriginalDeclarationType(leftExpression);
@@ -1043,28 +1044,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(final ClassNode from, final 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++) {
@@ -1075,7 +1076,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
genericsType.getLowerBound()
);
}
- to.setGenericsTypes(copy);
+ target.setGenericsTypes(copy);
}
/**
@@ -1397,13 +1398,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
return constructorList.get(0);
}
- private static String prettyPrintTypeName(final ClassNode node) {
- if (node.isArray()) {
- return prettyPrintTypeName(node.getComponentType()) + "[]";
- }
- return node.isGenericsPlaceHolder() ? node.getUnresolvedName() : node.getText();
- }
-
/**
* When instanceof checks are found in the code, we store temporary type
* information data in the {@link TypeCheckingContext#temporaryIfBranchTypeInformation}
@@ -1610,11 +1604,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
// GROOVY-5568: the property may be defined by DGM
- List<ClassNode> dgmReceivers = new ArrayList<>(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 method : findDGMMethodsByNameAndArguments(getSourceUnit().getClassLoader(), dgmReceiver, "is" + capName, ClassNode.EMPTY_ARRAY)) {
if (Boolean_TYPE.equals(getWrapper(method.getReturnType()))) methods.add(method);
@@ -2199,12 +2189,13 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
MethodNode enclosingMethod = typeCheckingContext.getEnclosingMethod();
if (enclosingMethod != null && !enclosingMethod.isVoidMethod()) {
+ ClassNode returnType = enclosingMethod.getReturnType();
if (!isNullConstant(expression)
&& !type.equals(VOID_TYPE)
&& !type.equals(void_WRAPPER_TYPE)
- && !checkCompatibleAssignmentTypes(enclosingMethod.getReturnType(), type, null, false)) {
+ && !checkCompatibleAssignmentTypes(returnType, type, null, false)) {
if (!extension.handleIncompatibleReturnType(statement, type)) {
- addStaticTypeError("Cannot return value of type " + prettyPrintType(type) + " on method returning type " + prettyPrintType(enclosingMethod.getReturnType()), expression);
+ addStaticTypeError("Cannot return value of type " + prettyPrintType(type) + " on method returning type " + prettyPrintType(returnType), expression);
}
} else {
ClassNode previousType = getInferredReturnType(enclosingMethod);
@@ -2335,7 +2326,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
List<ClassNode> tempTypes = getTemporaryTypesForExpression(expression);
if (tempTypes != null && !tempTypes.isEmpty()) {
List<ClassNode> types = new ArrayList<>(tempTypes.size() + 1);
- if (expressionType != null && !expressionType.equals(ClassHelper.OBJECT_TYPE) // GROOVY-7333
+ if (expressionType != null && !expressionType.equals(OBJECT_TYPE) // GROOVY-7333
&& tempTypes.stream().noneMatch(t -> implementsInterfaceOrIsSubclassOf(t, expressionType))) { // GROOVY-9769
types.add(expressionType);
}
@@ -2731,7 +2722,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
params = ((ExtensionMethodNode) selectedMethod).getExtensionMethodNode().getParameters();
expressions.add(0, varX("$self", receiver));
}
- ArgumentListExpression newArgs = args(expressions);
int nExpressions = expressions.size();
for (int i = 0; i < nExpressions; i += 1) {
@@ -2742,13 +2732,13 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
Parameter target = params[i];
ClassNode targetType = target.getType();
ClosureExpression source = (ClosureExpression) expression;
- checkClosureWithDelegatesTo(receiver, selectedMethod, newArgs, params, source, target);
+ checkClosureWithDelegatesTo(receiver, selectedMethod, args(expressions), params, source, target);
if (selectedMethod instanceof ExtensionMethodNode) {
if (i > 0) {
inferClosureParameterTypes(receiver, arguments, source, target, selectedMethod);
}
} else {
- inferClosureParameterTypes(receiver, newArgs, source, target, selectedMethod);
+ inferClosureParameterTypes(receiver, arguments, source, target, selectedMethod);
}
if (isFunctionalInterface(targetType)) {
storeInferredReturnType(source, GenericsUtils.parameterizeSAM(targetType).getV2());
@@ -3462,7 +3452,7 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
// ensure that all methods are either static or declared by the current receiver or a superclass
if (!mn.isEmpty()
&& (call.isImplicitThis() || isThisExpression(objectExpression))
- && (typeCheckingContext.isInStaticContext || (receiverType.getModifiers() & Opcodes.ACC_STATIC) != 0)) {
+ && (typeCheckingContext.isInStaticContext || Modifier.isStatic(receiverType.getModifiers()))) {
// we create separate method lists just to be able to print out
// a nice error message to the user
// a method is accessible if it is static, or if we are not in a static context and it is
@@ -4162,9 +4152,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;
@@ -4218,8 +4208,6 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
popAssignmentTracking(oldTracker);
}
- // currently just for empty literals, not for e.g. Collections.emptyList() at present
- /// it seems attractive to want to do this for more cases but perhaps not all cases
private ClassNode checkForTargetType(final Expression expr, final ClassNode type) {
BinaryExpression enclosingBinaryExpression = typeCheckingContext.getEnclosingBinaryExpression();
if (enclosingBinaryExpression instanceof DeclarationExpression
@@ -4837,15 +4825,14 @@ public class StaticTypeCheckingVisitor extends ClassCodeVisitorSupport {
}
if (isClassClassNodeWrappingConcreteType(receiver)) {
- List<MethodNode> result = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
- if (!result.isEmpty()) return result;
+ chosen = findMethod(receiver.getGenericsTypes()[0].getType(), name, args);
+ if (!chosen.isEmpty()) return chosen;
+ }
+ if (GSTRING_TYPE.equals(receiver)) {
+ return findMethod(STRING_TYPE, name, args);
}
-
- if (GSTRING_TYPE.equals(receiver)) return findMethod(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;
@@ -4923,7 +4910,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);
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
index 5a5c0c3..a7f1c49 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitComposer.java
@@ -296,7 +296,7 @@ public abstract class TraitComposer {
// but add empty body for setter for legacy compatibility
MethodNode impl = new MethodNode(
methodNode.getName(),
- Opcodes.ACC_PUBLIC | isStatic,
+ Opcodes.ACC_PUBLIC | isStatic | Opcodes.ACC_SYNTHETIC,
returnType,
newParams,
ClassNode.EMPTY_ARRAY,
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
index 1092271..879b7a9 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitReceiverTransformer.java
@@ -220,7 +220,7 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
args(super.transform(rightExpression))
);
mce.setImplicitThis(false);
- mce.setSourcePosition(exp);
+ mce.setSourcePosition(leftExpression instanceof PropertyExpression ? ((PropertyExpression) leftExpression).getProperty() : leftExpression);
markDynamicCall(mce, staticField, isStatic);
return mce;
}
@@ -242,7 +242,7 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
MethodCallExpression mce = callX(receiver, Traits.helperGetterName(fn));
mce.setImplicitThis(false);
- mce.setSourcePosition(exp);
+ mce.setSourcePosition(exp instanceof PropertyExpression ? ((PropertyExpression) exp).getProperty() : exp);
markDynamicCall(mce, fn, isStatic);
return mce;
}
@@ -290,9 +290,9 @@ class TraitReceiverTransformer extends ClassCodeExpressionTransformer {
Traits.getSuperTraitMethodName(traitClass, method),
superCallArgs
);
- newCall.setSourcePosition(call);
- newCall.setSafe(call.isSafe());
+ newCall.getMethod().setSourcePosition(call.getMethod());
newCall.setSpreadSafe(call.isSpreadSafe());
+ newCall.setSafe(call.isSafe());
newCall.setImplicitThis(false);
return newCall;
}
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
index a2c5110..9165658 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/Traits.java
@@ -159,7 +159,7 @@ public abstract class Traits {
throw new GroovyBugError("Couldn't find trait helper classes on compile classpath!",e);
}
}
- return new TraitHelpersTuple(helperClassNode, fieldHelperClassNode, staticFieldHelperClassNode);
+ return new TraitHelpersTuple(helperClassNode, fieldHelperClassNode, staticFieldHelperClassNode);
}
/**
@@ -404,5 +404,4 @@ public abstract class Traits {
*/
String desc();
}
-
}