diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java index 57e80615..35f0fcd0 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/ASTGen.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import java.util.HashMap; import java.util.HashSet; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -17,10 +18,14 @@ 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.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.ModifierContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; @@ -29,13 +34,17 @@ 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.statement.Block; import de.dhbwstuttgart.syntaxtree.statement.Statement; public class ASTGen { @@ -69,6 +78,8 @@ public class ASTGen { 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() { @@ -110,8 +121,7 @@ public class ASTGen { int modifiers = 0; if (!clsoif.classOrInterfaceModifier().isEmpty()) { for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) { - int newMod = convertModifier(mod); - modifiers += newMod; + modifiers += allmodifiers.get(mod.getText()); } } fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden @@ -145,20 +155,116 @@ public class ASTGen { 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); + 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()); + } + switch (member.memberDeclaration()) { + case MemberclassorinterfaceContext memberclsoif: { + break; + } + case MemberfieldContext memberfield: { + fielddecl.addAll(convert(memberfield.fieldDeclaration(), membermodifiers, generics)); + break; + } + case MembermethodContext membermethod: { + // TODO: parse methods + 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); + } - private RefType convert(Java17Parser.TypeTypeContext typeType) { + /** + * 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 { @@ -175,56 +281,51 @@ public class ASTGen { } } + 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(Java17Parser.MethodDeclarationContext methodDeclarationContext, JavaClassName parentClass, RefType superClass, GenericsRegistry generics) { return null; } - private List convertFields(Java17Parser.ClassBodyContext classBodyContext, GenericsRegistry generics) { - List ret = new ArrayList<>(); - for (Java17Parser.ClassBodyDeclarationContext classBody : classBodyContext.classBodyDeclaration()) { - if (classBody instanceof MemberdeclContext) { - MemberdeclContext memberdecl = new MemberdeclContext(classBody); - int modifiers = 0; - for (ModifierContext mod : memberdecl.modifier()) { - modifiers += convert(mod); - } - if (memberdecl.memberDeclaration() instanceof MemberfieldContext) { - ret.addAll( - convert(new MemberfieldContext(memberdecl.memberDeclaration()).fieldDeclaration(), modifiers, generics)); - } - } - } - return ret; - } - private List convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) { List ret = new ArrayList<>(); RefTypeOrTPHOrWildcardOrGeneric fieldType; if (fieldDeclContext.typeType() != null) { - // TODO: fieldType = TypeGenerator.convert() + 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; } - private int convert(Java17Parser.ClassOrInterfaceModifierContext ctx) { - if (ctx.annotation() != null) - return 0; - return convertModifier(ctx.getText()); - } - - private int convert(Java17Parser.ModifierContext ctx) { - return convertModifier(ctx.getText()); + // 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) { - int ret = 0; - for (String m : this.allmodifiers.keySet()) { - if (modifier.contains(m)) - ret += allmodifiers.get(m); - } - return ret; + return allmodifiers.get(modifier); } private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass, @@ -239,11 +340,4 @@ public class ASTGen { } return ret; } - - 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); - } } diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index bd9289ee..7cb16ff7 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.antlr.Java17Parser; -import de.dhbwstuttgart.parser.antlr.Java17Parser.UnannClassType_lfno_unannClassOrInterfaceTypeContext; import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;