Skip to content

Commit

Permalink
Reorganize metamodel generator and fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
matozoid committed Jan 18, 2017
1 parent d34926f commit 807a312
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 88 deletions.
Expand Up @@ -25,6 +25,7 @@
import com.github.javaparser.ast.NodeList; import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.expr.AnnotationExpr; import com.github.javaparser.ast.expr.AnnotationExpr;
import com.github.javaparser.ast.expr.SimpleName; import com.github.javaparser.ast.expr.SimpleName;
import com.github.javaparser.ast.nodeTypes.NodeWithAnnotations;
import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName; import com.github.javaparser.ast.nodeTypes.NodeWithSimpleName;
import com.github.javaparser.ast.observer.ObservableProperty; import com.github.javaparser.ast.observer.ObservableProperty;
import com.github.javaparser.ast.visitor.GenericVisitor; import com.github.javaparser.ast.visitor.GenericVisitor;
Expand All @@ -44,12 +45,12 @@
* @author Julio Vilmar Gesser * @author Julio Vilmar Gesser
* @see com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters * @see com.github.javaparser.ast.nodeTypes.NodeWithTypeParameters
*/ */
public final class TypeParameter extends ReferenceType<TypeParameter> implements NodeWithSimpleName<TypeParameter> { public final class TypeParameter extends ReferenceType<TypeParameter> implements
NodeWithSimpleName<TypeParameter>,
NodeWithAnnotations<TypeParameter> {


private SimpleName name; private SimpleName name;


private NodeList<AnnotationExpr> annotations;

private NodeList<ClassOrInterfaceType> typeBound; private NodeList<ClassOrInterfaceType> typeBound;


public TypeParameter() { public TypeParameter() {
Expand Down Expand Up @@ -132,16 +133,9 @@ public TypeParameter setTypeBound(final NodeList<ClassOrInterfaceType> typeBound
return this; return this;
} }


@Override
public NodeList<AnnotationExpr> getAnnotations() {
return annotations;
}

@Override @Override
public TypeParameter setAnnotations(NodeList<AnnotationExpr> annotations) { public TypeParameter setAnnotations(NodeList<AnnotationExpr> annotations) {
notifyPropertyChange(ObservableProperty.ANNOTATIONS, this.annotations, annotations); super.setAnnotations(annotations);
this.annotations = assertNotNull(annotations);
setAsParentNodeOf(this.annotations);
return this; return this;
} }
} }
Expand Up @@ -8,7 +8,6 @@ public class TypeParameterMetaModel extends ClassMetaModel {


TypeParameterMetaModel(JavaParserMetaModel parent, Optional<ClassMetaModel> superClassMetaModel) { TypeParameterMetaModel(JavaParserMetaModel parent, Optional<ClassMetaModel> superClassMetaModel) {
super(superClassMetaModel, parent, com.github.javaparser.ast.type.TypeParameter.class, "TypeParameter", "com.github.javaparser.ast.type.TypeParameter", "com.github.javaparser.ast.type", false); super(superClassMetaModel, parent, com.github.javaparser.ast.type.TypeParameter.class, "TypeParameter", "com.github.javaparser.ast.type.TypeParameter", "com.github.javaparser.ast.type", false);
fieldMetaModels.add(new FieldMetaModel(this, "getAnnotations", "setAnnotations", "annotations", com.github.javaparser.ast.expr.AnnotationExpr.class, getField("annotations"), true, false, true, false, false));
fieldMetaModels.add(new FieldMetaModel(this, "getName", "setName", "name", com.github.javaparser.ast.expr.SimpleName.class, getField("name"), true, false, false, false, false)); fieldMetaModels.add(new FieldMetaModel(this, "getName", "setName", "name", com.github.javaparser.ast.expr.SimpleName.class, getField("name"), true, false, false, false, false));
fieldMetaModels.add(new FieldMetaModel(this, "getTypeBound", "setTypeBound", "typeBound", com.github.javaparser.ast.type.ClassOrInterfaceType.class, getField("typeBound"), true, false, true, false, false)); fieldMetaModels.add(new FieldMetaModel(this, "getTypeBound", "setTypeBound", "typeBound", com.github.javaparser.ast.type.ClassOrInterfaceType.class, getField("typeBound"), true, false, true, false, false));
} }
Expand Down
Expand Up @@ -3,21 +3,17 @@
import com.github.javaparser.JavaParser; import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.*; import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.body.Parameter;
import com.github.javaparser.ast.comments.BlockComment; import com.github.javaparser.ast.comments.BlockComment;
import com.github.javaparser.ast.comments.Comment; import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.comments.JavadocComment; import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.comments.LineComment; import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*; import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*; import com.github.javaparser.ast.type.*;
import com.github.javaparser.ast.type.Type;
import com.github.javaparser.ast.type.WildcardType;
import com.github.javaparser.generator.utils.SourceRoot; import com.github.javaparser.generator.utils.SourceRoot;


import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
Expand All @@ -26,9 +22,7 @@
import static com.github.javaparser.JavaParser.*; import static com.github.javaparser.JavaParser.*;
import static com.github.javaparser.ast.Modifier.FINAL; import static com.github.javaparser.ast.Modifier.FINAL;
import static com.github.javaparser.ast.Modifier.PUBLIC; import static com.github.javaparser.ast.Modifier.PUBLIC;
import static com.github.javaparser.generator.utils.GeneratorUtils.capitalize; import static com.github.javaparser.generator.utils.GeneratorUtils.*;
import static com.github.javaparser.generator.utils.GeneratorUtils.decapitalize;
import static com.github.javaparser.generator.utils.GeneratorUtils.f;


public class MetaModelGenerator { public class MetaModelGenerator {
private static List<Class<?>> ALL_MODEL_CLASSES = new ArrayList<Class<?>>() {{ private static List<Class<?>> ALL_MODEL_CLASSES = new ArrayList<Class<?>>() {{
Expand Down Expand Up @@ -159,7 +153,14 @@ private void run() throws IOException, NoSuchMethodException {


CompilationUnit javaParserMetaModel = sourceRoot.parse(METAMODEL_PACKAGE, "JavaParserMetaModel.java", javaParser).get(); CompilationUnit javaParserMetaModel = sourceRoot.parse(METAMODEL_PACKAGE, "JavaParserMetaModel.java", javaParser).get();


ClassOrInterfaceDeclaration mmClass = javaParserMetaModel.getClassByName("JavaParserMetaModel").get();
generateClassMetaModel(javaParserMetaModel, sourceRoot);

sourceRoot.saveAll();
}

private void generateClassMetaModel(CompilationUnit javaParserMetaModelCu, SourceRoot sourceRoot) throws NoSuchMethodException {
ClassOrInterfaceDeclaration mmClass = javaParserMetaModelCu.getClassByName("JavaParserMetaModel").get();
BlockStmt constructor = mmClass.getDefaultConstructor().get().getBody(); BlockStmt constructor = mmClass.getDefaultConstructor().get().getBody();
constructor.getStatements().clear(); constructor.getStatements().clear();


Expand All @@ -177,7 +178,6 @@ private void run() throws IOException, NoSuchMethodException {
superClassMetaModel = "Optional.empty()"; superClassMetaModel = "Optional.empty()";
} }



f.getVariable(0).setInitializer(parseExpression(f("new %s(this, %s)", className, superClassMetaModel))); f.getVariable(0).setInitializer(parseExpression(f("new %s(this, %s)", className, superClassMetaModel)));
constructor.addStatement(parseStatement(f("classMetaModels.add(%s);", fieldName))); constructor.addStatement(parseStatement(f("classMetaModels.add(%s);", fieldName)));


Expand All @@ -195,81 +195,82 @@ private void run() throws IOException, NoSuchMethodException {
classMMConstructor classMMConstructor
.getBody() .getBody()
.addStatement(parseExplicitConstructorInvocationStmt(f("super(superClassMetaModel, parent, %s.class, \"%s\", \"%s\", \"%s\", %s);", c.getName(), c.getSimpleName(), c.getName(), c.getPackage().getName(), java.lang.reflect.Modifier.isAbstract(c.getModifiers())))); .addStatement(parseExplicitConstructorInvocationStmt(f("super(superClassMetaModel, parent, %s.class, \"%s\", \"%s\", \"%s\", %s);", c.getName(), c.getSimpleName(), c.getName(), c.getPackage().getName(), java.lang.reflect.Modifier.isAbstract(c.getModifiers()))));
generateFieldMetaModels(c, classMetaModelJavaFile, classMetaModelClass, classMMConstructor);


constructor.getStatements().sort(Comparator.comparing(o -> ((NameExpr) ((MethodCallExpr) ((ExpressionStmt) o).getExpression()).getArgument(0)).getNameAsString()));
}
}


// FIXME parent's fields too!!! private void generateFieldMetaModels(Class<?> c, CompilationUnit classMetaModelJavaFile, ClassOrInterfaceDeclaration classMetaModelClass, ConstructorDeclaration classMMConstructor) throws NoSuchMethodException {
List<Field> fields = new ArrayList<>(Arrays.asList(c.getDeclaredFields())); List<Field> fields = new ArrayList<>(Arrays.asList(c.getDeclaredFields()));
fields.sort(Comparator.comparing(Field::getName)); fields.sort(Comparator.comparing(Field::getName));
boolean anyFieldsGenerated = false; boolean anyFieldsGenerated = false;
for (Field field : fields) { for (Field field : fields) {
if (!isPartOfModel(field)) { if (!isPartOfModel(field)) {
continue; continue;
}
boolean isOptional = false;
boolean isEnumSet = false;
boolean isNodeList = false;
boolean hasWildcard = false;
boolean ignore = false;

java.lang.reflect.Type fieldType = c.getMethod(getter(field)).getGenericReturnType();

while (fieldType instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType) fieldType;
java.lang.reflect.Type currentOuterType = t.getRawType();
if (currentOuterType == List.class) {
ignore = true;
} }
boolean isOptional = false; if (currentOuterType == NodeList.class) {
boolean isEnumSet = false; isNodeList = true;
boolean isNodeList = false;
boolean hasWildcard = false;
boolean ignore = false;

java.lang.reflect.Type fieldType = c.getMethod(getter(field)).getGenericReturnType();

while (fieldType instanceof ParameterizedType) {
ParameterizedType t = (ParameterizedType) fieldType;
java.lang.reflect.Type currentOuterType = t.getRawType();
if (currentOuterType == java.util.List.class) {
ignore = true;
}
if (currentOuterType == NodeList.class) {
isNodeList = true;
}
if (currentOuterType == Optional.class) {
isOptional = true;
}
if (currentOuterType == EnumSet.class) {
isEnumSet = true;
}

if (t.getActualTypeArguments()[0] instanceof java.lang.reflect.WildcardType) {
fieldType = t.getRawType();
hasWildcard = true;
break;
}
fieldType = t.getActualTypeArguments()[0];
} }

if (currentOuterType == Optional.class) {
if (ignore) { isOptional = true;
continue; }
if (currentOuterType == EnumSet.class) {
isEnumSet = true;
} }


String fieldAddition = f("fieldMetaModels.add(new FieldMetaModel(this, \"%s\", \"%s\", \"%s\", %s.class, getField(\"%s\"), true, %s, %s, %s, %s));", if (t.getActualTypeArguments()[0] instanceof java.lang.reflect.WildcardType) {
getter(field), fieldType = t.getRawType();
setter(field), hasWildcard = true;
field.getName(), break;
fieldType.getTypeName().replace('$', '.'), }
field.getName(), fieldType = t.getActualTypeArguments()[0];
isOptional,
isNodeList,
isEnumSet,
hasWildcard);

classMMConstructor.getBody().addStatement(fieldAddition);
anyFieldsGenerated = true;
}
if (anyFieldsGenerated) {
classMetaModelJavaFile.addImport("java.lang.reflect.Field");
classMetaModelJavaFile.addImport(c);
classMetaModelClass.addMember(parseClassBodyDeclaration(f("private Field getField(String name) {\n" +
" try {\n" +
" return %s.class.getDeclaredField(name);\n" +
" } catch (NoSuchFieldException e) {\n" +
" throw new RuntimeException(e);\n" +
" }\n" +
" }\n", c.getSimpleName())));
} }
}


constructor.getStatements().sort(Comparator.comparing(o -> ((NameExpr) ((MethodCallExpr) ((ExpressionStmt) o).getExpression()).getArgument(0)).getNameAsString())); if (ignore) {
continue;
}


sourceRoot.saveAll(); String fieldAddition = f("fieldMetaModels.add(new FieldMetaModel(this, \"%s\", \"%s\", \"%s\", %s.class, getField(\"%s\"), true, %s, %s, %s, %s));",
getter(field),
setter(field),
field.getName(),
fieldType.getTypeName().replace('$', '.'),
field.getName(),
isOptional,
isNodeList,
isEnumSet,
hasWildcard);

classMMConstructor.getBody().addStatement(fieldAddition);
anyFieldsGenerated = true;
}
if (anyFieldsGenerated) {
classMetaModelJavaFile.addImport("java.lang.reflect.Field");
classMetaModelJavaFile.addImport(c);
classMetaModelClass.addMember(parseClassBodyDeclaration(f("private Field getField(String name) {\n" +
" try {\n" +
" return %s.class.getDeclaredField(name);\n" +
" } catch (NoSuchFieldException e) {\n" +
" throw new RuntimeException(e);\n" +
" }\n" +
" }\n", c.getSimpleName())));
}
} }


private String setter(Field field) { private String setter(Field field) {
Expand Down

0 comments on commit 807a312

Please sign in to comment.