Skip to content

Commit

Permalink
fix: improve line preservation mode
Browse files Browse the repository at this point in the history
  • Loading branch information
monperrus committed May 30, 2017
1 parent d0d3f65 commit 2f546ed
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 20 deletions.
20 changes: 13 additions & 7 deletions src/main/java/spoon/reflect/visitor/DefaultJavaPrettyPrinter.java
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public DefaultJavaPrettyPrinter scan(CtElement e) {
context.elementStack.push(e);
if (env.isPreserveLineNumbers()) {
if (!(e instanceof CtNamedElement)) {
printer.adjustPosition(e, sourceCompilationUnit);
printer.adjustStartPosition(e);
}
}
e.accept(this);
Expand Down Expand Up @@ -436,9 +436,10 @@ public <R> void visitCtBlock(CtBlock<R> block) {
}
}
printer.decTab();
printer.adjustEndPosition(block);
if (env.isPreserveLineNumbers()) {
if (!block.isImplicit()) {
printer.write("}");
printer.writeTabs().write("}");
}
} else {
printer.writeln().writeTabs();
Expand Down Expand Up @@ -528,7 +529,7 @@ public <T> void visitCtClass(CtClass<T> ctClass) {
// lst.addAll(elementPrinterHelper.getComments(ctClass, CommentOffset.INSIDE));
printer.write(" {").incTab();
elementPrinterHelper.writeElementList(ctClass.getTypeMembers());
printer.decTab().writeTabs().write("}");
printer.adjustEndPosition(ctClass).decTab().writeTabs().write("}");
context.popCurrentThis();
}

Expand Down Expand Up @@ -1090,7 +1091,7 @@ public <T> void visitCtInvocation(CtInvocation<T> invocation) {

elementPrinterHelper.writeActualTypeArguments(invocation);
if (env.isPreserveLineNumbers()) {
printer.adjustPosition(invocation, sourceCompilationUnit);
printer.adjustStartPosition(invocation);
}
printer.write(invocation.getExecutable().getSimpleName());
}
Expand Down Expand Up @@ -1161,7 +1162,7 @@ public <T> void visitCtLocalVariable(CtLocalVariable<T> localVariable) {
enterCtStatement(localVariable);
}
if (env.isPreserveLineNumbers()) {
printer.adjustPosition(localVariable, sourceCompilationUnit);
printer.adjustStartPosition(localVariable);
}
if (!context.noTypeDecl()) {
elementPrinterHelper.writeModifiers(localVariable);
Expand All @@ -1183,7 +1184,7 @@ public <T> void visitCtLocalVariableReference(CtLocalVariableReference<T> refere
@Override
public <T> void visitCtCatchVariable(CtCatchVariable<T> catchVariable) {
if (env.isPreserveLineNumbers()) {
printer.adjustPosition(catchVariable, sourceCompilationUnit);
printer.adjustStartPosition(catchVariable);
}
elementPrinterHelper.writeModifiers(catchVariable);
scan(catchVariable.getType());
Expand Down Expand Up @@ -1809,7 +1810,12 @@ public void calculate(CompilationUnit sourceCompilationUnit, List<CtType<?>> typ
elementPrinterHelper.writeHeader(types, imports);
for (CtType<?> t : types) {
scan(t);
printer.writeln().writeln().writeTabs();
if (!env.isPreserveLineNumbers()) {
// saving lines and chars
printer.writeln().writeln().writeTabs();
} else {
printer.adjustEndPosition(t);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void writeModifiers(CtModifiable modifiable) {
public void visitCtNamedElement(CtNamedElement namedElement, CompilationUnit sourceCompilationUnit) {
writeAnnotations(namedElement);
if (env.isPreserveLineNumbers()) {
printer.adjustPosition(namedElement, sourceCompilationUnit);
printer.adjustStartPosition(namedElement);
}
}

Expand Down Expand Up @@ -257,7 +257,7 @@ public void writeHeader(List<CtType<?>> types, Collection<CtReference> imports)
if (!types.isEmpty()) {
for (CtType<?> ctType : types) {
writeComment(ctType, CommentOffset.TOP_FILE);
printer.writeln().writeln().writeTabs();
//printer.writeln().writeln().writeTabs();
}
// writing the header package
if (!types.get(0).getPackage().isUnnamedPackage()) {
Expand Down
24 changes: 15 additions & 9 deletions src/main/java/spoon/reflect/visitor/printer/PrinterHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
*/
package spoon.reflect.visitor.printer;

import org.apache.log4j.Level;
import spoon.compiler.Environment;
import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.UnaryOperatorKind;
Expand Down Expand Up @@ -159,23 +158,30 @@ private boolean isWhite(char c) {
return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\r');
}

public void adjustPosition(CtElement e, CompilationUnit unitExpected) {
if (e.getPosition() != null && !e.isImplicit() && e.getPosition().getCompilationUnit() != null && e.getPosition().getCompilationUnit() == unitExpected) {
public PrinterHelper adjustStartPosition(CtElement e) {
if (e.getPosition() != null && !e.isImplicit()) {
// we should add some lines
while (line < e.getPosition().getLine()) {
insertLine();
}
// trying to remove some lines
while (line > e.getPosition().getLine()) {
if (!removeLine()) {
if (line > e.getPosition().getEndLine()) {
final String message = "cannot adjust position of " + e.getClass().getSimpleName() + " '" //
+ e.getShortRepresentation() + "' " + " to match lines: " + line + " > [" //
+ e.getPosition().getLine() + ", " + e.getPosition().getEndLine() + "]"; //
env.report(null, Level.WARN, e, message);
}
break;
}
}
}
return this;
}

public PrinterHelper adjustEndPosition(CtElement e) {
if (env.isPreserveLineNumbers() && e.getPosition() != null) {
// let's add lines if required
while (line < e.getPosition().getEndLine()) {
insertLine();
}
}
return this;
}

public void undefineLine() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,7 @@ protected void generateProcessedSourceFilesUsingCUs() {

IOUtils.copy(is, new FileOutputStream(file));


if (!printedFiles.contains(file)) {
printedFiles.add(file);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -261,7 +263,7 @@ public void printClassCreatedWithSpoon() throws Exception {
File javaFile = new File(pathname);
assertTrue(javaFile.exists());

assertEquals(nl + nl + "package foo;" + nl + nl + nl + "class Bar {}" + nl + nl,
assertEquals("package foo;" + nl + nl + nl + "class Bar {}" + nl + nl,
IOUtils.toString(new FileInputStream(javaFile), "UTF-8"));
}

Expand Down Expand Up @@ -291,4 +293,5 @@ public void testTernaryParenthesesOnLocalVariable() {
snippet = launcher.getFactory().Code().createCodeSnippetStatement(compile.toString());
assertEquals(compile, snippet.compile());
}

}
63 changes: 63 additions & 0 deletions src/test/java/spoon/test/prettyprinter/LinesTest.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,31 @@
package spoon.test.prettyprinter;

import org.apache.commons.io.IOUtils;
import org.junit.Before;
import org.junit.Test;
import spoon.Launcher;
import spoon.compiler.SpoonResourceHelper;
import spoon.reflect.code.CtThisAccess;
import spoon.reflect.code.CtTypeAccess;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtNamedElement;
import spoon.reflect.declaration.CtType;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.DefaultJavaPrettyPrinter;
import spoon.reflect.visitor.filter.NameFilter;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.test.prettyprinter.testclasses.QualifiedThisRef;

import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertTrue;
import static spoon.test.limits.StaticFieldAccesOnInstance.test;

public class LinesTest {

Expand Down Expand Up @@ -45,4 +62,50 @@ public void testPrettyPrinterWithLines() throws Exception {

}

@Test
public void testIdenticalPrettyPrinter() throws Exception{
// contract: the end line should also be preserved

// setup
String[] options = {"--output-type", "compilationunits",
"--output", "target/testIdenticalPrettyPrinter",
// those three options together are the closest to what the developer wrote
"--enable-comments", "--lines", "--with-imports"};

List<String> paths = new ArrayList<>();
paths.add("spoon/test/prettyprinter/testclasses/A.java");
paths.add("spoon/test/prettyprinter/testclasses/AClass.java");
//paths.add("spoon/test/prettyprinter/testclasses/QualifiedThisRef.java");
//paths.add("spoon/test/prettyprinter/testclasses/ImportStatic.java");
//paths.add("spoon/test/prettyprinter/testclasses/QualifiedThisRef.java");
//paths.add("spoon/test/prettyprinter/testclasses/Rule.java");
//paths.add("spoon/test/prettyprinter/testclasses/TypeIdentifierCollision.java");


final Launcher launcher = new Launcher();
launcher.setArgs(options);
for (String path : paths) {
launcher.addInputResource("./src/test/java/" + path);
}
launcher.run();

final Launcher launcher2 = new Launcher();
launcher2.setArgs(options);
for (String path : paths) {
launcher2.addInputResource("./target/testIdenticalPrettyPrinter/" + path);
}
launcher2.run();

int n=0;
List<CtElement> elements = launcher.getModel().getElements(new TypeFilter<>(CtElement.class));
for (int i = 0; i < elements.size(); i++) {
n++;
CtElement e = elements.get(i);
CtElement el2 = launcher2.getModel().getElements(new TypeFilter<>(CtElement.class)).get(i);
assertNotSame(e, el2);
assertEquals(e.toString() + " not handled", e.getPosition().getLine(), el2.getPosition().getLine());
assertEquals(e.toString() + " not handled", e.getPosition().getEndLine(), el2.getPosition().getEndLine());
}
assertTrue(n>20);
}
}
2 changes: 1 addition & 1 deletion src/test/java/spoon/test/prettyprinter/PrinterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ public void testFQNModeWriteFQNConstructorInCtVisitor() {
@Test
public void testAutoimportModeDontImportUselessStatic() {
Launcher spoon = new Launcher();
PrettyPrinter printer = spoon.createPrettyPrinter();
spoon.getEnvironment().setAutoImports(true);
PrettyPrinter printer = spoon.createPrettyPrinter();
spoon.addInputResource("./src/test/java/spoon/test/prettyprinter/testclasses/ImportStatic.java");
spoon.buildModel();

Expand Down

0 comments on commit 2f546ed

Please sign in to comment.