diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java index 118b5655b2..f60e1dadf5 100644 --- a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java +++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/CoreGenerator.java @@ -30,6 +30,7 @@ public static void main(String[] args) throws Exception { new HashCodeVisitorGenerator(javaParser, sourceRoot).generate(); new CloneVisitorGenerator(javaParser, sourceRoot).generate(); new TreeStructureVisitorGenerator(javaParser, sourceRoot).generate(); + new ModifierVisitorGenerator(javaParser, sourceRoot).generate(); new GetNodeListsGenerator(javaParser, sourceRoot).generate(); new PropertyGenerator(javaParser, sourceRoot).generate(); diff --git a/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java new file mode 100644 index 0000000000..45fcdb7336 --- /dev/null +++ b/javaparser-core-generators/src/main/java/com/github/javaparser/generator/core/visitor/ModifierVisitorGenerator.java @@ -0,0 +1,68 @@ +package com.github.javaparser.generator.core.visitor; + +import com.github.javaparser.JavaParser; +import com.github.javaparser.ast.CompilationUnit; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.stmt.BlockStmt; +import com.github.javaparser.generator.VisitorGenerator; +import com.github.javaparser.generator.utils.SeparatedItemStringBuilder; +import com.github.javaparser.generator.utils.SourceRoot; +import com.github.javaparser.metamodel.BaseNodeMetaModel; +import com.github.javaparser.metamodel.PropertyMetaModel; + +import static com.github.javaparser.generator.utils.GeneratorUtils.f; + +/** + * Generates JavaParser's EqualsVisitor. + */ +public class ModifierVisitorGenerator extends VisitorGenerator { + public ModifierVisitorGenerator(JavaParser javaParser, SourceRoot sourceRoot) { + super(javaParser, sourceRoot, "com.github.javaparser.ast.visitor", "ModifierVisitor", "Visitable", "A", true); + } + + @Override + protected void generateVisitMethodBody(BaseNodeMetaModel node, MethodDeclaration visitMethod, CompilationUnit compilationUnit) { + BlockStmt body = visitMethod.getBody().get(); + body.getStatements().clear(); + + String s1 = "Expression target = (Expression) n.getTarget().accept(this, arg);" + + " if (target == null) return null;" + + " n.setTarget(target);"; + + String s = "n.setExtendedTypes(modifyList(n.getExtendedTypes(), arg));"; + String s2 = "n.getPackageDeclaration().ifPresent(p -> n.setPackageDeclaration((PackageDeclaration) p.accept(this, arg)));"; + + + for (PropertyMetaModel field : node.getAllPropertyMetaModels()) { + final String getter = field.getGetterMethodName() + "()"; + if (field.getNodeReference().isPresent()) { + if (field.isNodeList()) { + body.addStatement(f("NodeList<%s> %s = modifyList(n.%s().orElse(null), arg);", field.getTypeNameGenerified(), field.getName(), getter)); + } else { + body.addStatement(f("%s %s = (Expression) n.getTarget().accept(this, arg);", field.getTypeNameGenerified(), field.getName(), getter)); + } + } + } + + SeparatedItemStringBuilder builder = new SeparatedItemStringBuilder(f("%s r = new %s(", node.getTypeNameGenerified(), node.getTypeNameGenerified()), ",", ");"); + builder.append("_n.getRange().orElse(null)"); + for (PropertyMetaModel field : node.getConstructorParameters()) { + if (field.getName().equals("comment")) { + continue; + } + if (field.getNodeReference().isPresent()) { + builder.append(field.getName()); + } else { + builder.append(f("_n.%s()", field.getGetterMethodName())); + } + } + + body.addStatement(builder.toString()); + body.addStatement("r.setComment(comment);"); + body.addStatement("return r;"); + } +} + +// TODO FieldDeclaration.variables may not be empty +// TODO BinaryExpr if left==null return right, etc. +// TODO VariableDeclarationExpr.variables may not be empty \ No newline at end of file diff --git a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java index 58223b84d4..40c943cc4a 100644 --- a/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java +++ b/javaparser-core/src/main/java/com/github/javaparser/ast/visitor/ModifierVisitor.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; /** * This visitor can be used to save time when some specific nodes needs @@ -46,14 +47,6 @@ */ public class ModifierVisitor implements GenericVisitor { - private void removeNulls(final List list) { - for (int i = list.size() - 1; i >= 0; i--) { - if (list.get(i) == null) { - list.remove(i); - } - } - } - @Override public Visitable visit(final AnnotationDeclaration n, final A arg) { visitAnnotations(n, arg); @@ -214,17 +207,10 @@ public Visitable visit(final ClassOrInterfaceDeclaration n, final A arg) { n.setTypeParameters(modifyList(n.getTypeParameters(), arg)); n.setExtendedTypes(modifyList(n.getExtendedTypes(), arg)); n.setImplementedTypes(modifyList(n.getImplementedTypes(), arg)); - n.setMembers((NodeList>) n.getMembers().accept(this, arg)); + n.setMembers(modifyList(n.getMembers(), arg)); return n; } - private NodeList modifyList(NodeList list, A arg) { - if (list == null) { - return null; - } - return (NodeList) list.accept(this, arg); - } - @Override public Visitable visit(final ClassOrInterfaceType n, final A arg) { visitComment(n, arg); @@ -239,9 +225,7 @@ public Visitable visit(final ClassOrInterfaceType n, final A arg) { @Override public Visitable visit(final CompilationUnit n, final A arg) { visitComment(n, arg); - if (n.getPackageDeclaration().isPresent()) { - n.setPackageDeclaration((PackageDeclaration) n.getPackageDeclaration().get().accept(this, arg)); - } + n.getPackageDeclaration().ifPresent(p -> n.setPackageDeclaration((PackageDeclaration) p.accept(this, arg))); n.setImports((NodeList) n.getImports().accept(this, arg)); n.setTypes((NodeList>) n.getTypes().accept(this, arg)); return n; @@ -795,7 +779,8 @@ public Visitable visit(final LambdaExpr n, final A arg) { @Override public Visitable visit(final MethodReferenceExpr n, final A arg) { visitComment(n, arg); - n.setTypeArguments(modifyList(n.getTypeArguments().orElse(null), arg)); + NodeList typeArguments = modifyList(n.getTypeArguments(), arg); + n.setTypeArguments(typeArguments); if (n.getScope() != null) { n.setScope((Expression) n.getScope().accept(this, arg)); } @@ -861,4 +846,13 @@ private void visitComment(Node n, final A arg) { n.setComment((Comment) n.getComment().get().accept(this, arg)); } } + + private NodeList modifyList(NodeList list, A arg) { + return (NodeList) list.accept(this, arg); + } + + private NodeList modifyList(Optional> list, A arg) { + return list.map(ns -> modifyList(list, arg)).orElse(null); + } + } diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java index 3848eaff78..6e5136a5de 100644 --- a/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java +++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/visitor/ModifierVisitorTest.java @@ -21,15 +21,22 @@ package com.github.javaparser.ast.visitor; +import com.github.javaparser.JavaParser; import com.github.javaparser.ast.NodeList; +import com.github.javaparser.ast.body.BodyDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.IntegerLiteralExpr; import com.github.javaparser.ast.expr.StringLiteralExpr; import org.junit.Test; +import static com.github.javaparser.JavaParser.parseExpression; +import static com.github.javaparser.utils.Utils.EOL; import static org.junit.Assert.assertEquals; public class ModifierVisitorTest { @Test - public void x() { + public void makeSureParentListsCanBeModified() { NodeList list = new NodeList<>(); list.add(new StringLiteralExpr("t")); list.add(new StringLiteralExpr("a")); @@ -63,4 +70,58 @@ public Visitable visit(final StringLiteralExpr n, final Void arg) { assertEquals("c", list.get(5).getValue()); assertEquals(6, list.size()); } + + @Test + public void binaryExprReturnsLeftExpressionWhenRightSideIsRemoved() { + Expression expression = parseExpression("1+2"); + Visitable result = expression.accept(new ModifierVisitor() { + public Visitable visit(IntegerLiteralExpr integerLiteralExpr, Void arg) { + if (integerLiteralExpr.getValue().equals("1")) { + return null; + } + return integerLiteralExpr; + } + }, null); + assertEquals("2", result.toString()); + } + + @Test + public void binaryExprReturnsRightExpressionWhenLeftSideIsRemoved() { + final Expression expression = parseExpression("1+2"); + final Visitable result = expression.accept(new ModifierVisitor() { + public Visitable visit(IntegerLiteralExpr integerLiteralExpr, Void arg) { + if (integerLiteralExpr.getValue().equals("2")) { + return null; + } + return integerLiteralExpr; + } + }, null); + assertEquals("1", result.toString()); + } + + @Test + public void fieldDeclarationCantSurviveWithoutVariables() { + final BodyDeclaration bodyDeclaration = JavaParser.parseClassBodyDeclaration("int x=1;"); + + final Visitable result = bodyDeclaration.accept(new ModifierVisitor() { + public Visitable visit(VariableDeclarator x, Void arg) { + return null; + } + }, null); + + assertEquals(null, result); + } + + @Test + public void variableDeclarationCantSurviveWithoutVariables() { + final BodyDeclaration bodyDeclaration = JavaParser.parseClassBodyDeclaration("void x() {int x=1;}"); + + final Visitable result = bodyDeclaration.accept(new ModifierVisitor() { + public Visitable visit(VariableDeclarator x, Void arg) { + return null; + } + }, null); + + assertEquals("void x() {" + EOL + "}", result.toString()); + } }