• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.github.javaparser.generator.core.node;
2 
3 import com.github.javaparser.ast.CompilationUnit;
4 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
5 import com.github.javaparser.ast.body.MethodDeclaration;
6 import com.github.javaparser.generator.NodeGenerator;
7 import com.github.javaparser.metamodel.BaseNodeMetaModel;
8 import com.github.javaparser.metamodel.JavaParserMetaModel;
9 import com.github.javaparser.utils.Pair;
10 import com.github.javaparser.utils.SourceRoot;
11 
12 import java.util.Optional;
13 import java.util.Set;
14 import java.util.function.Consumer;
15 
16 import static com.github.javaparser.StaticJavaParser.parseBodyDeclaration;
17 import static com.github.javaparser.utils.CodeGenerationUtils.f;
18 import static com.github.javaparser.utils.Utils.set;
19 
20 public class TypeCastingGenerator extends NodeGenerator {
21     private final Set<BaseNodeMetaModel> baseNodes = set(
22             JavaParserMetaModel.statementMetaModel,
23             JavaParserMetaModel.expressionMetaModel,
24             JavaParserMetaModel.typeMetaModel,
25             JavaParserMetaModel.moduleDirectiveMetaModel,
26             JavaParserMetaModel.bodyDeclarationMetaModel,
27             JavaParserMetaModel.commentMetaModel
28     );
29 
TypeCastingGenerator(SourceRoot sourceRoot)30     public TypeCastingGenerator(SourceRoot sourceRoot) {
31         super(sourceRoot);
32     }
33 
34     @Override
generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid)35     protected void generateNode(BaseNodeMetaModel nodeMetaModel, CompilationUnit nodeCu, ClassOrInterfaceDeclaration nodeCoid) throws Exception {
36         Pair<CompilationUnit, ClassOrInterfaceDeclaration> baseCode = null;
37         for (BaseNodeMetaModel baseNode : baseNodes) {
38             if(nodeMetaModel == baseNode) {
39                 // We adjust the base models from the child nodes,
40                 // so we don't do anything when we *are* the base model.
41                 return;
42             }
43             if (nodeMetaModel.isInstanceOfMetaModel(baseNode)) {
44                 baseCode = parseNode(baseNode);
45             }
46         }
47 
48         if (baseCode == null) {
49             // Node is not a child of one of the base nodes, so we don't want to generate this method for it.
50             return;
51         }
52 
53         final String typeName = nodeMetaModel.getTypeName();
54         final ClassOrInterfaceDeclaration baseCoid = baseCode.b;
55         final CompilationUnit baseCu = baseCode.a;
56 
57         generateIsType(baseCu, nodeCoid, baseCoid, typeName);
58         generateAsType(baseCu, nodeCoid, baseCoid, typeName);
59         generateToType(nodeCu, baseCu, nodeCoid, baseCoid, typeName);
60         generateIfType(nodeCu, baseCu, nodeCoid, baseCoid, typeName);
61     }
62 
generateAsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName)63     private void generateAsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
64         final MethodDeclaration asTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public %s as%s() { throw new IllegalStateException(f(\"%%s is not an %s\", this)); }", typeName, typeName, typeName));
65         final MethodDeclaration asTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public %s as%s() { return this; }", typeName, typeName));
66         addOrReplaceWhenSameSignature(baseCoid, asTypeBaseMethod);
67         addOrReplaceWhenSameSignature(nodeCoid, asTypeNodeMethod);
68         baseCu.addImport("com.github.javaparser.utils.CodeGenerationUtils.f", true, false);
69     }
70 
generateToType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName)71     private void generateToType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
72         baseCu.addImport(Optional.class);
73         nodeCu.addImport(Optional.class);
74         final MethodDeclaration asTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public Optional<%s> to%s() { return Optional.empty(); }", typeName, typeName, typeName));
75         final MethodDeclaration asTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public Optional<%s> to%s() { return Optional.of(this); }", typeName, typeName));
76         addOrReplaceWhenSameSignature(baseCoid, asTypeBaseMethod);
77         addOrReplaceWhenSameSignature(nodeCoid, asTypeNodeMethod);
78     }
79 
generateIfType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName)80     private void generateIfType(CompilationUnit nodeCu, CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
81         final MethodDeclaration ifTypeBaseMethod = (MethodDeclaration) parseBodyDeclaration(f("public void if%s(Consumer<%s> action) { }", typeName, typeName));
82         final MethodDeclaration ifTypeNodeMethod = (MethodDeclaration) parseBodyDeclaration(f("public void if%s(Consumer<%s> action) { action.accept(this); }", typeName, typeName));
83         addOrReplaceWhenSameSignature(baseCoid, ifTypeBaseMethod);
84         addOrReplaceWhenSameSignature(nodeCoid, ifTypeNodeMethod);
85 
86         baseCu.addImport(Consumer.class);
87         nodeCu.addImport(Consumer.class);
88     }
89 
generateIsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName)90     private void generateIsType(CompilationUnit baseCu, ClassOrInterfaceDeclaration nodeCoid, ClassOrInterfaceDeclaration baseCoid, String typeName) {
91         final MethodDeclaration baseIsTypeMethod = (MethodDeclaration) parseBodyDeclaration(f("public boolean is%s() { return false; }", typeName));
92         final MethodDeclaration overriddenIsTypeMethod = (MethodDeclaration) parseBodyDeclaration(f("@Override public boolean is%s() { return true; }", typeName));
93 
94         addOrReplaceWhenSameSignature(nodeCoid, overriddenIsTypeMethod);
95         addOrReplaceWhenSameSignature(baseCoid, baseIsTypeMethod);
96     }
97 }
98