diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 1c7fbf86..e66267de 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -1,7 +1,10 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; +import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; @@ -11,25 +14,29 @@ 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.BlockContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceModifierContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceTypeContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.ConstructorDeclarationContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.ConstructordeclContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.EmptymethodContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericConstructorDeclarationContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericDeclarationListContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericInterfaceMethodDeclarationContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericconstructorContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericinterfacemethodContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.GenericmethodContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceCommonBodyDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceMethodDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceMethodModifierContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceconstContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacemethodContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberconstructorContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext; @@ -56,12 +63,12 @@ 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.Block; +import de.dhbwstuttgart.syntaxtree.statement.Statement; 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 SyntaxTreeGenerator { private JavaClassRegistry reg; @@ -96,6 +103,8 @@ public class SyntaxTreeGenerator { this.allmodifiers.put(Modifier.toString(Modifier.INTERFACE), Modifier.INTERFACE); this.allmodifiers.put("sealed", 4096); this.allmodifiers.put("non-sealed", 8192); + this.allmodifiers.put("default", 16384); + this.allmodifiers.put("strictfp", 32768); } public JavaClassRegistry getReg() { @@ -141,10 +150,12 @@ public class SyntaxTreeGenerator { } } fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden - if (clsoif.classDeclaration() != null) { + if (!Objects.isNull(clsoif.classDeclaration())) { newClass = convertClass(clsoif.classDeclaration(), modifiers); + } else if (!Objects.isNull(clsoif.interfaceDeclaration())) { + newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers); + // TODO: else if(!Objects.isNull(clsoif.recordDeclaration())){ } else { - // TODO: newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers); throw new NotImplementedException(); } classes.add(newClass); @@ -249,6 +260,115 @@ public class SyntaxTreeGenerator { methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); } + private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext 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()); + } + if (!Modifier.isInterface(modifiers)) + modifiers += Modifier.INTERFACE; + + GenericsRegistry generics = createGenerics(ctx.genericDeclarationList(), name, "", reg, + new GenericsRegistry(globalGenerics)); + + GenericDeclarationList genericParams; + if (!Objects.isNull(ctx.genericDeclarationList())) { + genericParams = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics); + } else { + genericParams = createEmptyGenericDeclarationList(ctx.identifier().getStart()); + } + RefType superClass = ASTFactory.createObjectType(); + + List fields = new ArrayList<>(); + List methods = new ArrayList<>(); + for (InterfaceBodyDeclarationContext interfacebody : ctx.interfaceBody().interfaceBodyDeclaration()) { + if (interfacebody instanceof Java17Parser.EmptyinterfaceContext) { + continue; + } else { + InterfacememberContext interfacemember = (InterfacememberContext) interfacebody; + int membermodifiers = 0; + for (ModifierContext mod : interfacemember.modifier()) { + membermodifiers += allmodifiers.get(mod.getText()); + } + int methodmodifiers = membermodifiers; + switch (interfacemember.interfaceMemberDeclaration()) { + case InterfaceconstContext constant: + fields.add(convert(constant)); + break; + case InterfacemethodContext method: + InterfaceMethodDeclarationContext declaration = method.interfaceMethodDeclaration(); + for (InterfaceMethodModifierContext mod : declaration.interfaceMethodModifier()) { + methodmodifiers += allmodifiers.get(mod.getText()); + } + InterfaceCommonBodyDeclarationContext commonbody = declaration.interfaceCommonBodyDeclaration(); + methods.add(convert(methodmodifiers, commonbody, new GenericDeclarationList(new ArrayList<>(), + commonbody.getStart()), generics)); + break; + case GenericinterfacemethodContext genericmethod: + GenericInterfaceMethodDeclarationContext genericdeclaration = genericmethod + .genericInterfaceMethodDeclaration(); + int genericmethodmodifiers = 0; + for (InterfaceMethodModifierContext mod : genericdeclaration.interfaceMethodModifier()) { + genericmethodmodifiers += allmodifiers.get(mod.getText()); + } + commonbody = genericdeclaration.interfaceCommonBodyDeclaration(); + GenericDeclarationList gtv = TypeGenerator.convert(genericdeclaration.genericDeclarationList(), name, + commonbody.identifier().getText(), reg, generics); + methods.add(convert(genericmethodmodifiers, commonbody, gtv, generics)); + break; + default: + throw new NotImplementedException(); + } + } + } + List extendedInterfaces = new ArrayList<>(); + if (!Objects.isNull(ctx.EXTENDS())) { + extendedInterfaces.addAll(convert(ctx.typeList(0), 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); + } + + private Field convert(InterfaceconstContext constant) { + // TODO: Erstelle hier ein Feld! + throw new NotImplementedException(); + } + + private Method convert(int modifiers, InterfaceCommonBodyDeclarationContext bodydeclaration, + GenericDeclarationList gtvDeclarations, + GenericsRegistry generics) { + String name = bodydeclaration.identifier().getText(); + + RefTypeOrTPHOrWildcardOrGeneric retType; + if (Objects.isNull(bodydeclaration.refType())) { + retType = TypePlaceholder.fresh(bodydeclaration.getStart()); + } else { + if (bodydeclaration.refType() instanceof ReftypeContext reftype) { + retType = TypeGenerator.convert(reftype.typeType(), reg, generics); + } else { + retType = new Void(bodydeclaration.refType().getStart()); + } + } + StatementGenerator stmtgen = new StatementGenerator(reg, generics, fields, new HashMap<>()); + ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList()); + MethodBodyContext body = bodydeclaration.methodBody(); + Block block = null; + if (!(body instanceof EmptymethodContext)) { + MethodblockContext methodblock = (MethodblockContext) body; + block = stmtgen.convert(methodblock.block(), true); + } + return new Method(modifiers, name, retType, paramlist, block, gtvDeclarations, bodydeclaration.getStart()); + } + /** * http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.9 */ @@ -281,7 +401,8 @@ public class SyntaxTreeGenerator { } private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) { - if (typeType.classOrInterfaceType() != null) { + ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType(); + if (supertypecontext != null && supertypecontext.DOT().size() > 0) { throw new NotImplementedException(); } else { RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(