You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2021/01/15 11:33:10 UTC

[groovy] 03/03: GROOVY-9858: additional refactoring (port to 2_5_X)

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

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

commit 346461fffefbd22dcf8c330429f9196b30be9959
Author: Paul King <pa...@asert.com.au>
AuthorDate: Fri Jan 15 21:27:18 2021 +1000

    GROOVY-9858: additional refactoring (port to 2_5_X)
---
 .../apache/groovy/ast/tools/ClassNodeUtils.java    | 10 +++
 .../groovy/classgen/asm/ClosureWriter.java         | 76 ++++++++++------------
 .../classgen/asm/sc/StaticTypesClosureWriter.java  | 59 +++++++----------
 3 files changed, 71 insertions(+), 74 deletions(-)

diff --git a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
index 9f88b89..573542f 100644
--- a/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/ClassNodeUtils.java
@@ -106,6 +106,16 @@ public class ClassNodeUtils {
     }
 
     /**
+     * Add a method and mark it as {@code @Generated}.
+     *
+     * @see ClassNode#addMethod(MethodNode)
+     */
+    public static void addGeneratedMethod(final ClassNode cNode, final MethodNode mNode, final boolean skipChecks) {
+        cNode.addMethod(mNode);
+        markAsGenerated(cNode, mNode, skipChecks);
+    }
+
+    /**
      * Add an inner class that is marked as {@code @Generated}.
      *
      * @see org.codehaus.groovy.ast.ModuleNode#addClass(ClassNode)
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
index b687e07..b47ece8 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/ClosureWriter.java
@@ -30,19 +30,15 @@ import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
 import org.codehaus.groovy.ast.Variable;
 import org.codehaus.groovy.ast.VariableScope;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ClassExpression;
 import org.codehaus.groovy.ast.expr.ClosureExpression;
 import org.codehaus.groovy.ast.expr.ConstantExpression;
 import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
 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.TupleExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
 import org.codehaus.groovy.classgen.AsmClassGenerator;
 import org.codehaus.groovy.classgen.Verifier;
 import org.objectweb.asm.MethodVisitor;
@@ -53,6 +49,15 @@ import java.util.List;
 import java.util.Map;
 
 import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorSuperX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.fieldX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
+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.objectweb.asm.Opcodes.ACC_FINAL;
 import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
 import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
@@ -121,8 +126,8 @@ public class ClosureWriter {
             Parameter param = localVariableParams[i];
             String name = param.getName();
             loadReference(name, controller);
-            if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class)==null) {
-                param.setNodeMetaData(ClosureWriter.UseExistingReference.class,Boolean.TRUE);
+            if (param.getNodeMetaData(ClosureWriter.UseExistingReference.class) == null) {
+                param.setNodeMetaData(ClosureWriter.UseExistingReference.class, Boolean.TRUE);
             }
         }
 
@@ -196,10 +201,10 @@ public class ClosureWriter {
             parameters = Parameter.EMPTY_ARRAY;
         } else if (parameters.length == 0) {
             // let's create a default 'it' parameter
-            Parameter it = new Parameter(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
+            Parameter it = param(ClassHelper.OBJECT_TYPE, "it", ConstantExpression.NULL);
             parameters = new Parameter[]{it};
             Variable ref = expression.getVariableScope().getDeclaredVariable("it");
-            if (ref!=null) it.setClosureSharedVariable(ref.isClosureSharedVariable());
+            if (ref != null) it.setClosureSharedVariable(ref.isClosureSharedVariable());
         }
 
         Parameter[] localVariableParams = getClosureSharedVariables(expression);
@@ -232,22 +237,16 @@ public class ClosureWriter {
                 || (parameters.length == 1
                 && parameters[0].getType() != null
                 && parameters[0].getType() != ClassHelper.OBJECT_TYPE
-                && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType())))
-        {
-
+                && !ClassHelper.OBJECT_TYPE.equals(parameters[0].getType().getComponentType()))) {
             // let's add a typesafe call method
-            MethodNode call = answer.addMethod(
+            MethodNode call = new MethodNode(
                     "call",
                     ACC_PUBLIC,
                     ClassHelper.OBJECT_TYPE,
                     parameters,
                     ClassNode.EMPTY_ARRAY,
-                    new ReturnStatement(
-                            new MethodCallExpression(
-                                    VariableExpression.THIS_EXPRESSION,
-                                    "doCall",
-                                    new ArgumentListExpression(parameters))));
-            markAsGenerated(answer, call, true);
+                    returnS(callThisX("doCall", args(parameters))));
+            addGeneratedMethod(answer, call, true);
             call.setSourcePosition(expression);
         }
 
@@ -262,17 +261,13 @@ public class ClosureWriter {
         thisObject.setSourcePosition(expression);
         block.getVariableScope().putReferencedLocalVariable(thisObject);
         TupleExpression conArgs = new TupleExpression(outer, thisObject);
-        block.addStatement(
-                new ExpressionStatement(
-                        new ConstructorCallExpression(
-                                ClassNode.SUPER,
-                                conArgs)));
+        block.addStatement(stmt(ctorSuperX(conArgs)));
 
         // let's assign all the parameter fields from the outer context
         for (Parameter param : localVariableParams) {
             String paramName = param.getName();
             ClassNode type = param.getType();
-            VariableExpression initialValue = new VariableExpression(paramName);
+            VariableExpression initialValue = varX(paramName);
             initialValue.setAccessedVariable(param);
             initialValue.setUseReferenceDirectly(true);
             ClassNode realType = type;
@@ -284,21 +279,21 @@ public class ClosureWriter {
             String methodName = Verifier.capitalize(paramName);
 
             // let's add a getter & setter
-            Expression fieldExp = new FieldExpression(paramField);
+            Expression fieldExp = fieldX(paramField);
             markAsGenerated(answer,
-                answer.addMethod(
-                    "get" + methodName,
-                    ACC_PUBLIC,
-                    realType.getPlainNodeReference(),
-                    Parameter.EMPTY_ARRAY,
-                    ClassNode.EMPTY_ARRAY,
-                    new ReturnStatement(fieldExp)),
-                true);
+                    answer.addMethod(
+                            "get" + methodName,
+                            ACC_PUBLIC,
+                            realType.getPlainNodeReference(),
+                            Parameter.EMPTY_ARRAY,
+                            ClassNode.EMPTY_ARRAY,
+                            returnS(fieldExp)),
+                    true);
         }
 
         Parameter[] params = new Parameter[2 + localVariableParams.length];
-        params[0] = new Parameter(ClassHelper.OBJECT_TYPE, "_outerInstance");
-        params[1] = new Parameter(ClassHelper.OBJECT_TYPE, "_thisObject");
+        params[0] = param(ClassHelper.OBJECT_TYPE, "_outerInstance");
+        params[1] = param(ClassHelper.OBJECT_TYPE, "_thisObject");
         System.arraycopy(localVariableParams, 0, params, 2, localVariableParams.length);
 
         ASTNode sn = answer.addConstructor(ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, block);
@@ -336,7 +331,7 @@ public class ClosureWriter {
     private static void removeInitialValues(Parameter[] params) {
         for (int i = 0; i < params.length; i++) {
             if (params[i].hasInitialExpression()) {
-                Parameter p = new Parameter(params[i].getType(), params[i].getName());
+                Parameter p = param(params[i].getType(), params[i].getName());
                 p.setOriginType(p.getOriginType());
                 params[i] = p;
             }
@@ -354,14 +349,15 @@ public class ClosureWriter {
         mv.visitVarInsn(ALOAD, 0);
         ClassNode callNode = classNode.getSuperClass();
         TupleExpression arguments = (TupleExpression) call.getArguments();
-        if (arguments.getExpressions().size()!=2) throw new GroovyBugError("expected 2 arguments for closure constructor super call, but got"+arguments.getExpressions().size());
+        if (arguments.getExpressions().size() != 2)
+            throw new GroovyBugError("expected 2 arguments for closure constructor super call, but got" + arguments.getExpressions().size());
         arguments.getExpression(0).visit(acg);
         operandStack.box();
         arguments.getExpression(1).visit(acg);
         operandStack.box();
         //TODO: replace with normal String, p not needed
-        Parameter p = new Parameter(ClassHelper.OBJECT_TYPE,"_p");
-        String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[]{p,p});
+        Parameter p = param(ClassHelper.OBJECT_TYPE, "_p");
+        String descriptor = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[]{p, p});
         mv.visitMethodInsn(INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
         operandStack.remove(2);
         return true;
@@ -373,7 +369,7 @@ public class ClosureWriter {
         int index = 0;
         for (Iterator iter = scope.getReferencedLocalVariablesIterator(); iter.hasNext();) {
             Variable element = (org.codehaus.groovy.ast.Variable) iter.next();
-            Parameter p = new Parameter(element.getType(), element.getName());
+            Parameter p = param(element.getType(), element.getName());
             p.setOriginType(element.getOriginType());
             p.setClosureSharedVariable(element.isClosureSharedVariable());
             ret[index] = p;
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesClosureWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesClosureWriter.java
index 1f91824..e10c8c9 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesClosureWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesClosureWriter.java
@@ -18,19 +18,15 @@
  */
 package org.codehaus.groovy.classgen.asm.sc;
 
-import org.apache.groovy.ast.tools.AnnotatedNodeUtils;
 import org.codehaus.groovy.GroovyBugError;
 import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
 import org.codehaus.groovy.ast.MethodNode;
 import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
 import org.codehaus.groovy.classgen.asm.ClosureWriter;
 import org.codehaus.groovy.classgen.asm.WriterController;
 import org.codehaus.groovy.control.SourceUnit;
@@ -40,6 +36,14 @@ import org.objectweb.asm.Opcodes;
 
 import java.util.List;
 
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedMethod;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.returnS;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+
 /**
  * Writer responsible for generating closure classes in statically compiled mode.
  */
@@ -80,37 +84,24 @@ public class StaticTypesClosureWriter extends ClosureWriter {
         // is too complex!
 
         // call(Object)
-        Parameter args = new Parameter(ClassHelper.OBJECT_TYPE, "args");
-        MethodCallExpression doCall1arg = new MethodCallExpression(
-                new VariableExpression("this", closureClass),
-                "doCall",
-                new ArgumentListExpression(new VariableExpression(args))
-        );
-        doCall1arg.setImplicitThis(true);
-        doCall1arg.setMethodTarget(doCallMethod);
-        closureClass.addMethod(AnnotatedNodeUtils.markAsGenerated(closureClass,
-                new MethodNode("call",
-                        Opcodes.ACC_PUBLIC,
-                        ClassHelper.OBJECT_TYPE,
-                        new Parameter[]{args},
-                        ClassNode.EMPTY_ARRAY,
-                        new ReturnStatement(doCall1arg)),
-                true
-        ));
+        Parameter args = param(ClassHelper.OBJECT_TYPE, "args");
+        addGeneratedCallMethod(closureClass, doCallMethod, varX(args), new Parameter[]{args});
 
         // call()
-        MethodCallExpression doCallNoArgs = new MethodCallExpression(new VariableExpression("this", closureClass), "doCall", new ArgumentListExpression(new ConstantExpression(null)));
-        doCallNoArgs.setImplicitThis(true);
-        doCallNoArgs.setMethodTarget(doCallMethod);
-        closureClass.addMethod(AnnotatedNodeUtils.markAsGenerated(closureClass,
-                new MethodNode("call",
-                        Opcodes.ACC_PUBLIC,
-                        ClassHelper.OBJECT_TYPE,
-                        Parameter.EMPTY_ARRAY,
-                        ClassNode.EMPTY_ARRAY,
-                        new ReturnStatement(doCallNoArgs)),
-                true
-        ));
+        addGeneratedCallMethod(closureClass, doCallMethod, constX(null), Parameter.EMPTY_ARRAY);
+    }
+
+    private static void addGeneratedCallMethod(ClassNode closureClass, MethodNode doCallMethod, Expression expression, Parameter[] params) {
+        MethodCallExpression doCallarg = callX(varX("this", closureClass), "doCall", args(expression));
+        doCallarg.setImplicitThis(true);
+        doCallarg.setMethodTarget(doCallMethod);
+        MethodNode call = new MethodNode("call",
+                Opcodes.ACC_PUBLIC,
+                ClassHelper.OBJECT_TYPE,
+                params,
+                ClassNode.EMPTY_ARRAY,
+                returnS(doCallarg));
+        addGeneratedMethod(closureClass, call, true);
     }
 
     private static final class MethodTargetCompletionVisitor extends ClassCodeVisitorSupport {