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 {