You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/08/09 02:35:34 UTC

[groovy] 07/07: minor refactor

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 55429fbfb37e409083fe776416c4af81aa689a8d
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat Aug 8 10:50:37 2020 -0500

    minor refactor
    
    (cherry picked from commit 6eea0beb1386fe9e6bac39eda8fc27772ef48f1f)
---
 .../transform/trait/SuperCallTraitTransformer.java |   6 +-
 .../transform/trait/TraitASTTransformation.java    | 228 ++++++++++-----------
 .../traitx/TraitASTTransformationTest.groovy       | 116 ++++++-----
 3 files changed, 171 insertions(+), 179 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java b/src/main/java/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
index edd1e12..e8f1c35 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/SuperCallTraitTransformer.java
@@ -95,7 +95,7 @@ class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
                 ClassNode traitType = getTraitSuperTarget(leftExpression.getObjectExpression());
                 if (traitType != null) {
                     ClassNode helperType = getHelper(traitType);
-                    // TraitType.super.foo = ... -> TraitType$Helper.setFoo(this, ...)
+                    // TraitType.super.foo = ... -> TraitType$Trait$Helper.setFoo(this, ...)
 
                     String setterName = MetaProperty.getSetterName(leftExpression.getPropertyAsString());
                     for (MethodNode method : helperType.getMethods(setterName)) {
@@ -136,7 +136,7 @@ class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
             ClassNode traitType = getTraitSuperTarget(exp.getObjectExpression());
             if (traitType != null) {
                 ClassNode helperType = getHelper(traitType);
-                // TraitType.super.foo -> TraitType$Helper.getFoo(this)
+                // TraitType.super.foo -> TraitType$Trait$Helper.getFoo(this)
 
                 Function<MethodNode, MethodCallExpression> xform = (methodNode) -> {
                     MethodCallExpression methodCall = new MethodCallExpression(
@@ -181,7 +181,7 @@ class SuperCallTraitTransformer extends ClassCodeExpressionTransformer {
         ClassNode traitType = getTraitSuperTarget(exp.getObjectExpression());
         if (traitType != null) {
             ClassNode helperType = getHelper(traitType);
-            // TraitType.super.foo() -> TraitType$Helper.foo(this)
+            // TraitType.super.foo() -> TraitType$Trait$Helper.foo(this)
 
             ArgumentListExpression newArgs = new ArgumentListExpression();
             newArgs.addExpression(new VariableExpression("this"));
diff --git a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
index 2daeae2..da8cf12 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -32,13 +32,8 @@ import org.codehaus.groovy.ast.InnerClassNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.BinaryExpression;
-import org.codehaus.groovy.ast.expr.CastExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.FieldExpression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
@@ -53,13 +48,10 @@ import org.codehaus.groovy.control.CompilePhase;
 import org.codehaus.groovy.control.SourceUnit;
 import org.codehaus.groovy.runtime.InvokerHelper;
 import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.syntax.Token;
-import org.codehaus.groovy.syntax.Types;
 import org.codehaus.groovy.transform.ASTTransformationCollectorCodeVisitor;
 import org.codehaus.groovy.transform.AbstractASTTransformation;
 import org.codehaus.groovy.transform.GroovyASTTransformation;
 
-import java.lang.reflect.Modifier;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
@@ -70,7 +62,19 @@ import java.util.Set;
 
 import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
 import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
+import static org.apache.groovy.util.BeanUtils.capitalize;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.castX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.fieldX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
 import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
 import static org.codehaus.groovy.transform.trait.SuperCallTraitTransformer.UNRESOLVED_HELPER_CLASS;
 
 /**
@@ -85,21 +89,26 @@ import static org.codehaus.groovy.transform.trait.SuperCallTraitTransformer.UNRE
 @GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
 public class TraitASTTransformation extends AbstractASTTransformation implements CompilationUnitAware {
 
-    public static final String DO_DYNAMIC = TraitReceiverTransformer.class+".doDynamic";
-    public static final String POST_TYPECHECKING_REPLACEMENT = TraitReceiverTransformer.class+".replacement";
+    public static final String DO_DYNAMIC = TraitReceiverTransformer.class + ".doDynamic";
+    public static final String POST_TYPECHECKING_REPLACEMENT = TraitReceiverTransformer.class + ".replacement";
 
     private static final ClassNode INVOKERHELPER_CLASSNODE = ClassHelper.make(InvokerHelper.class);
-
     private static final ClassNode OVERRIDE_CLASSNODE = ClassHelper.make(Override.class);
 
-    private SourceUnit unit;
+    private SourceUnit sourceUnit;
     private CompilationUnit compilationUnit;
 
-    public void visit(ASTNode[] nodes, SourceUnit source) {
+    @Override
+    public void setCompilationUnit(final CompilationUnit unit) {
+        this.compilationUnit = unit;
+    }
+
+    @Override
+    public void visit(final ASTNode[] nodes, final SourceUnit source) {
         AnnotatedNode parent = (AnnotatedNode) nodes[1];
         AnnotationNode anno = (AnnotationNode) nodes[0];
         if (!Traits.TRAIT_CLASSNODE.equals(anno.getClassNode())) return;
-        unit = source;
+        sourceUnit = source;
         init(nodes, source);
         if (parent instanceof ClassNode) {
             ClassNode cNode = (ClassNode) parent;
@@ -117,7 +126,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         if (helperClassNode == null) {
             return;
         }
-        for (ClassNode cNode : unit.getAST().getClasses()) {
+        for (ClassNode cNode : sourceUnit.getAST().getClasses()) {
             ClassNode unresolvedHelperNode = cNode.getNodeMetaData(UNRESOLVED_HELPER_CLASS);
             if (unresolvedHelperNode != null
                     && unresolvedHelperNode.getName().equals(helperClassNode.getName())) {
@@ -151,14 +160,13 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
 
     private void resolveScope(final ClassNode cNode) {
         // we need to resolve again!
-        VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(unit);
+        VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(sourceUnit);
         scopeVisitor.visitClass(cNode);
     }
 
     private void checkNoConstructor(final ClassNode cNode) {
         if (!cNode.getDeclaredConstructors().isEmpty()) {
-            addError("Error processing trait '" + cNode.getName() + "'. " +
-                    " Constructors are not allowed.", cNode);
+            addError("Error processing trait '" + cNode.getName() + "'. " + " Constructors are not allowed.", cNode);
         }
     }
 
@@ -182,8 +190,8 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         generatePropertyMethods(cNode);
 
         // prepare fields
-        List<FieldNode> fields = new ArrayList<FieldNode>();
-        Set<String> fieldNames = new HashSet<String>();
+        List<FieldNode> fields = new ArrayList<>();
+        Set<String> fieldNames = new HashSet<>();
         boolean hasStatic = false;
         for (FieldNode field : cNode.getFields()) {
             if (!"metaClass".equals(field.getName()) && (!field.isSynthetic() || field.getName().indexOf('$') < 0)) {
@@ -200,28 +208,28 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
             fieldHelper = new InnerClassNode(
                     cNode,
                     Traits.fieldHelperClassName(cNode),
-                    ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC,
+                    ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_SYNTHETIC,
                     ClassHelper.OBJECT_TYPE
             );
             if (hasStatic) {
                 staticFieldHelper = new InnerClassNode(
                         cNode,
                         Traits.staticFieldHelperClassName(cNode),
-                        ACC_STATIC | ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT | ACC_SYNTHETIC,
+                        ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_INTERFACE | ACC_SYNTHETIC,
                         ClassHelper.OBJECT_TYPE
                 );
             }
         }
 
         // add methods
-        List<MethodNode> methods = new ArrayList<MethodNode>(cNode.getMethods());
-        List<MethodNode> nonPublicAPIMethods = new LinkedList<MethodNode>();
+        List<MethodNode> methods = new ArrayList<>(cNode.getMethods());
+        List<MethodNode> nonPublicAPIMethods = new LinkedList<>();
         List<Statement> staticInitStatements = null;
         for (final MethodNode methodNode : methods) {
             boolean declared = methodNode.getDeclaringClass() == cNode;
             if (declared) {
                 if (!methodNode.isSynthetic() && (methodNode.isProtected() || (!methodNode.isPrivate() && !methodNode.isPublic()))) {
-                    unit.addError(new SyntaxException("Cannot have protected/package-private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")",
+                    sourceUnit.addError(new SyntaxException("Cannot have protected/package-private method in a trait (" + cNode.getName() + "#" + methodNode.getTypeDescriptor() + ")",
                             methodNode.getLineNumber(), methodNode.getColumnNumber()));
                     return null;
                 }
@@ -262,7 +270,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         BlockStatement toBlock = getBlockStatement(initializer, toCode);
         for (Statement next : initStatements) {
             Parameter selfParam = createSelfParameter(cNode, false);
-            toBlock.addStatement(processBody(new VariableExpression(selfParam), next, cNode, helper, fieldHelper, fieldNames));
+            toBlock.addStatement(processBody(varX(selfParam), next, cNode, helper, fieldHelper, fieldNames));
         }
         initStatements.clear();
 
@@ -273,7 +281,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         copyClassAnnotations(cNode, helper);
         markAsGenerated(cNode, helper);
 
-        fields = new ArrayList<FieldNode>(cNode.getFields()); // reuse the full list of fields
+        fields = new ArrayList<>(cNode.getFields()); // reuse the full list of fields
         for (FieldNode field : fields) {
             cNode.removeField(field.getName());
         }
@@ -281,11 +289,11 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         // visit AST xforms
         registerASTTransformations(helper);
 
-        unit.getAST().addClass(helper);
+        sourceUnit.getAST().addClass(helper);
         if (fieldHelper != null) {
-            unit.getAST().addClass(fieldHelper);
+            sourceUnit.getAST().addClass(fieldHelper);
             if (staticFieldHelper != null) {
-                unit.getAST().addClass(staticFieldHelper);
+                sourceUnit.getAST().addClass(staticFieldHelper);
             }
         }
 
@@ -300,22 +308,21 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         return helper;
     }
 
-    private BlockStatement getBlockStatement(MethodNode targetMethod, Statement code) {
-        BlockStatement toBlock;
+    private BlockStatement getBlockStatement(final MethodNode targetMethod, final Statement code) {
+        BlockStatement blockStmt;
         if (code instanceof BlockStatement) {
-            toBlock = (BlockStatement) code;
+            blockStmt = (BlockStatement) code;
         } else {
-            toBlock = new BlockStatement();
-            toBlock.addStatement(code);
-            targetMethod.setCode(toBlock);
+            blockStmt = block(code);
+            targetMethod.setCode(blockStmt);
         }
-        return toBlock;
+        return blockStmt;
     }
 
     private static MethodNode createInitMethod(final boolean isStatic, final ClassNode cNode, final ClassNode helper) {
         MethodNode initializer = new MethodNode(
-                isStatic?Traits.STATIC_INIT_METHOD:Traits.INIT_METHOD,
-                ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC,
+                isStatic ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD,
+                ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
                 ClassHelper.VOID_TYPE,
                 new Parameter[]{createSelfParameter(cNode, isStatic)},
                 ClassNode.EMPTY_ARRAY,
@@ -333,7 +340,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
 
     private void registerASTTransformations(final ClassNode helper) {
         {
-            GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(unit, compilationUnit.getTransformLoader());
+            GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(sourceUnit, compilationUnit.getTransformLoader());
             visitor.visitClass(helper);
         }
         // Perform an additional phase which has to be done *after* type checking
@@ -346,7 +353,8 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
     }
 
     /**
-     * Copies annotation from the trait to the helper, excluding the trait annotation itself
+     * Copies annotation from the trait to the helper, excluding the trait annotation itself.
+     *
      * @param cNode the trait class node
      * @param helper the helper class node
      */
@@ -360,11 +368,10 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
     }
 
     private void checkInnerClasses(final ClassNode cNode) {
-        Iterator<InnerClassNode> it = cNode.getInnerClasses();
-        while (it.hasNext()) {
+        for (Iterator<InnerClassNode> it = cNode.getInnerClasses(); it.hasNext(); ) {
             InnerClassNode origin = it.next();
             if ((origin.getModifiers() & ACC_STATIC) == 0) {
-                unit.addError(new SyntaxException("Cannot have non-static inner class inside a trait ("+origin.getName()+")", origin.getLineNumber(), origin.getColumnNumber()));
+                sourceUnit.addError(new SyntaxException("Cannot have non-static inner class inside a trait ("+origin.getName()+")", origin.getLineNumber(), origin.getColumnNumber()));
             }
         }
     }
@@ -376,87 +383,65 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
     }
 
     /**
-     * Mostly copied from the {@link Verifier} class but does *not* generate bytecode
-     *
-     * @param cNode
-     * @param node
+     * Mostly copied from the {@link Verifier} class but does *not* generate bytecode.
      */
-    private static void processProperty(final ClassNode cNode, PropertyNode node) {
+    private static void processProperty(final ClassNode cNode, final PropertyNode node) {
         String name = node.getName();
         FieldNode field = node.getField();
-        int propNodeModifiers = node.getModifiers();
-
-        String getterName = "get" + Verifier.capitalize(name);
-        String setterName = "set" + Verifier.capitalize(name);
+        int propNodeModifiers = node.getModifiers() & 0x1F; // GROOVY-3726
 
-        // GROOVY-3726: clear volatile, transient modifiers so that they don't get applied to methods
-        if ((propNodeModifiers & Modifier.VOLATILE) != 0) {
-            propNodeModifiers = propNodeModifiers - Modifier.VOLATILE;
-        }
-        if ((propNodeModifiers & Modifier.TRANSIENT) != 0) {
-            propNodeModifiers = propNodeModifiers - Modifier.TRANSIENT;
-        }
+        String getterName = GeneralUtils.getGetterName(node);
+        String setterName = GeneralUtils.getSetterName(name);
 
         Statement getterBlock = node.getGetterBlock();
         if (getterBlock == null) {
             MethodNode getter = cNode.getGetterMethod(getterName);
-            if (getter == null && ClassHelper.boolean_TYPE == node.getType()) {
-                String secondGetterName = "is" + Verifier.capitalize(name);
-                getter = cNode.getGetterMethod(secondGetterName);
+            if (getter == null && node.getType().equals(ClassHelper.boolean_TYPE)) {
+                getter = cNode.getGetterMethod("is" + capitalize(name));
             }
             if (!node.isPrivate() && methodNeedsReplacement(cNode, getter)) {
-                getterBlock = new ExpressionStatement(new FieldExpression(field));
+                getterBlock = stmt(fieldX(field));
             }
         }
         Statement setterBlock = node.getSetterBlock();
         if (setterBlock == null) {
             // 2nd arg false below: though not usual, allow setter with non-void return type
             MethodNode setter = cNode.getSetterMethod(setterName, false);
-            if (!node.isPrivate() &&
-                    (propNodeModifiers & ACC_FINAL) == 0 &&
-                    methodNeedsReplacement(cNode, setter)) {
-                setterBlock = new ExpressionStatement(
-                        new BinaryExpression(
-                                new FieldExpression(field),
-                                Token.newSymbol(Types.EQUAL, 0, 0),
-                                new VariableExpression("value")
-                        )
-                );
+            if (!node.isPrivate() && (propNodeModifiers & ACC_FINAL) == 0
+                    && methodNeedsReplacement(cNode, setter)) {
+                setterBlock = assignS(fieldX(field), varX(name));
             }
         }
 
         if (getterBlock != null) {
-            MethodNode getter =
-                    new MethodNode(getterName, propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
+            MethodNode getter = new MethodNode(getterName, propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
             getter.setSynthetic(true);
             cNode.addMethod(getter);
 
-            if (ClassHelper.boolean_TYPE == node.getType() || ClassHelper.Boolean_TYPE == node.getType()) {
-                String secondGetterName = "is" + Verifier.capitalize(name);
-                MethodNode secondGetter =
-                        new MethodNode(secondGetterName, propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
+            if (node.getType().equals(ClassHelper.boolean_TYPE) || node.getType().equals(ClassHelper.Boolean_TYPE)) {
+                MethodNode secondGetter = new MethodNode("is" + capitalize(name), propNodeModifiers, node.getType(), Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, getterBlock);
                 secondGetter.setSynthetic(true);
                 cNode.addMethod(secondGetter);
             }
         }
         if (setterBlock != null) {
-            Parameter[] setterParameterTypes = {new Parameter(node.getType(), "value")};
             VariableExpression var = (VariableExpression) ((BinaryExpression) ((ExpressionStatement) setterBlock).getExpression()).getRightExpression();
-            var.setAccessedVariable(setterParameterTypes[0]);
-            MethodNode setter =
-                    new MethodNode(setterName, propNodeModifiers, ClassHelper.VOID_TYPE, setterParameterTypes, ClassNode.EMPTY_ARRAY, setterBlock);
+            Parameter setterParameter = new Parameter(node.getType(), name);
+            var.setAccessedVariable(setterParameter);
+
+            MethodNode setter = new MethodNode(setterName, propNodeModifiers, ClassHelper.VOID_TYPE, params(setterParameter), ClassNode.EMPTY_ARRAY, setterBlock);
             setter.setSynthetic(true);
             cNode.addMethod(setter);
         }
     }
 
-    private static boolean methodNeedsReplacement(ClassNode classNode, MethodNode m) {
+    private static boolean methodNeedsReplacement(final ClassNode cNode, final MethodNode mNode) {
         // no method found, we need to replace
-        if (m == null) return true;
+        if (mNode == null) return true;
         // method is in current class, nothing to be done
-        if (m.getDeclaringClass() == classNode) return false;
+        if (mNode.getDeclaringClass() == cNode) return false;
         // do not overwrite final
-        if ((m.getModifiers() & ACC_FINAL) != 0) return false;
+        if ((mNode.getModifiers() & ACC_FINAL) != 0) return false;
         return true;
     }
 
@@ -464,23 +449,23 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                               final ClassNode fieldHelper, final ClassNode helper, final ClassNode staticFieldHelper, final ClassNode trait,
                               final Set<String> knownFields) {
         if (field.isProtected()) {
-            unit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")",
+            sourceUnit.addError(new SyntaxException("Cannot have protected field in a trait (" + trait.getName() + "#" + field.getName() + ")",
                     field.getLineNumber(), field.getColumnNumber()));
             return;
         }
 
         Expression initialExpression = field.getInitialExpression();
-        MethodNode selectedMethod = field.isStatic()?staticInitializer:initializer;
+        MethodNode selectedMethod = field.isStatic() ? staticInitializer : initializer;
         ClassNode target = field.isStatic() && staticFieldHelper != null ? staticFieldHelper : fieldHelper;
         if (initialExpression != null) {
-            VariableExpression thisObject = new VariableExpression(selectedMethod.getParameters()[0]);
+            VariableExpression thisObject = varX(selectedMethod.getParameters()[0]);
             ExpressionStatement initCode = new ExpressionStatement(initialExpression);
             processBody(thisObject, initCode, trait, helper, fieldHelper, knownFields);
             if (field.isFinal()) {
                 String baseName = field.isStatic() ? Traits.STATIC_INIT_METHOD : Traits.INIT_METHOD;
                 MethodNode fieldInitializer = new MethodNode(
                         baseName + Traits.remappedFieldName(trait, field.getName()),
-                        ACC_STATIC | ACC_PUBLIC | ACC_SYNTHETIC,
+                        ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC,
                         field.getOriginType(),
                         new Parameter[]{createSelfParameter(trait, field.isStatic())},
                         ClassNode.EMPTY_ARRAY,
@@ -494,25 +479,25 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                     if (staticFieldHelper != null) {
                         target = staticFieldHelper;
                     }
-                    mce = new MethodCallExpression(
-                            new ClassExpression(INVOKERHELPER_CLASSNODE),
+                    mce = callX(
+                            classX(INVOKERHELPER_CLASSNODE),
                             "invokeStaticMethod",
-                            new ArgumentListExpression(
+                            args(
                                     thisObject,
-                                    new ConstantExpression(Traits.helperSetterName(field)),
+                                    constX(Traits.helperSetterName(field)),
                                     initCode.getExpression()
                             )
                     );
                 } else {
-                    mce = new MethodCallExpression(
-                            new CastExpression(createReceiverType(field.isStatic(), fieldHelper), thisObject),
+                    mce = callX(
+                            castX(createReceiverType(field.isStatic(), fieldHelper), thisObject),
                             Traits.helperSetterName(field),
-                            new CastExpression(field.getOriginType(),initCode.getExpression())
+                            castX(field.getOriginType(), initCode.getExpression())
                     );
                 }
                 mce.setImplicitThis(false);
                 mce.setSourcePosition(initialExpression);
-                code.addStatement(new ExpressionStatement(mce));
+                code.addStatement(stmt(mce));
             }
         }
         // define setter/getter helper methods (setter added even for final fields for legacy compatibility)
@@ -539,38 +524,38 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         String dummyFieldName = String.format("$0x%04x", mods) + Traits.remappedFieldName(field.getOwner(), field.getName());
         FieldNode dummyField = new FieldNode(
                 dummyFieldName,
-                ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC,
+                ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC,
                 field.getOriginType(),
                 fieldHelper,
                 null
         );
         // copy annotations from field to dummy field
-        List<AnnotationNode> copied = new LinkedList<AnnotationNode>();
-        List<AnnotationNode> notCopied = new LinkedList<AnnotationNode>();
+        List<AnnotationNode> copied = new LinkedList<>();
+        List<AnnotationNode> notCopied = new LinkedList<>();
         GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
         dummyField.addAnnotations(copied);
         fieldHelper.addField(dummyField);
 
         // retain legacy field (will be given lower precedence than above)
         dummyFieldName = (field.isStatic() ? Traits.STATIC_FIELD_PREFIX : Traits.FIELD_PREFIX) +
-                (field.isPublic()? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX)+
+                (field.isPublic() ? Traits.PUBLIC_FIELD_PREFIX : Traits.PRIVATE_FIELD_PREFIX) +
                 Traits.remappedFieldName(field.getOwner(), field.getName());
         dummyField = new FieldNode(
                 dummyFieldName,
-                ACC_STATIC | ACC_PUBLIC | ACC_FINAL | ACC_SYNTHETIC,
+                ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_SYNTHETIC,
                 field.getOriginType(),
                 fieldHelper,
                 null
         );
         // copy annotations from field to legacy dummy field
-        copied = new LinkedList<AnnotationNode>();
-        notCopied = new LinkedList<AnnotationNode>();
+        copied = new LinkedList<>();
+        notCopied = new LinkedList<>();
         GeneralUtils.copyAnnotatedNodeAnnotations(field, copied, notCopied);
         dummyField.addAnnotations(copied);
         fieldHelper.addField(dummyField);
     }
 
-    private MethodNode processMethod(ClassNode traitClass, ClassNode traitHelperClass, MethodNode methodNode, ClassNode fieldHelper, Collection<String> knownFields) {
+    private MethodNode processMethod(final ClassNode traitClass, final ClassNode traitHelperClass, final MethodNode methodNode, final ClassNode fieldHelper, final Collection<String> knownFields) {
         Parameter[] initialParams = methodNode.getParameters();
         Parameter[] newParams = new Parameter[initialParams.length + 1];
         newParams[0] = createSelfParameter(traitClass, methodNode.isStatic());
@@ -582,7 +567,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
                 methodNode.getReturnType(),
                 newParams,
                 methodNode.getExceptions(),
-                processBody(new VariableExpression(newParams[0]), methodNode.getCode(), traitClass, traitHelperClass, fieldHelper, knownFields)
+                processBody(varX(newParams[0]), methodNode.getCode(), traitClass, traitHelperClass, fieldHelper, knownFields)
         );
         mNode.setSourcePosition(methodNode);
         mNode.addAnnotations(filterAnnotations(methodNode.getAnnotations()));
@@ -600,8 +585,8 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         return mNode;
     }
 
-    private static List<AnnotationNode> filterAnnotations(List<AnnotationNode> annotations) {
-        List<AnnotationNode> result = new ArrayList<AnnotationNode>(annotations.size());
+    private static List<AnnotationNode> filterAnnotations(final List<AnnotationNode> annotations) {
+        List<AnnotationNode> result = new ArrayList<>(annotations.size());
         for (AnnotationNode annotation : annotations) {
             if (!OVERRIDE_CLASSNODE.equals(annotation.getClassNode())) {
                 result.add(annotation);
@@ -614,7 +599,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
     private static Parameter createSelfParameter(final ClassNode traitClass, boolean isStatic) {
         final ClassNode rawType = traitClass.getPlainNodeReference();
         ClassNode type = createReceiverType(isStatic, rawType);
-        return new Parameter(type, isStatic?Traits.STATIC_THIS_OBJECT:Traits.THIS_OBJECT);
+        return new Parameter(type, isStatic ? Traits.STATIC_THIS_OBJECT : Traits.THIS_OBJECT);
     }
 
     private static ClassNode createReceiverType(final boolean isStatic, final ClassNode rawType) {
@@ -632,20 +617,18 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         return type;
     }
 
-    private Statement processBody(VariableExpression thisObject, Statement code, ClassNode trait, ClassNode traitHelper, ClassNode fieldHelper, Collection<String> knownFields) {
+    private Statement processBody(final VariableExpression thisObject, final Statement code, final ClassNode trait, final ClassNode traitHelper, final ClassNode fieldHelper, final Collection<String> knownFields) {
         if (code == null) return null;
-        NAryOperationRewriter operationRewriter = new NAryOperationRewriter(unit, knownFields);
+        NAryOperationRewriter operationRewriter = new NAryOperationRewriter(sourceUnit, knownFields);
         code.visit(operationRewriter);
-        SuperCallTraitTransformer superTrn = new SuperCallTraitTransformer(unit);
+        SuperCallTraitTransformer superTrn = new SuperCallTraitTransformer(sourceUnit);
         code.visit(superTrn);
-        TraitReceiverTransformer trn = new TraitReceiverTransformer(thisObject, unit, trait, traitHelper, fieldHelper, knownFields);
+        TraitReceiverTransformer trn = new TraitReceiverTransformer(thisObject, sourceUnit, trait, traitHelper, fieldHelper, knownFields);
         code.visit(trn);
         return code;
     }
 
-    public void setCompilationUnit(final CompilationUnit unit) {
-        this.compilationUnit = unit;
-    }
+    //--------------------------------------------------------------------------
 
     private static class DefaultArgsMethodsAdder extends Verifier {
 
@@ -659,7 +642,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
     private static class PostTypeCheckingExpressionReplacer extends ClassCodeExpressionTransformer {
         private final SourceUnit sourceUnit;
 
-        private PostTypeCheckingExpressionReplacer(final SourceUnit sourceUnit) {
+        PostTypeCheckingExpressionReplacer(final SourceUnit sourceUnit) {
             this.sourceUnit = sourceUnit;
         }
 
@@ -671,13 +654,12 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
         @Override
         public Expression transform(final Expression exp) {
             if (exp != null) {
-                Expression replacement = exp.getNodeMetaData(TraitASTTransformation.POST_TYPECHECKING_REPLACEMENT);
-                if (replacement!=null) {
+                Expression replacement = exp.getNodeMetaData(POST_TYPECHECKING_REPLACEMENT);
+                if (replacement != null) {
                     return replacement;
                 }
             }
             return super.transform(exp);
         }
     }
-
 }
diff --git a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
index dfd956a..45a91b1 100644
--- a/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
+++ b/src/test/org/codehaus/groovy/transform/traitx/TraitASTTransformationTest.groovy
@@ -1019,48 +1019,48 @@ final class TraitASTTransformationTest {
     void testTraitSuperPropertyGet() {
         assertScript '''
             trait T {
-              def x = 'value'
+                def x = 'value'
             }
             class C implements T {
-              def test() {
-                T.super.x
-              }
+                def test() {
+                    T.super.x
+                }
             }
             assert new C().test() == 'value'
         '''
 
         assertScript '''
             trait T {
-              boolean x = true
+                boolean x = true
             }
             class C implements T {
-              def test() {
-                T.super.x
-              }
+                def test() {
+                    T.super.x
+                }
             }
             assert new C().test() == true
         '''
 
         assertScript '''
             trait T {
-              def getX() { 'value' }
+                def getX() { 'value' }
             }
             class C implements T {
-              def test() {
-                T.super.x
-              }
+                def test() {
+                    T.super.x
+                }
             }
             assert new C().test() == 'value'
         '''
 
         assertScript '''
             trait T {
-              boolean isX() { true }
+                boolean isX() { true }
             }
             class C implements T {
-              def test() {
-                T.super.x
-              }
+                def test() {
+                    T.super.x
+                }
             }
             assert new C().test() == true
         '''
@@ -1070,40 +1070,54 @@ final class TraitASTTransformationTest {
     void testTraitSuperPropertySet() {
         assertScript '''
             trait T {
-              def x
+                def x
             }
             class C implements T {
-              def test() {
-                T.super.x = 'value'
-                return x
-              }
+                def test() {
+                    T.super.x = 'value'
+                    return x
+                }
+            }
+            assert new C().test() == 'value'
+        '''
+
+        def err = shouldFail '''
+            trait T {
+                final x = 'const'
+            }
+            class C implements T {
+                def test() {
+                    T.super.x = 'value'
+                    return x
+                }
             }
             assert new C().test() == 'value'
         '''
+        assert err =~ /No such property: super for class: T/
 
         // TODO: add support for compound assignment
         shouldFail MissingPropertyException, '''
             trait T {
-              def x = 'value'
+                def x = 'value'
             }
             class C implements T {
-              def test() {
-                T.super.x -= ~/e\b/
-                T.super.x += 'able'
-                return x
-              }
+                def test() {
+                    T.super.x -= ~/e\b/
+                    T.super.x += 'able'
+                    return x
+                }
             }
             assert new C().test() == 'valuable'
         '''
 
         assertScript '''
             trait T {
-              def setX(value) { 'retval' }
+                def setX(value) { 'retval' }
             }
             class C implements T {
-              def test() {
-                T.super.x = 'value'
-              }
+                def test() {
+                    T.super.x = 'value'
+                }
             }
             assert new C().test() == 'retval'
         '''
@@ -1113,39 +1127,35 @@ final class TraitASTTransformationTest {
     void testTraitSuperPropertySetWithOverloads() {
         assertScript '''
             trait T {
-              def setX(Number n) {
-                'Number'
-              }
-              def setX(String s) {
-                'String'
-              }
+                def setX(Number n) {
+                    'Number'
+                }
+                def setX(String s) {
+                    'String'
+                }
             }
-
             class C implements T {
-              def test() {
-                T.super.x = 42
-              }
+                def test() {
+                    T.super.x = 42
+                }
             }
-
             assert new C().test() == 'Number'
         '''
 
         assertScript '''
             trait T {
-              def setX(Number n) {
-                'Number'
-              }
-              def setX(String s) {
-                'String'
-              }
+                def setX(Number n) {
+                    'Number'
+                }
+                def setX(String s) {
+                    'String'
+                }
             }
-
             class C implements T {
-              def test() {
-                T.super.x = 'x'
-              }
+                def test() {
+                    T.super.x = 'x'
+                }
             }
-
             assert new C().test() == 'String'
         '''
     }