blob: 796da14a2dbaefb817567dd16a999e1709610795 [file] [log] [blame]
package com.github.javaparser.printer.lexicalpreservation;
import com.github.javaparser.*;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.UnionType;
import com.github.javaparser.ast.type.VoidType;
import com.github.javaparser.ast.visitor.ModifierVisitor;
import com.github.javaparser.ast.visitor.Visitable;
import org.junit.Test;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import static com.github.javaparser.printer.lexicalpreservation.LexicalPreservingPrinter.NODE_TEXT_DATA;
import static com.github.javaparser.utils.TestUtils.assertEqualsNoEol;
import static com.github.javaparser.utils.Utils.EOL;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
public class LexicalPreservingPrinterTest extends AbstractLexicalPreservingTest {
private NodeText getTextForNode(Node node) {
return node.getData(NODE_TEXT_DATA);
}
//
// Tests on TextNode definition
//
@Test
public void checkNodeTextCreatedForSimplestClass() {
considerCode("class A {}");
// CU
assertEquals(1, getTextForNode(cu).numberOfElements());
assertEquals(true, getTextForNode(cu).getTextElement(0) instanceof ChildTextElement);
assertEquals(cu.getClassByName("A").get(), ((ChildTextElement)getTextForNode(cu).getTextElement(0)).getChild());
// Class
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
assertEquals(7, getTextForNode(classA).numberOfElements());
assertEquals("class", getTextForNode(classA).getTextElement(0).expand());
assertEquals(" ", getTextForNode(classA).getTextElement(1).expand());
assertEquals("A", getTextForNode(classA).getTextElement(2).expand());
assertEquals(" ", getTextForNode(classA).getTextElement(3).expand());
assertEquals("{", getTextForNode(classA).getTextElement(4).expand());
assertEquals("}", getTextForNode(classA).getTextElement(5).expand());
assertEquals("", getTextForNode(classA).getTextElement(6).expand());
assertEquals(true, getTextForNode(classA).getTextElement(6) instanceof TokenTextElement);
assertEquals(GeneratedJavaParserConstants.EOF, ((TokenTextElement)getTextForNode(classA).getTextElement(6)).getTokenKind());
}
@Test
public void checkNodeTextCreatedForField() {
String code = "class A {int i;}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
FieldDeclaration fd = classA.getFieldByName("i").get();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(fd);
assertEquals(Arrays.asList("int", " ", "i", ";"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedForVariableDeclarator() {
String code = "class A {int i;}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
FieldDeclaration fd = classA.getFieldByName("i").get();
VariableDeclarator vd = fd.getVariables().get(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(vd);
assertEquals(Arrays.asList("i"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedForMethod() {
String code = "class A {void foo(int p1, float p2) { }}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
MethodDeclaration md = classA.getMethodsByName("foo").get(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
assertEquals(Arrays.asList("void", " ", "foo", "(", "int p1", ",", " ", "float p2", ")", " ", "{ }"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedForMethodParameter() {
String code = "class A {void foo(int p1, float p2) { }}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
MethodDeclaration md = classA.getMethodsByName("foo").get(0);
Parameter p1 = md.getParameterByName("p1").get();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(p1);
assertEquals(Arrays.asList("int", " ", "p1"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedForPrimitiveType() {
String code = "class A {void foo(int p1, float p2) { }}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
MethodDeclaration md = classA.getMethodsByName("foo").get(0);
Parameter p1 = md.getParameterByName("p1").get();
Type t = p1.getType();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(t);
assertEquals(Arrays.asList("int"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedForSimpleImport() {
String code = "import a.b.c.D;";
considerCode(code);
ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(imp);
assertEquals(Arrays.asList("import", " ", "a.b.c.D", ";", ""),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedGenericType() {
String code = "class A {ParseResult<T> result;}";
considerCode(code);
FieldDeclaration field = cu.getClassByName("A").get().getFieldByName("result").get();
Node t = field.getCommonType();
Node t2 = field.getVariable(0).getType();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(field);
assertEquals(Arrays.asList("ParseResult", "<", "T", ">", " ", "result", ";"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedAnnotationDeclaration() {
String code = "public @interface ClassPreamble { String author(); }";
considerCode(code);
AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(ad);
assertEquals(Arrays.asList("public", " ", "@", "interface", " ", "ClassPreamble", " ", "{", " ", "String author();", " ", "}", ""),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedAnnotationMemberDeclaration() {
String code = "public @interface ClassPreamble { String author(); }";
considerCode(code);
AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
assertEquals(Arrays.asList("String", " ", "author", "(", ")", ";"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedAnnotationMemberDeclarationWithArrayType() {
String code = "public @interface ClassPreamble { String[] author(); }";
considerCode(code);
AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
assertEquals(Arrays.asList("String[]", " ", "author", "(", ")", ";"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedAnnotationMemberDeclarationArrayType() {
String code = "public @interface ClassPreamble { String[] author(); }";
considerCode(code);
AnnotationDeclaration ad = cu.getAnnotationDeclarationByName("ClassPreamble").get();
AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)ad.getMember(0).asAnnotationMemberDeclaration();
Type type = md.getType();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(type);
assertEquals(Arrays.asList("String", "[", "]"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedAnnotationMemberDeclarationWithComment() throws IOException {
considerExample("AnnotationDeclaration_Example3_original");
AnnotationMemberDeclaration md = (AnnotationMemberDeclaration)cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(5).asAnnotationMemberDeclaration();
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(md);
assertEquals(Arrays.asList("String[]", " ", "reviewers", "(", ")", ";"),
nodeText.getElements().stream().map(TextElement::expand).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedArrayCreationLevelWithoutExpression() throws IOException {
considerExpression("new int[]");
ArrayCreationExpr arrayCreationExpr = (ArrayCreationExpr)expression.asArrayCreationExpr();
ArrayCreationLevel arrayCreationLevel = arrayCreationExpr.getLevels().get(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(arrayCreationLevel);
assertEquals(Arrays.asList("[", "]"),
nodeText.getElements().stream().map(TextElement::expand).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
}
@Test
public void checkNodeTextCreatedArrayCreationLevelWith() throws IOException {
considerExpression("new int[123]");
ArrayCreationExpr arrayCreationExpr = (ArrayCreationExpr)expression.asArrayCreationExpr();
ArrayCreationLevel arrayCreationLevel = arrayCreationExpr.getLevels().get(0);
NodeText nodeText = LexicalPreservingPrinter.getOrCreateNodeText(arrayCreationLevel);
assertEquals(Arrays.asList("[", "123", "]"),
nodeText.getElements().stream().map(TextElement::expand).filter(e -> !e.isEmpty()).collect(Collectors.toList()));
}
//
// Tests on findIndentation
//
@Test
public void findIndentationForAnnotationMemberDeclarationWithoutComment() throws IOException {
considerExample("AnnotationDeclaration_Example3_original");
Node node = cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(4);
List<TokenTextElement> indentation = LexicalPreservingPrinter.findIndentation(node);
assertEquals(Arrays.asList(" ", " ", " "), indentation.stream().map(TokenTextElement::expand).collect(Collectors.toList()));
}
@Test
public void findIndentationForAnnotationMemberDeclarationWithComment() throws IOException {
considerExample("AnnotationDeclaration_Example3_original");
Node node = cu.getAnnotationDeclarationByName("ClassPreamble").get().getMember(5);
List<TokenTextElement> indentation = LexicalPreservingPrinter.findIndentation(node);
assertEquals(Arrays.asList(" ", " ", " "), indentation.stream().map(TokenTextElement::expand).collect(Collectors.toList()));
}
//
// Tests on printing
//
@Test
public void printASuperSimpleCUWithoutChanges() {
String code = "class A {}";
considerCode(code);
assertEquals(code, LexicalPreservingPrinter.print(cu));
}
@Test
public void printASuperSimpleClassWithAFieldAdded() {
String code = "class A {}";
considerCode(code);
ClassOrInterfaceDeclaration classA = cu.getClassByName("A").get();
classA.addField("int", "myField");
assertEquals("class A {" + EOL + " int myField;"+EOL+"}", LexicalPreservingPrinter.print(classA));
}
@Test
public void printASuperSimpleClassWithoutChanges() {
String code = "class A {}";
considerCode(code);
assertEquals(code, LexicalPreservingPrinter.print(cu.getClassByName("A").get()));
}
@Test
public void printASimpleCUWithoutChanges() {
String code = "class /*a comment*/ A {\t\t"+EOL+" int f;"+EOL+EOL+EOL+" void foo(int p ) { return 'z' \t; }}";
considerCode(code);
assertEquals(code, LexicalPreservingPrinter.print(cu));
assertEquals(code, LexicalPreservingPrinter.print(cu.getClassByName("A").get()));
assertEquals("void foo(int p ) { return 'z' \t; }", LexicalPreservingPrinter.print(cu.getClassByName("A").get().getMethodsByName("foo").get(0)));
}
@Test
public void printASimpleClassRemovingAField() {
String code = "class /*a comment*/ A {\t\t"+EOL+" int f;"+EOL+EOL+EOL+" void foo(int p ) { return 'z' \t; }}";
considerCode(code);
ClassOrInterfaceDeclaration c = cu.getClassByName("A").get();
c.getMembers().remove(0);
assertEquals("class /*a comment*/ A {\t\t"+ EOL +
EOL +
" void foo(int p ) { return 'z' \t; }}", LexicalPreservingPrinter.print(c));
}
@Test
public void printASimpleMethodAddingAParameterToAMethodWithZeroParameters() {
String code = "class A { void foo() {} }";
considerCode(code);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
m.addParameter("float", "p1");
assertEquals("void foo(float p1) {}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleMethodAddingAParameterToAMethodWithOneParameter() {
String code = "class A { void foo(char p1) {} }";
considerCode(code);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
m.addParameter("float", "p2");
assertEquals("void foo(char p1, float p2) {}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleMethodRemovingAParameterToAMethodWithOneParameter() {
String code = "class A { void foo(float p1) {} }";
considerCode(code);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
m.getParameters().remove(0);
assertEquals("void foo() {}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleMethodRemovingParameterOneFromMethodWithTwoParameters() {
String code = "class A { void foo(char p1, int p2) {} }";
considerCode(code);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
m.getParameters().remove(0);
assertEquals("void foo(int p2) {}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleMethodRemovingParameterTwoFromMethodWithTwoParameters() {
String code = "class A { void foo(char p1, int p2) {} }";
considerCode(code);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
m.getParameters().remove(1);
assertEquals("void foo(char p1) {}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleMethodAddingAStatement() {
String code = "class A { void foo(char p1, int p2) {} }";
considerCode(code);
Statement s = new ExpressionStmt(new BinaryExpr(
new IntegerLiteralExpr("10"), new IntegerLiteralExpr("2"), BinaryExpr.Operator.PLUS
));
NodeList<Statement> stmts = cu.getClassByName("A").get().getMethodsByName("foo").get(0).getBody().get().getStatements();
stmts.add(s);
MethodDeclaration m = cu.getClassByName("A").get().getMethodsByName("foo").get(0);
assertEquals("void foo(char p1, int p2) {"+EOL +
" 10 + 2;"+ EOL +
"}", LexicalPreservingPrinter.print(m));
}
@Test
public void printASimpleImport() {
String code = "import a.b.c.D;";
considerCode(code);
ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
assertEquals("import a.b.c.D;", LexicalPreservingPrinter.print(imp));
}
@Test
public void printAnotherImport() {
String code = "import com.github.javaparser.ast.CompilationUnit;";
considerCode(code);
ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
assertEquals("import com.github.javaparser.ast.CompilationUnit;", LexicalPreservingPrinter.print(imp));
}
@Test
public void printAStaticImport() {
String code = "import static com.github.javaparser.ParseStart.*;";
considerCode(code);
ImportDeclaration imp = (ImportDeclaration)cu.getChildNodes().get(0);
assertEquals("import static com.github.javaparser.ParseStart.*;", LexicalPreservingPrinter.print(imp));
}
@Test
public void checkAnnidatedTypeParametersPrinting() {
String code = "class A { private final Stack<Iterator<Triple>> its = new Stack<Iterator<Triple>>(); }";
considerCode(code);
assertEquals("class A { private final Stack<Iterator<Triple>> its = new Stack<Iterator<Triple>>(); }", LexicalPreservingPrinter.print(cu));
}
@Test
public void printASingleCatch() {
String code = "class A {{try { doit(); } catch (Exception e) {}}}";
considerCode(code);
assertEquals("class A {{try { doit(); } catch (Exception e) {}}}", LexicalPreservingPrinter.print(cu));
}
@Test
public void printAMultiCatch() {
String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
considerCode(code);
assertEquals("class A {{try { doit(); } catch (Exception | AssertionError e) {}}}", LexicalPreservingPrinter.print(cu));
}
@Test
public void printASingleCatchType() {
String code = "class A {{try { doit(); } catch (Exception e) {}}}";
considerCode(code);
InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
CatchClause catchClause = tryStmt.getCatchClauses().get(0);
Type catchType = catchClause.getParameter().getType();
assertEquals("Exception", LexicalPreservingPrinter.print(catchType));
}
@Test
public void printUnionType() {
String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
considerCode(code);
InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
CatchClause catchClause = tryStmt.getCatchClauses().get(0);
UnionType unionType = (UnionType)catchClause.getParameter().getType();
assertEquals("Exception | AssertionError", LexicalPreservingPrinter.print(unionType));
}
@Test
public void printParameterHavingUnionType() {
String code = "class A {{try { doit(); } catch (Exception | AssertionError e) {}}}";
considerCode(code);
InitializerDeclaration initializerDeclaration = (InitializerDeclaration)cu.getType(0).getMembers().get(0);
TryStmt tryStmt = (TryStmt)initializerDeclaration.getBody().getStatements().get(0);
CatchClause catchClause = tryStmt.getCatchClauses().get(0);
Parameter parameter = catchClause.getParameter();
assertEquals("Exception | AssertionError e", LexicalPreservingPrinter.print(parameter));
}
@Test
public void printLambaWithUntypedParams() {
String code = "class A {Function<String,String> f = a -> a;}";
considerCode(code);
assertEquals("class A {Function<String,String> f = a -> a;}", LexicalPreservingPrinter.print(cu));
}
@Test
public void printAModuleInfoSpecificKeywordUsedAsIdentifier1() {
considerCode("class module { }");
cu.getClassByName("module").get().setName("xyz");
assertEquals("class xyz { }", LexicalPreservingPrinter.print(cu));
}
@Test
public void printAModuleInfoSpecificKeywordUsedAsIdentifier2() {
considerCode("class xyz { }");
cu.getClassByName("xyz").get().setName("module");
assertEquals("class module { }", LexicalPreservingPrinter.print(cu));
}
// Issue 823: setPackageDeclaration on CU starting with a comment
@Test
public void reactToSetPackageDeclarationOnCuStartingWithComment() {
considerCode("// Hey, this is a comment\n" +
"\n" +
"\n" +
"// Another one\n" +
"\n" +
"class A {}");
cu.setPackageDeclaration("org.javaparser.lexicalpreservation.examples");
}
@Test
public void printLambdaIntersectionTypeAssignment() {
String code = "class A {" + EOL +
" void f() {" + EOL +
" Runnable r = (Runnable & Serializable) (() -> {});" + EOL +
" r = (Runnable & Serializable)() -> {};" + EOL +
" r = (Runnable & I)() -> {};" + EOL +
" }}";
considerCode(code);
assertEquals(code, LexicalPreservingPrinter.print(cu));
}
@Test
public void printLambdaIntersectionTypeReturn() {
String code = "class A {" + EOL
+ " Object f() {" + EOL
+ " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+ "}}";
considerCode(code);
assertEquals(code, LexicalPreservingPrinter.print(cu));
}
// See issue #855
@Test
public void handleOverrideAnnotation() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> type.getMembers()
.forEach(member -> {
if (member instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration) member;
if (!methodDeclaration.getAnnotationByName("Override").isPresent()) {
methodDeclaration.addAnnotation("Override");
}
}
}));
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" @Override()" + EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
@Test
public void preserveSpaceAsIsForASimpleClassWithMoreFormatting() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
assertEquals(readExample("ASimpleClassWithMoreFormatting"), LexicalPreservingPrinter.print(cu));
}
@Test
public void renameASimpleClassWithMoreFormatting() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
cu.getClassByName("ASimpleClass").get()
.setName("MyRenamedClass");
assertEquals(readExample("ASimpleClassWithMoreFormatting_step1"), LexicalPreservingPrinter.print(cu));
}
@Test
public void theLexicalPreservationStringForAnAddedMethodShouldBeIndented() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
cu.getClassByName("ASimpleClass").get()
.setName("MyRenamedClass");
MethodDeclaration setter = cu
.getClassByName("MyRenamedClass").get()
.addMethod("setAField", Modifier.PUBLIC);
assertEquals("public void setAField() {" + EOL +
" }", LexicalPreservingPrinter.print(setter));
}
@Test
public void addMethodToASimpleClassWithMoreFormatting() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
cu.getClassByName("ASimpleClass").get()
.setName("MyRenamedClass");
MethodDeclaration setter = cu
.getClassByName("MyRenamedClass").get()
.addMethod("setAField", Modifier.PUBLIC);
assertEquals(readExample("ASimpleClassWithMoreFormatting_step2"), LexicalPreservingPrinter.print(cu));
}
@Test
public void addingParameterToAnAddedMethodInASimpleClassWithMoreFormatting() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
cu.getClassByName("ASimpleClass").get()
.setName("MyRenamedClass");
MethodDeclaration setter = cu
.getClassByName("MyRenamedClass").get()
.addMethod("setAField", Modifier.PUBLIC);
setter.addParameter("boolean", "aField");
assertEquals(readExample("ASimpleClassWithMoreFormatting_step3"), LexicalPreservingPrinter.print(cu));
}
@Test
public void findIndentationOfEmptyMethod() throws IOException {
considerExample("ASimpleClassWithMoreFormatting_step3");
MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
.getMethodsByName("setAField").get(0);
assertEquals(4, LexicalPreservingPrinter.findIndentation(setter).size());
assertEquals(4, LexicalPreservingPrinter.findIndentation(setter.getBody().get()).size());
}
@Test
public void findIndentationOfMethodWithStatements() throws IOException {
considerExample("ASimpleClassWithMoreFormatting_step4");
MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
.getMethodsByName("setAField").get(0);
assertEquals(4, LexicalPreservingPrinter.findIndentation(setter).size());
assertEquals(4, LexicalPreservingPrinter.findIndentation(setter.getBody().get()).size());
assertEquals(8, LexicalPreservingPrinter.findIndentation(setter.getBody().get().getStatement(0)).size());
}
@Test
public void addingStatementToAnAddedMethodInASimpleClassWithMoreFormatting() throws IOException {
considerExample("ASimpleClassWithMoreFormatting");
cu.getClassByName("ASimpleClass").get()
.setName("MyRenamedClass");
MethodDeclaration setter = cu
.getClassByName("MyRenamedClass").get()
.addMethod("setAField", Modifier.PUBLIC);
setter.addParameter("boolean", "aField");
setter.getBody().get().getStatements().add(new ExpressionStmt(
new AssignExpr(
new FieldAccessExpr(new ThisExpr(),"aField"),
new NameExpr("aField"),
AssignExpr.Operator.ASSIGN
)));
assertEquals(readExample("ASimpleClassWithMoreFormatting_step4"), LexicalPreservingPrinter.print(cu));
}
@Test
public void addingStatementToAnAddedMethodInASimpleClassWithMoreFormattingFromStep3() throws IOException {
considerExample("ASimpleClassWithMoreFormatting_step3");
MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
.getMethodsByName("setAField").get(0);
setter.getBody().get().getStatements().add(new ExpressionStmt(
new AssignExpr(
new FieldAccessExpr(new ThisExpr(),"aField"),
new NameExpr("aField"),
AssignExpr.Operator.ASSIGN
)));
assertEquals(readExample("ASimpleClassWithMoreFormatting_step4"), LexicalPreservingPrinter.print(cu));
}
@Test
public void nodeTextForMethod() throws IOException {
considerExample("ASimpleClassWithMoreFormatting_step4");
MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
.getMethodsByName("setAField").get(0);
NodeText nodeText;
nodeText = getTextForNode(setter);
int index = 0;
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.PUBLIC));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(VoidType.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(SimpleName.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LPAREN));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(Parameter.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RPAREN));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(BlockStmt.class));
assertEquals(index, nodeText.getElements().size());
nodeText = getTextForNode(setter.getBody().get());
index = 0;
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LBRACE));
assertTrue(nodeText.getElements().get(index++).isNewline());
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(ExpressionStmt.class));
assertTrue(nodeText.getElements().get(index++).isNewline());
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RBRACE));
assertEquals(index, nodeText.getElements().size());
nodeText = getTextForNode(setter.getBody().get().getStatement(0));
index = 0;
assertTrue(nodeText.getElements().get(index++).isChildOfClass(AssignExpr.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SEMICOLON));
assertEquals(index, nodeText.getElements().size());
}
@Test
public void nodeTextForModifiedMethod() throws IOException {
considerExample("ASimpleClassWithMoreFormatting_step3");
MethodDeclaration setter = cu.getClassByName("MyRenamedClass").get()
.getMethodsByName("setAField").get(0);
setter.getBody().get().getStatements().add(new ExpressionStmt(
new AssignExpr(
new FieldAccessExpr(new ThisExpr(),"aField"),
new NameExpr("aField"),
AssignExpr.Operator.ASSIGN
)));
NodeText nodeText;
nodeText = getTextForNode(setter);
int index = 0;
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.PUBLIC));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(VoidType.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(SimpleName.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LPAREN));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(Parameter.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RPAREN));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(BlockStmt.class));
assertEquals(index, nodeText.getElements().size());
nodeText = getTextForNode(setter.getBody().get());
index = 0;
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.LBRACE));
assertTrue(nodeText.getElements().get(index++).isNewline());
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isChildOfClass(ExpressionStmt.class));
assertTrue(nodeText.getElements().get(index++).isNewline());
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SPACE));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.RBRACE));
assertEquals(index, nodeText.getElements().size());
nodeText = LexicalPreservingPrinter.getOrCreateNodeText(setter.getBody().get().getStatement(0));
index = 0;
assertTrue(nodeText.getElements().get(index++).isChildOfClass(AssignExpr.class));
assertTrue(nodeText.getElements().get(index++).isToken(GeneratedJavaParserConstants.SEMICOLON));
assertEquals(index, nodeText.getElements().size());
}
// See issue #926
@Test
public void addASecondStatementToExistingMethod() throws IOException {
considerExample("MethodWithOneStatement");
MethodDeclaration methodDeclaration = cu.getType(0).getMethodsByName("someMethod").get(0);
methodDeclaration.getBody().get().getStatements().add(new ExpressionStmt(
new VariableDeclarationExpr(
new VariableDeclarator(
JavaParser.parseClassOrInterfaceType("String"),
"test2",
new StringLiteralExpr("")))
));
assertEquals("public void someMethod() {" + EOL
+ " String test = \"\";" + EOL
+ " String test2 = \"\";" + EOL
+ " }", LexicalPreservingPrinter.print(methodDeclaration));
}
// See issue #866
@Test
public void moveOverrideAnnotations() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" protected @Override void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> {
type.getMembers()
.forEach(member -> {
member.ifMethodDeclaration(methodDeclaration -> {
if (methodDeclaration.getAnnotationByName("Override").isPresent()) {
while (methodDeclaration.getAnnotations().isNonEmpty()) {
AnnotationExpr annotationExpr = methodDeclaration.getAnnotations().get(0);
annotationExpr.remove();
}
methodDeclaration.addMarkerAnnotation("Override");
}
});
});
});
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
// See issue #866
@Test
public void moveOrAddOverrideAnnotations() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" protected @Override void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> {
type.getMembers()
.forEach(member -> {
if (member instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration) member;
if (methodDeclaration.getAnnotationByName("Override").isPresent()) {
while (methodDeclaration.getAnnotations().isNonEmpty()) {
AnnotationExpr annotationExpr = methodDeclaration.getAnnotations().get(0);
annotationExpr.remove();
}
}
methodDeclaration.addMarkerAnnotation("Override");
}
});
});
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" @Override" + EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
// See issue #865
@Test
public void handleAddingMarkerAnnotation() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> {
type.getMembers()
.forEach(member -> {
if (member instanceof MethodDeclaration) {
MethodDeclaration methodDeclaration = (MethodDeclaration) member;
if (!methodDeclaration.getAnnotationByName("Override").isPresent()) {
methodDeclaration.addMarkerAnnotation("Override");
}
}
});
});
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" @Override" + EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
// See issue #865
@Test
public void handleOverrideMarkerAnnotation() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" protected void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> type.getMembers()
.forEach(member ->
member.ifMethodDeclaration(methodDeclaration -> methodDeclaration.addMarkerAnnotation("Override")
)));
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" @Override" + EOL +
" protected void test() {}" + EOL +
EOL +
" @Override" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
// See issue #865
@Test
public void handleOverrideAnnotationAlternative() {
String code = "public class TestPage extends Page {" + EOL +
EOL +
" protected void test() {}" + EOL +
EOL +
" protected void initializePage() {}" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes()
.forEach(type -> type.getMembers()
.forEach(member -> member.ifMethodDeclaration(methodDeclaration -> methodDeclaration.addAnnotation("Override"))));
assertEquals("public class TestPage extends Page {" + EOL +
EOL +
" @Override()" + EOL +
" protected void test() {}" + EOL +
EOL +
" @Override()" + EOL +
" protected void initializePage() {}" + EOL +
"}", LexicalPreservingPrinter.print(cu));
}
@Test
public void invokeModifierVisitor() {
String code = "class A {" + EOL
+ " Object f() {" + EOL
+ " return (Comparator<Map.Entry<K, V>> & Serializable)(c1, c2) -> c1.getKey().compareTo(c2.getKey()); " + EOL
+ "}}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.accept(new ModifierVisitor<>(), null);
}
@Test
public void handleDeprecatedAnnotationFinalClass() {
String code = "public final class A {}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes().forEach(type -> type.addAndGetAnnotation(Deprecated.class));
assertEquals("@Deprecated()" + EOL +
"public final class A {}" , LexicalPreservingPrinter.print(cu));
}
@Test
public void handleDeprecatedAnnotationAbstractClass() {
String code = "public abstract class A {}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.getTypes().forEach(type -> type.addAndGetAnnotation(Deprecated.class));
assertEquals("@Deprecated()" + EOL +
"public abstract class A {}" , LexicalPreservingPrinter.print(cu));
}
@Test
public void issue1244() {
String code = "public class Foo {" + EOL + EOL
+ "// Some comment" + EOL + EOL // does work with only one \n
+ "public void writeExternal() {}" + EOL + "}";
CompilationUnit originalCu = JavaParser.parse(code);
CompilationUnit cu = LexicalPreservingPrinter.setup(originalCu);
cu.findAll(ClassOrInterfaceDeclaration.class).stream().forEach(c -> {
List<MethodDeclaration> methods = c.getMethodsByName("writeExternal");
for (MethodDeclaration method : methods) {
c.remove(method);
}
});
assertEqualsNoEol("public class Foo {\n" +
"// Some comment\n\n" +
"}", LexicalPreservingPrinter.print(cu));
}
static class AddFooCallModifierVisitor extends ModifierVisitor<Void> {
@Override
public Visitable visit(MethodCallExpr n, Void arg) {
// Add a call to foo() on every found method call
return new MethodCallExpr(n, "foo");
}
}
// See issue 1277
@Test
public void testInvokeModifierVisitor() throws IOException {
String code = "class A {" + EOL +
" public String message = \"hello\";" + EOL +
" void bar() {" + EOL +
" System.out.println(\"hello\");" + EOL +
" }" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.accept(new AddFooCallModifierVisitor(), null);
}
static class CallModifierVisitor extends ModifierVisitor<Void> {
@Override
public Visitable visit(MethodCallExpr n, Void arg) {
// Add a call to foo() on every found method call
return new MethodCallExpr(n.clone(), "foo");
}
}
@Test
public void invokeModifierVisitorIssue1297() {
String code = "class A {" + EOL +
" public void bar() {" + EOL +
" System.out.println(\"hello\");" + EOL +
" System.out.println(\"hello\");" + EOL +
" // comment" + EOL +
" }" + EOL +
"}";
CompilationUnit cu = JavaParser.parse(code);
LexicalPreservingPrinter.setup(cu);
cu.accept(new CallModifierVisitor(), null);
}
}