• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.github.javaparser.generator.metamodel;
2 
3 import com.github.javaparser.ParserConfiguration;
4 import com.github.javaparser.StaticJavaParser;
5 import com.github.javaparser.ast.*;
6 import com.github.javaparser.ast.body.*;
7 import com.github.javaparser.ast.comments.BlockComment;
8 import com.github.javaparser.ast.comments.Comment;
9 import com.github.javaparser.ast.comments.JavadocComment;
10 import com.github.javaparser.ast.comments.LineComment;
11 import com.github.javaparser.ast.expr.*;
12 import com.github.javaparser.ast.modules.*;
13 import com.github.javaparser.ast.stmt.*;
14 import com.github.javaparser.ast.type.*;
15 import com.github.javaparser.printer.PrettyPrinter;
16 import com.github.javaparser.printer.PrettyPrinterConfiguration;
17 import com.github.javaparser.utils.SourceRoot;
18 
19 import java.lang.reflect.Field;
20 import java.nio.file.Path;
21 import java.nio.file.Paths;
22 import java.util.ArrayList;
23 import java.util.Comparator;
24 import java.util.List;
25 
26 import static com.github.javaparser.utils.Utils.decapitalize;
27 
28 public class MetaModelGenerator {
29     static final String BASE_NODE_META_MODEL = "BaseNodeMetaModel";
30     private static List<Class<? extends Node>> ALL_NODE_CLASSES = new ArrayList<Class<? extends Node>>() {{
31         /* Base classes go first, so we don't have to do any sorting to make sure
32          generated classes can refer to their base generated classes without
33          being afraid those are not initialized yet. */
34         add(Node.class);
35 
36         add(BodyDeclaration.class);
37         add(CallableDeclaration.class);
38         add(Statement.class);
39         add(Expression.class);
40         add(Type.class);
41 
42         add(AnnotationExpr.class);
43         add(TypeDeclaration.class);
44         add(ReferenceType.class);
45 
46         add(LiteralExpr.class);
47         add(LiteralStringValueExpr.class);
48         add(StringLiteralExpr.class);
49 
50         add(ModuleDeclaration.class);
51         add(ModuleDirective.class);
52 
53         //
54         add(ArrayCreationLevel.class);
55         add(CompilationUnit.class);
56         add(PackageDeclaration.class);
57         add(Modifier.class);
58 
59         add(AnnotationDeclaration.class);
60         add(AnnotationMemberDeclaration.class);
61         add(ClassOrInterfaceDeclaration.class);
62         add(ConstructorDeclaration.class);
63         add(EnumConstantDeclaration.class);
64         add(EnumDeclaration.class);
65         add(FieldDeclaration.class);
66         add(InitializerDeclaration.class);
67         add(MethodDeclaration.class);
68         add(Parameter.class);
69         add(ReceiverParameter.class);
70         add(VariableDeclarator.class);
71 
72         add(Comment.class);
73         add(BlockComment.class);
74         add(JavadocComment.class);
75         add(LineComment.class);
76 
77         add(ArrayAccessExpr.class);
78         add(ArrayCreationExpr.class);
79         add(ArrayInitializerExpr.class);
80         add(AssignExpr.class);
81         add(BinaryExpr.class);
82         add(BooleanLiteralExpr.class);
83         add(CastExpr.class);
84         add(CharLiteralExpr.class);
85         add(ClassExpr.class);
86         add(ConditionalExpr.class);
87         add(DoubleLiteralExpr.class);
88         add(EnclosedExpr.class);
89         add(FieldAccessExpr.class);
90         add(InstanceOfExpr.class);
91         add(IntegerLiteralExpr.class);
92         add(LambdaExpr.class);
93         add(LongLiteralExpr.class);
94         add(MarkerAnnotationExpr.class);
95         add(MemberValuePair.class);
96         add(MethodCallExpr.class);
97         add(MethodReferenceExpr.class);
98         add(NameExpr.class);
99         add(Name.class);
100         add(NormalAnnotationExpr.class);
101         add(NullLiteralExpr.class);
102         add(ObjectCreationExpr.class);
103         add(SimpleName.class);
104         add(SingleMemberAnnotationExpr.class);
105         add(SuperExpr.class);
106         add(ThisExpr.class);
107         add(TypeExpr.class);
108         add(UnaryExpr.class);
109         add(VariableDeclarationExpr.class);
110         add(SwitchExpr.class);
111 
112         add(ImportDeclaration.class);
113 
114         add(AssertStmt.class);
115         add(BlockStmt.class);
116         add(BreakStmt.class);
117         add(CatchClause.class);
118         add(ContinueStmt.class);
119         add(DoStmt.class);
120         add(EmptyStmt.class);
121         add(ExplicitConstructorInvocationStmt.class);
122         add(ExpressionStmt.class);
123         add(ForEachStmt.class);
124         add(ForStmt.class);
125         add(IfStmt.class);
126         add(LabeledStmt.class);
127         add(ReturnStmt.class);
128         add(SwitchEntry.class);
129         add(SwitchStmt.class);
130         add(SynchronizedStmt.class);
131         add(ThrowStmt.class);
132         add(TryStmt.class);
133         add(LocalClassDeclarationStmt.class);
134         add(WhileStmt.class);
135         add(UnparsableStmt.class);
136 
137         add(ArrayType.class);
138         add(ClassOrInterfaceType.class);
139         add(IntersectionType.class);
140         add(PrimitiveType.class);
141         add(TypeParameter.class);
142         add(UnionType.class);
143         add(UnknownType.class);
144         add(VoidType.class);
145         add(WildcardType.class);
146         add(VarType.class);
147 
148         add(ModuleRequiresDirective.class);
149         add(ModuleExportsDirective.class);
150         add(ModuleProvidesDirective.class);
151         add(ModuleUsesDirective.class);
152         add(ModuleOpensDirective.class);
153     }};
154 
155     static String METAMODEL_PACKAGE = "com.github.javaparser.metamodel";
156 
main(String[] args)157     public static void main(String[] args) throws NoSuchMethodException {
158         if (args.length != 1) {
159             throw new RuntimeException("Need 1 parameter: the JavaParser source checkout root directory.");
160         }
161         final Path root = Paths.get(args[0], "..", "javaparser-core", "src", "main", "java");
162         final ParserConfiguration parserConfiguration = new ParserConfiguration()
163                 .setLanguageLevel(ParserConfiguration.LanguageLevel.RAW)
164                 .setStoreTokens(false);
165         final SourceRoot sourceRoot = new SourceRoot(root, parserConfiguration);
166         sourceRoot.setPrinter(new PrettyPrinter(new PrettyPrinterConfiguration().setEndOfLineCharacter("\n"))::print);
167         StaticJavaParser.setConfiguration(parserConfiguration);
168 
169         new MetaModelGenerator().run(sourceRoot);
170 
171         sourceRoot.saveAll();
172     }
173 
run(SourceRoot sourceRoot)174     private void run(SourceRoot sourceRoot) throws NoSuchMethodException {
175         final CompilationUnit javaParserMetaModel = sourceRoot.parse(METAMODEL_PACKAGE, "JavaParserMetaModel.java");
176 
177         generateNodeMetaModels(javaParserMetaModel, sourceRoot);
178     }
179 
generateNodeMetaModels(CompilationUnit javaParserMetaModelCu, SourceRoot sourceRoot)180     private void generateNodeMetaModels(CompilationUnit javaParserMetaModelCu, SourceRoot sourceRoot) throws NoSuchMethodException {
181         final ClassOrInterfaceDeclaration metaModelCoid = javaParserMetaModelCu.getClassByName("JavaParserMetaModel").get();
182         final NodeList<Statement> initializeNodeMetaModelsStatements = metaModelCoid.getMethodsByName("initializeNodeMetaModels").get(0).getBody().get().getStatements();
183         final NodeList<Statement> initializePropertyMetaModelsStatements = metaModelCoid.getMethodsByName("initializePropertyMetaModels").get(0).getBody().get().getStatements();
184         final NodeList<Statement> initializeConstructorParametersStatements = metaModelCoid.getMethodsByName("initializeConstructorParameters").get(0).getBody().get().getStatements();
185         initializeNodeMetaModelsStatements.clear();
186         initializePropertyMetaModelsStatements.clear();
187         initializeConstructorParametersStatements.clear();
188 
189         metaModelCoid.getFields().stream().filter(f -> f.getVariable(0).getNameAsString().endsWith("MetaModel")).forEach(Node::remove);
190         final NodeMetaModelGenerator nodeMetaModelGenerator = new NodeMetaModelGenerator();
191         for (Class<? extends Node> nodeClass : ALL_NODE_CLASSES) {
192             nodeMetaModelGenerator.generate(nodeClass, metaModelCoid, initializeNodeMetaModelsStatements, initializePropertyMetaModelsStatements, initializeConstructorParametersStatements, sourceRoot);
193         }
194 
195         initializeNodeMetaModelsStatements.sort(Comparator.comparing(Node::toString));
196     }
197 
isNode(Class<?> c)198     static boolean isNode(Class<?> c) {
199         return Node.class.isAssignableFrom(c);
200     }
201 
nodeMetaModelName(Class<?> c)202     static String nodeMetaModelName(Class<?> c) {
203         return c.getSimpleName() + "MetaModel";
204     }
205 
propertyMetaModelFieldName(Field field)206     static String propertyMetaModelFieldName(Field field) {
207         return field.getName() + "PropertyMetaModel";
208     }
209 
nodeMetaModelFieldName(Class<?> nodeClass)210     static String nodeMetaModelFieldName(Class<?> nodeClass) {
211         return decapitalize(nodeMetaModelName(nodeClass));
212     }
213 
214 }
215