package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.ClassNotFoundException; import de.dhbwstuttgart.parser.PackageCrawler; import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typecheck.*; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.tree.TerminalNode; public class SyntaxTreeGenerator{ private JavaClassRegistry reg; private String pkgName = ""; List imports = new ArrayList(); private GenericsRegistry generics = new GenericsRegistry(); public SyntaxTreeGenerator(JavaClassRegistry reg){ this.reg = reg; } public void setPackageName(Java8Parser.CompilationUnitContext ctx){ if(ctx.packageDeclaration() != null){ for(TerminalNode t : ctx.packageDeclaration().Identifier()){ this.pkgName = this.pkgName + "." + t.toString(); } this.pkgName = this.pkgName.substring(1); } } public void getNames(Java8Parser.CompilationUnitContext ctx){ if(this.pkgName == "") this.setPackageName(ctx); String nameString = ""; for (Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ if(typeDecl.interfaceDeclaration() != null){ if(typeDecl.interfaceDeclaration().normalInterfaceDeclaration() != null){ if(this.pkgName != ""){ nameString = this.pkgName + "." + typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString(); } else{ nameString = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString(); } //Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry anfügen: if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){ for(Java8Parser.TypeParameterContext tp : typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter()){ //this.reg.add(tp.Identifier().toString()); } } this.reg.add(nameString); } } else{ if(typeDecl.classDeclaration().normalClassDeclaration() != null){ if(this.pkgName != ""){ nameString = this.pkgName + "." + typeDecl.classDeclaration().normalClassDeclaration().Identifier().toString(); } else{ nameString = typeDecl.classDeclaration().normalClassDeclaration().Identifier().toString(); } //Die Generic TypeParameter Definitionen ebenfalls an die JavaClassName-Registry anfügen: if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){ for(Java8Parser.TypeParameterContext tp : typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter()){ this.reg.add(tp.Identifier().toString()); } } this.reg.add(nameString); } } } } public JavaClassRegistry getReg(){ return this.reg; } // Converts type name to String. public String convertTypeName(Java8Parser.TypeNameContext ctx){ String ret; if(ctx.packageOrTypeName() == null){ ret = ctx.Identifier().toString(); } else{ ret = convertPackageOrTypeName(ctx.packageOrTypeName()) + "." + ctx.Identifier().toString(); } return ret; } // Converts PackageOrTypeName to String. public String convertPackageOrTypeName(Java8Parser.PackageOrTypeNameContext ctx){ String ret; if(ctx.packageOrTypeName() == null){ ret = ctx.Identifier().toString(); } else{ ret = convertPackageOrTypeName(ctx.packageOrTypeName()) + "." + ctx.Identifier().toString(); } return ret; } public void setImports(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException { List newImports = new ArrayList(); for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ if(importDeclCtx.singleTypeImportDeclaration() != null){ newImports.add(convertSingleTypeImportDeclaration(importDeclCtx.singleTypeImportDeclaration())); } else if(importDeclCtx.typeImportOnDemandDeclaration() != null){ newImports.add(convertTypeImportOnDemandDeclaration(importDeclCtx.typeImportOnDemandDeclaration())); } else if(importDeclCtx.singleStaticImportDeclaration() != null){ newImports.add(convertSingleStaticImportDeclaration(importDeclCtx.singleStaticImportDeclaration())); } else{ newImports.add(convertStaticImportOnDemandDeclaration(importDeclCtx.staticImportOnDemandDeclaration())); } } this.imports.addAll(newImports); } private JavaClassName convertSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) throws ClassNotFoundException{ String typeName = convertTypeName(ctx.typeName()); String packageName = getPackageFromClass(typeName); List classes = PackageCrawler.getClassNames(packageName); reg.add(typeName); JavaClassName ret = reg.getName(typeName); if(classes.contains(ret)){ return ret; } else{ throw new ClassNotFoundException(); } } private JavaClassName convertTypeImportOnDemandDeclaration(Java8Parser.TypeImportOnDemandDeclarationContext ctx){ return null; } private JavaClassName convertSingleStaticImportDeclaration(Java8Parser.SingleStaticImportDeclarationContext ctx){ return null; } private JavaClassName convertStaticImportOnDemandDeclaration(Java8Parser.StaticImportOnDemandDeclarationContext ctx){ return null; } private String getPackageFromClass(String cls){ String ret = ""; String[] parts = cls.split("\\."); for(int i = 0; i < parts.length - 1; i++){ ret = ret + "." + parts[i]; } ret = ret.substring(1); return ret; } public SourceFile convert(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException{ List classes = new ArrayList<>(); this.getNames(ctx); this.setImports(ctx); for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ ClassOrInterface newClass; if(typeDecl.classDeclaration() != null){ newClass = convertClass(typeDecl.classDeclaration()); } else{ newClass = convertInterface(typeDecl.interfaceDeclaration()); } classes.add(newClass); } return new SourceFile(this.pkgName, classes, this.imports); } private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) { ClassOrInterface newClass; if(ctx.normalClassDeclaration() != null){ newClass = convertNormal(ctx.normalClassDeclaration()); } else{ newClass = convertEnum(ctx.enumDeclaration()); } return newClass; } private ClassOrInterface convertNormal(Java8Parser.NormalClassDeclarationContext ctx){ int modifiers = 0; if(ctx.classModifier() != null){ for(Java8Parser.ClassModifierContext mod : ctx.classModifier()){ int newModifier = convert(mod); modifiers += newModifier; } } JavaClassName name = reg.getName(ctx.Identifier().getText()); Token offset = ctx.getStart(); GenericDeclarationList genericClassParameters = TypeGenerator.convert(ctx.typeParameters(), name, "",reg, generics); List fielddecl = convertFields(ctx.classBody()); List methods = convertMethods(ctx.classBody(), name); List konstruktoren = new ArrayList<>(); for(int i = 0; i implementedInterfaces = null; return new ClassOrInterface(modifiers, name, fielddecl, methods, konstruktoren, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); } private Constructor generateStandardConstructor(String className, GenericDeclarationList classGenerics, Token offset){ RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); int modifiers = 0; ParameterList params = new ParameterList(new ArrayList<>(), offset); //TODO: Konstruktor muss Felder initialisieren: Block block = new Block(new ArrayList<>(), offset); return new Constructor(className, classType, modifiers, params, block, classGenerics, offset); } private RefType convert(Java8Parser.SuperclassContext superclass) { throw new NotImplementedException(); } private List convertMethods(Java8Parser.ClassBodyContext classBodyContext, JavaClassName parentClass) { List ret = new ArrayList<>(); for(Java8Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()){ if(classMember.classMemberDeclaration() != null){ Java8Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration(); if(classMemberDeclarationContext.fieldDeclaration() != null){ //Do nothing! }else if(classMemberDeclarationContext.methodDeclaration()!= null){ StatementGenerator stmtGen = new StatementGenerator(reg, generics); ret.add(stmtGen.convert(classMemberDeclarationContext.methodDeclaration(), parentClass)); } } } return ret; } private List convertFields(Java8Parser.ClassBodyContext classBodyContext) { List ret = new ArrayList<>(); for(Java8Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()){ if(classMember.classMemberDeclaration() != null){ Java8Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration(); if(classMemberDeclarationContext.fieldDeclaration() != null){ ret.addAll(convert(classMember.classMemberDeclaration().fieldDeclaration())); }else if(classMemberDeclarationContext.methodDeclaration()!= null){ //Do nothing! } } } return ret; } public static int convert(List methodModifierContexts) { int ret = 0; for(Java8Parser.MethodModifierContext mod : methodModifierContexts){ if(mod.annotation() == null)convertModifier(mod.getText()); } return ret; } private List convert(Java8Parser.FieldDeclarationContext fieldDeclarationContext) { List ret = new ArrayList<>(); int modifiers = 0; for(Java8Parser.FieldModifierContext fieldModifierContext : fieldDeclarationContext.fieldModifier()){ modifiers+=(convert(fieldModifierContext)); } RefTypeOrTPHOrWildcardOrGeneric fieldType; if(fieldDeclarationContext.unannType() != null){ fieldType = TypeGenerator.convert(fieldDeclarationContext.unannType(), reg, generics); }else{ fieldType = TypePlaceholder.fresh(fieldDeclarationContext.getStart()); } for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){ String fieldName = convert(varCtx.variableDeclaratorId()); if(varCtx.variableInitializer() != null){ initializeField(fieldDeclarationContext); } else{ ret.add(new Field(fieldName,fieldType,modifiers,varCtx.getStart())); } } return ret; } public static String convert(Java8Parser.VariableDeclaratorIdContext variableDeclaratorIdContext) { return variableDeclaratorIdContext.getText(); } // Initialize a field by creating implicit constructor. private void initializeField(Java8Parser.FieldDeclarationContext ctx){ //TODO throw new NotImplementedException(); } public static int convertModifier(String modifier){ HashMap modifiers = new HashMap<>(); modifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC); modifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE); modifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED); modifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT); modifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC); modifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT); modifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL); modifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT); modifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE); modifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED); modifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE); modifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); int ret = 0; for(String m : modifiers.keySet()){ if(modifier.startsWith(m))ret+=modifiers.get(m); } return ret; } private int convert(Java8Parser.ClassModifierContext ctx){ if(ctx.annotation() != null)return 0; return convertModifier(ctx.getText()); } private int convert(Java8Parser.FieldModifierContext ctx){ if(ctx.annotation() != null)return 0; return convertModifier(ctx.getText()); } private ClassOrInterface convertEnum(Java8Parser.EnumDeclarationContext ctx){ return null; } private ClassOrInterface convertInterface(Java8Parser.InterfaceDeclarationContext ctx){ return null; } }