forked from phoedos/pmd
Add pretty printing for lambdas
This commit is contained in:
@@ -9,11 +9,13 @@ import static net.sourceforge.pmd.util.AssertionUtil.shouldNotReachHere;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
|
||||
import net.sourceforge.pmd.lang.ast.NodeStream;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAmbiguousName;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTAnnotationTypeDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArgumentList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArrayAccess;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTArrayType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTBlock;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCastExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTClassLiteral;
|
||||
@@ -28,8 +30,12 @@ import net.sourceforge.pmd.lang.java.ast.ASTFieldDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTForInit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameter;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTFormalParameters;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTGuard;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTImportDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTIntersectionType;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaParameter;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaParameterList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTList;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLiteral;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
|
||||
@@ -338,6 +344,41 @@ public final class PrettyPrintingUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Void visit(ASTLambdaExpression node, StringBuilder sb) {
|
||||
node.getParameters().acceptVisitor(this, sb);
|
||||
sb.append(" -> ");
|
||||
ASTExpression exprBody = node.getExpression();
|
||||
if (exprBody != null) {
|
||||
exprBody.acceptVisitor(this, sb);
|
||||
} else {
|
||||
sb.append("{ ... }");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTLambdaParameterList node, StringBuilder sb) {
|
||||
if (node.size() == 1) {
|
||||
sb.append(node.get(0).getVarId().getName());
|
||||
return null;
|
||||
} else if (node.isEmpty()) {
|
||||
sb.append("()");
|
||||
return null;
|
||||
}
|
||||
|
||||
sb.append('(');
|
||||
sb.append(node.get(0).getVarId().getName());
|
||||
node.toStream().drop(1).forEach(it -> {
|
||||
sb.append(", ");
|
||||
sb.append(it.getVarId().getName());
|
||||
});
|
||||
sb.append(')');
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Void visit(ASTMethodCall node, StringBuilder sb) {
|
||||
addQualifier(node, sb);
|
||||
|
@@ -20,9 +20,12 @@ import org.junit.jupiter.api.Test;
|
||||
import net.sourceforge.pmd.lang.java.BaseParserTest;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTConstructorCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTLambdaExpression;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodCall;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodDeclaration;
|
||||
import net.sourceforge.pmd.lang.java.ast.ASTMethodReference;
|
||||
import net.sourceforge.pmd.lang.java.ast.ExpressionParsingCtx;
|
||||
import net.sourceforge.pmd.util.StringUtil;
|
||||
|
||||
class PrettyPrintingUtilTest extends BaseParserTest {
|
||||
@@ -47,42 +50,53 @@ class PrettyPrintingUtilTest extends BaseParserTest {
|
||||
|
||||
@Test
|
||||
void ppMethodCallArgsTooBig() {
|
||||
ASTCompilationUnit root = java.parse("class A { { this.foo(\"a long string\", 12, 12, 12, 12, 12); } }");
|
||||
@NonNull ASTMethodCall m = root.descendants(ASTMethodCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("this.foo(\"a long string\", 12...)"));
|
||||
testPrettyPrint("this.foo(\"a long string\", 12, 12, 12, 12, 12)",
|
||||
ASTMethodCall.class, "this.foo(\"a long string\", 12...)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodCallOnCast() {
|
||||
ASTCompilationUnit root = java.parse("class A { { ((Object) this).foo(12); } }");
|
||||
@NonNull ASTMethodCall m = root.descendants(ASTMethodCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("((Object) this).foo(12)"));
|
||||
testPrettyPrintIdentity("((Object) this).foo(12)", ASTMethodCall.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodRef() {
|
||||
ASTCompilationUnit root = java.parse("class A { { foo(ASTW::meth); } }");
|
||||
@NonNull ASTMethodReference m = root.descendants(ASTMethodReference.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("ASTW::meth"));
|
||||
testPrettyPrintIdentity("ASTW::meth", ASTMethodReference.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppCtorCall() {
|
||||
ASTCompilationUnit root = java.parse("class A { { new Foo(1); } }");
|
||||
@NonNull ASTConstructorCall m = root.descendants(ASTConstructorCall.class).firstOrThrow();
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("new Foo(1)"));
|
||||
testPrettyPrintIdentity("new Foo(1)", ASTConstructorCall.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppMethodRefWithTyArgs() {
|
||||
ASTCompilationUnit root = java.parse("class A { { foo(ASTW::<String>meth); } }");
|
||||
@NonNull ASTMethodReference m = root.descendants(ASTMethodReference.class).firstOrThrow();
|
||||
testPrettyPrint("foo(ASTW::<String>meth)", ASTMethodReference.class,
|
||||
"ASTW::<String>meth");
|
||||
}
|
||||
|
||||
assertThat(prettyPrint(m), contentEquals("ASTW::<String>meth"));
|
||||
@Test
|
||||
void ppLambdaExpr() {
|
||||
testPrettyPrintIdentity("(a, b) -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrintIdentity("() -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrintIdentity("x -> new Foo()", ASTLambdaExpression.class);
|
||||
testPrettyPrint("(x) -> new Foo()", ASTLambdaExpression.class, "x -> new Foo()");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ppLambdaBlock() {
|
||||
testPrettyPrint("(a, b) -> {return new Foo(); }", ASTLambdaExpression.class,
|
||||
"(a, b) -> { ... }");
|
||||
}
|
||||
|
||||
private <T extends ASTExpression> void testPrettyPrint(String expr, Class<T> nodeTy, String expected) {
|
||||
ASTCompilationUnit root = java.parse("class A { { Object x = " + expr + "; } }");
|
||||
@NonNull T node = root.descendants(nodeTy).firstOrThrow();
|
||||
assertThat(prettyPrint(node), contentEquals(expected));
|
||||
}
|
||||
|
||||
private <T extends ASTExpression> void testPrettyPrintIdentity(String expr, Class<T> nodeTy) {
|
||||
testPrettyPrint(expr, nodeTy, expr);
|
||||
}
|
||||
|
||||
private static Matcher<CharSequence> contentEquals(String str) {
|
||||
|
Reference in New Issue
Block a user