diff --git a/resources/syntaxtreegenerator/javFiles/Switch.jav b/resources/syntaxtreegenerator/javFiles/Switch.jav index 5d3a1ff5..20ff2a4f 100644 --- a/resources/syntaxtreegenerator/javFiles/Switch.jav +++ b/resources/syntaxtreegenerator/javFiles/Switch.jav @@ -1,4 +1,5 @@ import java.lang.Integer; +import java.lang.Boolean; import java.lang.String; import java.lang.Object; diff --git a/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Parser.g4 b/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Parser.g4 index c2781f1c..54dca0d8 100644 --- a/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Parser.g4 +++ b/src/main/antlr4/de/dhbwstuttgart/parser/antlr/Java17Parser.g4 @@ -199,11 +199,7 @@ interfaceMemberDeclaration : constDeclaration # interfaceconst | interfaceMethodDeclaration # interfacemethod | genericInterfaceMethodDeclaration # genericinterfacemethod - | interfaceDeclaration # subinterface - | annotationTypeDeclaration # interfaceannotationtype - | classDeclaration # interfaceclass - | enumDeclaration # interfaceenum - | recordDeclaration # interfacerecord // Java17 + | classOrInterface # subclassorinterface ; constDeclaration @@ -391,11 +387,7 @@ annotationTypeElementDeclaration annotationTypeElementRest : typeType annotationMethodOrConstantRest ';' - | classDeclaration ';'? - | interfaceDeclaration ';'? - | enumDeclaration ';'? - | annotationTypeDeclaration ';'? - | recordDeclaration ';'? // Java17 + | classOrInterface ';'? ; annotationMethodOrConstantRest diff --git a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java index c1d2aa53..a1c9424e 100644 --- a/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java +++ b/src/main/java/de/dhbwstuttgart/parser/scope/GatherNames.java @@ -1,88 +1,136 @@ package de.dhbwstuttgart.parser.scope; -import java.util.*; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; -import org.antlr.v4.runtime.ParserRuleContext; - -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassDeclarationContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext; -import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; import de.dhbwstuttgart.environment.PackageCrawler; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.antlr.Java17Parser; +import de.dhbwstuttgart.parser.antlr.Java17Parser.AnnotationTypeElementDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassBodyDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassOrInterfaceContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.ClassorinterfacedeclContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.EnumConstantsContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfaceBodyDeclarationContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.InterfacememberContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberclassorinterfaceContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.MemberdeclContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.NoclassorinterfaceContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; +import de.dhbwstuttgart.parser.antlr.Java17Parser.SubclassorinterfaceContext; public class GatherNames { public static Map getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { Map ret = new HashMap<>(); - String pkgName = getPackageName(ctx); - String nameString = ""; - for (Java17Parser.ClassOrInterfaceContext member : ctx.classOrInterface()) { - if (member instanceof NoclassorinterfaceContext) { + for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) { + if (clsoifctx instanceof NoclassorinterfaceContext) { continue; } - ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member; - String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName(); - String classname = fullname.substring(fullname.indexOf("$") + 1); - int numGenerics = 0; - /* - * Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden. - */ - switch (classname) { - case "ClassDeclarationContext": - if (!pkgName.isEmpty()) { - nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText(); - } else { - nameString = clsoif.classDeclaration().identifier().getText(); - } - numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0; - ret.put(nameString, numGenerics); - break; - case "EnumDeclarationContext": - if (!pkgName.isEmpty()) { - nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText(); - } else { - nameString = clsoif.enumDeclaration().identifier().getText(); - } - numGenerics = 0; - ret.put(nameString, numGenerics); - break; - case "InterfaceDeclarationContext": - if (pkgName != "") { - nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText(); - } else { - nameString = clsoif.interfaceDeclaration().identifier().getText(); - } - numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0; - ret.put(nameString, numGenerics); - break; - case "AnnotationTypeDeclarationContext": - if (pkgName != "") { - nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText(); - } else { - nameString = clsoif.annotationTypeDeclaration().identifier().getText(); - } - numGenerics = 0; - ret.put(nameString, numGenerics); - break; - case "RecordDeclarationContext": - if (pkgName != "") { - nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText(); - } else { - nameString = clsoif.recordDeclaration().identifier().getText(); - } - numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0; - ret.put(nameString, numGenerics); - break; - default: - throw new NotImplementedException(); - } + ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, classLoader)); } ret.putAll(getImports(ctx, packages, classLoader)); return ret; } + public static Map getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { + Map ret = new HashMap<>(); + ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) clsoifctx; + String nameString = ""; + String fullname = clsoif.getChild(clsoif.getChildCount() - 1).getClass().getName(); + String classname = fullname.substring(fullname.indexOf("$") + 1); + int numGenerics = 0; + /* + * Es werden alle Namen gesammelt, die syntaktisch von Java-TX (sprich der Grammatik) erkannt werden. Auch wenn z.B. Annotationen oder Enumerationen noch nicht im Compiler implementiert sind. Die "NotImplementedException" wird dann im "SyntaxTreeGenerator" geworfen. Das Statement soll als Vorbereitung dienen, für den Fall, dass weitere Sprachkonstrukte in den Compiler aufgenommen werden. + */ + switch (classname) { + case "ClassDeclarationContext": + if (!pkgName.isEmpty()) { + nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText(); + } else { + nameString = clsoif.classDeclaration().identifier().getText(); + } + numGenerics = clsoif.classDeclaration().genericDeclarationList() != null ? clsoif.classDeclaration().genericDeclarationList().genericTypeVar().size() : 0; + ret.put(nameString, numGenerics); + ret.putAll(getNames(clsoif.classDeclaration().classBody().classBodyDeclaration(), pkgName, packages, classLoader)); + break; + case "EnumDeclarationContext": + if (!pkgName.isEmpty()) { + nameString = pkgName + "." + clsoif.enumDeclaration().identifier().getText(); + } else { + nameString = clsoif.enumDeclaration().identifier().getText(); + } + numGenerics = 0; + ret.put(nameString, numGenerics); + EnumConstantsContext enumConstants = clsoif.enumDeclaration().enumConstants(); + if (!Objects.isNull(enumConstants)) { + for (EnumConstantContext enumConstant : enumConstants.enumConstant()) { + ClassBodyContext enumConstClassBody = enumConstant.classBody(); + if (!Objects.isNull(enumConstClassBody)) { + ret.putAll(getNames(enumConstClassBody.classBodyDeclaration(), pkgName, packages, classLoader)); + } + } + } + break; + case "InterfaceDeclarationContext": + if (pkgName != "") { + nameString = pkgName + "." + clsoif.interfaceDeclaration().identifier().getText(); + } else { + nameString = clsoif.interfaceDeclaration().identifier().getText(); + } + numGenerics = clsoif.interfaceDeclaration().genericDeclarationList() != null ? clsoif.interfaceDeclaration().genericDeclarationList().genericTypeVar().size() : 0; + ret.put(nameString, numGenerics); + for (InterfaceBodyDeclarationContext ifbody : clsoif.interfaceDeclaration().interfaceBody().interfaceBodyDeclaration()) { + if (ifbody instanceof InterfacememberContext member && member.interfaceMemberDeclaration() instanceof SubclassorinterfaceContext sub) { + ret.putAll(getNames(sub.classOrInterface(), pkgName, packages, classLoader)); + } + } + break; + case "AnnotationTypeDeclarationContext": + if (pkgName != "") { + nameString = pkgName + "." + clsoif.annotationTypeDeclaration().identifier().getText(); + } else { + nameString = clsoif.annotationTypeDeclaration().identifier().getText(); + } + numGenerics = 0; + ret.put(nameString, numGenerics); + for (AnnotationTypeElementDeclarationContext anTypeElem : clsoif.annotationTypeDeclaration().annotationTypeBody().annotationTypeElementDeclaration()) { + ClassOrInterfaceContext anClsoifctx = anTypeElem.annotationTypeElementRest().classOrInterface(); + if (!Objects.isNull(anClsoifctx)) { + ret.putAll(getNames(anClsoifctx, pkgName, packages, classLoader)); + } + } + break; + case "RecordDeclarationContext": + if (pkgName != "") { + nameString = pkgName + "." + clsoif.recordDeclaration().identifier().getText(); + } else { + nameString = clsoif.recordDeclaration().identifier().getText(); + } + numGenerics = clsoif.recordDeclaration().genericDeclarationList() != null ? clsoif.recordDeclaration().genericDeclarationList().genericTypeVar().size() : 0; + ret.put(nameString, numGenerics); + ret.putAll(getNames(clsoif.recordDeclaration().recordBody().classBodyDeclaration(), pkgName, packages, classLoader)); + break; + default: + throw new NotImplementedException(); + } + return ret; + } + + public static Map getNames(List clsBodyDecl, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { + Map ret = new HashMap<>(); + for (ClassBodyDeclarationContext clsbody : clsBodyDecl) { + if (clsbody instanceof MemberdeclContext member && member.memberDeclaration() instanceof MemberclassorinterfaceContext memberclsoifctx) { + ret.putAll(getNames(memberclsoifctx.classOrInterface(), pkgName, packages, classLoader)); + } + } + return ret; + } + public static Map getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { Map ret = new HashMap<>(); // ret.putAll(packages.getClassNames("java.lang"));