diff --git a/doc/command_line.md b/doc/command_line.md
index cedc8aba886..0499e2d9d8f 100644
--- a/doc/command_line.md
+++ b/doc/command_line.md
@@ -89,21 +89,6 @@ Options :
[--compile]
Enable compilation and output class files.
- [--precompile]
- Enable pre-compilation of input source files before processing. Compiled
- classes will be added to the classpath so that they are accessible to
- the processing manager (typically, processors, annotations, and
- templates should be pre-compiled most of the time).
-
- [--buildOnlyOutdatedFiles]
- Set Spoon to build only the source files that have been modified since
- the latest source code generation, for performance purpose. Note that
- this option requires to have the --ouput-type option not set to none.
- This option is not appropriate to all kinds of processing. In particular
- processings that implement or rely on a global analysis should avoid
- this option because the processor will only have access to the outdated
- source code (the files modified since the latest processing).
-
[--lines]
Set Spoon to try to preserve the original line numbers when generating
the source code (may lead to human-unfriendly formatting).
diff --git a/src/main/java/spoon/Launcher.java b/src/main/java/spoon/Launcher.java
index d4ce5858e3d..a29b87ab2cc 100644
--- a/src/main/java/spoon/Launcher.java
+++ b/src/main/java/spoon/Launcher.java
@@ -347,8 +347,7 @@ protected static JSAP defineArgs() {
// Enable pre-compilation
sw1 = new Switch("precompile");
sw1.setLongFlag("precompile");
- sw1.setHelp("Enable pre-compilation of input source files " + "before processing. Compiled classes " + "will be added to the classpath so that " + "they are accessible to the processing "
- + "manager (typically, processors, " + "annotations, and templates should be " + "pre-compiled most of the time).");
+ sw1.setHelp("[experimental] Enable pre-compilation of input source files " + "before processing. The compiled classes " + "will be added to the classpath.");
sw1.setDefault("false");
jsap.registerParameter(sw1);
@@ -468,6 +467,11 @@ protected void processArguments() {
}
}
+ if (jsapActualArgs.getBoolean("precompile")) {
+ modelBuilder.compile(InputType.FILES);
+ getEnvironment().setSourceClasspath(new String[]{getEnvironment().getBinaryOutputDirectory()});
+ }
+
if (getArguments().getFile("output") != null) {
setSourceOutputDirectory(getArguments().getFile("output"));
}
@@ -570,10 +574,6 @@ public SpoonCompiler createCompiler(Factory factory) {
env.debugMessage("source classpath: " + Arrays.toString(comp.getSourceClasspath()));
env.debugMessage("template classpath: " + Arrays.toString(comp.getTemplateClasspath()));
- if (jsapActualArgs.getBoolean("precompile")) {
- comp.compile(InputType.FILES);
- }
-
return comp;
}
diff --git a/src/main/java/spoon/support/QueueProcessingManager.java b/src/main/java/spoon/support/QueueProcessingManager.java
index 6c19d69427c..1781141c8ea 100644
--- a/src/main/java/spoon/support/QueueProcessingManager.java
+++ b/src/main/java/spoon/support/QueueProcessingManager.java
@@ -74,9 +74,9 @@ public boolean addProcessor(Processor> p) {
@SuppressWarnings("unchecked")
public void addProcessor(String qualifiedName) {
try {
- addProcessor((Class extends Processor>>) Thread.currentThread().getContextClassLoader().loadClass(qualifiedName));
+ addProcessor((Class extends Processor>>) getFactory().getEnvironment().getClassLoader().loadClass(qualifiedName));
} catch (ClassNotFoundException e) {
- throw new SpoonException("Unable to load processor \"" + qualifiedName + "\" - Check your classpath. Did you use the --precompile option?", e);
+ throw new SpoonException("Unable to load processor \"" + qualifiedName + "\" - Check your classpath.", e);
}
}
diff --git a/src/main/java/spoon/support/RuntimeProcessingManager.java b/src/main/java/spoon/support/RuntimeProcessingManager.java
index 0ca23a86522..254f8d1979c 100644
--- a/src/main/java/spoon/support/RuntimeProcessingManager.java
+++ b/src/main/java/spoon/support/RuntimeProcessingManager.java
@@ -76,9 +76,9 @@ public boolean addProcessor(Processor> p) {
@SuppressWarnings("unchecked")
public void addProcessor(String qualifiedName) {
try {
- addProcessor((Class extends Processor>>) Thread.currentThread().getContextClassLoader().loadClass(qualifiedName));
+ addProcessor((Class extends Processor>>) getFactory().getEnvironment().getClassLoader().loadClass(qualifiedName));
} catch (ClassNotFoundException e) {
- factory.getEnvironment().report(null, Level.ERROR, "Unable to load processor \"" + qualifiedName + "\" - Check your classpath. Did you use the --precompile option?");
+ factory.getEnvironment().report(null, Level.ERROR, "Unable to load processor \"" + qualifiedName + "\" - Check your classpath.");
}
}
diff --git a/src/main/java/spoon/support/compiler/jdt/FileCompiler.java b/src/main/java/spoon/support/compiler/jdt/FileCompiler.java
index b5f906fafa5..24068d8dd3f 100644
--- a/src/main/java/spoon/support/compiler/jdt/FileCompiler.java
+++ b/src/main/java/spoon/support/compiler/jdt/FileCompiler.java
@@ -16,15 +16,14 @@
*/
package spoon.support.compiler.jdt;
-import java.util.ArrayList;
-import java.util.List;
-
import org.apache.commons.io.IOUtils;
import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
-
import spoon.SpoonException;
import spoon.compiler.SpoonFile;
+import java.util.ArrayList;
+import java.util.List;
+
public class FileCompiler extends JDTBatchCompiler {
public FileCompiler(JDTBasedSpoonCompiler jdtCompiler) {
diff --git a/src/test/java/spoon/test/comment/CommentTest.java b/src/test/java/spoon/test/comment/CommentTest.java
index b248ab679a1..ab45db20f41 100644
--- a/src/test/java/spoon/test/comment/CommentTest.java
+++ b/src/test/java/spoon/test/comment/CommentTest.java
@@ -31,6 +31,7 @@
import spoon.reflect.factory.Factory;
import spoon.reflect.factory.FactoryImpl;
import spoon.reflect.visitor.filter.AbstractFilter;
+import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.DefaultCoreFactory;
import spoon.support.StandardEnvironment;
@@ -47,6 +48,7 @@
import static org.apache.commons.io.IOUtils.write;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
public class CommentTest {
diff --git a/src/test/java/spoon/test/compilation/CompilationTest.java b/src/test/java/spoon/test/compilation/CompilationTest.java
index ad979905224..f53db2e8968 100644
--- a/src/test/java/spoon/test/compilation/CompilationTest.java
+++ b/src/test/java/spoon/test/compilation/CompilationTest.java
@@ -16,9 +16,11 @@
import spoon.reflect.factory.CodeFactory;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.factory.Factory;
+import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.support.compiler.jdt.FileCompiler;
import spoon.support.compiler.jdt.JDTBasedSpoonCompiler;
+import spoon.support.reflect.reference.SpoonClassNotFoundException;
import spoon.test.compilation.testclasses.Bar;
import spoon.test.compilation.testclasses.IBar;
import spoon.testing.utils.ModelUtils;
@@ -31,6 +33,7 @@
import java.util.List;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -229,4 +232,34 @@ public CompilationUnit[] getCompilationUnits() {
}
+ @Test
+ public void testPrecompile() {
+ // without precompile
+ Launcher l = new Launcher();
+ l.setArgs(new String[] {"--noclasspath", "-i", "src/test/resources/compilation/"});
+ l.buildModel();
+ CtClass klass = l.getFactory().Class().get("compilation.Bar");
+ // without precompile, actualClass does not exist (an exception is thrown)
+ try {
+ klass.getSuperInterfaces().toArray(new CtTypeReference[0])[0].getActualClass();
+ fail();
+ } catch (SpoonClassNotFoundException ignore) {}
+
+ // with precompile
+ Launcher l2 = new Launcher();
+ l2.setArgs(new String[] {"--precompile", "--noclasspath", "-i", "src/test/resources/compilation/"});
+ l2.buildModel();
+ CtClass klass2 = l2.getFactory().Class().get("compilation.Bar");
+ // with precompile, actualClass is not null
+ Class actualClass = klass2.getSuperInterfaces().toArray(new CtTypeReference[0])[0].getActualClass();
+ assertNotNull(actualClass);
+ assertEquals("IBar", actualClass.getSimpleName());
+
+ // precompile can be used to compile processors on the fly
+ Launcher l3 = new Launcher();
+ l3.setArgs(new String[] {"--precompile", "--noclasspath", "-i", "src/test/resources/compilation/", "-p", "compilation.SimpleProcessor"});
+ l3.run();
+ }
+
+
}
diff --git a/src/test/resources/compilation/SimpleProcessor.java b/src/test/resources/compilation/SimpleProcessor.java
new file mode 100644
index 00000000000..46cb1c43f14
--- /dev/null
+++ b/src/test/resources/compilation/SimpleProcessor.java
@@ -0,0 +1,18 @@
+package compilation;
+
+import spoon.processing.AbstractProcessor;
+import spoon.reflect.declaration.CtType;
+
+/**
+ * Simple Processor to demonstrate --precompile
issue
+ *
+ * @author Michael Stocker
+ * @since 0.1.0
+ */
+public class SimpleProcessor extends AbstractProcessor> {
+
+ @Override
+ public void process(CtType> element) {
+ System.out.println(">> Hello: " + element.getSimpleName() + " <<");
+ }
+}
diff --git a/src/test/resources/compilation/compilation-tests/Bar.java b/src/test/resources/compilation/compilation-tests/Bar.java
new file mode 100644
index 00000000000..b773deecf18
--- /dev/null
+++ b/src/test/resources/compilation/compilation-tests/Bar.java
@@ -0,0 +1,11 @@
+package compilation;
+
+public class Bar implements IBar {
+
+ @Override
+ public int m() {
+ return 1;
+ }
+}
+
+class FooEx extends RuntimeException {}
diff --git a/src/test/resources/compilation/compilation-tests/IBar.java b/src/test/resources/compilation/compilation-tests/IBar.java
new file mode 100644
index 00000000000..d8296927f67
--- /dev/null
+++ b/src/test/resources/compilation/compilation-tests/IBar.java
@@ -0,0 +1,8 @@
+package compilation;
+
+/**
+ * Created by thomas on 28/10/16.
+ */
+public interface IBar {
+ int m();
+}