Skip to content

Commit

Permalink
Merge pull request #1545 from matozoid/issue_1543
Browse files Browse the repository at this point in the history
prettyAlignMethodCallChainsIndentsArgumentsWithBlocksCorrectly
  • Loading branch information
matozoid committed May 11, 2018
2 parents 1a3cabb + 3b70e62 commit 12f3222
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

package com.github.javaparser.printer;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.FieldDeclaration;
Expand Down Expand Up @@ -98,21 +99,20 @@ public void printUseTestVisitor() {
@Test
public void prettyColumnAlignParameters_enabled() {
PrettyPrinterConfiguration config = new PrettyPrinterConfiguration()
.setIndent("\t")
.setColumnAlignParameters(true);

final String EOL = config.getEndOfLineCharacter();

String code = "class Example { void foo(Object arg0,Object arg1){ myMethod(1, 2, 3, 5, Object.class); } }";
String expected = "class Example {" + EOL +
"" + EOL +
"\tvoid foo(Object arg0, Object arg1) {" + EOL +
"\t\tmyMethod(1," + EOL +
"\t\t 2," + EOL +
"\t\t 3," + EOL +
"\t\t 5," + EOL +
"\t\t Object.class);" + EOL +
"\t}" + EOL +
" void foo(Object arg0, Object arg1) {" + EOL +
" myMethod(1," + EOL +
" 2," + EOL +
" 3," + EOL +
" 5," + EOL +
" Object.class);" + EOL +
" }" + EOL +
"}" + EOL +
"";

Expand All @@ -139,21 +139,20 @@ public void prettyColumnAlignParameters_disabled() {
@Test
public void prettyAlignMethodCallChains_enabled() {
PrettyPrinterConfiguration config = new PrettyPrinterConfiguration()
.setIndent("\t")
.setColumnAlignFirstMethodChain(true);

final String EOL = config.getEndOfLineCharacter();

String code = "class Example { void foo() { IntStream.range(0, 10).filter(x -> x % 2 == 0).map(x -> x * IntStream.of(1,3,5,1).sum()).forEach(System.out::println); } }";
String expected = "class Example {" + EOL +
"" + EOL +
"\tvoid foo() {" + EOL +
"\t\tIntStream.range(0, 10)" + EOL +
"\t\t .filter(x -> x % 2 == 0)" + EOL +
"\t\t .map(x -> x * IntStream.of(1, 3, 5, 1)" + EOL +
"\t\t .sum())" + EOL +
"\t\t .forEach(System.out::println);" + EOL +
"\t}" + EOL +
" void foo() {" + EOL +
" IntStream.range(0, 10)" + EOL +
" .filter(x -> x % 2 == 0)" + EOL +
" .map(x -> x * IntStream.of(1, 3, 5, 1)" + EOL +
" .sum())" + EOL +
" .forEach(System.out::println);" + EOL +
" }" + EOL +
"}" + EOL +
"";

Expand Down Expand Up @@ -203,4 +202,24 @@ public void printingInconsistentVariables() {

assertEquals("double a, b;", fieldDeclaration.toString());
}

@Test
public void prettyAlignMethodCallChainsIndentsArgumentsWithBlocksCorrectly() {

CompilationUnit cu = JavaParser.parse("class Foo { void bar() { foo().bar().baz(() -> { boo().baa().bee(); }).bam(); } }");
String printed = new PrettyPrinter(new PrettyPrinterConfiguration().setColumnAlignFirstMethodChain(true))
.print(cu);

assertEqualsNoEol("class Foo {\n" +
"\n" +
" void bar() {\n" +
" foo().bar()\n" +
" .baz(() -> {\n" +
" boo().baa()\n" +
" .bee();\n" +
" })\n" +
" .bam();\n" +
" }\n" +
"}\n", printed);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@

package com.github.javaparser.printer;

import com.github.javaparser.Position;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.comments.BlockComment;
Expand All @@ -30,6 +29,7 @@
import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.modules.*;
import com.github.javaparser.ast.nodeTypes.NodeWithName;
import com.github.javaparser.ast.nodeTypes.NodeWithTypeArguments;
import com.github.javaparser.ast.nodeTypes.NodeWithVariables;
import com.github.javaparser.ast.stmt.*;
Expand All @@ -42,9 +42,8 @@

import static com.github.javaparser.ast.Node.Parsedness.UNPARSABLE;
import static com.github.javaparser.utils.PositionUtils.sortByBeginPosition;
import static com.github.javaparser.utils.Utils.isNullOrEmpty;
import static com.github.javaparser.utils.Utils.normalizeEolInTextBlock;
import static com.github.javaparser.utils.Utils.trimTrailingSpaces;
import static com.github.javaparser.utils.Utils.*;
import static java.util.Comparator.comparingInt;

/**
* Outputs the AST as formatted Java source code.
Expand All @@ -54,35 +53,16 @@
public class PrettyPrintVisitor implements VoidVisitor<Void> {
protected final PrettyPrinterConfiguration configuration;
protected final SourcePrinter printer;
private Deque<Position> methodChainPositions = new LinkedList<>();

public PrettyPrintVisitor(PrettyPrinterConfiguration prettyPrinterConfiguration) {
configuration = prettyPrinterConfiguration;
printer = new SourcePrinter(configuration.getIndent(), configuration.getEndOfLineCharacter());
pushMethodChainPosition(printer.getCursor()); // initialize a default position for methodChainPositions, it is expected by method #resetMethodChainPosition()
}

public String getSource() {
return printer.getSource();
}

public void resetMethodChainPosition(Position position) {
this.methodChainPositions.pop();
this.methodChainPositions.push(position);
}

public void pushMethodChainPosition(Position position) {
this.methodChainPositions.push(position);
}

public Position peekMethodChainPosition() {
return this.methodChainPositions.peek();
}

public Position popMethodChainPosition() {
return this.methodChainPositions.pop();
}

private void printModifiers(final EnumSet<Modifier> modifiers) {
if (modifiers.size() > 0) {
printer.print(modifiers.stream().map(Modifier::asString).collect(Collectors.joining(" ")) + " ");
Expand Down Expand Up @@ -152,22 +132,27 @@ private void printTypeParameters(final NodeList<TypeParameter> args, final Void

private void printArguments(final NodeList<Expression> args, final Void arg) {
printer.print("(");
Position cursorRef = printer.getCursor();
if (configuration.isColumnAlignParameters()) {
printer.indentTo(printer.getCursor().column);
}
if (!isNullOrEmpty(args)) {
for (final Iterator<Expression> i = args.iterator(); i.hasNext(); ) {
final Expression e = i.next();
e.accept(this, arg);
if (i.hasNext()) {
printer.print(",");
if (configuration.isColumnAlignParameters()) {
printer.wrapToColumn(cursorRef.column);
printer.println();
} else {
printer.print(" ");
}
}
}
}
printer.print(")");
if (configuration.isColumnAlignParameters()) {
printer.unindent();
}
}

private void printPrePostFixOptionalList(final NodeList<? extends Visitable> args, final Void arg, String prefix, String separator, String postfix) {
Expand Down Expand Up @@ -732,22 +717,23 @@ public void visit(final SuperExpr n, final Void arg) {
@Override
public void visit(final MethodCallExpr n, final Void arg) {
printComment(n.getComment(), arg);
if (n.getScope().isPresent()) {
n.getScope().get().accept(this, arg);
n.getScope().ifPresent(scope -> {
scope.accept(this, arg);
if (configuration.isColumnAlignFirstMethodChain()) {
if (!(n.getScope().get() instanceof MethodCallExpr) || (!((MethodCallExpr) n.getScope().get()).getScope().isPresent())) {
resetMethodChainPosition(printer.getCursor());
if (!(scope instanceof MethodCallExpr) || !((MethodCallExpr) scope).getScope().isPresent()) {
printer.unindent();
printer.indentToCursor();
} else {
printer.wrapToColumn(peekMethodChainPosition().column);
printer.println();
}
}
printer.print(".");
}
});
printTypeArgs(n, arg);
n.getName().accept(this, arg);
pushMethodChainPosition(printer.getCursor());
printer.duplicateIndent();
printArguments(n.getArguments(), arg);
popMethodChainPosition();
printer.unindent();
}

@Override
Expand Down Expand Up @@ -1464,13 +1450,9 @@ public void visit(NodeList n, Void arg) {
if (configuration.isOrderImports() && n.size() > 0 && n.get(0) instanceof ImportDeclaration) {
//noinspection unchecked
NodeList<ImportDeclaration> modifiableList = new NodeList<>(n);
modifiableList.sort((left, right) -> {
int sort = Integer.compare(left.isStatic() ? 0 : 1, right.isStatic() ? 0 : 1);
if (sort == 0) {
sort = left.getNameAsString().compareTo(right.getNameAsString());
}
return sort;
});
modifiableList.sort(
comparingInt((ImportDeclaration i) -> i.isStatic() ? 0 : 1)
.thenComparing(NodeWithName::getNameAsString));
for (Object node : modifiableList) {
((Node) node).accept(this, arg);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@

package com.github.javaparser.printer;

import sun.reflect.generics.reflectiveObjects.NotImplementedException;

import java.util.function.Function;

import static com.github.javaparser.utils.Utils.EOL;
Expand All @@ -31,26 +33,52 @@
*/
public class PrettyPrinterConfiguration {
public static final int DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY = 5;

private boolean orderImports = false;
private boolean printComments = true;
private boolean printJavadoc = true;
private boolean columnAlignParameters = false;
private boolean columnAlignFirstMethodChain = false;
private String indent = " ";
private int indentSize = 4;
private String endOfLineCharacter = EOL;
private Function<PrettyPrinterConfiguration, PrettyPrintVisitor> visitorFactory = PrettyPrintVisitor::new;
private int maxEnumConstantsToAlignHorizontally = DEFAULT_MAX_ENUM_CONSTANTS_TO_ALIGN_HORIZONTALLY;

/**
* Set the string to use for indenting. For example: "\t", " ", "".
*
* @deprecated use setIndentSize. Tabs are no longer supported.
*/
@Deprecated
public PrettyPrinterConfiguration setIndent(String indent) {
System.err.println("PrettyPrinterConfiguration.setIndent is deprecated, please review the changes.");
indentSize = indent.length();
return this;
}

/**
* @return the string that will be used to indent.
*/
public String getIndent() {
return indent;
StringBuilder indentString = new StringBuilder();
for (int i = 0; i < indentSize; i++) {
indentString.append(' ');
}
return indentString.toString();
}

public int getIndentSize() {
return indentSize;
}

/**
* Set the string to use for indenting. For example: "\t", " ", "".
* Set the size of the indent in spaces.
*/
public PrettyPrinterConfiguration setIndent(String indent) {
this.indent = assertNotNull(indent);
public PrettyPrinterConfiguration setIndentSize(int size) {
if (size < 0) {
throw new IllegalArgumentException("Indent must be >= 0");
}
this.indentSize = size;
return this;
}

Expand Down

0 comments on commit 12f3222

Please sign in to comment.