-
-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add and remove a method to a class and compile it #575
Comments
Hi, I can reproduce you problem, it appears when you try to compile more than one time a class (cache). Unfortunately there is no good workaround (you can use reflection see below). You can get the compilation error via: SpoonModelBuilder modelBuilder = launcher.getModelBuilder();
if (modelBuilder instanceof JDTBasedSpoonCompiler) {
((JDTBasedSpoonCompiler) modelBuilder).getProblems();
} But there is no way to get the warning messages (the method that handles the output is Clear compilation cache manuallyField loadedContent = modelBuilder.getClass().getDeclaredField("loadedContent");
loadedContent.setAccessible(true);
Object loadedContentObj = loadedContent.get(modelBuilder);
Method clear = loadedContentObj.getClass().getDeclaredMethod("clear");
clear.invoke(loadedContentObj); |
Hi |
What is the message of ModelBuildingException? |
After first compile this is the part or output: and after the second compile it shows the same error: |
Ok, can you provide the content of ClassA? |
`package test; public class ClazzA {
}` I remove a1(int x) and add a new version of method by commenting the first line (//s1="test";) and then try to rollback to the original version by removing the modified method and add the original method. |
How do you comment the first line (//s1="test";) because comments are not yet supported by spoon? |
There is no different. even when I remove that line, the result is the same. public class ClazzA {
}` I remove the a1(int x) method and add a method with this code: |
I cannot reproduce your problem. @Test
public void test() throws Exception {
Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/" + ClazzA.class.getName().replace('.', '/') + ".java");
launcher.buildModel();
CoreFactory core = launcher.getFactory().Core();
CodeFactory code = launcher.getFactory().Code();
TypeFactory type = launcher.getFactory().Type();
final CtClass<?> clazzA = (CtClass<?>) launcher.getFactory().Type().get(ClazzA.class);
SpoonModelBuilder modelBuilder = launcher.getModelBuilder();
// first compilation
System.out.println(clazzA);
modelBuilder.compile();
// get method a1
CtMethod<?> a1 = clazzA.getMethodsByName("a1").get(1);
CtMethod<?> a1Clone = core.clone(a1);
// create field s1
CtField f1 = (CtField) core.createField().<CtField>setSimpleName("s1").setType(type.createReference(String.class));
clazzA.addField(f1);
// create s1 assignment
CtStatement test = (CtStatement) core.createAssignment().setAssigned(core.createFieldWrite().setVariable(f1.getReference())).setAssignment(code.createLiteral("test"));
a1Clone.getBody().insertBegin(test);
// change invocation parameter
((CtInvocation)a1Clone.getBody().getLastStatement()).setArguments(Arrays.asList(code.createLiteral(5)));
// change a1
clazzA.removeMethod(a1);
clazzA.addMethod(a1Clone);
// second compilation
System.out.println(clazzA);
clearCompilationCache(modelBuilder);
modelBuilder.compile();
// rollback
clazzA.removeMethod(a1Clone);
clazzA.addMethod(a1);
clazzA.removeField(f1);
// third compilation
System.out.println(clazzA);
clearCompilationCache(modelBuilder);
modelBuilder.compile();
}
private void clearCompilationCache(SpoonModelBuilder modelBuilder)
throws NoSuchFieldException, IllegalAccessException,
NoSuchMethodException, InvocationTargetException {
Field loadedContent = modelBuilder.getClass().getDeclaredField("loadedContent");
loadedContent.setAccessible(true);
Object loadedContentObj = loadedContent.get(modelBuilder);
Method clear = loadedContentObj.getClass().getDeclaredMethod("clear");
clear.invoke(loadedContentObj);
} |
Let me explain my problem clearly: public class ClazzA {
}` on the new version I remove field s1 and also the line which can use s1 in a1(int x). (I also remove a3() in my test case)
} |
Where can I find this fixed version? |
A snapshot isn't deployed for each PR. If you want to use my fix before its merge, you must:
|
Thanks @GerardPaligot I couldn't build it. mvn install terminates with an error: |
I temporary fix the problem on my code by calling |
I propose to always invalidate |
Hi
I have a ctClass object and add a ctMethod to its compilation. It works well but when I remove this method from class again and try to compile, it keeps the ctMethod. Actually it shows that it has been removed successfully but when I compile, it is already there and makes the same compilation error.
I have another question. How can I get the compilation output message when I call compile() from ModelBuilder? It only returns a boolean value but I need detail of the compilation output which is shown in console.
This is a my code:
`ctClazz.addMethod(ctMethod);
launcher.getModelBuilder().compile();
ctClazz.removeMethod(ctMethod);
launcher.getModelBuilder().compile();`
The text was updated successfully, but these errors were encountered: