diff --git a/src/main/java/spoon/Launcher.java b/src/main/java/spoon/Launcher.java index 4f2996eed8d..b099a0a9da2 100644 --- a/src/main/java/spoon/Launcher.java +++ b/src/main/java/spoon/Launcher.java @@ -596,7 +596,7 @@ protected JSAPResult parseArgs() { * the factory this compiler works on */ public SpoonModelBuilder createCompiler(Factory factory) { - SpoonModelBuilder comp = new JDTBasedSpoonCompiler(factory); + SpoonModelBuilder comp = getCompilerInstance(factory); Environment env = getEnvironment(); // building comp.setBinaryOutputDirectory(jsapActualArgs.getFile("destination")); @@ -614,6 +614,17 @@ public SpoonModelBuilder createCompiler(Factory factory) { return comp; } + /** + * Instantiates the compiler. This method is invoked by {@link #createCompiler(Factory)} to retrieve + * an empty compiler instance. Clients can override this method to use their custom compiler implementation. + * @param factory the factory to pass on to the compiler. + * @return a new compiler. + * @see #createCompiler(Factory) + */ + protected SpoonModelBuilder getCompilerInstance(Factory factory) { + return new JDTBasedSpoonCompiler(factory); + } + public SpoonModelBuilder createCompiler(Factory factory, List inputSources) { SpoonModelBuilder c = createCompiler(factory); c.addInputSources(inputSources); diff --git a/src/main/java/spoon/support/compiler/jdt/JDTBasedSpoonCompiler.java b/src/main/java/spoon/support/compiler/jdt/JDTBasedSpoonCompiler.java index 92f6c200e47..e92bb0afe17 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTBasedSpoonCompiler.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTBasedSpoonCompiler.java @@ -11,8 +11,10 @@ import org.apache.logging.log4j.Level; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.IProblem; +import org.eclipse.jdt.internal.compiler.ASTVisitor; import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration; import org.eclipse.jdt.internal.compiler.env.INameEnvironment; +import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope; import spoon.OutputType; import spoon.SpoonException; import spoon.compiler.Environment; @@ -432,7 +434,7 @@ protected void buildModel(CompilationUnitDeclaration[] units, Factory aFactory) forEachCompilationUnit(unitList, SpoonProgress.Process.MODEL, unit -> { // we need first to go through the whole model before getting the right reference for imports - unit.traverse(builder, unit.scope); + traverseUnitDeclaration(builder, unit); }); //we need first imports before we can place comments. Mainly comments on imports need that forEachCompilationUnit(unitList, SpoonProgress.Process.IMPORT, unit -> { @@ -461,12 +463,24 @@ private void forEachCompilationUnit(List unitList, S if (canProcessCompilationUnit(unitPath)) { consumer.accept(unit); } - getEnvironment().getSpoonProgress().step(process, unitPath, ++i, unitList.size()); + getEnvironment().getSpoonProgress().step(process, unitPath, ++i, unitList.size()); } } - getEnvironment().getSpoonProgress().end(process); + getEnvironment().getSpoonProgress().end(process); } + /** + * Invokes the traversal of the given compilation unit declaration using the given builder as a visitor. + * Overriders of this method must either invoke {@link CompilationUnitDeclaration#traverse(ASTVisitor, CompilationUnitScope)})} )} + * or this method before returning. + * @param builder the builder to use to traverse the unit. + * @param unitDeclaration the unit declaration. + */ + protected void traverseUnitDeclaration(JDTTreeBuilder builder, CompilationUnitDeclaration unitDeclaration) { + unitDeclaration.traverse(builder, unitDeclaration.scope); + } + + private boolean canProcessCompilationUnit(String unitPath) { for (final CompilationUnitFilter cuf : compilationUnitFilters) { if (cuf.exclude(unitPath)) {