Home | History | Annotate | Download | only in node
      1 package com.github.javaparser.generator.core.node;
      2 
      3 import com.github.javaparser.ast.CompilationUnit;
      4 import com.github.javaparser.ast.Node;
      5 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
      6 import com.github.javaparser.ast.body.MethodDeclaration;
      7 import com.github.javaparser.ast.stmt.BlockStmt;
      8 import com.github.javaparser.generator.NodeGenerator;
      9 import com.github.javaparser.utils.SourceRoot;
     10 import com.github.javaparser.metamodel.BaseNodeMetaModel;
     11 import com.github.javaparser.metamodel.PropertyMetaModel;
     12 
     13 import static com.github.javaparser.JavaParser.*;
     14 import static com.github.javaparser.utils.CodeGenerationUtils.f;
     15 import static com.github.javaparser.utils.Utils.capitalize;
     16 
     17 
     18 public class RemoveMethodGenerator extends NodeGenerator {
     19     public RemoveMethodGenerator(SourceRoot sourceRoot) {
     20         super(sourceRoot);
     21     }
     22 
     23     @Override
     24     protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) {
     25         MethodDeclaration removeNodeMethod = (MethodDeclaration) parseBodyDeclaration("public boolean remove(Node node) {}");
     26         nodeCu.addImport(Node.class);
     27         nodeMetaModel.getSuperNodeMetaModel().ifPresent(s -> annotateOverridden(removeNodeMethod));
     28 
     29         final BlockStmt body = removeNodeMethod.getBody().get();
     30 
     31         body.addStatement("if (node == null) return false;");
     32 
     33         for (PropertyMetaModel property : nodeMetaModel.getDeclaredPropertyMetaModels()) {
     34             if (!property.isNode()) {
     35                 continue;
     36             }
     37             String check;
     38             if (property.isNodeList()) {
     39                 check = nodeListCheck(property);
     40             } else {
     41                 if (property.isRequired()) {
     42                     continue;
     43                 }
     44                 String removeAttributeMethodName = generateRemoveMethodForAttribute(nodeCoid, nodeMetaModel, property);
     45                 check = attributeCheck(property, removeAttributeMethodName);
     46             }
     47             if (property.isOptional()) {
     48                 check = f("if (%s != null) { %s }", property.getName(), check);
     49             }
     50             body.addStatement(check);
     51         }
     52         if (nodeMetaModel.getSuperNodeMetaModel().isPresent()) {
     53             body.addStatement("return super.remove(node);");
     54         } else {
     55             body.addStatement("return false;");
     56         }
     57 
     58         addOrReplaceWhenSameSignature(nodeCoid, removeNodeMethod);
     59     }
     60 
     61     private String attributeCheck(PropertyMetaModel property, String removeAttributeMethodName) {
     62         return f("if (node == %s) {" +
     63                 "    %s();" +
     64                 "    return true;\n" +
     65                 "}", property.getName(), removeAttributeMethodName);
     66     }
     67 
     68     private String nodeListCheck(PropertyMetaModel property) {
     69         return f("for (int i = 0; i < %s.size(); i++) {" +
     70                 "  if (%s.get(i) == node) {" +
     71                 "    %s.remove(i);" +
     72                 "    return true;" +
     73                 "  }" +
     74                 "}", property.getName(), property.getName(), property.getName());
     75     }
     76 
     77     private String generateRemoveMethodForAttribute(ClassOrInterfaceDeclaration nodeCoid, BaseNodeMetaModel nodeMetaModel, PropertyMetaModel property) {
     78         final String methodName = "remove" + capitalize(property.getName());
     79         final MethodDeclaration removeMethod = (MethodDeclaration) parseBodyDeclaration(f("public %s %s() {}", nodeMetaModel.getTypeName(), methodName));
     80 
     81         final BlockStmt block = removeMethod.getBody().get();
     82         block.addStatement(f("return %s((%s) null);", property.getSetterMethodName(), property.getTypeNameForSetter()));
     83 
     84         addOrReplaceWhenSameSignature(nodeCoid, removeMethod);
     85         return methodName;
     86     }
     87 }
     88