Changed GatherNames to add types declared inside of other types to the JavaClassRegistry

This commit is contained in:
luca9913 2023-07-07 09:24:45 +02:00
parent 492cbe48e9
commit 939d402b1e
3 changed files with 118 additions and 77 deletions

View File

@ -1,4 +1,5 @@
import java.lang.Integer; import java.lang.Integer;
import java.lang.Boolean;
import java.lang.String; import java.lang.String;
import java.lang.Object; import java.lang.Object;

View File

@ -199,11 +199,7 @@ interfaceMemberDeclaration
: constDeclaration # interfaceconst : constDeclaration # interfaceconst
| interfaceMethodDeclaration # interfacemethod | interfaceMethodDeclaration # interfacemethod
| genericInterfaceMethodDeclaration # genericinterfacemethod | genericInterfaceMethodDeclaration # genericinterfacemethod
| interfaceDeclaration # subinterface | classOrInterface # subclassorinterface
| annotationTypeDeclaration # interfaceannotationtype
| classDeclaration # interfaceclass
| enumDeclaration # interfaceenum
| recordDeclaration # interfacerecord // Java17
; ;
constDeclaration constDeclaration
@ -391,11 +387,7 @@ annotationTypeElementDeclaration
annotationTypeElementRest annotationTypeElementRest
: typeType annotationMethodOrConstantRest ';' : typeType annotationMethodOrConstantRest ';'
| classDeclaration ';'? | classOrInterface ';'?
| interfaceDeclaration ';'?
| enumDeclaration ';'?
| annotationTypeDeclaration ';'?
| recordDeclaration ';'? // Java17
; ;
annotationMethodOrConstantRest annotationMethodOrConstantRest

View File

@ -1,88 +1,136 @@
package de.dhbwstuttgart.parser.scope; 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.environment.PackageCrawler;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.antlr.Java17Parser; 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 class GatherNames {
public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { public static Map<String, Integer> getNames(SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>(); Map<String, Integer> ret = new HashMap<>();
String pkgName = getPackageName(ctx); for (Java17Parser.ClassOrInterfaceContext clsoifctx : ctx.classOrInterface()) {
String nameString = ""; if (clsoifctx instanceof NoclassorinterfaceContext) {
for (Java17Parser.ClassOrInterfaceContext member : ctx.classOrInterface()) {
if (member instanceof NoclassorinterfaceContext) {
continue; continue;
} }
ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member; ret.putAll(getNames(clsoifctx, getPackageName(ctx), packages, classLoader));
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(getImports(ctx, packages, classLoader)); ret.putAll(getImports(ctx, packages, classLoader));
return ret; return ret;
} }
public static Map<String, Integer> getNames(ClassOrInterfaceContext clsoifctx, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> 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<String, Integer> getNames(List<ClassBodyDeclarationContext> clsBodyDecl, String pkgName, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> 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<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException { public static Map<String, Integer> getImports(Java17Parser.SrcfileContext ctx, PackageCrawler packages, ClassLoader classLoader) throws ClassNotFoundException {
Map<String, Integer> ret = new HashMap<>(); Map<String, Integer> ret = new HashMap<>();
// ret.putAll(packages.getClassNames("java.lang")); // ret.putAll(packages.getClassNames("java.lang"));