-
-
Notifications
You must be signed in to change notification settings - Fork 354
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
Problem modifying file code with static import. #2927
Comments
Thanks for the bug report. Could you create a pull-request with a failing test case? |
I'm not sure how to create a test to show this BUG. Should I go in the "/src/test/java/spoon/test" folder and I memo create a case with my tested files? |
You can put the test data (i.e. the file containing source code with static import imports) in |
I created here a test scene in which it generates the file shown above. How does the creation of PULL REQUEST work? But my test only generates the OUTPUT in /target/spoon/static_imports/src/org/apache/hadoop/mapred/ShuffleHandler.java for you to analyze the code. |
this is the output of the test, the compilation errors in HADOOP. |
Here is the output of the HADOOP tests when I make the modification using setAutoImports (false). |
To create a pull request, you need to (assuming that you have already cloned spoon on your machine)
Note that once your pull request is created (and until it is accepted or refused) you will still be able to push new changes. Here is some relevant documentation |
Okay, I think I made it. |
Guys, my master degree needs this :( |
instead of :( go for a more positive emoji 🍺 |
Ok after investigation, this problem should only happen in NoClassPath mode. So if you have the possibility to give the full classpath, you could easily get around it. For exemple, if the sources that you are processing are part of a maven project, I suggest you use the Launcher spoon;
spoon = new Launcher();
spoon.getEnvironment().setSourceClasspath(new String[]{path}); Note that in this context, Anyway, this is still an issue that we should fix. I am only suggesting this if this is a pressing issue for you! |
Depending on what you want to do with the transformed sources, you could also consider using spoon.getEnvironment().setAutoImports(false); In this case your processed source will be printed with no imports at all but the code will directly refer to fully qulified name, making these import unecessary for compilation (but less human readable). A last option you may consider would be to use the SnipperPrettyPrinter with launcher.getEnvironment().setPrettyPrinterCreator(() -> {
return new SniperJavaPrettyPrinter(launcher.getEnvironment());
}
); This should only changer part of the source file that you transformed. (And hopefully, import won't be impacted. To sums things up, to bypass this problem you have 4 options:
This page of the documentation should help with all these options. |
I have tested your solutions that showed me. I used the Maven Launcher and got the same problem (compile error for 'can not find symbol'). I did not test the first, as Maven Launcher automatically adds the classpath. With SniperPrettyPrinter, I get errors at the time of modifying the file (besides the error in the console, some java classes are without anything written). I also tested with another HADOOP subproject, but I have the same results. |
I am having a hard time reproducing your errors. Can you give me a little bit more context on what you want to achieve and the errors that you get? |
Yes. I'm making modifications to HADOOP subsystems (https://github.com/apache/hadoop). The example I cited above was the (https://github.com/apache/hadoop/tree/trunk/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle). I used the class (https://github.com/apache/hadoop/blob/trunk/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-shuffle/src/main/java/org/apache/hadoop/mapred/ShuffleHandler.java) to remove block catchs and add a finally block (if it does not exist). I make modifications to the try catchs blocks, as they are part of my research (creation of mutations with focus on exception handling). I already used several systems to do this, now I was using HADOOP and I came across these problems that I showed you. Basically when modifying the code, the java file generated by the modification generates compilation error, due to the lack of imports that are not added as they should by SPOON. You can do a test to see the problem: Get the same java class I showed above in the repository, and make a simple modification to it (add only one comment), get the modified output class and replace it in the HADOOP project and run the tests (subproject only) you will see several compilation errors that did not exist before. When I analyzed the classes I noticed that static imports were not being added as they should. |
Did you get the same problem? |
No we cannot reproduce your problem. Hadoop is a huge project with a very complex build and classpath setup. Can you try with something that is smaller (see projects of Table 5 of this paper) and tell us how it goes? |
Ah, but these dependency problems can be solved by running the configuration file: https://github.com/apache/hadoop/blob/trunk/start-build-env.sh, from this a container in docker runs , and there are already all the dependencies installed. When you execute this file on the machine you can already execute the tests of this subproject that I showed. I've already run SPOON on other projects, and what interests me now for the master degree is HADOOP. |
I understand. Then we have to work on the exact same bug. Could you reproduce the bug on Travis using docker in the dedicated repo https://github.com/SpoonLabs/spoon-hadoop? (you have the right to push here) |
I have never used Travis, I do not know how to proceed to show you the result of the problem using it. I use an image of docker here on my computer, in case I should commmit this image and send it to the Docker Cloud? And then generate a script on this travis for him to use that image? Or something. |
exactly. or build the docker image on Travis directly.
|
Fixed in master by #2936 |
Thanks for the bug report. |
Here below is the compilation problem.
Here is the part of the modified code. CodeBefore= CodeAfter= SPOON CONFIGURATION: spoon.getEnvironment().setNoClasspath(true); |
When using ExampleLauncher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource(
new VirtualFile("package com.test;\n\n" +
"\n" +
"import static org.assertj.core.api.Assertions.*;\n" +
"\n" +
"public class ImportTest {\n" +
"\n" +
" public static void foo() {\n" +
" assertThat(42).isEqualTo(42);\n" +
" }\n" +
"}"));
launcher.buildModel();
System.out.println(launcher.getFactory().Class().getAll().get(0).toStringWithImports()); Resultpackage com.test;
public class ImportTest {
public static void foo() {
assertThat(42).isEqualTo(42);
}
} Using a ExampleLauncher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource(
new VirtualFile("package com.test;\n\n" +
"\n" +
"import static org.assertj.core.api.Assertions.*;\n" +
"\n" +
"public class ImportTest {\n" +
"\n" +
" public static void foo() {\n" +
" assertThat(42).isEqualTo(42);\n" +
" }\n" +
"}"));
launcher.buildModel();
PrettyPrinter printer = launcher.createPrettyPrinter();
CtType<?> type = launcher.getFactory().Class().getAll().get(0);
printer.calculate(type.getPosition().getCompilationUnit(), List.of(type));
System.out.println(printer.getResult()); Resultpackage com.test;
import static org.assertj.core.api.Assertions.*;
public class ImportTest {
public static void foo() {
isEqualTo(42);
}
} Note how |
Thanks for the bug report, reopening this one. Would you have a look at a possible fix, inspired from #2936? |
I stepped through the code and found that package com.test;
import static org.assertj.core.api.Assertions.*;
public class StaticImports {
public static void foo() {
assertThat(42).isEqualTo(42);
}
} @Test
public void testStaticMethodImports() {
Launcher launcher = new Launcher();
launcher.getEnvironment().setNoClasspath(true);
launcher.getEnvironment().setAutoImports(true);
launcher.addInputResource("./src/test/resources/noclasspath/imports/StaticImports.java");
launcher.buildModel();
DefaultJavaPrettyPrinter printer = new DefaultJavaPrettyPrinter(launcher.getEnvironment());
printer.calculate(null, Collections.singletonList(launcher.getFactory().Class().getAll().get(0)));
String result = printer.getResult();
assertTrue(result.contains("assertThat(42)"));
} Looking further, |
Great analysis.
Something like |
When I modify the file (I only modify the parts that have TRY CATCH). Everything that is modified with static (example: import static org.fusesource.leveldbjni.JniDBFactory.asString;), are removed from the code, so when I am going to compile the code again I have not found variable errors, which are exactly these static imports .
I have here the two files for comparison.
I will show only the imports.
ORIGINAL CODE:
OUTPUT CODE:
this is the SPOON (7.3.0) configuration that I use in code.
I have already tried using
spoon.getEnvironment().setAutoImports(false);
also, but I continued with the same problem.The text was updated successfully, but these errors were encountered: