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 2019/12/16 18:31:42 UTC
[groovy] 03/03: normalize addPhaseOperations()
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
commit 85c1891df466c10fe4aa450dfd90c45fcc6a3124
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Dec 16 12:31:23 2019 -0600
normalize addPhaseOperations()
---
.../codehaus/groovy/control/CompilationUnit.java | 235 +++++++++++----------
.../groovy/control/DefaultTransformer.java | 69 ------
2 files changed, 125 insertions(+), 179 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
index 29ca6f3..210ec3f 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
@@ -21,12 +21,15 @@ package org.codehaus.groovy.control;
import groovy.lang.GroovyClassLoader;
import groovy.transform.CompilationUnitAware;
import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.CompileUnit;
import org.codehaus.groovy.ast.GroovyClassVisitor;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.ModuleNode;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
import org.codehaus.groovy.classgen.AsmClassGenerator;
import org.codehaus.groovy.classgen.ClassCompletionVerifier;
import org.codehaus.groovy.classgen.EnumCompletionVisitor;
@@ -48,7 +51,6 @@ import org.codehaus.groovy.syntax.SyntaxException;
import org.codehaus.groovy.tools.GroovyClass;
import org.codehaus.groovy.transform.ASTTransformationVisitor;
import org.codehaus.groovy.transform.AnnotationCollectorTransform;
-import org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys;
import org.codehaus.groovy.transform.trait.TraitComposer;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
@@ -72,6 +74,11 @@ import java.util.Queue;
import java.util.Set;
import java.util.stream.Collectors;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
+import static org.codehaus.groovy.transform.sc.StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK;
+import static org.codehaus.groovy.transform.stc.StaticTypesMarker.SWITCH_CONDITION_EXPRESSION_TYPE;
+
/**
* The CompilationUnit collects all compilation data as it is generated by the compiler system.
* You can use this object to add additional source units to the compilation, or force the
@@ -114,8 +121,6 @@ public class CompilationUnit extends ProcessingUnit {
/** A callback for use during {@link #compile()} */
protected ProgressCallback progressCallback;
- protected StaticImportVisitor staticImportVisitor = new StaticImportVisitor();
- protected DefaultTransformer defaultTransformer = new DefaultTransformer();
protected ClassNodeResolver classNodeResolver = new ClassNodeResolver();
protected ResolveVisitor resolveVisitor = new ResolveVisitor(this);
protected OptimizerVisitor optimizer = new OptimizerVisitor(this);
@@ -182,97 +187,175 @@ public class CompilationUnit extends ProcessingUnit {
private void addPhaseOperations() {
addPhaseOperation(new SourceUnitOperation() {
@Override
- public void call(SourceUnit source) throws CompilationFailedException {
+ public void call(final SourceUnit source) throws CompilationFailedException {
source.parse();
}
}, Phases.PARSING);
- addPhaseOperation(convert, Phases.CONVERSION);
+
+ addPhaseOperation(new SourceUnitOperation() {
+ @Override
+ public void call(final SourceUnit source) throws CompilationFailedException {
+ source.convert();
+ // add module to compile unit
+ getAST().addModule(source.getAST());
+
+ if (progressCallback != null) {
+ progressCallback.call(source, phase);
+ }
+ }
+ }, Phases.CONVERSION);
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- EnumVisitor ev = new EnumVisitor(CompilationUnit.this, source);
- ev.visitClass(classNode);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ GroovyClassVisitor visitor = new EnumVisitor(CompilationUnit.this, source);
+ visitor.visitClass(classNode);
}
}, Phases.CONVERSION);
+
addPhaseOperation(resolve, Phases.SEMANTIC_ANALYSIS);
- addPhaseOperation(staticImport, Phases.SEMANTIC_ANALYSIS);
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- InnerClassVisitor iv = new InnerClassVisitor(CompilationUnit.this, source);
- iv.visitClass(classNode);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ StaticImportVisitor visitor = new StaticImportVisitor();
+ visitor.visitClass(classNode, source);
}
}, Phases.SEMANTIC_ANALYSIS);
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ GroovyClassVisitor visitor = new InnerClassVisitor(CompilationUnit.this, source);
+ visitor.visitClass(classNode);
+ }
+ }, Phases.SEMANTIC_ANALYSIS);
+ addPhaseOperation(new PrimaryClassNodeOperation() {
+ @Override
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
if (!classNode.isSynthetic()) {
- GenericsVisitor genericsVisitor = new GenericsVisitor(source);
- genericsVisitor.visitClass(classNode);
+ GroovyClassVisitor visitor = new GenericsVisitor(source);
+ visitor.visitClass(classNode);
}
}
}, Phases.SEMANTIC_ANALYSIS);
+
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
TraitComposer.doExtendTraits(classNode, source, CompilationUnit.this);
}
}, Phases.CANONICALIZATION);
- addPhaseOperation(compileCompleteCheck, Phases.CANONICALIZATION);
+ addPhaseOperation(new SourceUnitOperation() {
+ @Override
+ public void call(final SourceUnit source) throws CompilationFailedException {
+ List<ClassNode> classes = source.ast.getClasses();
+ for (ClassNode node : classes) {
+ CompileUnit cu = node.getCompileUnit();
+ for (Iterator<String> it = cu.iterateClassNodeToCompile(); it.hasNext(); ) {
+ String name = it.next();
+ StringBuilder message = new StringBuilder();
+ message
+ .append("Compilation incomplete: expected to find the class ")
+ .append(name)
+ .append(" in ")
+ .append(source.getName());
+ if (classes.isEmpty()) {
+ message.append(", but the file seems not to contain any classes");
+ } else {
+ message.append(", but the file contains the classes: ");
+ boolean first = true;
+ for (ClassNode cn : classes) {
+ if (!first) {
+ message.append(", ");
+ } else {
+ first = false;
+ }
+ message.append(cn.getName());
+ }
+ }
+
+ getErrorCollector().addErrorAndContinue(
+ new SimpleMessage(message.toString(), CompilationUnit.this)
+ );
+ it.remove();
+ }
+ }
+ }
+ }, Phases.CANONICALIZATION);
+
addPhaseOperation(classgen, Phases.CLASS_GENERATION);
addPhaseOperation(output);
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- AnnotationCollectorTransform.ClassChanger actt = new AnnotationCollectorTransform.ClassChanger();
- actt.transformClass(classNode);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ AnnotationCollectorTransform.ClassChanger xformer = new AnnotationCollectorTransform.ClassChanger();
+ xformer.transformClass(classNode);
}
}, Phases.SEMANTIC_ANALYSIS);
ASTTransformationVisitor.addPhaseOperations(this);
+
+ // post-transform operations:
+
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- StaticVerifier sv = new StaticVerifier();
- sv.visitClass(classNode, source);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ StaticVerifier verifier = new StaticVerifier();
+ verifier.visitClass(classNode, source);
}
}, Phases.SEMANTIC_ANALYSIS);
+
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- InnerClassCompletionVisitor iv = new InnerClassCompletionVisitor(CompilationUnit.this, source);
- iv.visitClass(classNode);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ GroovyClassVisitor visitor = new InnerClassCompletionVisitor(CompilationUnit.this, source);
+ visitor.visitClass(classNode);
}
}, Phases.CANONICALIZATION);
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- EnumCompletionVisitor ecv = new EnumCompletionVisitor(CompilationUnit.this, source);
- ecv.visitClass(classNode);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ GroovyClassVisitor visitor = new EnumCompletionVisitor(CompilationUnit.this, source);
+ visitor.visitClass(classNode);
}
}, Phases.CANONICALIZATION);
+
addPhaseOperation(new PrimaryClassNodeOperation() {
@Override
- public void call(SourceUnit source, GeneratorContext context,
- ClassNode classNode) throws CompilationFailedException {
- Object callback = classNode.getNodeMetaData(StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK);
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ Object callback = classNode.getNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK);
if (callback instanceof PrimaryClassNodeOperation) {
((PrimaryClassNodeOperation) callback).call(source, context, classNode);
- classNode.removeNodeMetaData(StaticCompilationMetadataKeys.DYNAMIC_OUTER_NODE_CALLBACK);
+ classNode.removeNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK);
}
}
}, Phases.INSTRUCTION_SELECTION);
+ addPhaseOperation(new PrimaryClassNodeOperation() {
+ @Override
+ public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
+ // TODO: Could this be moved into org.codehaus.groovy.transform.sc.transformers.VariableExpressionTransformer?
+ new ClassCodeExpressionTransformer() {
+ @Override
+ protected SourceUnit getSourceUnit() {
+ return source;
+ }
- addPhaseOperation(defaultTransform, Phases.INSTRUCTION_SELECTION);
+ @Override
+ public Expression transform(final Expression expression) {
+ if (expression instanceof VariableExpression) {
+ // check for "switch(enumType) { case CONST: ... }"
+ ClassNode enumType = expression.getNodeMetaData(SWITCH_CONDITION_EXPRESSION_TYPE);
+ if (enumType != null) {
+ // replace "CONST" variable expression with "EnumType.CONST" property expression
+ Expression propertyExpression = propX(classX(enumType), expression.getText());
+ setSourcePosition(propertyExpression, expression);
+ return propertyExpression;
+ }
+ }
+ return expression;
+ }
+ }.visitClass(classNode);
+ }
+ }, Phases.INSTRUCTION_SELECTION);
}
private void applyCompilationCustomizers() {
@@ -667,34 +750,6 @@ public class CompilationUnit extends ProcessingUnit {
}
};
- private final PrimaryClassNodeOperation staticImport = new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- staticImportVisitor.visitClass(classNode, source);
- }
- };
-
- private PrimaryClassNodeOperation defaultTransform = new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- defaultTransformer.visitClass(classNode, source);
- }
- };
-
- /**
- * Runs convert() on a single SourceUnit.
- */
- private final SourceUnitOperation convert = new SourceUnitOperation() {
- @Override
- public void call(final SourceUnit source) throws CompilationFailedException {
- source.convert();
- getAST().addModule(source.getAST());
- if (progressCallback != null) {
- progressCallback.call(source, phase);
- }
- }
- };
-
private final GroovyClassOperation output = new GroovyClassOperation() {
@Override
public void call(final GroovyClass groovyClass) throws CompilationFailedException {
@@ -718,46 +773,6 @@ public class CompilationUnit extends ProcessingUnit {
}
};
- /* checks if all needed classes are compiled before generating the bytecode */
- private final SourceUnitOperation compileCompleteCheck = new SourceUnitOperation() {
- public void call(SourceUnit source) throws CompilationFailedException {
- List<ClassNode> classes = source.ast.getClasses();
- for (ClassNode node : classes) {
- CompileUnit cu = node.getCompileUnit();
- for (Iterator<String> iter = cu.iterateClassNodeToCompile(); iter.hasNext();) {
- String name = iter.next();
- SourceUnit su = ast.getScriptSourceLocation(name);
- List<ClassNode> classesInSourceUnit = su.ast.getClasses();
- StringBuilder message = new StringBuilder();
- message
- .append("Compilation incomplete: expected to find the class ")
- .append(name)
- .append(" in ")
- .append(su.getName());
- if (classesInSourceUnit.isEmpty()) {
- message.append(", but the file seems not to contain any classes");
- } else {
- message.append(", but the file contains the classes: ");
- boolean first = true;
- for (ClassNode cn : classesInSourceUnit) {
- if (!first) {
- message.append(", ");
- } else {
- first = false;
- }
- message.append(cn.getName());
- }
- }
-
- getErrorCollector().addErrorAndContinue(
- new SimpleMessage(message.toString(), CompilationUnit.this)
- );
- iter.remove();
- }
- }
- }
- };
-
/**
* Runs classgen() on a single ClassNode.
*/
diff --git a/src/main/java/org/codehaus/groovy/control/DefaultTransformer.java b/src/main/java/org/codehaus/groovy/control/DefaultTransformer.java
deleted file mode 100644
index 6daa511..0000000
--- a/src/main/java/org/codehaus/groovy/control/DefaultTransformer.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * 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.codehaus.groovy.control;
-
-import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-
-import static org.codehaus.groovy.transform.stc.StaticTypesMarker.SWITCH_CONDITION_EXPRESSION_TYPE;
-
-/**
- * The default transformer a.k.a. the last transformer to transform expressions, it can use type info if STC is enabled
- *
- * @since 3.0.0
- */
-public class DefaultTransformer extends ClassCodeExpressionTransformer {
- private ClassNode currentClass;
- private SourceUnit source;
-
- public void visitClass(ClassNode node, SourceUnit source) {
- this.currentClass = node;
- this.source = source;
- super.visitClass(node);
- }
-
- public Expression transform(Expression exp) {
- if (null == exp) return null;
-
- if (exp.getClass() == VariableExpression.class) {
- return transformVariableExpression((VariableExpression) exp);
- }
- return exp;
- }
-
- private Expression transformVariableExpression(VariableExpression ve) {
- ClassNode enumClassNode = ve.getNodeMetaData(SWITCH_CONDITION_EXPRESSION_TYPE);
- if (null != enumClassNode) {
- Expression result = new PropertyExpression(new ClassExpression(enumClassNode), ve.getName());
- setSourcePosition(result, ve);
-
- return result;
- }
- return ve;
- }
-
- @Override
- protected SourceUnit getSourceUnit() {
- return source;
- }
-}