• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package com.github.javaparser.generator.metamodel;
2 
3 import com.github.javaparser.ast.AllFieldsConstructor;
4 import com.github.javaparser.ast.Node;
5 import com.github.javaparser.ast.NodeList;
6 import com.github.javaparser.ast.stmt.Statement;
7 
8 import java.lang.annotation.Annotation;
9 import java.lang.reflect.Constructor;
10 import java.lang.reflect.Field;
11 
12 import static com.github.javaparser.JavaParser.parseStatement;
13 import static com.github.javaparser.generator.metamodel.MetaModelGenerator.nodeMetaModelFieldName;
14 import static com.github.javaparser.generator.metamodel.MetaModelGenerator.propertyMetaModelFieldName;
15 import static com.github.javaparser.utils.CodeGenerationUtils.f;
16 
17 class InitializeConstructorParametersStatementsGenerator {
generate(Class<? extends Node> nodeClass, NodeList<Statement> initializeConstructorParametersStatements)18     void generate(Class<? extends Node> nodeClass, NodeList<Statement> initializeConstructorParametersStatements) {
19         if (nodeClass == Node.class) {
20             return;
21         }
22         Constructor<?> constructor = findAllFieldsConstructor(nodeClass);
23         for (java.lang.reflect.Parameter parameter : constructor.getParameters()) {
24             Field field = findFieldInClass(nodeClass, parameter.getName());
25 
26             String addFieldStatement = f("%s.getConstructorParameters().add(%s.%s);",
27                     nodeMetaModelFieldName(nodeClass),
28                     nodeMetaModelFieldName(field.getDeclaringClass()),
29                     propertyMetaModelFieldName(field));
30 
31             initializeConstructorParametersStatements.add(parseStatement(addFieldStatement));
32         }
33     }
34 
findFieldInClass(Class<?> nodeClass, String name)35     private Field findFieldInClass(Class<?> nodeClass, String name) {
36         Class<?> searchClass = nodeClass;
37         do {
38             for (Field field : searchClass.getDeclaredFields()) {
39                 if (field.getName().equals(name)) {
40                     return field;
41                 }
42             }
43             searchClass = searchClass.getSuperclass();
44         } while (searchClass != null);
45         throw new AssertionError(f("Couldn't find constructor parameter %s as a field, class %s", name, nodeClass.getSimpleName()));
46     }
47 
findAllFieldsConstructor(Class<? extends Node> nodeClass)48     private Constructor<?> findAllFieldsConstructor(Class<? extends Node> nodeClass) {
49         for (Constructor<?> constructor : nodeClass.getDeclaredConstructors()) {
50             for (Annotation annotation : constructor.getAnnotations()) {
51                 if (annotation.annotationType() == AllFieldsConstructor.class) {
52                     return constructor;
53                 }
54             }
55         }
56         throw new AssertionError(f("Node class %s has no constructor annotated with @AllFieldsConstructor", nodeClass.getSimpleName()));
57     }
58 }
59