blob: 43d9112fd8e3d0b2e4e51e15cff136220d534115 [file] [log] [blame]
package com.github.javaparser.generator.metamodel;
import com.github.javaparser.ast.*;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.comments.BlockComment;
import com.github.javaparser.ast.comments.Comment;
import com.github.javaparser.ast.comments.JavadocComment;
import com.github.javaparser.ast.comments.LineComment;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.modules.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.*;
import com.github.javaparser.printer.PrettyPrinter;
import com.github.javaparser.printer.PrettyPrinterConfiguration;
import com.github.javaparser.utils.SourceRoot;
import java.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import static com.github.javaparser.utils.Utils.decapitalize;
public class MetaModelGenerator {
static final String BASE_NODE_META_MODEL = "BaseNodeMetaModel";
private static List<Class<? extends Node>> ALL_NODE_CLASSES = new ArrayList<Class<? extends Node>>() {{
/* Base classes go first, so we don't have to do any sorting to make sure
generated classes can refer to their base generated classes without
being afraid those are not initialized yet. */
add(Node.class);
add(BodyDeclaration.class);
add(CallableDeclaration.class);
add(Statement.class);
add(Expression.class);
add(Type.class);
add(AnnotationExpr.class);
add(TypeDeclaration.class);
add(ReferenceType.class);
add(LiteralExpr.class);
add(LiteralStringValueExpr.class);
add(StringLiteralExpr.class);
add(ModuleDeclaration.class);
add(ModuleStmt.class);
//
add(ArrayCreationLevel.class);
add(CompilationUnit.class);
add(PackageDeclaration.class);
add(AnnotationDeclaration.class);
add(AnnotationMemberDeclaration.class);
add(ClassOrInterfaceDeclaration.class);
add(ConstructorDeclaration.class);
add(EnumConstantDeclaration.class);
add(EnumDeclaration.class);
add(FieldDeclaration.class);
add(InitializerDeclaration.class);
add(MethodDeclaration.class);
add(Parameter.class);
add(ReceiverParameter.class);
add(VariableDeclarator.class);
add(Comment.class);
add(BlockComment.class);
add(JavadocComment.class);
add(LineComment.class);
add(ArrayAccessExpr.class);
add(ArrayCreationExpr.class);
add(ArrayInitializerExpr.class);
add(AssignExpr.class);
add(BinaryExpr.class);
add(BooleanLiteralExpr.class);
add(CastExpr.class);
add(CharLiteralExpr.class);
add(ClassExpr.class);
add(ConditionalExpr.class);
add(DoubleLiteralExpr.class);
add(EnclosedExpr.class);
add(FieldAccessExpr.class);
add(InstanceOfExpr.class);
add(IntegerLiteralExpr.class);
add(LambdaExpr.class);
add(LongLiteralExpr.class);
add(MarkerAnnotationExpr.class);
add(MemberValuePair.class);
add(MethodCallExpr.class);
add(MethodReferenceExpr.class);
add(NameExpr.class);
add(Name.class);
add(NormalAnnotationExpr.class);
add(NullLiteralExpr.class);
add(ObjectCreationExpr.class);
add(SimpleName.class);
add(SingleMemberAnnotationExpr.class);
add(SuperExpr.class);
add(ThisExpr.class);
add(TypeExpr.class);
add(UnaryExpr.class);
add(VariableDeclarationExpr.class);
add(ImportDeclaration.class);
add(AssertStmt.class);
add(BlockStmt.class);
add(BreakStmt.class);
add(CatchClause.class);
add(ContinueStmt.class);
add(DoStmt.class);
add(EmptyStmt.class);
add(ExplicitConstructorInvocationStmt.class);
add(ExpressionStmt.class);
add(ForeachStmt.class);
add(ForStmt.class);
add(IfStmt.class);
add(LabeledStmt.class);
add(ReturnStmt.class);
add(SwitchEntryStmt.class);
add(SwitchStmt.class);
add(SynchronizedStmt.class);
add(ThrowStmt.class);
add(TryStmt.class);
add(LocalClassDeclarationStmt.class);
add(WhileStmt.class);
add(UnparsableStmt.class);
add(ArrayType.class);
add(ClassOrInterfaceType.class);
add(IntersectionType.class);
add(PrimitiveType.class);
add(TypeParameter.class);
add(UnionType.class);
add(UnknownType.class);
add(VoidType.class);
add(WildcardType.class);
add(VarType.class);
add(ModuleRequiresStmt.class);
add(ModuleExportsStmt.class);
add(ModuleProvidesStmt.class);
add(ModuleUsesStmt.class);
add(ModuleOpensStmt.class);
}};
static String METAMODEL_PACKAGE = "com.github.javaparser.metamodel";
public static void main(String[] args) throws IOException, NoSuchMethodException {
if (args.length != 1) {
throw new RuntimeException("Need 1 parameter: the JavaParser source checkout root directory.");
}
final Path root = Paths.get(args[0], "..", "javaparser-core", "src", "main", "java");
final SourceRoot sourceRoot = new SourceRoot(root);
sourceRoot.setPrinter(new PrettyPrinter(new PrettyPrinterConfiguration().setEndOfLineCharacter("\n"))::print);
new MetaModelGenerator().run(sourceRoot);
sourceRoot.saveAll();
}
private void run(SourceRoot sourceRoot) throws IOException, NoSuchMethodException {
final CompilationUnit javaParserMetaModel = sourceRoot.parse(METAMODEL_PACKAGE, "JavaParserMetaModel.java");
generateNodeMetaModels(javaParserMetaModel, sourceRoot);
}
private void generateNodeMetaModels(CompilationUnit javaParserMetaModelCu, SourceRoot sourceRoot) throws NoSuchMethodException {
final ClassOrInterfaceDeclaration metaModelCoid = javaParserMetaModelCu.getClassByName("JavaParserMetaModel").get();
final NodeList<Statement> initializeNodeMetaModelsStatements = metaModelCoid.getMethodsByName("initializeNodeMetaModels").get(0).getBody().get().getStatements();
final NodeList<Statement> initializePropertyMetaModelsStatements = metaModelCoid.getMethodsByName("initializePropertyMetaModels").get(0).getBody().get().getStatements();
final NodeList<Statement> initializeConstructorParametersStatements = metaModelCoid.getMethodsByName("initializeConstructorParameters").get(0).getBody().get().getStatements();
initializeNodeMetaModelsStatements.clear();
initializePropertyMetaModelsStatements.clear();
initializeConstructorParametersStatements.clear();
metaModelCoid.getFields().stream().filter(f -> f.getVariable(0).getNameAsString().endsWith("MetaModel")).forEach(Node::remove);
final NodeMetaModelGenerator nodeMetaModelGenerator = new NodeMetaModelGenerator();
for (Class<? extends Node> nodeClass : ALL_NODE_CLASSES) {
nodeMetaModelGenerator.generate(nodeClass, metaModelCoid, initializeNodeMetaModelsStatements, initializePropertyMetaModelsStatements, initializeConstructorParametersStatements, sourceRoot);
}
initializeNodeMetaModelsStatements.sort(Comparator.comparing(Node::toString));
}
static boolean isNode(Class<?> c) {
return Node.class.isAssignableFrom(c);
}
static String nodeMetaModelName(Class<?> c) {
return c.getSimpleName() + "MetaModel";
}
static String propertyMetaModelFieldName(Field field) {
return field.getName() + "PropertyMetaModel";
}
static String nodeMetaModelFieldName(Class<?> nodeClass) {
return decapitalize(nodeMetaModelName(nodeClass));
}
}