diff --git a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java index 9e34c54f..2cd81c73 100644 --- a/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/main/java/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -11,6 +11,7 @@ import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.exceptions.DebugException; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; @@ -69,11 +70,16 @@ public class CompilationEnvironment { throws ClassNotFoundException, IOException { Map allNames; SourceFileContext tree = JavaTXParser.parse(forSourceFile); - allNames = GatherNames.getNames(tree, packageCrawler, classLoader); - for (Class c : loadDefaultPackageClasses(forSourceFile, classLoader)) { - allNames.put(c.getName(), c.getTypeParameters().length); + if (tree instanceof SrcfileContext srcfile) { + allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, classLoader); + for (Class c : loadDefaultPackageClasses(forSourceFile, classLoader)) { + allNames.put(c.getName(), c.getTypeParameters().length); + } + return new JavaClassRegistry(allNames); + } else { + throw new NotImplementedException(); } - return new JavaClassRegistry(allNames); + } public static List loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader) diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java deleted file mode 100644 index fe00ea79..00000000 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java +++ /dev/null @@ -1,403 +0,0 @@ -package de.dhbwstuttgart.parser.SyntaxTreeGenerator; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; - -import org.antlr.v4.runtime.CommonToken; -import org.antlr.v4.runtime.Token; - -import java.util.List; -import java.lang.reflect.Modifier; -import java.util.ArrayList; - -import de.dhbwstuttgart.environment.PackageCrawler; -import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.exceptions.TypeinferenceException; -import de.dhbwstuttgart.parser.antlr.Java17Parser; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceModifierContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.EmptymethodContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericDeclarationListContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericmethodContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberconstructorContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberfieldContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MembermethodContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodBodyContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodDeclarationContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodHeaderContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodblockContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.MethoddeclContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ModifierContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ReftypeContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; -import de.dhbwstuttgart.parser.scope.GatherNames; -import de.dhbwstuttgart.parser.scope.GenericsRegistry; -import de.dhbwstuttgart.parser.scope.JavaClassName; -import de.dhbwstuttgart.parser.scope.JavaClassRegistry; -import de.dhbwstuttgart.syntaxtree.ClassOrInterface; -import de.dhbwstuttgart.syntaxtree.Constructor; -import de.dhbwstuttgart.syntaxtree.Field; -import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; -import de.dhbwstuttgart.syntaxtree.Method; -import de.dhbwstuttgart.syntaxtree.ParameterList; -import de.dhbwstuttgart.syntaxtree.SourceFile; -import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; -import de.dhbwstuttgart.syntaxtree.type.Void; -import de.dhbwstuttgart.syntaxtree.statement.Block; -import de.dhbwstuttgart.syntaxtree.statement.Statement; - -public class ASTGen { - private JavaClassRegistry reg; - private final GenericsRegistry globalGenerics; - private String pkgName = ""; - Set imports = new HashSet<>(); - HashMap allmodifiers = new HashMap<>(); - // PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH - // bekommen - private Map fields = new HashMap<>(); - // PL 2019-10-23: Muss für jede Klasse neu initilisiert werden - List fieldInitializations = new ArrayList<>(); - - public ASTGen(JavaClassRegistry reg, GenericsRegistry globalGenerics) { - // Die Generics müssen während des Bauens des AST erstellt werden, - // da diese mit der Methode oder Klasse, in welcher sie deklariert werden - // verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer - // globalen Datenbank benötigt. - this.globalGenerics = globalGenerics; - this.reg = reg; - this.allmodifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC); - this.allmodifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE); - this.allmodifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED); - this.allmodifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT); - this.allmodifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC); - this.allmodifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT); - this.allmodifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL); - this.allmodifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT); - this.allmodifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE); - this.allmodifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED); - this.allmodifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE); - this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); - this.allmodifiers.put("sealed", 4096); - this.allmodifiers.put("non-sealed", 8192); - } - - public JavaClassRegistry getReg() { - return this.reg; - } - - public String convertQualifiedName(Java17Parser.QualifiedNameContext ctx) { - String ret = ""; - for (Java17Parser.IdentifierContext ident : ctx.identifier()) { - ret += ident.getText(); - if (ctx.identifier().iterator().hasNext()) { - ret += '.'; - } - } - return ret; - } - - public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) - throws Exception { - SrcfileContext srcfile; - List classes = new ArrayList<>(); - if (ctx instanceof Java17Parser.SrcfileContext) { - srcfile = new SrcfileContext(ctx); - } else { - return new SourceFile(this.pkgName, classes, this.imports); - } - if (srcfile.packageDeclaration() != null) - this.pkgName = convert(srcfile.packageDeclaration()); - Map imports = GatherNames.getImports(srcfile, packageCrawler, classLoader); - this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); - for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) { - ClassorinterfacedeclContext clsoif; - if (type instanceof NoclassorinterfaceContext) { - continue; - } else { - clsoif = new ClassorinterfacedeclContext(type); - } - ClassOrInterface newClass; - int modifiers = 0; - if (!clsoif.classOrInterfaceModifier().isEmpty()) { - for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) { - modifiers += allmodifiers.get(mod.getText()); - } - } - fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden - if (clsoif.classDeclaration() != null) { - newClass = convertClass(clsoif.classDeclaration(), modifiers); - } else { - // TODO: newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers); - throw new NotImplementedException(); - } - classes.add(newClass); - } - if (classes.size() > 0) { - return new SourceFile(this.pkgName, classes, this.imports); - } else { - throw new Exception("SourceFile enthält keine Klassen"); - } - } - - private String convert(Java17Parser.PackageDeclarationContext ctx) { - return convertQualifiedName(ctx.qualifiedName()); - } - - private ClassOrInterface convertClass(Java17Parser.ClassDeclarationContext ctx, int modifiers) { - String className = this.pkgName.length() > 0 ? this.pkgName + "." : "" + ctx.identifier().getText(); - JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu - if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor? - throw new TypeinferenceException( - "Name " + className + " bereits vorhanden in " + reg.getName(className).toString(), ctx.getStart()); - } - GenericsRegistry generics = createGenerics(ctx.genericDeclarationList(), name, "", reg, - new GenericsRegistry(globalGenerics)); - Token offset = ctx.getStart(); - GenericDeclarationList genericClassParameters; - if (ctx.genericDeclarationList() == null) { - genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.identifier().getStop()); - } else { - genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics); - } - RefType superClass; - if (ctx.EXTENDS() != null) { - superClass = convertSuperType(ctx.typeType()); - } else { - superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); - } - List fielddecl = new ArrayList<>(); - List methods = new ArrayList<>(); - List constructors = new ArrayList<>(); - Boolean isInterface = false; - List implementedInterfaces = new ArrayList<>(); - List permittedSubtypes = new ArrayList<>(); - for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) { - MemberdeclContext member; - // Statement-Blöcke und "leere Zeilen" (;) werden noch nicht berücksichtigt - if (clsbodydecl instanceof MemberdeclContext) { - member = new MemberdeclContext(clsbodydecl); - Integer membermodifiers = 0; - for (ModifierContext mod : member.modifier()) { - membermodifiers += allmodifiers.get(mod.getText()); - } - String membername; - switch (member.memberDeclaration()) { - case MemberclassorinterfaceContext memberclsoif: { - break; - } - case MemberfieldContext memberfield: { - fielddecl.addAll(convert(memberfield.fieldDeclaration(), membermodifiers, generics)); - break; - } - case MembermethodContext membermethod: { - methods.add(convert(membermodifiers, membermethod.method(), name, superClass, generics)); - break; - } - case MemberconstructorContext memberconstructor: { - // TODO: parse constructors - break; - } - default: - break; - } - } else { - continue; - } - if (constructors.isEmpty()) { - constructors.add(generateStandardConstructor( - ctx.identifier().getText(), name, superClass, genericClassParameters, offset)); - } - if (ctx.IMPLEMENTS() != null) { - implementedInterfaces.addAll(convert(ctx.typeList(0), generics)); - } - // Ist Bit für 'sealed'-Modifier gesetzt - if ((modifiers & 4096) != 0) { - switch (ctx.typeList().size()) { - case 1: { - permittedSubtypes.addAll(convert(ctx.typeList(0), generics)); - break; - } - case 2: { - permittedSubtypes.addAll(convert(ctx.typeList(1), generics)); - break; - } - default: { - break; - } - } - } - } - return new ClassOrInterface(modifiers, name, fielddecl, - Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, - offset)), - methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); - } - - /** - * http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 - */ - private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, - GenericDeclarationList classGenerics, Token offset) { - RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); - ParameterList params = new ParameterList(new ArrayList<>(), offset); - Block block = new Block(new ArrayList<>(), offset); - // - // - return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset); // fieldInitializations - // geloescht PL - // 2018-11-24 - } - - /* - * fieldInitializations werden in einem Psedokonstruktor in der abstrakten - * Syntax gespeichert - */ - private Constructor generatePseudoConstructor(String className, JavaClassName parentClass, RefType superClass, - GenericDeclarationList classGenerics, Token offset) { - RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); - ParameterList params = new ParameterList(new ArrayList<>(), offset); - Block block = new Block(new ArrayList<>(fieldInitializations), offset); - return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /* - * fieldInitializations - * geloescht PL - * 2018-11-24 - */); - } - - private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) { - if (typeType.classOrInterfaceType() != null) { - throw new NotImplementedException(); - } else { - RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName( - typeType.classOrInterfaceType().typeIdentifier().getText(), - typeType.classOrInterfaceType().typeArguments() - .get(typeType.classOrInterfaceType().typeArguments().size() - 1), - typeType.getStart(), reg, globalGenerics); - if (ret instanceof RefType) { - return (RefType) ret; - } else { - throw new TypeinferenceException(typeType.getText() + " ist kein gültiger Supertyp", typeType.getStart()); - } - } - } - - private List convert(Java17Parser.TypeListContext ctx, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.TypeTypeContext type : ctx.typeType()) { - ret.add((RefType) TypeGenerator.convert(type, reg, generics)); - } - return ret; - } - - public Method convert(int modifiers, Java17Parser.MethodContext methodContext, JavaClassName parentClass, - RefType superClass, GenericsRegistry generics) { - GenericsRegistry localgenerics = generics; - MethodDeclarationContext methoddeclaration; - GenericDeclarationListContext genericdeclarations; - GenericDeclarationList gtvDeclarations; - MethodHeaderContext header; - String name; - if (methodContext instanceof GenericmethodContext) { - GenericmethodContext gmc = new GenericmethodContext(methodContext); - genericdeclarations = gmc.genericMethodDeclaration().genericDeclarationList(); - methoddeclaration = gmc.genericMethodDeclaration().methodDeclaration(); - header = methoddeclaration.methodHeader(); - name = header.identifier().getText(); - localgenerics.putAll(createGenerics(genericdeclarations, parentClass, name, reg, generics)); - gtvDeclarations = TypeGenerator.convert(genericdeclarations, parentClass, name, reg, localgenerics); - } else { - MethoddeclContext mdc = new MethoddeclContext(methodContext); - methoddeclaration = mdc.methodDeclaration(); - header = methoddeclaration.methodHeader(); - gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); - name = header.identifier().getText(); - } - - RefTypeOrTPHOrWildcardOrGeneric retType; - if (Objects.isNull(header.refType())) { - retType = TypePlaceholder.fresh(header.getStart()); - } else { - if (header.refType() instanceof ReftypeContext reftype) { - retType = TypeGenerator.convert(reftype.typeType(), reg, generics); - } else { - retType = new Void(header.refType().getStart()); - } - } - StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>()); - ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList()); - MethodBodyContext body = methoddeclaration.methodBody(); - Block block = null; - if (body instanceof EmptymethodContext emptymethod) { - if (!Modifier.isAbstract(modifiers)) { - // TODO: Error! Abstrakte Methode ohne abstrakt Keyword - } - } else { - block = stmtgen.convert(new MethodblockContext(body).block(), true); - } - if (parentClass.equals(new JavaClassName(name))) { - // TODO: Konstruktoren in eigener Methode behandeln - /* fieldInitializations geloescht PL 2018-11-24 */ - return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, header.getStart()); - } else { - return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, header.getStart()); - } - } - - private List convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, - GenericsRegistry generics) { - List ret = new ArrayList<>(); - RefTypeOrTPHOrWildcardOrGeneric fieldType; - if (fieldDeclContext.typeType() != null) { - fieldType = TypeGenerator.convert(fieldDeclContext.typeType(), reg, generics); - } else { - // PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die - // Modifier zu bekommen - fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart()); - } - for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) { - String fieldName = varDecl.variableDeclaratorId().getText(); - this.fields.put(fieldName, fieldType); - if (varDecl.variableInitializer() != null) { - initializeField(varDecl, fieldType, generics); - } - ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart())); - } - return ret; - } - - // Initialize a field by creating implicit constructor. - private void initializeField(Java17Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, - GenericsRegistry generics) { - StatementGenerator statementGenerator = new StatementGenerator(reg, generics, fields, new HashMap<>()); - fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField)); - } - - public int convertModifier(String modifier) { - return allmodifiers.get(modifier); - } - - private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass, - String parentMethod, JavaClassRegistry reg, GenericsRegistry generics) { - GenericsRegistry ret = new GenericsRegistry(this.globalGenerics); - ret.putAll(generics); - if (ctx == null) - return ret; - for (Java17Parser.GenericTypeVarContext tp : ctx.genericTypeVar()) { - ret.put(tp.identifier().getText(), new GenericContext(parentClass, parentMethod)); - TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret); - } - return ret; - } -} diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index dd1b254a..86fb69fa 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -325,11 +325,9 @@ public class StatementGenerator { } private Statement convert(Java17Parser.ConditionalstmtContext stmt) { - if (stmt.statement().size() < 2) - throw new NotImplementedException(); Expression expr = convert(stmt.parExpression().expression()); Statement thenBlock = convert(stmt.statement(0)); - Statement elseBlock = convert(stmt.statement(1)); + Statement elseBlock = (stmt.statement().size() >= 2) ? convert(stmt.statement(1)) : null; return new IfStmt(TypePlaceholder.fresh(stmt.getStart()), expr, thenBlock, elseBlock, stmt.getStart()); } @@ -492,7 +490,7 @@ public class StatementGenerator { case PrimaryexpressionContext primary: return convert(primary.primary()); case DottedexpressionContext dotted: - return convert(new DottedexpressionContext(expression), expression.getStart()); + return convert((DottedexpressionContext) expression, expression.getStart()); case MethodcallexpressionContext methodcall: return convert(methodcall.methodCall(), methodcall.getStart()); case NewinstanceexpressionContext newinstance: diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 4e1790c3..0162a744 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -1,59 +1,75 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.antlr.v4.runtime.CommonToken; +import org.antlr.v4.runtime.Token; + +import java.util.List; +import java.lang.reflect.Modifier; +import java.util.ArrayList; + import de.dhbwstuttgart.environment.PackageCrawler; import de.dhbwstuttgart.exceptions.NotImplementedException; -import java.lang.ClassNotFoundException; - import de.dhbwstuttgart.exceptions.TypeinferenceException; -import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.antlr.Java17Parser; +import de.dhbwstuttgart.parser.antlr.Java17Parser.BlockContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceModifierContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.EmptymethodContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericDeclarationListContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericmethodContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberconstructorContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberfieldContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MembermethodContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodBodyContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodHeaderContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MethodblockContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MethoddeclContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ModifierContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ReftypeContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; import de.dhbwstuttgart.parser.scope.GatherNames; import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassRegistry; -import de.dhbwstuttgart.syntaxtree.*; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.SourceFile; 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 java.lang.reflect.Modifier; -import java.net.URL; -import java.sql.Ref; -import java.util.*; -import java.util.stream.Collectors; - -//import jdk.internal.dynalink.support.TypeConverterFactory; -import org.antlr.v4.runtime.CommonToken; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.TerminalNode; - -/* - * TODO: Für additional type bounds mit '&', muss im SyntaxTreeGenerator - * abgefangen - * werden - * private static RefTypeOrTPHOrWildcardOrGeneric - * convert(Java17Parser.InterfaceTypeContext interfaceTypeContext) { - * throw new NotImplementedException(); - * } - */ +import de.dhbwstuttgart.syntaxtree.type.Void; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.Statement; public class SyntaxTreeGenerator { private JavaClassRegistry reg; private final GenericsRegistry globalGenerics; private String pkgName = ""; Set imports = new HashSet<>(); - private Map fields = new HashMap<>(); // PL 2018-11-01 fields eingefuegt, - // damit die fields immer die gleiche - // TPH bekommen - - List fieldInitializations = new ArrayList<>(); // PL 2019-10-23: Muss für jede Klasse neu initilisiert - // werden + HashMap allmodifiers = new HashMap<>(); + // PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH + // bekommen + private Map fields = new HashMap<>(); + // PL 2019-10-23: Muss für jede Klasse neu initilisiert werden + List fieldInitializations = new ArrayList<>(); public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics) { // Die Generics müssen während des Bauens des AST erstellt werden, @@ -62,30 +78,26 @@ public class SyntaxTreeGenerator { // globalen Datenbank benötigt. this.globalGenerics = globalGenerics; this.reg = reg; + this.allmodifiers.put(Modifier.toString(Modifier.PUBLIC), Modifier.PUBLIC); + this.allmodifiers.put(Modifier.toString(Modifier.PRIVATE), Modifier.PRIVATE); + this.allmodifiers.put(Modifier.toString(Modifier.PROTECTED), Modifier.PROTECTED); + this.allmodifiers.put(Modifier.toString(Modifier.ABSTRACT), Modifier.ABSTRACT); + this.allmodifiers.put(Modifier.toString(Modifier.STATIC), Modifier.STATIC); + this.allmodifiers.put(Modifier.toString(Modifier.STRICT), Modifier.STRICT); + this.allmodifiers.put(Modifier.toString(Modifier.FINAL), Modifier.FINAL); + this.allmodifiers.put(Modifier.toString(Modifier.TRANSIENT), Modifier.TRANSIENT); + this.allmodifiers.put(Modifier.toString(Modifier.VOLATILE), Modifier.VOLATILE); + this.allmodifiers.put(Modifier.toString(Modifier.SYNCHRONIZED), Modifier.SYNCHRONIZED); + this.allmodifiers.put(Modifier.toString(Modifier.NATIVE), Modifier.NATIVE); + this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); + this.allmodifiers.put("sealed", 4096); + this.allmodifiers.put("non-sealed", 8192); } public JavaClassRegistry getReg() { return this.reg; } - // Converts PackageOrTypeName to String. - /* - * Package und Type Namen sind qualified Names und werden durch nachfolgende - * Methode behandelt. Diese Methode sollte damit überflüssig sein. - * - * public String convertPackageOrTypeName(Java17Parser.PackageOrTypeNameContext - * ctx) { - * String ret; - * if (ctx.packageOrTypeName() == null) { - * ret = ctx.Identifier().toString(); - * } else { - * ret = convertPackageOrTypeName(ctx.packageOrTypeName()) + "." + - * ctx.Identifier().toString(); - * } - * return ret; - * } - */ - public String convertQualifiedName(Java17Parser.QualifiedNameContext ctx) { String ret = ""; for (Java17Parser.IdentifierContext ident : ctx.identifier()) { @@ -98,111 +110,54 @@ public class SyntaxTreeGenerator { } public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) - throws ClassNotFoundException { - SrcfileContext srcfile = new SrcfileContext(ctx); + throws ClassNotFoundException, NotImplementedException { + SrcfileContext srcfile; + List classes = new ArrayList<>(); + if (ctx instanceof Java17Parser.SrcfileContext) { + srcfile = (SrcfileContext) ctx; + } else { + return new SourceFile(this.pkgName, classes, this.imports); + } if (srcfile.packageDeclaration() != null) this.pkgName = convert(srcfile.packageDeclaration()); - List classes = new ArrayList<>(); - Map imports = GatherNames.getImports(ctx, packageCrawler, classLoader); + Map imports = GatherNames.getImports(srcfile, packageCrawler, classLoader); this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); - for (Java17Parser.ClassOrInterfaceContext member : srcfile.classOrInterface()) { + for (Java17Parser.ClassOrInterfaceContext type : srcfile.classOrInterface()) { ClassorinterfacedeclContext clsoif; - if (member instanceof NoclassorinterfaceContext) { + if (type instanceof NoclassorinterfaceContext) { continue; } else { - clsoif = new ClassorinterfacedeclContext(member); + clsoif = (ClassorinterfacedeclContext) type; } ClassOrInterface newClass; int modifiers = 0; if (!clsoif.classOrInterfaceModifier().isEmpty()) { for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) { - int newModifier = convert(mod); - modifiers += newModifier; + modifiers += allmodifiers.get(mod.getText()); } } fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden if (clsoif.classDeclaration() != null) { - newClass = convertClass(clsoif.classDeclaration()); + newClass = convertClass(clsoif.classDeclaration(), modifiers); } else { - newClass = convertInterface(clsoif.interfaceDeclaration()); + // TODO: newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers); + throw new NotImplementedException(); } classes.add(newClass); } - return new SourceFile(this.pkgName, classes, this.imports); - } - - private String convert(Java17Parser.PackageDeclarationContext packageDeclarationContext) { - return convertQualifiedName(packageDeclarationContext.qualifiedName()); - } - - public Method convert(Java17Parser.MethodDeclarationContext methodDeclarationContext, JavaClassName parentClass, - RefType superClass, GenericsRegistry generics) { - Java17Parser.MethodHeaderContext header = methodDeclarationContext.methodHeader(); - int modifiers = SyntaxTreeGenerator.convert(methodDeclarationContext.methodModifier()); - GenericsRegistry localGenerics = createGenerics(methodDeclarationContext.methodHeader().typeParameters(), - parentClass, header.methodDeclarator().Identifier().getText(), reg, generics); - localGenerics.putAll(generics); - return convert(modifiers, header, methodDeclarationContext.methodBody(), parentClass, superClass, localGenerics); - } - - public Method convert(Java17Parser.InterfaceMethodDeclarationContext ctx, JavaClassName parentClass, - RefType superClass, GenericsRegistry generics) { - Java17Parser.MethodHeaderContext header = ctx.methodHeader(); - int modifiers = SyntaxTreeGenerator.convertInterfaceModifier(ctx.interfaceMethodModifier()); - - GenericsRegistry localGenerics = createGenerics(header.typeParameters(), parentClass, - header.methodDeclarator().Identifier().getText(), reg, generics); - localGenerics.putAll(generics); - - return convert(modifiers, header, ctx.methodBody(), parentClass, superClass, localGenerics); - } - - private Method convert(int modifiers, Java17Parser.MethodHeaderContext header, Java17Parser.MethodBodyContext body, - JavaClassName parentClass, RefType superClass, GenericsRegistry localGenerics) { - - StatementGenerator stmtGen = new StatementGenerator(reg, localGenerics, fields, new HashMap<>()); - - String name = header.methodDeclarator().Identifier().getText(); - GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); - if (header.typeParameters() != null) { - gtvDeclarations = TypeGenerator.convert(header.typeParameters(), parentClass, name, reg, localGenerics); + if (classes.size() > 0) { + return new SourceFile(this.pkgName, classes, this.imports); } else { - gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); - } - RefTypeOrTPHOrWildcardOrGeneric retType; - if (header.result() != null) { - if (header.result().unannType() != null) { - retType = TypeGenerator.convert(header.result().unannType(), reg, localGenerics); - } else - retType = new de.dhbwstuttgart.syntaxtree.type.Void(header.result().getStart()); - } else { - retType = TypePlaceholder.fresh(header.getStart()); - } - ParameterList parameterList = stmtGen.convert(header.methodDeclarator().formalParameterList()); - Block block = null; - if (body.block() == null) { - if (!Modifier.isAbstract(modifiers)) { - // TODO: Error! Abstrakte Methode ohne abstrakt Keyword - } - } else { - block = stmtGen.convert(body.block(), true); - } - if (parentClass.equals(new JavaClassName(name))) { - return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart() /* - * , - * fieldInitializations - * geloescht - * PL - * 2018- - * 11-24 - */); - } else { - return new Method(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart()); + throw new NotImplementedException("SourceFile enthält keine Klassen"); } } - private ClassOrInterface convertClass(Java17Parser.ClassDeclarationContext ctx) { - String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + ctx.identifier().getText(); + private String convert(Java17Parser.PackageDeclarationContext ctx) { + return convertQualifiedName(ctx.qualifiedName()); + } + + private ClassOrInterface convertClass(Java17Parser.ClassDeclarationContext ctx, int modifiers) { + String className = this.pkgName.length() > 0 ? this.pkgName + "." : "" + ctx.identifier().getText(); JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor? throw new TypeinferenceException( @@ -213,94 +168,82 @@ public class SyntaxTreeGenerator { Token offset = ctx.getStart(); GenericDeclarationList genericClassParameters; if (ctx.genericDeclarationList() == null) { - genericClassParameters = createEmptyGenericDeclarationList(ctx.identifier().getStop()); + genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.identifier().getStop()); } else { genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics); } RefType superClass; if (ctx.EXTENDS() != null) { - superClass = convert(ctx.typeType()); + superClass = convertSuperType(ctx.typeType()); } else { superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); } - List fielddecl = convertFields(ctx.classBody(), generics); - // fieldInitializations = generateFieldInitializations(ctx.classBody(), - // generics); - List methodsAndConstructors = convertMethods(ctx.classBody(), name, superClass, generics); + List fielddecl = new ArrayList<>(); List methods = new ArrayList<>(); - List konstruktoren = new ArrayList<>(); - // int noOfMethods = methods.size(); - for (Method m : methodsAndConstructors) { - if (m instanceof Constructor) { - konstruktoren.add((Constructor) m); + List constructors = new ArrayList<>(); + Boolean isInterface = false; + List implementedInterfaces = new ArrayList<>(); + List permittedSubtypes = new ArrayList<>(); + for (ClassBodyDeclarationContext clsbodydecl : ctx.classBody().classBodyDeclaration()) { + MemberdeclContext member; + // Statement-Blöcke und "leere Zeilen" (;) werden noch nicht berücksichtigt + if (clsbodydecl instanceof MemberdeclContext) { + member = (MemberdeclContext) clsbodydecl; + Integer membermodifiers = 0; + for (ModifierContext mod : member.modifier()) { + membermodifiers += allmodifiers.get(mod.getText()); + } + String membername; + switch (member.memberDeclaration()) { + case MemberclassorinterfaceContext memberclsoif: { + break; + } + case MemberfieldContext memberfield: { + fielddecl.addAll(convert(memberfield.fieldDeclaration(), membermodifiers, generics)); + break; + } + case MembermethodContext membermethod: { + methods.add(convert(membermodifiers, membermethod.method(), name, superClass, generics)); + break; + } + case MemberconstructorContext memberconstructor: { + // TODO: parse constructors + break; + } + default: + break; + } } else { - methods.add(m); + continue; + } + if (constructors.isEmpty()) { + constructors.add(generateStandardConstructor( + ctx.identifier().getText(), name, superClass, genericClassParameters, offset)); + } + if (ctx.IMPLEMENTS() != null) { + implementedInterfaces.addAll(convert(ctx.typeList(0), generics)); + } + // Ist Bit für 'sealed'-Modifier gesetzt + if ((modifiers & 4096) != 0) { + switch (ctx.typeList().size()) { + case 1: { + permittedSubtypes.addAll(convert(ctx.typeList(0), generics)); + break; + } + case 2: { + permittedSubtypes.addAll(convert(ctx.typeList(1), generics)); + break; + } + default: { + break; + } + } } } - if (konstruktoren.size() < 1) {// Standardkonstruktor anfügen: - konstruktoren.add( - generateStandardConstructor( - ctx.Identifier().getText(), name, superClass, - genericClassParameters, offset)); - } - - Boolean isInterface = false; - List implementedInterfaces = convert(ctx.superinterfaces(), generics); - return new ClassOrInterface(modifiers, name, fielddecl, - Optional.of(this.generatePseudoConstructor(ctx.Identifier().getText(), name, superClass, genericClassParameters, + Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), - methods, konstruktoren, genericClassParameters, superClass, - isInterface, implementedInterfaces, offset); - } - - /* - * private List - * generateFieldInitializations(Java17Parser.ClassBodyContext classBodyContext, - * GenericsRegistry generics) { - * List ret = new ArrayList<>(); - * for(Java17Parser.ClassBodyDeclarationContext classMember : - * classBodyContext.classBodyDeclaration()){ - * if(classMember.classMemberDeclaration() != null){ - * Java17Parser.ClassMemberDeclarationContext classMemberDeclarationContext = - * classMember.classMemberDeclaration(); - * if(classMemberDeclarationContext.fieldDeclaration() != null - * && classMemberDeclarationContext.fieldDeclaration().variableDeclaratorList() - * != null){ - * for(Java17Parser.VariableDeclaratorContext ctx : - * classMemberDeclarationContext.fieldDeclaration().variableDeclaratorList(). - * variableDeclarator()) { - * String fieldName = ctx.variableDeclaratorId().Identifier().getText(); - * if(ctx.variableDeclaratorId().dims() != null)throw new - * NotImplementedException(); - * Token offset = ctx.getStart(); - * RefTypeOrTPHOrWildcardOrGeneric fieldType; - * for(Field f : fields) - * AssignToField leftSide = new AssignToField(new FieldVar(new This(offset), - * fieldName, )); - * ret.addAll(); - * } - * }else if(classMemberDeclarationContext.methodDeclaration()!= null){ - * //Do nothing! - * } - * } - * } - * return ret; - * } - */ - - private List convert(Java17Parser.SuperinterfacesContext ctx, GenericsRegistry generics) { - if (ctx == null) - return new ArrayList<>(); - return convert(ctx.interfaceTypeList(), generics); - } - - private List convert(Java17Parser.InterfaceTypeListContext ctx, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.InterfaceTypeContext interfaceType : ctx.interfaceType()) { - ret.add((RefType) TypeGenerator.convert(interfaceType.classType(), reg, generics)); - } - return ret; + methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); } /** @@ -311,12 +254,11 @@ public class SyntaxTreeGenerator { RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset); - return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /* - * , - * fieldInitializations - * geloescht PL - * 2018-11-24 - */); + // + // + return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset); // fieldInitializations + // geloescht PL + // 2018-11-24 } /* @@ -329,105 +271,110 @@ public class SyntaxTreeGenerator { ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(fieldInitializations), offset); return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /* - * , * fieldInitializations * geloescht PL * 2018-11-24 */); } - private RefType convert(Java17Parser.SuperclassContext superclass) { - if (superclass.classType().classOrInterfaceType() != null) { + private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) { + if (typeType.classOrInterfaceType() != null) { throw new NotImplementedException(); } else { - RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(superclass.classType().Identifier().getText(), - superclass.classType().typeArguments(), - superclass.getStart(), reg, globalGenerics); + RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName( + typeType.classOrInterfaceType().typeIdentifier().getText(), + typeType.classOrInterfaceType().typeArguments() + .get(typeType.classOrInterfaceType().typeArguments().size() - 1), + typeType.getStart(), reg, globalGenerics); if (ret instanceof RefType) { return (RefType) ret; } else { - throw new TypeinferenceException(superclass.getText() + " ist kein gültiger Supertyp", superclass.getStart()); + throw new TypeinferenceException(typeType.getText() + " ist kein gültiger Supertyp", typeType.getStart()); } } } - private List convertMethods(Java17Parser.ClassBodyContext classBodyContext, - JavaClassName parentClass, RefType superClass, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()) { - if (classMember.classMemberDeclaration() != null) { - Java17Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration(); - if (classMemberDeclarationContext.fieldDeclaration() != null) { - // Do nothing! - } else if (classMemberDeclarationContext.methodDeclaration() != null) { + private List convert(Java17Parser.TypeListContext ctx, GenericsRegistry generics) { + List ret = new ArrayList<>(); + for (Java17Parser.TypeTypeContext type : ctx.typeType()) { + ret.add((RefType) TypeGenerator.convert(type, reg, generics)); + } + return ret; + } - ret.add(this.convert(classMemberDeclarationContext.methodDeclaration(), parentClass, superClass, generics)); - } + public Method convert(int modifiers, Java17Parser.MethodContext methodContext, JavaClassName parentClass, + RefType superClass, GenericsRegistry generics) { + GenericsRegistry localgenerics = generics; + MethodDeclarationContext methoddeclaration; + GenericDeclarationListContext genericdeclarations; + GenericDeclarationList gtvDeclarations; + MethodHeaderContext header; + String name; + if (methodContext instanceof GenericmethodContext) { + GenericmethodContext gmc = (GenericmethodContext) methodContext; + genericdeclarations = gmc.genericMethodDeclaration().genericDeclarationList(); + methoddeclaration = gmc.genericMethodDeclaration().methodDeclaration(); + header = methoddeclaration.methodHeader(); + name = header.identifier().getText(); + localgenerics.putAll(createGenerics(genericdeclarations, parentClass, name, reg, generics)); + gtvDeclarations = TypeGenerator.convert(genericdeclarations, parentClass, name, reg, localgenerics); + } else { + MethoddeclContext mdc = (MethoddeclContext) methodContext; + methoddeclaration = mdc.methodDeclaration(); + header = methoddeclaration.methodHeader(); + gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); + name = header.identifier().getText(); + } + + RefTypeOrTPHOrWildcardOrGeneric retType; + if (Objects.isNull(header.refType())) { + retType = TypePlaceholder.fresh(header.getStart()); + } else { + if (header.refType() instanceof ReftypeContext reftype) { + retType = TypeGenerator.convert(reftype.typeType(), reg, generics); + } else { + retType = new Void(header.refType().getStart()); } } - return ret; - } - - private List convertFields(Java17Parser.ClassBodyContext classBodyContext, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()) { - if (classMember.classMemberDeclaration() != null) { - Java17Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration(); - if (classMemberDeclarationContext.fieldDeclaration() != null) { - ret.addAll(convert(classMember.classMemberDeclaration().fieldDeclaration(), generics)); - } else if (classMemberDeclarationContext.methodDeclaration() != null) { - // Do nothing! - } + StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>()); + ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList()); + MethodBodyContext body = methoddeclaration.methodBody(); + Block block = null; + if (body instanceof EmptymethodContext emptymethod) { + if (!Modifier.isAbstract(modifiers)) { + // TODO: Error! Abstrakte Methode ohne abstrakt Keyword } + } else { + MethodblockContext methodblock = (MethodblockContext) body; + block = stmtgen.convert(methodblock.block(), true); + } + if (parentClass.equals(new JavaClassName(name))) { + // TODO: Konstruktoren in eigener Methode behandeln + /* fieldInitializations geloescht PL 2018-11-24 */ + return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, header.getStart()); + } else { + return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, header.getStart()); } - return ret; } - public static int convert(List methodModifierContexts) { - int ret = 0; - for (Java17Parser.MethodModifierContext mod : methodModifierContexts) { - if (mod.annotation() == null) - convertModifier(mod.getText()); - } - return ret; - } - - public static int convertInterfaceModifier(List methodModifierContexts) { - int ret = 0; - for (Java17Parser.InterfaceMethodModifierContext mod : methodModifierContexts) { - if (mod.annotation() == null) - convertModifier(mod.getText()); - } - return ret; - } - - private List convert(Java17Parser.FieldDeclarationContext fieldDeclarationContext, + private List convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) { List ret = new ArrayList<>(); - int modifiers = 0; - for (Java17Parser.FieldModifierContext fieldModifierContext : fieldDeclarationContext.fieldModifier()) { - modifiers += (convert(fieldModifierContext)); - } RefTypeOrTPHOrWildcardOrGeneric fieldType; - if (fieldDeclarationContext.unannTypeOrAuto() != null - && fieldDeclarationContext.unannTypeOrAuto().unannType() != null) { - fieldType = TypeGenerator.convert(fieldDeclarationContext.unannTypeOrAuto().unannType(), reg, generics); + if (fieldDeclContext.typeType() != null) { + fieldType = TypeGenerator.convert(fieldDeclContext.typeType(), reg, generics); } else { - fieldType = TypePlaceholder.fresh(fieldDeclarationContext.variableDeclaratorList().getStart()); // PL 2019-12-06: - // variableDeclaratorList() - // eingefuegt, um - // als Token nicht - // die Modifier zu - // bekommen + // PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die + // Modifier zu bekommen + fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart()); } - for (Java17Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList() - .variableDeclarator()) { - String fieldName = convert(varCtx.variableDeclaratorId()); - fields.put(fieldName, fieldType); - if (varCtx.variableInitializer() != null) { - initializeField(varCtx, fieldType, generics); + for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) { + String fieldName = varDecl.variableDeclaratorId().getText(); + this.fields.put(fieldName, fieldType); + if (varDecl.variableInitializer() != null) { + initializeField(varDecl, fieldType, generics); } - ret.add(new Field(fieldName, fieldType, modifiers, varCtx.getStart())); + ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart())); } return ret; } @@ -443,90 +390,8 @@ public class SyntaxTreeGenerator { fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField)); } - 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.contains(m)) - ret += modifiers.get(m); - } - return ret; - } - - private int convert(Java17Parser.ClassOrInterfaceModifierContext ctx) { - if (ctx.annotation() != null) - return 0; - return convertModifier(ctx.getText()); - } - - private int convert(Java17Parser.FieldModifierContext ctx) { - if (ctx.annotation() != null) - return 0; - return convertModifier(ctx.getText()); - } - - private ClassOrInterface convertEnum(Java17Parser.EnumDeclarationContext ctx) { - return null; - } - - private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext ctx) { - if (ctx.normalInterfaceDeclaration() != null) { - return convertNormal(ctx.normalInterfaceDeclaration()); - } else { - throw new NotImplementedException(); - } - } - - private ClassOrInterface convertNormal(Java17Parser.NormalInterfaceDeclarationContext ctx) { - int modifiers = 0; - if (ctx.interfaceModifier() != null) { - for (Java17Parser.InterfaceModifierContext mod : ctx.interfaceModifier()) { - int newModifier = convert(mod); - modifiers += newModifier; - } - } - if (!Modifier.isInterface(modifiers)) - modifiers += Modifier.INTERFACE; - - JavaClassName name = reg.getName(ctx.Identifier().getText()); - - GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "", reg, - new GenericsRegistry(globalGenerics)); - - GenericDeclarationList genericParams; - if (ctx.typeParameters() != null) { - genericParams = TypeGenerator.convert(ctx.typeParameters(), name, "", reg, generics); - } else { - genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); - } - RefType superClass = ASTFactory.createObjectType(); - - List fields = convertFields(ctx.interfaceBody()); - List methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); - - List extendedInterfaces = convert(ctx.extendsInterfaces(), generics); - - return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), - genericParams, superClass, true, extendedInterfaces, ctx.getStart()); - } - - private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) { - CommonToken gtvOffset = new CommonToken(classNameIdentifier); - gtvOffset.setCharPositionInLine(gtvOffset.getCharPositionInLine() + classNameIdentifier.getText().length()); - gtvOffset.setStartIndex(gtvOffset.getStopIndex() + 1); - return new GenericDeclarationList(new ArrayList<>(), gtvOffset); + public int convertModifier(String modifier) { + return allmodifiers.get(modifier); } private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass, @@ -537,42 +402,8 @@ public class SyntaxTreeGenerator { return ret; for (Java17Parser.GenericTypeVarContext tp : ctx.genericTypeVar()) { ret.put(tp.identifier().getText(), new GenericContext(parentClass, parentMethod)); - TypeGenerator.convert(tp.typeBound(), reg, ret); + TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret); } return ret; } - - private List convert(Java17Parser.ExtendsInterfacesContext extendsInterfacesContext, - GenericsRegistry generics) { - if (extendsInterfacesContext == null) - return new ArrayList<>(); - return convert(extendsInterfacesContext.interfaceTypeList(), generics); - } - - private List convertMethods(Java17Parser.InterfaceBodyContext interfaceBodyContext, - JavaClassName parentClass, RefType superClass, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.InterfaceMemberDeclarationContext member : interfaceBodyContext.interfaceMemberDeclaration()) { - if (member.interfaceMethodDeclaration() != null) { - ret.add(this.convert(member.interfaceMethodDeclaration(), parentClass, superClass, generics)); - // new Method(name, type, modifier, params, null, genericDecls, - // member.interfaceMethodDeclaration().getStart()); - } else { - throw new NotImplementedException(); - } - } - return ret; - } - - private List convertFields(Java17Parser.InterfaceBodyContext interfaceBodyContext) { - List ret = new ArrayList<>(); - for (Java17Parser.InterfaceMemberDeclarationContext member : interfaceBodyContext.interfaceMemberDeclaration()) { - if (member.constantDeclaration() != null) { - // TODO: Erstelle hier ein Feld! - throw new NotImplementedException(); - } - } - return ret; - } - } diff --git a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java index 3244b653..da84a068 100644 --- a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java +++ b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java @@ -19,7 +19,7 @@ public class GatherNames { if (member instanceof NoclassorinterfaceContext) { continue; } - ClassorinterfacedeclContext clsoif = new ClassorinterfacedeclContext(member); + ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member; if (clsoif.interfaceDeclaration() != null) { if (pkgName != "") { nameString = pkgName + "." @@ -49,7 +49,7 @@ public class GatherNames { if (!pkgName.isEmpty()) { nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText(); } else { - nameString = clsoif.classDeclaration().getText(); + nameString = clsoif.classDeclaration().identifier().getText(); } // Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry // anfügen: diff --git a/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java b/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java index d9ab804c..b2d436c7 100644 --- a/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java +++ b/src/main/java/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java @@ -10,29 +10,31 @@ import java.util.*; public class JavaClassRegistry { final Map existingClasses = new HashMap<>(); - public JavaClassRegistry(Map initialNames){ - for(String name : initialNames.keySet()){ + public JavaClassRegistry(Map initialNames) { + for (String name : initialNames.keySet()) { existingClasses.put(new JavaClassName(name), initialNames.get(name)); } } public JavaClassName getName(String className) { - for(JavaClassName name : existingClasses.keySet()){ - if(name.equals(new JavaClassName(className)))return name; + for (JavaClassName name : existingClasses.keySet()) { + if (name.equals(new JavaClassName(className))) + return name; } throw new NotImplementedException(); } @Override - public String toString(){ + public String toString() { return existingClasses.toString(); } public List getAllFromPackage(String packageName) { List ret = new ArrayList<>(); - for(JavaClassName className : this.existingClasses.keySet()){ - JavaClassName toCompare = new JavaClassName(packageName + "." + JavaClassName.stripClassName(className.toString())); - if(toCompare.toString().equals(className.toString())){ + for (JavaClassName className : this.existingClasses.keySet()) { + JavaClassName toCompare = new JavaClassName( + packageName + "." + JavaClassName.stripClassName(className.toString())); + if (toCompare.toString().equals(className.toString())) { ret.add(className); } } diff --git a/src/test/java/parser/AntlrTest.jav b/src/test/java/parser/AntlrTest.jav index 31ab067d..1d4532f4 100644 --- a/src/test/java/parser/AntlrTest.jav +++ b/src/test/java/parser/AntlrTest.jav @@ -1,3 +1,5 @@ +import java.lang.Boolean; + class Test{ method(){ if(true)i++; diff --git a/src/test/java/parser/GeneralParserTest.java b/src/test/java/parser/GeneralParserTest.java index b4328147..5f038c24 100644 --- a/src/test/java/parser/GeneralParserTest.java +++ b/src/test/java/parser/GeneralParserTest.java @@ -12,44 +12,44 @@ import de.dhbwstuttgart.parser.JavaTXParser; import org.junit.Test; - /** * Dieser Test pr�ft nur, ob .java-Dateien fehlerfrei geparst werden. * Der dabei erstellte Syntaxbaum wird nicht kontrolliert. + * * @author janulrich * */ -public class GeneralParserTest{ - private static final String rootDirectory = System.getProperty("user.dir")+"/src/test/java/parser/"; - - @Test - public void run(){ +public class GeneralParserTest { + private static final String rootDirectory = System.getProperty("user.dir") + "/src/test/java/parser/"; + + @Test + public void run() { - List filenames = new ArrayList(); /* - filenames.add("NewTest.jav"); - filenames.add("FieldInitializationTest.jav"); - filenames.add("ImportTest.jav"); - filenames.add("CastTest.jav"); - filenames.add("StatementsTest.jav"); - //filenames.add("Methods.jav"); - filenames.add("ImportTestGeneric.jav"); - filenames.add("CastTest.jav"); - //filenames.add("BoundedParameter.jav"); - //filenames.add("GenericFieldVarTest.jav"); - filenames.add("FieldVarTest.jav"); - filenames.add("StructuralTypes.jav"); - */ -// filenames.add("ExtendsTest.jav"); - filenames.add("PackageNameTest.jav"); - try{ + * filenames.add("NewTest.jav"); + * filenames.add("FieldInitializationTest.jav"); + * filenames.add("ImportTest.jav"); + * filenames.add("CastTest.jav"); + * filenames.add("StatementsTest.jav"); + * //filenames.add("Methods.jav"); + * filenames.add("ImportTestGeneric.jav"); + * filenames.add("CastTest.jav"); + * //filenames.add("BoundedParameter.jav"); + * //filenames.add("GenericFieldVarTest.jav"); + * filenames.add("FieldVarTest.jav"); + * filenames.add("StructuralTypes.jav"); + * filenames.add("ExtendsTest.jav"); + * filenames.add("PackageNameTest.jav"); + */ + filenames.add("AntlrTest.jav"); + try { new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList())); - }catch(Exception exc){ + } catch (Exception exc) { exc.printStackTrace(); fail(); } - assertTrue("Tests durchlaufen",filenames.size()>0); + assertTrue("Tests durchlaufen", filenames.size() > 0); } - + }