Skip to content

Commit

Permalink
Merge pull request #5 from INRIA/master
Browse files Browse the repository at this point in the history
fix: fix crash with SpoonException in sniper mode (INRIA#3205)
  • Loading branch information
moraispgsi authored Feb 8, 2020
2 parents a93b410 + 91cfbd4 commit 3220325
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,14 @@ public SourcePosition getSourcePosition() {

@Override
public String toString() {
return "|" + getStart() + ", " + getEnd() + "|" + getSourceCode() + "|";
String result = "|" + getStart() + ", " + getEnd() + "|" + getSourceCode() + "|";

if (element instanceof CtElement) {
// enrich the toString to facilitate debug
return ((CtElement) element).toStringDebug() + result;
}

return result;
}

/**
Expand Down Expand Up @@ -299,20 +306,14 @@ private void merge(ElementSourceFragment tobeMerged) {
/**
* adds `fragment` as child fragment of this fragment. If child is located before or after this fragment,
* then start/end of this fragment is moved
* @param fragment to be add
* @param fragment to be added
*/
public void addChild(ElementSourceFragment fragment) {
if (firstChild == null) {
firstChild = fragment;
} else {
firstChild = firstChild.add(fragment);
}
if (fragment.getElement() instanceof CtElement) {
CtElement fragmentEleParent = ((CtElement) fragment.getElement()).getParent();
if (element != fragmentEleParent && !(element instanceof CtCompilationUnit) && fragmentEleParent.getPosition().isValidPosition()) {
throw new SpoonException("Inconsistent child fragment " + fragment.getElement().getClass() + " has unexpected parent " + element.getClass());
}
}
}

private void addNextSibling(ElementSourceFragment sibling) {
Expand Down
70 changes: 70 additions & 0 deletions src/test/java/spoon/test/prettyprinter/SniperInnerTypeTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package spoon.test.prettyprinter;

import org.apache.commons.io.*;
import org.hamcrest.*;
import org.junit.*;
import static org.junit.Assert.*;

import spoon.Launcher;
import spoon.compiler.*;
import spoon.reflect.*;
import spoon.reflect.code.CtComment.*;
import spoon.reflect.declaration.*;
import spoon.reflect.visitor.filter.*;
import spoon.support.sniper.*;

import java.io.*;
import java.nio.charset.*;
import java.nio.file.*;

public class SniperInnerTypeTest {
private static final Path INPUT_PATH = Paths.get("src/test/java/");
private static final Path OUTPUT_PATH = Paths.get("target/test-output");

@BeforeClass
public static void setup() throws IOException {
FileUtils.deleteDirectory(OUTPUT_PATH.toFile());
}

@Test
public void innerTypeCrash() throws IOException {
runSniperJavaPrettyPrinter("spoon/test/prettyprinter/testclasses/innertype/InnerTypeCrash.java");
}

@Test
public void innerTypeOk() throws IOException {
runSniperJavaPrettyPrinter("spoon/test/prettyprinter/testclasses/innertype/InnerTypeOk.java");
}

@Test
public void innerTypeOk2() throws IOException {
runSniperJavaPrettyPrinter("spoon/test/prettyprinter/testclasses/innertype/InnerTypeOk2.java");
}

private void runSniperJavaPrettyPrinter(String path) throws IOException {
final Launcher launcher = new Launcher();
final Environment e = launcher.getEnvironment();
e.setLevel("INFO");
e.setPrettyPrinterCreator(() -> new SniperJavaPrettyPrinter(e));

launcher.addInputResource(INPUT_PATH.resolve(path).toString());
launcher.setSourceOutputDirectory(OUTPUT_PATH.toString());

CtModel model = launcher.buildModel();

CtClass ctClass = model.getElements(new TypeFilter<>(CtClass.class)).get(0);

ctClass.addComment(launcher.getFactory().Code().createComment("test", CommentType.BLOCK));

launcher.process();
launcher.prettyprint();
// Verify result file exist and is not empty
assertThat("Output file for " + path + " should exist", OUTPUT_PATH.resolve(path).toFile().exists(),
CoreMatchers.equalTo(true));

String content = new String(Files.readAllBytes(OUTPUT_PATH.resolve(path)), StandardCharsets.UTF_8);

assertThat(content, CoreMatchers.notNullValue());
assertThat("Result class should not be empty", content.trim(), CoreMatchers.not(CoreMatchers.equalTo("")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package spoon.test.prettyprinter.testclasses.innertype;

import java.util.*;

public class InnerTypeCrash {
private void test()
{
Map.Entry<String, String> test;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@

package spoon.test.prettyprinter.testclasses.innertype;

import java.util.Map.*;

public class InnerTypeOk {
private void test() {
Entry<String, String> test;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package spoon.test.prettyprinter.testclasses.innertype;

import java.util.*;

public class InnerTypeOk2 {
private void test() {
Map.Entry test;
}
}

0 comments on commit 3220325

Please sign in to comment.