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