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/17 02:40:27 UTC
[groovy] 01/02: add functional interfaces for phase operations to
support lambdas
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 33bbc38e7a443929e3be380741a7186a1244437f
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Mon Dec 16 16:12:03 2019 -0600
add functional interfaces for phase operations to support lambdas
- retain abstract classes and method overloads for binary compatibility
---
.../groovy/tools/ast/TransformTestHelper.groovy | 8 +-
src/main/java/groovy/lang/GroovyClassLoader.java | 2 +-
src/main/java/groovy/util/GroovyScriptEngine.java | 17 +-
.../codehaus/groovy/control/CompilationUnit.java | 667 ++++++++++-----------
.../groovy/control/CompilerConfiguration.java | 2 +-
.../groovy/control/StaticImportVisitor.java | 22 +-
.../control/customizers/CompilationCustomizer.java | 4 +-
.../tools/javac/JavaAwareCompilationUnit.java | 40 +-
.../tools/javac/JavaStubCompilationUnit.java | 26 +-
.../groovy/transform/ASTTransformationVisitor.java | 35 +-
.../transform/sc/StaticCompilationVisitor.java | 14 +-
.../transform/trait/TraitASTTransformation.java | 23 +-
src/test/groovy/lang/GroovyClassLoaderTest.groovy | 4 +-
.../ClosureAndInnerClassNodeStructureTest.groovy | 4 +-
.../codehaus/groovy/tools/gse/DependencyTest.java | 41 +-
.../console/ui/AstNodeToScriptAdapter.groovy | 3 +-
.../console/ui/ScriptToTreeNodeAdapter.groovy | 3 +-
.../groovysh/util/ScriptVariableAnalyzer.groovy | 4 +-
.../codehaus/groovy/jsr223/JSR223SecurityTest.java | 9 +-
.../groovy/parser/antlr4/util/AstDumper.groovy | 3 +-
20 files changed, 430 insertions(+), 501 deletions(-)
diff --git a/src/main/groovy/org/codehaus/groovy/tools/ast/TransformTestHelper.groovy b/src/main/groovy/org/codehaus/groovy/tools/ast/TransformTestHelper.groovy
index d4005e6..8a073bf 100644
--- a/src/main/groovy/org/codehaus/groovy/tools/ast/TransformTestHelper.groovy
+++ b/src/main/groovy/org/codehaus/groovy/tools/ast/TransformTestHelper.groovy
@@ -22,7 +22,6 @@ import groovy.transform.PackageScope
import org.codehaus.groovy.ast.ClassNode
import org.codehaus.groovy.classgen.GeneratorContext
import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
@@ -104,15 +103,16 @@ class TestHarnessClassLoader extends GroovyClassLoader {
* Operation exists so that an AstTransformation can be run against the SourceUnit.
*/
@PackageScope
-class TestHarnessOperation extends PrimaryClassNodeOperation {
+class TestHarnessOperation implements CompilationUnit.IPrimaryClassNodeOperation {
private final ASTTransformation transform
- TestHarnessOperation(transform) {
+ TestHarnessOperation(ASTTransformation transform) {
this.transform = transform
}
+ @Override
void call(SourceUnit source, GeneratorContext ignoredContext, ClassNode ignoredNode) {
- transform.visit(null, source)
+ this.transform.visit(null, source)
}
}
diff --git a/src/main/java/groovy/lang/GroovyClassLoader.java b/src/main/java/groovy/lang/GroovyClassLoader.java
index 27e7038..e4c8aae 100644
--- a/src/main/java/groovy/lang/GroovyClassLoader.java
+++ b/src/main/java/groovy/lang/GroovyClassLoader.java
@@ -1157,7 +1157,7 @@ public class GroovyClassLoader extends URLClassLoader {
clearCache();
}
- private static class TimestampAdder extends CompilationUnit.PrimaryClassNodeOperation implements Opcodes {
+ private static class TimestampAdder implements CompilationUnit.IPrimaryClassNodeOperation, Opcodes {
private static final TimestampAdder INSTANCE = new TimestampAdder();
private TimestampAdder() {}
diff --git a/src/main/java/groovy/util/GroovyScriptEngine.java b/src/main/java/groovy/util/GroovyScriptEngine.java
index fa813a6..7afd183 100644
--- a/src/main/java/groovy/util/GroovyScriptEngine.java
+++ b/src/main/java/groovy/util/GroovyScriptEngine.java
@@ -25,7 +25,6 @@ import groovy.lang.GroovyResourceLoader;
import groovy.lang.Script;
import org.codehaus.groovy.GroovyBugError;
import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.ClassNodeResolver;
import org.codehaus.groovy.control.CompilationFailedException;
@@ -166,16 +165,12 @@ public class GroovyScriptEngine implements ResourceConnector {
// remove all old entries including the "." entry
cache.clear();
- cu.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, GeneratorContext context, ClassNode classNode)
- throws CompilationFailedException {
- // GROOVY-4013: If it is an inner class, tracking its dependencies doesn't really
- // serve any purpose and also interferes with the caching done to track dependencies
- if (classNode instanceof InnerClassNode) return;
- DependencyTracker dt = new DependencyTracker(source, cache, precompiledEntries);
- dt.visitClass(classNode);
- }
+ cu.addPhaseOperation((final SourceUnit sourceUnit, final GeneratorContext context, final ClassNode classNode) -> {
+ // GROOVY-4013: If it is an inner class, tracking its dependencies doesn't really
+ // serve any purpose and also interferes with the caching done to track dependencies
+ if (classNode.getOuterClass() != null) return;
+ DependencyTracker dt = new DependencyTracker(sourceUnit, cache, precompiledEntries);
+ dt.visitClass(classNode);
}, Phases.CLASS_GENERATION);
cu.setClassNodeResolver(new ClassNodeResolver() {
diff --git a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
index 210ec3f..5b81391 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilationUnit.java
@@ -72,8 +72,8 @@ import java.util.Map;
import java.util.Optional;
import java.util.Queue;
import java.util.Set;
-import java.util.stream.Collectors;
+import static java.util.stream.Collectors.toList;
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;
@@ -123,8 +123,6 @@ public class CompilationUnit extends ProcessingUnit {
protected ClassNodeResolver classNodeResolver = new ClassNodeResolver();
protected ResolveVisitor resolveVisitor = new ResolveVisitor(this);
- protected OptimizerVisitor optimizer = new OptimizerVisitor(this);
- protected Verifier verifier = new Verifier();
/** The AST transformations state data. */
protected ASTTransformationsContext astTransformationsContext;
@@ -164,9 +162,10 @@ public class CompilationUnit extends ProcessingUnit {
* Initializes the CompilationUnit with a CodeSource for controlling
* security stuff, a class loader for loading classes, and a class
* loader for loading AST transformations.
- * <b>Note</b> The transform loader must be
- * able to load compiler classes. That means CompilationUnit.class.classLoader
- * must be at last a parent to transformLoader. The other loader has no such constraint.
+ * <p>
+ * <b>Note</b>: The transform loader must be able to load compiler classes.
+ * That means {@link #classLoader} must be at last a parent to {@code transformLoader}.
+ * The other loader has no such constraint.
*
* @param transformLoader - the loader for transforms
* @param loader - loader used to resolve classes against during compilation
@@ -178,188 +177,165 @@ public class CompilationUnit extends ProcessingUnit {
super(configuration, loader, null);
this.astTransformationsContext = new ASTTransformationsContext(this, transformLoader);
- this.ast = new CompileUnit(this.classLoader, codeSource, this.configuration);
+ this.ast = new CompileUnit(getClassLoader(), codeSource, getConfiguration());
addPhaseOperations();
applyCompilationCustomizers();
}
private void addPhaseOperations() {
- addPhaseOperation(new SourceUnitOperation() {
- @Override
- public void call(final SourceUnit source) throws CompilationFailedException {
- source.parse();
- }
- }, Phases.PARSING);
-
- 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);
- }
- }
+ addPhaseOperation(SourceUnit::parse, Phases.PARSING);
+
+ addPhaseOperation(source -> {
+ source.convert();
+ // add module to compile unit
+ getAST().addModule(source.getAST());
+ Optional.ofNullable(getProgressCallback())
+ .ifPresent(callback -> callback.call(source, getPhase()));
}, Phases.CONVERSION);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- GroovyClassVisitor visitor = new EnumVisitor(CompilationUnit.this, source);
- visitor.visitClass(classNode);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new EnumVisitor(this, source);
+ visitor.visitClass(classNode);
}, Phases.CONVERSION);
addPhaseOperation(resolve, Phases.SEMANTIC_ANALYSIS);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- StaticImportVisitor visitor = new StaticImportVisitor();
- visitor.visitClass(classNode, source);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new StaticImportVisitor(classNode, 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 {
- GroovyClassVisitor visitor = new InnerClassVisitor(CompilationUnit.this, source);
- visitor.visitClass(classNode);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new InnerClassVisitor(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()) {
- GroovyClassVisitor visitor = new GenericsVisitor(source);
- visitor.visitClass(classNode);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ if (!classNode.isSynthetic()) {
+ GroovyClassVisitor visitor = new GenericsVisitor(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 {
- TraitComposer.doExtendTraits(classNode, source, CompilationUnit.this);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ TraitComposer.doExtendTraits(classNode, source, this);
}, 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());
+
+ addPhaseOperation(source -> {
+ List<ClassNode> classes = source.getAST().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) {
+ first = false;
+ } else {
+ message.append(", ");
}
+ message.append(cn.getName());
}
-
- getErrorCollector().addErrorAndContinue(
- new SimpleMessage(message.toString(), CompilationUnit.this)
- );
- it.remove();
}
+
+ getErrorCollector().addErrorAndContinue(
+ new SimpleMessage(message.toString(), this)
+ );
+ it.remove();
}
}
}, Phases.CANONICALIZATION);
addPhaseOperation(classgen, Phases.CLASS_GENERATION);
- addPhaseOperation(output);
+ addPhaseOperation(groovyClass -> {
+ String name = groovyClass.getName().replace('.', File.separatorChar) + ".class";
+ File path = new File(getConfiguration().getTargetDirectory(), name);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- AnnotationCollectorTransform.ClassChanger xformer = new AnnotationCollectorTransform.ClassChanger();
- xformer.transformClass(classNode);
+ // ensure the path is ready for the file
+ File directory = path.getParentFile();
+ if (directory != null && !directory.exists()) {
+ directory.mkdirs();
}
+
+ // create the file and write out the data
+ try (FileOutputStream stream = new FileOutputStream(path)) {
+ byte[] bytes = groovyClass.getBytes();
+ stream.write(bytes, 0, bytes.length);
+ } catch (IOException e) {
+ getErrorCollector().addError(Message.create(e.getMessage(), this));
+ }
+ });
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ 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(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- StaticVerifier verifier = new StaticVerifier();
- verifier.visitClass(classNode, source);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ StaticVerifier verifier = new StaticVerifier();
+ verifier.visitClass(classNode, source);
}, Phases.SEMANTIC_ANALYSIS);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- 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(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- GroovyClassVisitor visitor = new EnumCompletionVisitor(CompilationUnit.this, source);
- visitor.visitClass(classNode);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new InnerClassCompletionVisitor(this, source);
+ visitor.visitClass(classNode);
+
+ visitor = new EnumCompletionVisitor(this, source);
+ visitor.visitClass(classNode);
}, Phases.CANONICALIZATION);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- 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(DYNAMIC_OUTER_NODE_CALLBACK);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ Object callback = classNode.getNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK);
+ if (callback instanceof IPrimaryClassNodeOperation) {
+ ((IPrimaryClassNodeOperation) callback).call(source, context, classNode);
+ 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;
- }
- @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;
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ // TODO: Can this be moved into org.codehaus.groovy.transform.sc.transformers.VariableExpressionTransformer?
+ GroovyClassVisitor visitor = new ClassCodeExpressionTransformer() {
+ @Override
+ protected SourceUnit getSourceUnit() {
+ return source;
+ }
+
+ @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);
- }
+ return expression;
+ }
+ };
+ visitor.visitClass(classNode);
}, Phases.INSTRUCTION_SELECTION);
}
private void applyCompilationCustomizers() {
- for (CompilationCustomizer customizer : configuration.getCompilationCustomizers()) {
+ for (CompilationCustomizer customizer : getConfiguration().getCompilationCustomizers()) {
if (customizer instanceof CompilationUnitAware) {
((CompilationUnitAware) customizer).setCompilationUnit(this);
}
@@ -367,26 +343,26 @@ public class CompilationUnit extends ProcessingUnit {
}
}
- public void addPhaseOperation(final GroovyClassOperation op) {
+ public void addPhaseOperation(final IGroovyClassOperation op) {
phaseOperations[Phases.OUTPUT].addFirst(op);
}
- public void addPhaseOperation(final SourceUnitOperation op, final int phase) {
+ public void addPhaseOperation(final ISourceUnitOperation op, final int phase) {
validatePhase(phase);
phaseOperations[phase].add(op);
}
- public void addPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
+ public void addPhaseOperation(final IPrimaryClassNodeOperation op, final int phase) {
validatePhase(phase);
phaseOperations[phase].add(op);
}
- public void addFirstPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
+ public void addFirstPhaseOperation(final IPrimaryClassNodeOperation op, final int phase) {
validatePhase(phase);
phaseOperations[phase].addFirst(op);
}
- public void addNewPhaseOperation(final SourceUnitOperation op, final int phase) {
+ public void addNewPhaseOperation(final ISourceUnitOperation op, final int phase) {
validatePhase(phase);
newPhaseOperations[phase].add(op);
}
@@ -404,7 +380,7 @@ public class CompilationUnit extends ProcessingUnit {
@Override
public void configure(final CompilerConfiguration configuration) {
super.configure(configuration);
- this.debug = this.configuration.getDebug();
+ this.debug = getConfiguration().getDebug();
this.configured = true;
}
@@ -435,16 +411,13 @@ public class CompilationUnit extends ProcessingUnit {
*/
public ClassNode getClassNode(final String name) {
ClassNode[] result = new ClassNode[1];
- PrimaryClassNodeOperation handler = new PrimaryClassNodeOperation() {
- @Override
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
- if (classNode.getName().equals(name)) {
- result[0] = classNode;
- }
+ IPrimaryClassNodeOperation handler = (source, context, classNode) -> {
+ if (classNode.getName().equals(name)) {
+ result[0] = classNode;
}
};
try {
- applyToPrimaryClassNodes(handler);
+ handler.doPhaseOperation(this);
} catch (CompilationFailedException e) {
if (debug) e.printStackTrace();
}
@@ -506,26 +479,26 @@ public class CompilationUnit extends ProcessingUnit {
* Adds a source file to the unit.
*/
public SourceUnit addSource(final File file) {
- return addSource(new SourceUnit(file, configuration, classLoader, getErrorCollector()));
+ return addSource(new SourceUnit(file, getConfiguration(), getClassLoader(), getErrorCollector()));
}
/**
* Adds a source file to the unit.
*/
public SourceUnit addSource(final URL url) {
- return addSource(new SourceUnit(url, configuration, classLoader, getErrorCollector()));
+ return addSource(new SourceUnit(url, getConfiguration(), getClassLoader(), getErrorCollector()));
}
/**
* Adds a InputStream source to the unit.
*/
public SourceUnit addSource(final String name, final InputStream stream) {
- ReaderSource source = new InputStreamReaderSource(stream, configuration);
- return addSource(new SourceUnit(name, source, configuration, classLoader, getErrorCollector()));
+ ReaderSource source = new InputStreamReaderSource(stream, getConfiguration());
+ return addSource(new SourceUnit(name, source, getConfiguration(), getClassLoader(), getErrorCollector()));
}
public SourceUnit addSource(final String name, final String scriptText) {
- return addSource(new SourceUnit(name, scriptText, configuration, classLoader, getErrorCollector()));
+ return addSource(new SourceUnit(name, scriptText, getConfiguration(), getClassLoader(), getErrorCollector()));
}
/**
@@ -533,7 +506,7 @@ public class CompilationUnit extends ProcessingUnit {
*/
public SourceUnit addSource(final SourceUnit source) {
String name = source.getName();
- source.setClassLoader(this.classLoader);
+ source.setClassLoader(getClassLoader());
for (SourceUnit su : queuedSources) {
if (name.equals(su.getName())) return su;
}
@@ -589,6 +562,10 @@ public class CompilationUnit extends ProcessingUnit {
void call(ClassVisitor writer, ClassNode node) throws CompilationFailedException;
}
+ public ClassgenCallback getClassgenCallback() {
+ return classgenCallback;
+ }
+
/**
* Sets a ClassgenCallback. You can have only one, and setting
* it to {@code null} removes any existing setting.
@@ -597,10 +574,6 @@ public class CompilationUnit extends ProcessingUnit {
this.classgenCallback = visitor;
}
- public ClassgenCallback getClassgenCallback() {
- return classgenCallback;
- }
-
/**
* A callback interface you can use to get a callback after every
* unit of the compile process. You will be called-back with a
@@ -612,6 +585,10 @@ public class CompilationUnit extends ProcessingUnit {
void call(ProcessingUnit context, int phase) throws CompilationFailedException;
}
+ public ProgressCallback getProgressCallback() {
+ return progressCallback;
+ }
+
/**
* Sets a ProgressCallback. You can have only one, and setting
* it to {@code null} removes any existing setting.
@@ -620,15 +597,11 @@ public class CompilationUnit extends ProcessingUnit {
this.progressCallback = callback;
}
- public ProgressCallback getProgressCallback() {
- return progressCallback;
- }
-
//---------------------------------------------------------------------------
// ACTIONS
/**
- * Synonym for compile(Phases.ALL).
+ * Synonym for {@code compile(Phases.ALL)}.
*/
public void compile() throws CompilationFailedException {
compile(Phases.ALL);
@@ -656,9 +629,10 @@ public class CompilationUnit extends ProcessingUnit {
// Grab processing may have brought in new AST transforms into various phases, process them as well
processNewPhaseOperations(phase);
- if (progressCallback != null) progressCallback.call(this, phase);
+ Optional.ofNullable(getProgressCallback())
+ .ifPresent(callback -> callback.call(this, phase));
completePhase();
- applyToSourceUnits(mark);
+ mark();
if (dequeued()) continue;
@@ -669,7 +643,7 @@ public class CompilationUnit extends ProcessingUnit {
}
}
- errorCollector.failIfErrors();
+ getErrorCollector().failIfErrors();
}
private void processPhaseOperations(final int phase) {
@@ -735,56 +709,28 @@ public class CompilationUnit extends ProcessingUnit {
/**
* Resolves all types.
*/
- private final SourceUnitOperation resolve = new SourceUnitOperation() {
- @Override
- public void call(final SourceUnit source) throws CompilationFailedException {
- List<ClassNode> classes = source.ast.getClasses();
- for (ClassNode node : classes) {
- VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
- scopeVisitor.visitClass(node);
-
- resolveVisitor.setClassNodeResolver(classNodeResolver);
- resolveVisitor.startResolving(node, source);
- }
-
- }
- };
-
- private final GroovyClassOperation output = new GroovyClassOperation() {
- @Override
- public void call(final GroovyClass groovyClass) throws CompilationFailedException {
- String name = groovyClass.getName().replace('.', File.separatorChar) + ".class";
- File path = new File(configuration.getTargetDirectory(), name);
-
- // ensure the path is ready for the file
- File directory = path.getParentFile();
- if (directory != null && !directory.exists()) {
- directory.mkdirs();
- }
-
- // create the file and write out the data
- byte[] bytes = groovyClass.getBytes();
+ private final ISourceUnitOperation resolve = (final SourceUnit source) -> {
+ for (ClassNode classNode : source.getAST().getClasses()) {
+ GroovyClassVisitor visitor = new VariableScopeVisitor(source);
+ visitor.visitClass(classNode);
- try (FileOutputStream stream = new FileOutputStream(path)) {
- stream.write(bytes, 0, bytes.length);
- } catch (IOException e) {
- getErrorCollector().addError(Message.create(e.getMessage(), CompilationUnit.this));
- }
+ resolveVisitor.setClassNodeResolver(classNodeResolver);
+ resolveVisitor.startResolving(classNode, source);
}
};
/**
- * Runs classgen() on a single ClassNode.
+ * Runs {@link #classgen()} on a single {@code ClassNode}.
*/
- private final PrimaryClassNodeOperation classgen = new PrimaryClassNodeOperation() {
+ private final IPrimaryClassNodeOperation classgen = new IPrimaryClassNodeOperation() {
@Override
public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- optimizer.visitClass(classNode, source); // GROOVY-4272: repositioned it here from static import visitor
+ new OptimizerVisitor(CompilationUnit.this).visitClass(classNode, source); // GROOVY-4272: repositioned from static import visitor
//
// Run the Verifier on the outer class
//
- GroovyClassVisitor visitor = verifier;
+ GroovyClassVisitor visitor = new Verifier();
try {
visitor.visitClass(classNode);
} catch (RuntimeParserException rpe) {
@@ -808,8 +754,6 @@ public class CompilationUnit extends ProcessingUnit {
visitor = new ExtendedVerifier(source);
visitor.visitClass(classNode);
- visitor = null;
-
// because the class may be generated even if a error was found
// and that class may have an invalid format we fail here if needed
getErrorCollector().failIfErrors();
@@ -822,33 +766,34 @@ public class CompilationUnit extends ProcessingUnit {
String sourceName = (source == null ? classNode.getModule().getDescription() : source.getName());
// only show the file name and its extension like javac does in its stacktraces rather than the full path
// also takes care of both \ and / depending on the host compiling environment
- if (sourceName != null)
+ if (sourceName != null) {
sourceName = sourceName.substring(Math.max(sourceName.lastIndexOf('\\'), sourceName.lastIndexOf('/')) + 1);
- AsmClassGenerator generator = new AsmClassGenerator(source, context, classVisitor, sourceName);
+ }
//
// Run the generation and create the class (if required)
//
- generator.visitClass(classNode);
+ visitor = new AsmClassGenerator(source, context, classVisitor, sourceName);
+ visitor.visitClass(classNode);
byte[] bytes = ((ClassWriter) classVisitor).toByteArray();
- generatedClasses.add(new GroovyClass(classNode.getName(), bytes));
+ getClasses().add(new GroovyClass(classNode.getName(), bytes));
//
// Handle any callback that's been set
//
- if (CompilationUnit.this.classgenCallback != null) {
- classgenCallback.call(classVisitor, classNode);
- }
+ Optional.ofNullable(getClassgenCallback())
+ .ifPresent(callback -> callback.call(classVisitor, classNode));
//
// Recurse for inner classes
//
- LinkedList<ClassNode> innerClasses = generator.getInnerClasses();
+ LinkedList<ClassNode> innerClasses = ((AsmClassGenerator) visitor).getInnerClasses();
while (!innerClasses.isEmpty()) {
classgen.call(source, context, innerClasses.removeFirst());
}
}
+
@Override
public boolean needSortedInput() {
return true;
@@ -866,10 +811,10 @@ public class CompilationUnit extends ProcessingUnit {
// try classes under compilation
CompileUnit cu = getAST();
ClassNode cn = cu.getClass(name);
- if (cn!=null) return cn;
+ if (cn != null) return cn;
// try inner classes
cn = cu.getGeneratedInnerClass(name);
- if (cn!=null) return cn;
+ if (cn != null) return cn;
ClassNodeResolver.LookupResult lookupResult = getClassNodeResolver().resolveName(name, CompilationUnit.this);
return lookupResult == null ? null : lookupResult.getClassNode();
}
@@ -880,8 +825,8 @@ public class CompilationUnit extends ProcessingUnit {
if (c.isInterface() || d.isInterface()) return ClassHelper.OBJECT_TYPE;
do {
c = c.getSuperClass();
- } while (c!=null && !d.isDerivedFrom(c));
- if (c==null) return ClassHelper.OBJECT_TYPE;
+ } while (c != null && !d.isDerivedFrom(c));
+ if (c == null) return ClassHelper.OBJECT_TYPE;
return c;
}
@Override
@@ -900,115 +845,153 @@ public class CompilationUnit extends ProcessingUnit {
* Updates the phase marker on all sources.
*/
protected void mark() throws CompilationFailedException {
- applyToSourceUnits(mark);
- }
-
- /**
- * Marks a single SourceUnit with the current phase,
- * if it isn't already there yet.
- */
- private final SourceUnitOperation mark = new SourceUnitOperation() {
- @Override
- public void call(final SourceUnit source) throws CompilationFailedException {
+ ISourceUnitOperation mark = (final SourceUnit source) -> {
if (source.phase < phase) {
source.gotoPhase(phase);
}
if (source.phase == phase && phaseComplete && !source.phaseComplete) {
source.completePhase();
}
- }
- };
+ };
+ mark.doPhaseOperation(this);
+ }
//---------------------------------------------------------------------------
// LOOP SIMPLIFICATION FOR SourceUnit OPERATIONS
private interface PhaseOperation {
- default void doPhaseOperation(final CompilationUnit unit) {
- if (this instanceof SourceUnitOperation) {
- unit.applyToSourceUnits((SourceUnitOperation) this);
- } else if (this instanceof PrimaryClassNodeOperation) {
- unit.applyToPrimaryClassNodes((PrimaryClassNodeOperation) this);
- } else {
- unit.applyToGeneratedGroovyClasses((GroovyClassOperation) this);
+ void doPhaseOperation(CompilationUnit unit);
+ }
+
+ @FunctionalInterface
+ public interface ISourceUnitOperation extends PhaseOperation {
+ void call(SourceUnit source) throws CompilationFailedException;
+
+ /**
+ * A loop driver for applying operations to all SourceUnits.
+ * Automatically skips units that have already been processed
+ * through the current phase.
+ */
+ @Override
+ default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
+ for (String name : unit.sources.keySet()) {
+ SourceUnit source = unit.sources.get(name);
+ if (source.phase < unit.phase || (source.phase == unit.phase && !source.phaseComplete)) {
+ try {
+ this.call(source);
+ } catch (CompilationFailedException e) {
+ throw e;
+ } catch (Exception e) {
+ GroovyBugError gbe = new GroovyBugError(e);
+ unit.changeBugText(gbe, source);
+ throw gbe;
+ } catch (GroovyBugError e) {
+ unit.changeBugText(e, source);
+ throw e;
+ }
+ }
}
+ unit.getErrorCollector().failIfErrors();
}
}
- /**
- * A callback interface for use in the applyToSourceUnits loop driver.
- */
- // TODO: convert to functional interface
- public abstract static class SourceUnitOperation implements PhaseOperation {
- public abstract void call(SourceUnit source) throws CompilationFailedException;
- }
+ //---------------------------------------------------------------------------
+ // LOOP SIMPLIFICATION FOR PRIMARY ClassNode OPERATIONS
- /**
- * A loop driver for applying operations to all SourceUnits.
- * Automatically skips units that have already been processed
- * through the current phase.
- */
- public void applyToSourceUnits(final SourceUnitOperation body) throws CompilationFailedException {
- for (String name : sources.keySet()) {
- SourceUnit source = sources.get(name);
- if ((source.phase < phase) || (source.phase == phase && !source.phaseComplete)) {
+ @FunctionalInterface
+ public interface IPrimaryClassNodeOperation extends PhaseOperation {
+ void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException;
+
+ /**
+ * A loop driver for applying operations to all primary ClassNodes in
+ * our AST. Automatically skips units that have already been processed
+ * through the current phase.
+ */
+ @Override
+ default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
+ for (ClassNode classNode : unit.getPrimaryClassNodes(this.needSortedInput())) {
+ SourceUnit context = null;
try {
- body.call(source);
+ context = classNode.getModule().getContext();
+ if (context == null || context.phase < unit.phase || (context.phase == unit.phase && !context.phaseComplete)) {
+ int offset = 1;
+ for (Iterator<InnerClassNode> it = classNode.getInnerClasses(); it.hasNext(); ) {
+ it.next();
+ offset += 1;
+ }
+ this.call(context, new GeneratorContext(unit.getAST(), offset), classNode);
+ }
} catch (CompilationFailedException e) {
- throw e;
- } catch (Exception e) {
- GroovyBugError gbe = new GroovyBugError(e);
- changeBugText(gbe, source);
+ // fall through
+ } catch (NullPointerException npe) {
+ GroovyBugError gbe = new GroovyBugError("unexpected NullPointerException", npe);
+ unit.changeBugText(gbe, context);
throw gbe;
} catch (GroovyBugError e) {
- changeBugText(e, source);
+ unit.changeBugText(e, context);
throw e;
+ } catch (NoClassDefFoundError | Exception e) {
+ // effort to get more logging in case a dependency of a class is loaded
+ // although it shouldn't have
+ unit.convertUncaughtExceptionToCompilationError(e);
}
}
+ unit.getErrorCollector().failIfErrors();
}
- getErrorCollector().failIfErrors();
- }
- //---------------------------------------------------------------------------
- // LOOP SIMPLIFICATION FOR PRIMARY ClassNode OPERATIONS
-
- /**
- * An callback interface for use in the applyToPrimaryClassNodes loop driver.
- */
- // TODO: convert to functional interface
- public abstract static class PrimaryClassNodeOperation implements PhaseOperation {
- public abstract void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException;
-
- public boolean needSortedInput() {
+ default boolean needSortedInput() {
return false;
}
}
- // TODO: convert to functional interface
- public abstract static class GroovyClassOperation implements PhaseOperation {
- public abstract void call(GroovyClass groovyClass) throws CompilationFailedException;
+ @FunctionalInterface
+ public interface IGroovyClassOperation extends PhaseOperation {
+ void call(GroovyClass groovyClass) throws CompilationFailedException;
+
+ @Override
+ default void doPhaseOperation(final CompilationUnit unit) throws CompilationFailedException {
+ if (unit.phase != Phases.OUTPUT && !(unit.phase == Phases.CLASS_GENERATION && unit.phaseComplete)) {
+ throw new GroovyBugError("CompilationUnit not ready for output(). Current phase=" + unit.getPhaseDescription());
+ }
+
+ for (GroovyClass groovyClass : unit.getClasses()) {
+ try {
+ this.call(groovyClass);
+ } catch (CompilationFailedException e) {
+ // fall through
+ } catch (NullPointerException npe) {
+ throw npe;
+ } catch (GroovyBugError e) {
+ unit.changeBugText(e, null);
+ throw e;
+ } catch (Exception e) {
+ throw new GroovyBugError(e);
+ }
+ }
+ unit.getErrorCollector().failIfErrors();
+ }
}
- private static int getSuperClassCount(ClassNode element) {
+ private static int getSuperClassCount(ClassNode classNode) {
int count = 0;
- while (element != null) {
+ while (classNode != null) {
count += 1;
- element = element.getSuperClass();
+ classNode = classNode.getSuperClass();
}
return count;
}
- private int getSuperInterfaceCount(final ClassNode element) {
+ private static int getSuperInterfaceCount(final ClassNode classNode) {
int count = 1;
- ClassNode[] interfaces = element.getInterfaces();
- for (ClassNode anInterface : interfaces) {
- count = Math.max(count, getSuperInterfaceCount(anInterface) + 1);
+ for (ClassNode face : classNode.getInterfaces()) {
+ count = Math.max(count, getSuperInterfaceCount(face) + 1);
}
return count;
}
private List<ClassNode> getPrimaryClassNodes(final boolean sort) {
List<ClassNode> unsorted = getAST().getModules().stream()
- .flatMap(module -> module.getClasses().stream()).collect(Collectors.toList());
+ .flatMap(module -> module.getClasses().stream()).collect(toList());
if (!sort) return unsorted;
@@ -1052,46 +1035,9 @@ public class CompilationUnit extends ProcessingUnit {
return sorted;
}
- /**
- * A loop driver for applying operations to all primary ClassNodes in
- * our AST. Automatically skips units that have already been processed
- * through the current phase.
- */
- public void applyToPrimaryClassNodes(final PrimaryClassNodeOperation body) throws CompilationFailedException {
- for (ClassNode classNode : getPrimaryClassNodes(body.needSortedInput())) {
- SourceUnit context = null;
- try {
- context = classNode.getModule().getContext();
- if (context == null || context.phase < phase || (context.phase == phase && !context.phaseComplete)) {
- int offset = 1;
- for (Iterator<InnerClassNode> it = classNode.getInnerClasses(); it.hasNext(); ) {
- it.next();
- offset += 1;
- }
- body.call(context, new GeneratorContext(getAST(), offset), classNode);
- }
- } catch (CompilationFailedException e) {
- // fall through, getErrorReporter().failIfErrors() will trigger
- } catch (NullPointerException npe) {
- GroovyBugError gbe = new GroovyBugError("unexpected NullPointerException", npe);
- changeBugText(gbe, context);
- throw gbe;
- } catch (GroovyBugError e) {
- changeBugText(e, context);
- throw e;
- } catch (NoClassDefFoundError | Exception e) {
- // effort to get more logging in case a dependency of a class is loaded
- // although it shouldn't have
- convertUncaughtExceptionToCompilationError(e);
- }
- }
-
- getErrorCollector().failIfErrors();
- }
-
private void convertUncaughtExceptionToCompilationError(final Throwable e) {
- // check the exception for a nested compilation exception
ErrorCollector nestedCollector = null;
+ // check the exception for a nested compilation exception
for (Throwable next = e.getCause(); next != e && next != null; next = next.getCause()) {
if (!(next instanceof MultipleCompilationErrorsException)) continue;
MultipleCompilationErrorsException mcee = (MultipleCompilationErrorsException) next;
@@ -1103,37 +1049,50 @@ public class CompilationUnit extends ProcessingUnit {
getErrorCollector().addCollectorContents(nestedCollector);
} else {
Exception err = e instanceof Exception?((Exception)e):new RuntimeException(e);
- getErrorCollector().addError(new ExceptionMessage(err, configuration.getDebug(), this));
+ getErrorCollector().addError(new ExceptionMessage(err, debug, this));
}
}
- public void applyToGeneratedGroovyClasses(final GroovyClassOperation body) throws CompilationFailedException {
- if (this.phase != Phases.OUTPUT && !(this.phase == Phases.CLASS_GENERATION && this.phaseComplete)) {
- throw new GroovyBugError("CompilationUnit not ready for output(). Current phase=" + getPhaseDescription());
- }
+ private void changeBugText(final GroovyBugError e, final SourceUnit context) {
+ e.setBugText("exception in phase '" + getPhaseDescription() + "' in source unit '" + (context != null ? context.getName() : "?") + "' " + e.getBugText());
+ }
- for (GroovyClass gclass : this.generatedClasses) {
- //
- // Get the class and calculate its filesystem name
- //
- try {
- body.call(gclass);
- } catch (CompilationFailedException e) {
- // fall through, getErrorReporter().failIfErrors() will trigger
- } catch (NullPointerException npe) {
- throw npe;
- } catch (GroovyBugError e) {
- changeBugText(e, null);
- throw e;
- } catch (Exception e) {
- throw new GroovyBugError(e);
- }
- }
+ //--------------------------------------------------------------------------
- getErrorCollector().failIfErrors();
+ @Deprecated
+ public void addPhaseOperation(final GroovyClassOperation op) {
+ addPhaseOperation((IGroovyClassOperation) op);
}
- private void changeBugText(final GroovyBugError e, final SourceUnit context) {
- e.setBugText("exception in phase '" + getPhaseDescription() + "' in source unit '" + (context != null ? context.getName() : "?") + "' " + e.getBugText());
+ @Deprecated
+ public void addPhaseOperation(final SourceUnitOperation op, final int phase) {
+ addPhaseOperation((ISourceUnitOperation) op, phase);
+ }
+
+ @Deprecated
+ public void addPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
+ addPhaseOperation((IPrimaryClassNodeOperation) op, phase);
+ }
+
+ @Deprecated
+ public void addFirstPhaseOperation(final PrimaryClassNodeOperation op, final int phase) {
+ addFirstPhaseOperation((IPrimaryClassNodeOperation) op, phase);
+ }
+
+ @Deprecated
+ public void addNewPhaseOperation(final SourceUnitOperation op, final int phase) {
+ addNewPhaseOperation((ISourceUnitOperation) op, phase);
+ }
+
+ @Deprecated
+ public abstract static class SourceUnitOperation implements ISourceUnitOperation {
+ }
+
+ @Deprecated
+ public abstract static class GroovyClassOperation implements IGroovyClassOperation {
+ }
+
+ @Deprecated
+ public abstract static class PrimaryClassNodeOperation implements IPrimaryClassNodeOperation {
}
}
diff --git a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
index 25d8e9c..214bb98 100644
--- a/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
+++ b/src/main/java/org/codehaus/groovy/control/CompilerConfiguration.java
@@ -1065,7 +1065,7 @@ public class CompilerConfiguration {
* META-INF/services/org.codehaus.groovy.transform.ASTTransformation file.
* If you explicitly add a global AST transformation in your compilation process,
* for example using the {@link org.codehaus.groovy.control.customizers.ASTTransformationCustomizer} or
- * using a {@link org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation},
+ * using a {@link org.codehaus.groovy.control.CompilationUnit.IPrimaryClassNodeOperation},
* then nothing will prevent the transformation from being loaded.
*
* @param disabledGlobalASTTransformations a set of fully qualified class names of global AST transformations
diff --git a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
index 1dea516..e1dd084 100644
--- a/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
+++ b/src/main/java/org/codehaus/groovy/control/StaticImportVisitor.java
@@ -68,7 +68,7 @@ import static org.codehaus.groovy.ast.tools.ClosureUtils.getParametersSafe;
public class StaticImportVisitor extends ClassCodeExpressionTransformer {
private ClassNode currentClass;
private MethodNode currentMethod;
- private SourceUnit source;
+ private SourceUnit sourceUnit;
private boolean inSpecialConstructorCall;
private boolean inClosure;
private boolean inPropertyExpression;
@@ -77,10 +77,19 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
private boolean inAnnotation;
private boolean inLeftExpression;
- public void visitClass(ClassNode node, SourceUnit source) {
- this.currentClass = node;
- this.source = source;
- super.visitClass(node);
+ public StaticImportVisitor(final ClassNode classNode, final SourceUnit sourceUnit) {
+ this.currentClass = classNode;
+ this.sourceUnit = sourceUnit;
+ }
+
+ /**
+ * Call {@link #StaticImportVisitor(ClassNode,SourceUnit)} then {@link #visitClass(ClassNode)}.
+ */
+ @Deprecated
+ public void visitClass(final ClassNode classNode, final SourceUnit sourceUnit) {
+ this.currentClass = classNode;
+ this.sourceUnit = sourceUnit;
+ visitClass(classNode);
}
@Override
@@ -565,7 +574,8 @@ public class StaticImportVisitor extends ClassCodeExpressionTransformer {
return new StaticMethodCallExpression(type.getPlainNodeReference(), name, args);
}
+ @Override
protected SourceUnit getSourceUnit() {
- return source;
+ return sourceUnit;
}
}
diff --git a/src/main/java/org/codehaus/groovy/control/customizers/CompilationCustomizer.java b/src/main/java/org/codehaus/groovy/control/customizers/CompilationCustomizer.java
index 9d0b565..63583c5 100644
--- a/src/main/java/org/codehaus/groovy/control/customizers/CompilationCustomizer.java
+++ b/src/main/java/org/codehaus/groovy/control/customizers/CompilationCustomizer.java
@@ -29,10 +29,10 @@ import org.codehaus.groovy.control.CompilePhase;
*
* @since 1.8.0
*/
-public abstract class CompilationCustomizer extends CompilationUnit.PrimaryClassNodeOperation {
+public abstract class CompilationCustomizer implements CompilationUnit.IPrimaryClassNodeOperation {
private final CompilePhase phase;
- public CompilationCustomizer(CompilePhase phase) {
+ public CompilationCustomizer(final CompilePhase phase) {
this.phase = phase;
}
diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java
index de646aa..f43141b 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaAwareCompilationUnit.java
@@ -20,6 +20,7 @@ package org.codehaus.groovy.tools.javac;
import groovy.lang.GroovyClassLoader;
import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyClassVisitor;
import org.codehaus.groovy.ast.ModuleNode;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.classgen.VariableScopeVisitor;
@@ -75,35 +76,24 @@ public class JavaAwareCompilationUnit extends CompilationUnit {
this.stubGenerator = new JavaStubGenerator(generationGoal, false, useJava5, encoding);
this.keepStubs = Boolean.TRUE.equals(options.get("keepStubs"));
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(SourceUnit source, GeneratorContext context, ClassNode node) throws CompilationFailedException {
- if (!javaSources.isEmpty()) {
- VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
- scopeVisitor.visitClass(node);
- new JavaAwareResolveVisitor(JavaAwareCompilationUnit.this).startResolving(node, source);
- AnnotationConstantsVisitor acv = new AnnotationConstantsVisitor();
- acv.visitClass(node, source);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ if (!javaSources.isEmpty()) {
+ new VariableScopeVisitor(source).visitClass(classNode);
+ new JavaAwareResolveVisitor(this).startResolving(classNode, source);
+ new AnnotationConstantsVisitor().visitClass(classNode, source);
}
}, Phases.CONVERSION);
- addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
- ASTTransformationCollectorCodeVisitor collector =
- new ASTTransformationCollectorCodeVisitor(source, JavaAwareCompilationUnit.this.getTransformLoader());
- collector.visitClass(classNode);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(source, getTransformLoader());
+ visitor.visitClass(classNode);
}, Phases.CONVERSION);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
- try {
- if (!javaSources.isEmpty()) stubGenerator.generateClass(classNode);
- } catch (FileNotFoundException fnfe) {
- source.addException(fnfe);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ try {
+ if (!javaSources.isEmpty()) stubGenerator.generateClass(classNode);
+ } catch (FileNotFoundException fnfe) {
+ source.addException(fnfe);
}
}, Phases.CONVERSION);
}
diff --git a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubCompilationUnit.java b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubCompilationUnit.java
index e5aefae..46e1d42 100644
--- a/src/main/java/org/codehaus/groovy/tools/javac/JavaStubCompilationUnit.java
+++ b/src/main/java/org/codehaus/groovy/tools/javac/JavaStubCompilationUnit.java
@@ -53,23 +53,17 @@ public class JavaStubCompilationUnit extends CompilationUnit {
String encoding = configuration.getSourceEncoding();
stubGenerator = new JavaStubGenerator(destDir, false, useJava5, encoding);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(SourceUnit source, GeneratorContext context, ClassNode node) throws CompilationFailedException {
- VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
- scopeVisitor.visitClass(node);
- new JavaAwareResolveVisitor(JavaStubCompilationUnit.this).startResolving(node, source);
- }
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ new VariableScopeVisitor(source).visitClass(classNode);
+ new JavaAwareResolveVisitor(this).startResolving(classNode, source);
}, Phases.CONVERSION);
- addPhaseOperation(new PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode node) throws CompilationFailedException {
- try {
- stubGenerator.generateClass(node);
- stubCount++;
- } catch (FileNotFoundException e) {
- source.addException(e);
- }
+
+ addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ try {
+ stubGenerator.generateClass(classNode);
+ stubCount += 1;
+ } catch (FileNotFoundException e) {
+ source.addException(e);
}
}, Phases.CONVERSION);
}
diff --git a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
index c2c508f..ea950a6 100644
--- a/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/ASTTransformationVisitor.java
@@ -27,10 +27,10 @@ import org.codehaus.groovy.ast.AnnotatedNode;
import org.codehaus.groovy.ast.AnnotationNode;
import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.GroovyClassVisitor;
import org.codehaus.groovy.ast.expr.Expression;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.ASTTransformationsContext;
-import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.Phases;
@@ -197,18 +197,14 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
public static void addPhaseOperations(final CompilationUnit compilationUnit) {
- final ASTTransformationsContext context = compilationUnit.getASTTransformationsContext();
+ ASTTransformationsContext context = compilationUnit.getASTTransformationsContext();
addGlobalTransforms(context);
- compilationUnit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
- ASTTransformationCollectorCodeVisitor collector =
- new ASTTransformationCollectorCodeVisitor(source, compilationUnit.getTransformLoader());
- collector.visitClass(classNode);
- }
+ compilationUnit.addPhaseOperation((final SourceUnit source, final GeneratorContext ignore, final ClassNode classNode) -> {
+ GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(source, compilationUnit.getTransformLoader());
+ visitor.visitClass(classNode);
}, Phases.SEMANTIC_ANALYSIS);
for (CompilePhase phase : CompilePhase.values()) {
- final ASTTransformationVisitor visitor = new ASTTransformationVisitor(phase, context);
switch (phase) {
case INITIALIZATION:
case PARSING:
@@ -217,11 +213,10 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
break;
default:
- compilationUnit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) throws CompilationFailedException {
- visitor.source = source;
- visitor.visitClass(classNode);
- }
+ compilationUnit.addPhaseOperation((final SourceUnit source, final GeneratorContext ignore, final ClassNode classNode) -> {
+ ASTTransformationVisitor visitor = new ASTTransformationVisitor(phase, context);
+ visitor.source = source;
+ visitor.visitClass(classNode);
}, phase.getPhaseNumber());
break;
@@ -322,8 +317,8 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
try {
- Class gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
- GroovyASTTransformation transformAnnotation = (GroovyASTTransformation) gTransClass.getAnnotation(GroovyASTTransformation.class);
+ Class<?> gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
+ GroovyASTTransformation transformAnnotation = gTransClass.getAnnotation(GroovyASTTransformation.class);
if (transformAnnotation == null) {
compilationUnit.getErrorCollector().addWarning(new WarningMessage(
WarningMessage.POSSIBLE_ERRORS,
@@ -335,14 +330,12 @@ public final class ASTTransformationVisitor extends ClassCodeVisitorSupport {
continue;
}
if (ASTTransformation.class.isAssignableFrom(gTransClass)) {
- final ASTTransformation instance = (ASTTransformation)gTransClass.getDeclaredConstructor().newInstance();
+ ASTTransformation instance = (ASTTransformation) gTransClass.getDeclaredConstructor().newInstance();
if (instance instanceof CompilationUnitAware) {
((CompilationUnitAware)instance).setCompilationUnit(compilationUnit);
}
- CompilationUnit.SourceUnitOperation suOp = new CompilationUnit.SourceUnitOperation() {
- public void call(SourceUnit source) throws CompilationFailedException {
- instance.visit(new ASTNode[] {source.getAST()}, source);
- }
+ CompilationUnit.ISourceUnitOperation suOp = source -> {
+ instance.visit(new ASTNode[] {source.getAST()}, source);
};
if (isFirstScan) {
compilationUnit.addPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
diff --git a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
index 99b72c1..3dec6b8 100644
--- a/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/transform/sc/StaticCompilationVisitor.java
@@ -49,14 +49,13 @@ import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.ast.stmt.ForStatement;
import org.codehaus.groovy.ast.stmt.Statement;
import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.classgen.asm.InvocationWriter;
import org.codehaus.groovy.classgen.asm.MopWriter;
import org.codehaus.groovy.classgen.asm.TypeChooser;
import org.codehaus.groovy.classgen.asm.WriterControllerFactory;
import org.codehaus.groovy.classgen.asm.sc.StaticCompilationMopWriter;
import org.codehaus.groovy.classgen.asm.sc.StaticTypesTypeChooser;
-import org.codehaus.groovy.control.CompilationUnit;
+import org.codehaus.groovy.control.CompilationUnit.IPrimaryClassNodeOperation;
import org.codehaus.groovy.control.SourceUnit;
import org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport;
import org.codehaus.groovy.transform.stc.StaticTypeCheckingVisitor;
@@ -155,13 +154,10 @@ public class StaticCompilationVisitor extends StaticTypeCheckingVisitor {
private void addDynamicOuterClassAccessorsCallback(final ClassNode outer) {
if (outer != null) {
if (!isStaticallyCompiled(outer) && outer.getNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK) == null) {
- outer.putNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK, new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) {
- if (classNode == outer) {
- addPrivateBridgeMethods(classNode);
- addPrivateFieldsAccessors(classNode);
- }
+ outer.putNodeMetaData(DYNAMIC_OUTER_NODE_CALLBACK, (IPrimaryClassNodeOperation) (source, context, classNode) -> {
+ if (classNode == outer) {
+ addPrivateBridgeMethods(classNode);
+ addPrivateFieldsAccessors(classNode);
}
});
}
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 a12584c..70952bf 100644
--- a/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/trait/TraitASTTransformation.java
@@ -27,6 +27,7 @@ import org.codehaus.groovy.ast.ClassHelper;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.ast.FieldNode;
import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.GroovyClassVisitor;
import org.codehaus.groovy.ast.InnerClassNode;
import org.codehaus.groovy.ast.MethodNode;
import org.codehaus.groovy.ast.Parameter;
@@ -47,7 +48,6 @@ import org.codehaus.groovy.ast.tools.GeneralUtils;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.classgen.VariableScopeVisitor;
import org.codehaus.groovy.classgen.Verifier;
-import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.CompilePhase;
import org.codehaus.groovy.control.SourceUnit;
@@ -340,19 +340,16 @@ public class TraitASTTransformation extends AbstractASTTransformation implements
}
private void registerASTTransformations(final ClassNode helper) {
- ASTTransformationCollectorCodeVisitor collector = new ASTTransformationCollectorCodeVisitor(
- unit, compilationUnit.getTransformLoader()
- );
- collector.visitClass(helper);
+ {
+ GroovyClassVisitor visitor = new ASTTransformationCollectorCodeVisitor(unit, compilationUnit.getTransformLoader());
+ visitor.visitClass(helper);
+ }
// Perform an additional phase which has to be done *after* type checking
- compilationUnit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, final GeneratorContext context, final ClassNode classNode) throws CompilationFailedException {
- if (classNode==helper) {
- PostTypeCheckingExpressionReplacer replacer = new PostTypeCheckingExpressionReplacer(source);
- replacer.visitClass(helper);
- }
- }
+ compilationUnit.addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ if (classNode != helper) return;
+
+ GroovyClassVisitor visitor = new PostTypeCheckingExpressionReplacer(source);
+ visitor.visitClass(helper);
}, CompilePhase.INSTRUCTION_SELECTION.getPhaseNumber());
}
diff --git a/src/test/groovy/lang/GroovyClassLoaderTest.groovy b/src/test/groovy/lang/GroovyClassLoaderTest.groovy
index 9466beb..41a41e3 100644
--- a/src/test/groovy/lang/GroovyClassLoaderTest.groovy
+++ b/src/test/groovy/lang/GroovyClassLoaderTest.groovy
@@ -270,13 +270,15 @@ class GroovyClassLoaderTestCustomGCL extends GroovyClassLoader {
}
}
-class GroovyClassLoaderTestPropertyAdder extends CompilationUnit.PrimaryClassNodeOperation {
+class GroovyClassLoaderTestPropertyAdder implements CompilationUnit.IPrimaryClassNodeOperation {
+ @Override
void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
classNode.addProperty("id", ClassNode.ACC_PUBLIC, ClassHelper.long_TYPE, null, null, null)
}
}
class GroovyClassLoaderTestCustomPhaseOperation extends GroovyClassLoader {
+ @Override
CompilationUnit createCompilationUnit(CompilerConfiguration config, CodeSource source) {
def cu = super.createCompilationUnit(config, source)
cu.addPhaseOperation(new GroovyClassLoaderTestPropertyAdder(), Phases.CONVERSION)
diff --git a/src/test/org/codehaus/groovy/ClosureAndInnerClassNodeStructureTest.groovy b/src/test/org/codehaus/groovy/ClosureAndInnerClassNodeStructureTest.groovy
index 9fc89b0..75d3196 100644
--- a/src/test/org/codehaus/groovy/ClosureAndInnerClassNodeStructureTest.groovy
+++ b/src/test/org/codehaus/groovy/ClosureAndInnerClassNodeStructureTest.groovy
@@ -20,7 +20,6 @@ package org.codehaus.groovy
import groovy.test.GroovyTestCase
import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation
import org.codehaus.groovy.classgen.GeneratorContext
import org.codehaus.groovy.control.SourceUnit
import org.codehaus.groovy.control.Phases
@@ -53,7 +52,8 @@ class ClosureAndInnerClassNodeStructureTest extends GroovyTestCase {
def classNodes = [:]
- cu.addPhaseOperation(new PrimaryClassNodeOperation() {
+ cu.addPhaseOperation(new CompilationUnit.IPrimaryClassNodeOperation() {
+ @Override
void call(SourceUnit source, GeneratorContext context, ClassNode cn) {
def recurse = { ClassNode node ->
classNodes[node.name] = node
diff --git a/src/test/org/codehaus/groovy/tools/gse/DependencyTest.java b/src/test/org/codehaus/groovy/tools/gse/DependencyTest.java
index e903298..5788b39 100644
--- a/src/test/org/codehaus/groovy/tools/gse/DependencyTest.java
+++ b/src/test/org/codehaus/groovy/tools/gse/DependencyTest.java
@@ -18,39 +18,32 @@
*/
package org.codehaus.groovy.tools.gse;
-import java.io.StringBufferInputStream;
-import java.util.Set;
-
+import groovy.test.GroovyTestCase;
import org.codehaus.groovy.ast.ClassNode;
import org.codehaus.groovy.classgen.GeneratorContext;
-import org.codehaus.groovy.control.CompilationFailedException;
import org.codehaus.groovy.control.CompilationUnit;
import org.codehaus.groovy.control.Phases;
import org.codehaus.groovy.control.SourceUnit;
-import groovy.test.GroovyTestCase;
+import java.io.StringBufferInputStream;
+import java.util.Set;
@SuppressWarnings("deprecation")
public class DependencyTest extends GroovyTestCase {
private CompilationUnit cu;
StringSetMap cache;
-
+
@Override
protected void setUp() throws Exception {
super.setUp();
- cu = new CompilationUnit();
cache = new StringSetMap();
- cu.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
- @Override
- public void call(final SourceUnit source, GeneratorContext context, ClassNode classNode)
- throws CompilationFailedException
- {
- DependencyTracker dt = new DependencyTracker(source,cache);
- dt.visitClass(classNode);
- }
+ cu = new CompilationUnit();
+ cu.addPhaseOperation((final SourceUnit source, final GeneratorContext context, final ClassNode classNode) -> {
+ DependencyTracker dt = new DependencyTracker(source, cache);
+ dt.visitClass(classNode);
}, Phases.CLASS_GENERATION);
}
-
+
public void testDep(){
cu.addSource("testDep.gtest", new StringBufferInputStream(
"class C1 {}\n" +
@@ -64,22 +57,22 @@ public class DependencyTest extends GroovyTestCase {
assertEquals(cache.get("C1").size(),1);
assertEquals(cache.get("C2").size(),1);
assertEquals(cache.get("C3").size(),1);
-
+
Set<String> dep = cache.get("A1");
assertEquals(dep.size(),2);
assertTrue(dep.contains("C1"));
-
+
dep = cache.get("A2");
assertEquals(dep.size(),2);
assertTrue(dep.contains("C2"));
-
+
dep = cache.get("A3");
assertEquals(dep.size(),4);
assertTrue(dep.contains("C1"));
assertTrue(dep.contains("C2"));
assertTrue(dep.contains("C3"));
}
-
+
public void testTransitiveDep(){
cu.addSource("testTransitiveDep.gtest", new StringBufferInputStream(
"class A1 {}\n" +
@@ -88,19 +81,19 @@ public class DependencyTest extends GroovyTestCase {
));
cu.compile(Phases.CLASS_GENERATION);
cache.makeTransitiveHull();
-
+
Set<String> dep = cache.get("A1");
assertEquals(dep.size(),1);
-
+
dep = cache.get("A2");
assertEquals(dep.size(),2);
assertTrue(dep.contains("A1"));
-
+
dep = cache.get("A3");
assertEquals(dep.size(),3);
assertTrue(dep.contains("A1"));
assertTrue(dep.contains("A2"));
}
-
+
}
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
index 292a8ae..1edda5f 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/AstNodeToScriptAdapter.groovy
@@ -95,7 +95,6 @@ import org.codehaus.groovy.classgen.GeneratorContext
import org.codehaus.groovy.classgen.Verifier
import org.codehaus.groovy.control.CompilationFailedException
import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation
import org.codehaus.groovy.control.CompilePhase
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
@@ -189,7 +188,7 @@ and [compilephase] is a valid Integer based org.codehaus.groovy.control.CompileP
* An adapter from ASTNode tree to source code.
*/
@CompileStatic
-class AstNodeToScriptVisitor extends PrimaryClassNodeOperation implements GroovyCodeVisitor, GroovyClassVisitor {
+class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperation, GroovyClassVisitor, GroovyCodeVisitor {
private final Writer _out
Stack<String> classNameStack = new Stack<String>()
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ScriptToTreeNodeAdapter.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ScriptToTreeNodeAdapter.groovy
index d42f3ba..c9e78f4 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ScriptToTreeNodeAdapter.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ScriptToTreeNodeAdapter.groovy
@@ -98,7 +98,6 @@ import org.codehaus.groovy.classgen.GeneratorContext
import org.codehaus.groovy.classgen.asm.BytecodeHelper
import org.codehaus.groovy.control.CompilationFailedException
import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation
import org.codehaus.groovy.control.CompilerConfiguration
import org.codehaus.groovy.control.SourceUnit
@@ -275,7 +274,7 @@ class ScriptToTreeNodeAdapter {
/**
* This Node Operation builds up a root tree node for the viewer.
*/
-class TreeNodeBuildingNodeOperation extends PrimaryClassNodeOperation {
+class TreeNodeBuildingNodeOperation implements CompilationUnit.IPrimaryClassNodeOperation {
final root
final sourceCollected = new AtomicBoolean(false)
diff --git a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/ScriptVariableAnalyzer.groovy b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/ScriptVariableAnalyzer.groovy
index 47e7990..281a31c 100644
--- a/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/ScriptVariableAnalyzer.groovy
+++ b/subprojects/groovy-groovysh/src/main/groovy/org/apache/groovy/groovysh/util/ScriptVariableAnalyzer.groovy
@@ -69,10 +69,10 @@ class ScriptVariableAnalyzer {
}
/**
- * custom PrimaryClassNodeOperation
+ * custom IPrimaryClassNodeOperation
* to be able to hook our code visitor
*/
- static class VisitorSourceOperation extends CompilationUnit.PrimaryClassNodeOperation {
+ static class VisitorSourceOperation implements CompilationUnit.IPrimaryClassNodeOperation {
final GroovyClassVisitor visitor
diff --git a/subprojects/groovy-jsr223/src/test/java/org/codehaus/groovy/jsr223/JSR223SecurityTest.java b/subprojects/groovy-jsr223/src/test/java/org/codehaus/groovy/jsr223/JSR223SecurityTest.java
index 52b98a3..561beb2 100644
--- a/subprojects/groovy-jsr223/src/test/java/org/codehaus/groovy/jsr223/JSR223SecurityTest.java
+++ b/subprojects/groovy-jsr223/src/test/java/org/codehaus/groovy/jsr223/JSR223SecurityTest.java
@@ -25,7 +25,6 @@ import org.codehaus.groovy.ast.expr.MethodCallExpression;
import org.codehaus.groovy.ast.stmt.ExpressionStatement;
import org.codehaus.groovy.classgen.GeneratorContext;
import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.CompilationUnit.PrimaryClassNodeOperation;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.codehaus.groovy.control.Phases;
import org.codehaus.groovy.control.SourceUnit;
@@ -35,6 +34,7 @@ import org.junit.Test;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
+
import java.lang.reflect.Field;
import java.security.CodeSource;
import java.util.HashSet;
@@ -161,11 +161,12 @@ class CustomGroovyClassLoader extends GroovyClassLoader {
}
}
-class CustomPrimaryClassNodeOperation extends PrimaryClassNodeOperation {
-
+class CustomPrimaryClassNodeOperation implements CompilationUnit.IPrimaryClassNodeOperation {
+ @Override
public void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
- for (Object statement : source.getAST().getStatementBlock().getStatements())
+ for (Object statement : source.getAST().getStatementBlock().getStatements()) {
((ExpressionStatement) statement).visit(new CustomCodeVisitorSupport());
+ }
}
}
diff --git a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
index a4a5616..8d3b8d4 100644
--- a/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
+++ b/subprojects/parser-antlr4/src/test/groovy/org/apache/groovy/parser/antlr4/util/AstDumper.groovy
@@ -147,7 +147,7 @@ class AstDumper {
* An adapter from ASTNode tree to source code.
*/
@CompileStatic
-class AstNodeToScriptVisitor extends CompilationUnit.PrimaryClassNodeOperation implements GroovyCodeVisitor, GroovyClassVisitor {
+class AstNodeToScriptVisitor implements CompilationUnit.IPrimaryClassNodeOperation, GroovyClassVisitor, GroovyCodeVisitor {
private final Writer _out
Stack<String> classNameStack = new Stack<String>()
@@ -164,6 +164,7 @@ class AstNodeToScriptVisitor extends CompilationUnit.PrimaryClassNodeOperation i
this.scriptHasBeenVisited = false
}
+ @Override
void call(SourceUnit source, GeneratorContext context, ClassNode classNode) {
visitPackage(source?.getAST()?.getPackage())