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();
     }
-
 }