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 2020/02/19 04:25:18 UTC
[groovy] 02/04: minor refactor: remove duplicate code
This is an automated email from the ASF dual-hosted git repository.
paulk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 9be1c9939091812b3a477049c54c7a6c5a0d9ce9
Author: Paul King <pa...@asert.com.au>
AuthorDate: Wed Feb 19 10:44:31 2020 +1000
minor refactor: remove duplicate code
---
.../groovy/ast/tools/ConstructorNodeUtils.java | 60 ++++++++++++++++++++++
.../apache/groovy/ast/tools/MethodNodeUtils.java | 26 ++++++++++
.../java/org/codehaus/groovy/ast/ClassNode.java | 12 +----
.../codehaus/groovy/ast/tools/GeneralUtils.java | 24 +++++++--
.../classgen/InnerClassCompletionVisitor.java | 42 ++++-----------
.../org/codehaus/groovy/classgen/Verifier.java | 21 ++------
.../tools/javac/JavaAwareResolveVisitor.java | 25 ++-------
.../groovy/tools/javac/JavaStubGenerator.java | 26 ++--------
.../transform/trait/TraitASTTransformation.java | 12 +----
9 files changed, 131 insertions(+), 117 deletions(-)
diff --git a/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
new file mode 100644
index 0000000..87851f4
--- /dev/null
+++ b/src/main/java/org/apache/groovy/ast/tools/ConstructorNodeUtils.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.groovy.ast.tools;
+
+import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
+
+import java.util.List;
+
+/**
+ * Utility class for working with ConstructorNodes
+ */
+public class ConstructorNodeUtils {
+ private ConstructorNodeUtils() { }
+
+ /**
+ * Return the first statement from the constructor code if it is a call to super or this, otherwise null.
+ *
+ * @param code
+ * @return the first statement if a special call or null
+ */
+ public static ConstructorCallExpression getFirstIfSpecialConstructorCall(Statement code) {
+ if (code == null) return null;
+
+ if (code instanceof BlockStatement) {
+ final BlockStatement block = (BlockStatement) code;
+ final List<Statement> statementList = block.getStatements();
+ if (statementList.isEmpty()) return null;
+ // handle blocks of blocks
+ return getFirstIfSpecialConstructorCall(statementList.get(0));
+ }
+
+ if (!(code instanceof ExpressionStatement)) return null;
+
+ Expression expression = ((ExpressionStatement) code).getExpression();
+ if (!(expression instanceof ConstructorCallExpression)) return null;
+ ConstructorCallExpression cce = (ConstructorCallExpression) expression;
+ if (cce.isSpecialCall()) return cce;
+ return null;
+ }
+}
diff --git a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
index 1dc0d33..aa7cd3d 100644
--- a/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
+++ b/src/main/java/org/apache/groovy/ast/tools/MethodNodeUtils.java
@@ -21,6 +21,8 @@ package org.apache.groovy.ast.tools;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
import static org.apache.groovy.util.BeanUtils.decapitalize;
@@ -94,4 +96,28 @@ public class MethodNodeUtils {
}
private MethodNodeUtils() { }
+
+ /**
+ * Gets the code for a method (or constructor) as a block.
+ * If no code is found, an empty block will be returned.
+ * If a single non-block statement is found, a block containing that statement will be returned.
+ * Otherwise the existing block statement will be returned.
+ * The original {@code node} is not modified.
+ *
+ * @param node the method (or constructor) node
+ * @return the found or created block statement
+ */
+ public static BlockStatement getCodeAsBlock(MethodNode node) {
+ Statement code = node.getCode();
+ BlockStatement block;
+ if (code == null) {
+ block = new BlockStatement();
+ } else if (!(code instanceof BlockStatement)) {
+ block = new BlockStatement();
+ block.addStatement(code);
+ } else {
+ block = (BlockStatement) code;
+ }
+ return block;
+ }
}
diff --git a/src/main/java/org/codehaus/groovy/ast/ClassNode.java b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
index 15f6eb0..4d0e12f 100644
--- a/src/main/java/org/codehaus/groovy/ast/ClassNode.java
+++ b/src/main/java/org/codehaus/groovy/ast/ClassNode.java
@@ -51,6 +51,7 @@ import java.util.stream.Collectors;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
/**
* Represents a class in the AST.
@@ -796,16 +797,7 @@ public class ClassNode extends AnnotatedNode implements Opcodes {
public void addStaticInitializerStatements(List<Statement> staticStatements, boolean fieldInit) {
MethodNode method = getOrAddStaticConstructorNode();
- BlockStatement block = null;
- Statement statement = method.getCode();
- if (statement == null) {
- block = new BlockStatement();
- } else if (statement instanceof BlockStatement) {
- block = (BlockStatement) statement;
- } else {
- block = new BlockStatement();
- block.addStatement(statement);
- }
+ BlockStatement block = getCodeAsBlock(method);
// while anything inside a static initializer block is appended
// we don't want to append in the case we have a initialization
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 0d850ce..38062a4 100644
--- a/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
+++ b/src/main/java/org/codehaus/groovy/ast/tools/GeneralUtils.java
@@ -271,19 +271,35 @@ public class GeneralUtils {
}
public static Statement ctorSuperS(final Expression args) {
- return stmt(ctorX(ClassNode.SUPER, args));
+ return stmt(ctorSuperX(args));
+ }
+
+ public static ConstructorCallExpression ctorSuperX(Expression args) {
+ return ctorX(ClassNode.SUPER, args);
}
public static Statement ctorThisS(final Expression args) {
- return stmt(ctorX(ClassNode.THIS, args));
+ return stmt(ctorThisX(args));
+ }
+
+ public static ConstructorCallExpression ctorThisX(Expression args) {
+ return ctorX(ClassNode.THIS, args);
}
public static Statement ctorSuperS() {
- return stmt(ctorX(ClassNode.SUPER));
+ return stmt(ctorSuperX());
+ }
+
+ public static ConstructorCallExpression ctorSuperX() {
+ return ctorX(ClassNode.SUPER);
}
public static Statement ctorThisS() {
- return stmt(ctorX(ClassNode.THIS));
+ return stmt(ctorThisX());
+ }
+
+ public static ConstructorCallExpression ctorThisX() {
+ return ctorX(ClassNode.THIS);
}
public static Statement declS(final Expression target, final Expression init) {
diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
index 4b8a1a2..077d84a 100644
--- a/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassCompletionVisitor.java
@@ -31,8 +31,6 @@ import org.codehaus.groovy.ast.expr.Expression;
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.Statement;
import org.codehaus.groovy.classgen.asm.BytecodeHelper;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.SourceUnit;
@@ -42,7 +40,13 @@ import org.objectweb.asm.Opcodes;
import java.util.List;
import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
+import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
import static org.codehaus.groovy.ast.ClassHelper.CLOSURE_TYPE;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorSuperX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
public class InnerClassCompletionVisitor extends InnerClassVisitorHelper implements Opcodes {
@@ -368,7 +372,6 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme
private void addThisReference(ConstructorNode node) {
if (!shouldHandleImplicitThisForInnerClass(classNode)) return;
- Statement code = node.getCode();
// add "this$0" field init
@@ -382,27 +385,19 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme
newParams[0] = thisPara;
node.setParameters(newParams);
- BlockStatement block = null;
- if (code == null) {
- block = new BlockStatement();
- } else if (!(code instanceof BlockStatement)) {
- block = new BlockStatement();
- block.addStatement(code);
- } else {
- block = (BlockStatement) code;
- }
- BlockStatement newCode = new BlockStatement();
+ BlockStatement block = getCodeAsBlock(node);
+ BlockStatement newCode = block();
addFieldInit(thisPara, thisField, newCode);
ConstructorCallExpression cce = getFirstIfSpecialConstructorCall(block);
if (cce == null) {
- cce = new ConstructorCallExpression(ClassNode.SUPER, new TupleExpression());
- block.getStatements().add(0, new ExpressionStatement(cce));
+ cce = ctorSuperX(new TupleExpression());
+ block.getStatements().add(0, stmt(cce));
}
if (shouldImplicitlyPassThisPara(cce)) {
// add thisPara to this(...)
TupleExpression args = (TupleExpression) cce.getArguments();
List<Expression> expressions = args.getExpressions();
- VariableExpression ve = new VariableExpression(thisPara.getName());
+ VariableExpression ve = varX(thisPara.getName());
ve.setAccessedVariable(thisPara);
expressions.add(0, ve);
}
@@ -446,19 +441,4 @@ public class InnerClassCompletionVisitor extends InnerClassVisitorHelper impleme
return namePrefix;
}
- private static ConstructorCallExpression getFirstIfSpecialConstructorCall(BlockStatement code) {
- if (code == null) return null;
-
- final List<Statement> statementList = code.getStatements();
- if (statementList.isEmpty()) return null;
-
- final Statement statement = statementList.get(0);
- if (!(statement instanceof ExpressionStatement)) return null;
-
- Expression expression = ((ExpressionStatement) statement).getExpression();
- if (!(expression instanceof ConstructorCallExpression)) return null;
- ConstructorCallExpression cce = (ConstructorCallExpression) expression;
- if (cce.isSpecialCall()) return cce;
- return null;
- }
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/Verifier.java b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
index 4310bfb..394ddfa 100644
--- a/src/main/java/org/codehaus/groovy/classgen/Verifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/Verifier.java
@@ -90,6 +90,8 @@ import static java.lang.reflect.Modifier.isPublic;
import static java.lang.reflect.Modifier.isStatic;
import static java.util.stream.Collectors.joining;
import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
+import static org.apache.groovy.ast.tools.MethodNodeUtils.getCodeAsBlock;
+import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
import static org.apache.groovy.ast.tools.MethodNodeUtils.getPropertyName;
import static org.apache.groovy.ast.tools.MethodNodeUtils.methodDescriptorWithoutReturnType;
@@ -1041,15 +1043,8 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
statements.addAll(node.getObjectInitializerStatements());
- Statement code = constructorNode.getCode();
- BlockStatement block = new BlockStatement();
+ BlockStatement block = getCodeAsBlock(constructorNode);
List<Statement> otherStatements = block.getStatements();
- if (code instanceof BlockStatement) {
- block = (BlockStatement) code;
- otherStatements = block.getStatements();
- } else if (code != null) {
- otherStatements.add(code);
- }
if (!otherStatements.isEmpty()) {
if (first != null) {
// it is super(..) since this(..) is already covered
@@ -1121,16 +1116,6 @@ public class Verifier implements GroovyClassVisitor, Opcodes {
return false;
}
- private static ConstructorCallExpression getFirstIfSpecialConstructorCall(Statement code) {
- if (!(code instanceof ExpressionStatement)) return null;
-
- Expression expression = ((ExpressionStatement) code).getExpression();
- if (!(expression instanceof ConstructorCallExpression)) return null;
- ConstructorCallExpression cce = (ConstructorCallExpression) expression;
- if (cce.isSpecialCall()) return cce;
- return null;
- }
-
protected void addFieldInitialization(List list, List staticList, FieldNode fieldNode,
boolean isEnumClassNode, List initStmtsAfterEnumValuesInit, Set explicitStaticPropsInEnum) {
Expression expression = fieldNode.getInitialExpression();
diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareResolveVisitor.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareResolveVisitor.java
index 4291ac4..c885885 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareResolveVisitor.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareResolveVisitor.java
@@ -20,42 +20,25 @@ package org.codehaus.groovy.tools.javac;
import org.codehaus.groovy.ast.ASTNode;
import org.codehaus.groovy.ast.ConstructorNode;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.ResolveVisitor;
+import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
+
public class JavaAwareResolveVisitor extends ResolveVisitor {
public JavaAwareResolveVisitor(CompilationUnit cu) {
super(cu);
}
- private static Expression getConstructorCall(Statement code) {
- if (code==null) return null;
- if (code instanceof BlockStatement) {
- BlockStatement bs = (BlockStatement) code;
- if (bs.isEmpty()) return null;
- return getConstructorCall(bs.getStatements().get(0));
- }
- if (!(code instanceof ExpressionStatement)) return null;
- ExpressionStatement es = (ExpressionStatement) code;
- Expression exp = es.getExpression();
- if (!(exp instanceof ConstructorCallExpression)) return null;
- ConstructorCallExpression cce = (ConstructorCallExpression) exp;
- if (!cce.isSpecialCall()) return null;
- return cce;
- }
-
@Override
public void visitConstructor(ConstructorNode node) {
super.visitConstructor(node);
Statement code = node.getCode();
- Expression cce = getConstructorCall(code);
- if (cce==null) return;
+ Expression cce = getFirstIfSpecialConstructorCall(code);
+ if (cce == null) return;
cce.visit(this);
}
diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
index 871fe37..7e73515 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubGenerator.java
@@ -76,6 +76,7 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.groovy.ast.tools.ConstructorNodeUtils.getFirstIfSpecialConstructorCall;
import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
@@ -531,27 +532,6 @@ public class JavaStubGenerator {
return "\"" + escapeSpecialChars(s) + "\"";
}
- private static ConstructorCallExpression getConstructorCallExpression(ConstructorNode constructorNode) {
- Statement code = constructorNode.getCode();
- if (!(code instanceof BlockStatement))
- return null;
-
- BlockStatement block = (BlockStatement) code;
- List stats = block.getStatements();
- if (stats == null || stats.isEmpty())
- return null;
-
- Statement stat = (Statement) stats.get(0);
- if (!(stat instanceof ExpressionStatement))
- return null;
-
- Expression expr = ((ExpressionStatement) stat).getExpression();
- if (!(expr instanceof ConstructorCallExpression))
- return null;
-
- return (ConstructorCallExpression) expr;
- }
-
private void printConstructor(PrintWriter out, ClassNode clazz, ConstructorNode constructorNode) {
printAnnotations(out, constructorNode);
// printModifiers(out, constructorNode.getModifiers());
@@ -564,8 +544,8 @@ public class JavaStubGenerator {
printParams(out, constructorNode);
- ConstructorCallExpression constrCall = getConstructorCallExpression(constructorNode);
- if (constrCall == null || !constrCall.isSpecialCall()) {
+ ConstructorCallExpression constrCall = getFirstIfSpecialConstructorCall(constructorNode.getCode());
+ if (constrCall == null) {
out.println(" {}");
} else {
out.println(" {");
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 70952bf..2daeae2 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -69,6 +69,7 @@ import java.util.List;
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.codehaus.groovy.ast.tools.GeneralUtils.returnS;
import static org.codehaus.groovy.transform.trait.SuperCallTraitTransformer.UNRESOLVED_HELPER_CLASS;
@@ -227,7 +228,7 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
if (!methodNode.isAbstract()) {
MethodNode newMethod = processMethod(cNode, helper, methodNode, fieldHelper, fieldNames);
if (methodNode.getName().equals("<clinit>")) {
- staticInitStatements = getStatements(newMethod.getCode());
+ staticInitStatements = getCodeAsBlock(newMethod).getStatements();
} else {
// add non-abstract methods; abstract methods covered from trait interface
helper.addMethod(newMethod);
@@ -311,15 +312,6 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
return toBlock;
}
- private List<Statement> getStatements(Statement stmt) {
- if (stmt instanceof BlockStatement) {
- return ((BlockStatement) stmt).getStatements();
- }
- List<Statement> result = new ArrayList<Statement>();
- result.add(stmt);
- return result;
- }
-
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,