Debugging komplett für test parser/AntlrTest.jav

This commit is contained in:
luca9913 2023-03-10 20:30:15 +01:00
parent 043dda660b
commit 1919e34eed
8 changed files with 286 additions and 850 deletions

View File

@ -11,6 +11,7 @@ import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SourceFileContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
@ -69,11 +70,16 @@ public class CompilationEnvironment {
throws ClassNotFoundException, IOException { throws ClassNotFoundException, IOException {
Map<String, Integer> allNames; Map<String, Integer> allNames;
SourceFileContext tree = JavaTXParser.parse(forSourceFile); SourceFileContext tree = JavaTXParser.parse(forSourceFile);
allNames = GatherNames.getNames(tree, packageCrawler, classLoader); if (tree instanceof SrcfileContext srcfile) {
for (Class c : loadDefaultPackageClasses(forSourceFile, classLoader)) { allNames = GatherNames.getNames((SrcfileContext) tree, packageCrawler, classLoader);
allNames.put(c.getName(), c.getTypeParameters().length); 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<Class> loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader) public static List<Class> loadDefaultPackageClasses(File forSourceFile, ClassLoader classLoader)

View File

@ -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<JavaClassName> imports = new HashSet<>();
HashMap<String, Integer> allmodifiers = new HashMap<>();
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
// bekommen
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>();
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
List<Statement> 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<ClassOrInterface> 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<String, Integer> 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<Field> fielddecl = new ArrayList<>();
List<Method> methods = new ArrayList<>();
List<Constructor> constructors = new ArrayList<>();
Boolean isInterface = false;
List<RefType> implementedInterfaces = new ArrayList<>();
List<RefType> 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<RefType> convert(Java17Parser.TypeListContext ctx, GenericsRegistry generics) {
List<RefType> 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<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers,
GenericsRegistry generics) {
List<Field> 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;
}
}

View File

@ -325,11 +325,9 @@ public class StatementGenerator {
} }
private Statement convert(Java17Parser.ConditionalstmtContext stmt) { private Statement convert(Java17Parser.ConditionalstmtContext stmt) {
if (stmt.statement().size() < 2)
throw new NotImplementedException();
Expression expr = convert(stmt.parExpression().expression()); Expression expr = convert(stmt.parExpression().expression());
Statement thenBlock = convert(stmt.statement(0)); 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()); return new IfStmt(TypePlaceholder.fresh(stmt.getStart()), expr, thenBlock, elseBlock, stmt.getStart());
} }
@ -492,7 +490,7 @@ public class StatementGenerator {
case PrimaryexpressionContext primary: case PrimaryexpressionContext primary:
return convert(primary.primary()); return convert(primary.primary());
case DottedexpressionContext dotted: case DottedexpressionContext dotted:
return convert(new DottedexpressionContext(expression), expression.getStart()); return convert((DottedexpressionContext) expression, expression.getStart());
case MethodcallexpressionContext methodcall: case MethodcallexpressionContext methodcall:
return convert(methodcall.methodCall(), methodcall.getStart()); return convert(methodcall.methodCall(), methodcall.getStart());
case NewinstanceexpressionContext newinstance: case NewinstanceexpressionContext newinstance:

View File

@ -1,59 +1,75 @@
package de.dhbwstuttgart.parser.SyntaxTreeGenerator; 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.environment.PackageCrawler;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import java.lang.ClassNotFoundException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.antlr.Java17Parser; 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.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.NoclassorinterfaceContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.ReftypeContext;
import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext; import de.dhbwstuttgart.parser.antlr.Java17Parser.SrcfileContext;
import de.dhbwstuttgart.parser.scope.GatherNames; import de.dhbwstuttgart.parser.scope.GatherNames;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; 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.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.Void;
import java.lang.reflect.Modifier; import de.dhbwstuttgart.syntaxtree.statement.Block;
import java.net.URL; import de.dhbwstuttgart.syntaxtree.statement.Statement;
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();
* }
*/
public class SyntaxTreeGenerator { public class SyntaxTreeGenerator {
private JavaClassRegistry reg; private JavaClassRegistry reg;
private final GenericsRegistry globalGenerics; private final GenericsRegistry globalGenerics;
private String pkgName = ""; private String pkgName = "";
Set<JavaClassName> imports = new HashSet<>(); Set<JavaClassName> imports = new HashSet<>();
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>(); // PL 2018-11-01 fields eingefuegt, HashMap<String, Integer> allmodifiers = new HashMap<>();
// damit die fields immer die gleiche // PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
// TPH bekommen // bekommen
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>();
List<Statement> fieldInitializations = new ArrayList<>(); // PL 2019-10-23: Muss für jede Klasse neu initilisiert // PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
// werden List<Statement> fieldInitializations = new ArrayList<>();
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics) { public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics) {
// Die Generics müssen während des Bauens des AST erstellt werden, // Die Generics müssen während des Bauens des AST erstellt werden,
@ -62,30 +78,26 @@ public class SyntaxTreeGenerator {
// globalen Datenbank benötigt. // globalen Datenbank benötigt.
this.globalGenerics = globalGenerics; this.globalGenerics = globalGenerics;
this.reg = reg; 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() { public JavaClassRegistry getReg() {
return this.reg; 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) { public String convertQualifiedName(Java17Parser.QualifiedNameContext ctx) {
String ret = ""; String ret = "";
for (Java17Parser.IdentifierContext ident : ctx.identifier()) { for (Java17Parser.IdentifierContext ident : ctx.identifier()) {
@ -98,111 +110,54 @@ public class SyntaxTreeGenerator {
} }
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader) public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, ClassLoader classLoader)
throws ClassNotFoundException { throws ClassNotFoundException, NotImplementedException {
SrcfileContext srcfile = new SrcfileContext(ctx); SrcfileContext srcfile;
List<ClassOrInterface> classes = new ArrayList<>();
if (ctx instanceof Java17Parser.SrcfileContext) {
srcfile = (SrcfileContext) ctx;
} else {
return new SourceFile(this.pkgName, classes, this.imports);
}
if (srcfile.packageDeclaration() != null) if (srcfile.packageDeclaration() != null)
this.pkgName = convert(srcfile.packageDeclaration()); this.pkgName = convert(srcfile.packageDeclaration());
List<ClassOrInterface> classes = new ArrayList<>(); Map<String, Integer> imports = GatherNames.getImports(srcfile, packageCrawler, classLoader);
Map<String, Integer> imports = GatherNames.getImports(ctx, packageCrawler, classLoader);
this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); 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; ClassorinterfacedeclContext clsoif;
if (member instanceof NoclassorinterfaceContext) { if (type instanceof NoclassorinterfaceContext) {
continue; continue;
} else { } else {
clsoif = new ClassorinterfacedeclContext(member); clsoif = (ClassorinterfacedeclContext) type;
} }
ClassOrInterface newClass; ClassOrInterface newClass;
int modifiers = 0; int modifiers = 0;
if (!clsoif.classOrInterfaceModifier().isEmpty()) { if (!clsoif.classOrInterfaceModifier().isEmpty()) {
for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) { for (Java17Parser.ClassOrInterfaceModifierContext mod : clsoif.classOrInterfaceModifier()) {
int newModifier = convert(mod); modifiers += allmodifiers.get(mod.getText());
modifiers += newModifier;
} }
} }
fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden fieldInitializations = new ArrayList<>(); // PL 2019-10-22: muss für jede Klasse neu initilisiert werden
if (clsoif.classDeclaration() != null) { if (clsoif.classDeclaration() != null) {
newClass = convertClass(clsoif.classDeclaration()); newClass = convertClass(clsoif.classDeclaration(), modifiers);
} else { } else {
newClass = convertInterface(clsoif.interfaceDeclaration()); // TODO: newClass = convertInterface(clsoif.interfaceDeclaration(), modifiers);
throw new NotImplementedException();
} }
classes.add(newClass); classes.add(newClass);
} }
return new SourceFile(this.pkgName, classes, this.imports); if (classes.size() > 0) {
} 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);
} else { } else {
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart()); throw new NotImplementedException("SourceFile enthält keine Klassen");
}
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());
} }
} }
private ClassOrInterface convertClass(Java17Parser.ClassDeclarationContext ctx) { private String convert(Java17Parser.PackageDeclarationContext ctx) {
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + ctx.identifier().getText(); 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 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? if (!name.toString().equals(className)) { // Kommt die Klasse schon in einem anderen Package vor?
throw new TypeinferenceException( throw new TypeinferenceException(
@ -213,94 +168,82 @@ public class SyntaxTreeGenerator {
Token offset = ctx.getStart(); Token offset = ctx.getStart();
GenericDeclarationList genericClassParameters; GenericDeclarationList genericClassParameters;
if (ctx.genericDeclarationList() == null) { if (ctx.genericDeclarationList() == null) {
genericClassParameters = createEmptyGenericDeclarationList(ctx.identifier().getStop()); genericClassParameters = new GenericDeclarationList(new ArrayList<>(), ctx.identifier().getStop());
} else { } else {
genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics); genericClassParameters = TypeGenerator.convert(ctx.genericDeclarationList(), name, "", reg, generics);
} }
RefType superClass; RefType superClass;
if (ctx.EXTENDS() != null) { if (ctx.EXTENDS() != null) {
superClass = convert(ctx.typeType()); superClass = convertSuperType(ctx.typeType());
} else { } else {
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
} }
List<Field> fielddecl = convertFields(ctx.classBody(), generics); List<Field> fielddecl = new ArrayList<>();
// fieldInitializations = generateFieldInitializations(ctx.classBody(),
// generics);
List<Method> methodsAndConstructors = convertMethods(ctx.classBody(), name, superClass, generics);
List<Method> methods = new ArrayList<>(); List<Method> methods = new ArrayList<>();
List<Constructor> konstruktoren = new ArrayList<>(); List<Constructor> constructors = new ArrayList<>();
// int noOfMethods = methods.size(); Boolean isInterface = false;
for (Method m : methodsAndConstructors) { List<RefType> implementedInterfaces = new ArrayList<>();
if (m instanceof Constructor) { List<RefType> permittedSubtypes = new ArrayList<>();
konstruktoren.add((Constructor) m); 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 { } 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<RefType> implementedInterfaces = convert(ctx.superinterfaces(), generics);
return new ClassOrInterface(modifiers, name, fielddecl, 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)), offset)),
methods, konstruktoren, genericClassParameters, superClass, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
isInterface, implementedInterfaces, offset);
}
/*
* private List<Statement>
* generateFieldInitializations(Java17Parser.ClassBodyContext classBodyContext,
* GenericsRegistry generics) {
* List<Statement> 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<RefType> convert(Java17Parser.SuperinterfacesContext ctx, GenericsRegistry generics) {
if (ctx == null)
return new ArrayList<>();
return convert(ctx.interfaceTypeList(), generics);
}
private List<RefType> convert(Java17Parser.InterfaceTypeListContext ctx, GenericsRegistry generics) {
List<RefType> ret = new ArrayList<>();
for (Java17Parser.InterfaceTypeContext interfaceType : ctx.interfaceType()) {
ret.add((RefType) TypeGenerator.convert(interfaceType.classType(), reg, generics));
}
return ret;
} }
/** /**
@ -311,12 +254,11 @@ public class SyntaxTreeGenerator {
RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset);
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /* //
* , //
* fieldInitializations return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset); // fieldInitializations
* geloescht PL // geloescht PL
* 2018-11-24 // 2018-11-24
*/);
} }
/* /*
@ -329,105 +271,110 @@ public class SyntaxTreeGenerator {
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(fieldInitializations), offset); Block block = new Block(new ArrayList<>(fieldInitializations), offset);
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /* return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
* ,
* fieldInitializations * fieldInitializations
* geloescht PL * geloescht PL
* 2018-11-24 * 2018-11-24
*/); */);
} }
private RefType convert(Java17Parser.SuperclassContext superclass) { private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) {
if (superclass.classType().classOrInterfaceType() != null) { if (typeType.classOrInterfaceType() != null) {
throw new NotImplementedException(); throw new NotImplementedException();
} else { } else {
RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(superclass.classType().Identifier().getText(), RefTypeOrTPHOrWildcardOrGeneric ret = TypeGenerator.convertTypeName(
superclass.classType().typeArguments(), typeType.classOrInterfaceType().typeIdentifier().getText(),
superclass.getStart(), reg, globalGenerics); typeType.classOrInterfaceType().typeArguments()
.get(typeType.classOrInterfaceType().typeArguments().size() - 1),
typeType.getStart(), reg, globalGenerics);
if (ret instanceof RefType) { if (ret instanceof RefType) {
return (RefType) ret; return (RefType) ret;
} else { } 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<Method> convertMethods(Java17Parser.ClassBodyContext classBodyContext, private List<RefType> convert(Java17Parser.TypeListContext ctx, GenericsRegistry generics) {
JavaClassName parentClass, RefType superClass, GenericsRegistry generics) { List<RefType> ret = new ArrayList<>();
List<Method> ret = new ArrayList<>(); for (Java17Parser.TypeTypeContext type : ctx.typeType()) {
for (Java17Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()) { ret.add((RefType) TypeGenerator.convert(type, reg, generics));
if (classMember.classMemberDeclaration() != null) { }
Java17Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration(); return ret;
if (classMemberDeclarationContext.fieldDeclaration() != null) { }
// Do nothing!
} else if (classMemberDeclarationContext.methodDeclaration() != null) {
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; StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>());
} ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
MethodBodyContext body = methoddeclaration.methodBody();
private List<Field> convertFields(Java17Parser.ClassBodyContext classBodyContext, GenericsRegistry generics) { Block block = null;
List<Field> ret = new ArrayList<>(); if (body instanceof EmptymethodContext emptymethod) {
for (Java17Parser.ClassBodyDeclarationContext classMember : classBodyContext.classBodyDeclaration()) { if (!Modifier.isAbstract(modifiers)) {
if (classMember.classMemberDeclaration() != null) { // TODO: Error! Abstrakte Methode ohne abstrakt Keyword
Java17Parser.ClassMemberDeclarationContext classMemberDeclarationContext = classMember.classMemberDeclaration();
if (classMemberDeclarationContext.fieldDeclaration() != null) {
ret.addAll(convert(classMember.classMemberDeclaration().fieldDeclaration(), generics));
} else if (classMemberDeclarationContext.methodDeclaration() != null) {
// Do nothing!
}
} }
} 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<Java17Parser.MethodModifierContext> methodModifierContexts) { private List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers,
int ret = 0;
for (Java17Parser.MethodModifierContext mod : methodModifierContexts) {
if (mod.annotation() == null)
convertModifier(mod.getText());
}
return ret;
}
public static int convertInterfaceModifier(List<Java17Parser.InterfaceMethodModifierContext> methodModifierContexts) {
int ret = 0;
for (Java17Parser.InterfaceMethodModifierContext mod : methodModifierContexts) {
if (mod.annotation() == null)
convertModifier(mod.getText());
}
return ret;
}
private List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclarationContext,
GenericsRegistry generics) { GenericsRegistry generics) {
List<Field> ret = new ArrayList<>(); List<Field> ret = new ArrayList<>();
int modifiers = 0;
for (Java17Parser.FieldModifierContext fieldModifierContext : fieldDeclarationContext.fieldModifier()) {
modifiers += (convert(fieldModifierContext));
}
RefTypeOrTPHOrWildcardOrGeneric fieldType; RefTypeOrTPHOrWildcardOrGeneric fieldType;
if (fieldDeclarationContext.unannTypeOrAuto() != null if (fieldDeclContext.typeType() != null) {
&& fieldDeclarationContext.unannTypeOrAuto().unannType() != null) { fieldType = TypeGenerator.convert(fieldDeclContext.typeType(), reg, generics);
fieldType = TypeGenerator.convert(fieldDeclarationContext.unannTypeOrAuto().unannType(), reg, generics);
} else { } else {
fieldType = TypePlaceholder.fresh(fieldDeclarationContext.variableDeclaratorList().getStart()); // PL 2019-12-06: // PL 2019-12-06: variableDeclaratorList() eingefuegt, um als Token nicht die
// variableDeclaratorList() // Modifier zu bekommen
// eingefuegt, um fieldType = TypePlaceholder.fresh(fieldDeclContext.variableDeclarators().getStart());
// als Token nicht
// die Modifier zu
// bekommen
} }
for (Java17Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList() for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
.variableDeclarator()) { String fieldName = varDecl.variableDeclaratorId().getText();
String fieldName = convert(varCtx.variableDeclaratorId()); this.fields.put(fieldName, fieldType);
fields.put(fieldName, fieldType); if (varDecl.variableInitializer() != null) {
if (varCtx.variableInitializer() != null) { initializeField(varDecl, fieldType, generics);
initializeField(varCtx, fieldType, generics);
} }
ret.add(new Field(fieldName, fieldType, modifiers, varCtx.getStart())); ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart()));
} }
return ret; return ret;
} }
@ -443,90 +390,8 @@ public class SyntaxTreeGenerator {
fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField)); fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField));
} }
public static int convertModifier(String modifier) { public int convertModifier(String modifier) {
HashMap<String, Integer> modifiers = new HashMap<>(); return allmodifiers.get(modifier);
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<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);
List<RefType> 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);
} }
private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass, private GenericsRegistry createGenerics(Java17Parser.GenericDeclarationListContext ctx, JavaClassName parentClass,
@ -537,42 +402,8 @@ public class SyntaxTreeGenerator {
return ret; return ret;
for (Java17Parser.GenericTypeVarContext tp : ctx.genericTypeVar()) { for (Java17Parser.GenericTypeVarContext tp : ctx.genericTypeVar()) {
ret.put(tp.identifier().getText(), new GenericContext(parentClass, parentMethod)); ret.put(tp.identifier().getText(), new GenericContext(parentClass, parentMethod));
TypeGenerator.convert(tp.typeBound(), reg, ret); TypeGenerator.convert(tp, parentClass, parentMethod, reg, ret);
} }
return ret; return ret;
} }
private List<RefType> convert(Java17Parser.ExtendsInterfacesContext extendsInterfacesContext,
GenericsRegistry generics) {
if (extendsInterfacesContext == null)
return new ArrayList<>();
return convert(extendsInterfacesContext.interfaceTypeList(), generics);
}
private List<Method> convertMethods(Java17Parser.InterfaceBodyContext interfaceBodyContext,
JavaClassName parentClass, RefType superClass, GenericsRegistry generics) {
List<Method> 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<Field> convertFields(Java17Parser.InterfaceBodyContext interfaceBodyContext) {
List<Field> ret = new ArrayList<>();
for (Java17Parser.InterfaceMemberDeclarationContext member : interfaceBodyContext.interfaceMemberDeclaration()) {
if (member.constantDeclaration() != null) {
// TODO: Erstelle hier ein Feld!
throw new NotImplementedException();
}
}
return ret;
}
} }

View File

@ -19,7 +19,7 @@ public class GatherNames {
if (member instanceof NoclassorinterfaceContext) { if (member instanceof NoclassorinterfaceContext) {
continue; continue;
} }
ClassorinterfacedeclContext clsoif = new ClassorinterfacedeclContext(member); ClassorinterfacedeclContext clsoif = (ClassorinterfacedeclContext) member;
if (clsoif.interfaceDeclaration() != null) { if (clsoif.interfaceDeclaration() != null) {
if (pkgName != "") { if (pkgName != "") {
nameString = pkgName + "." nameString = pkgName + "."
@ -49,7 +49,7 @@ public class GatherNames {
if (!pkgName.isEmpty()) { if (!pkgName.isEmpty()) {
nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText(); nameString = pkgName + "." + clsoif.classDeclaration().identifier().getText();
} else { } else {
nameString = clsoif.classDeclaration().getText(); nameString = clsoif.classDeclaration().identifier().getText();
} }
// Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry // Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry
// anfügen: // anfügen:

View File

@ -10,29 +10,31 @@ import java.util.*;
public class JavaClassRegistry { public class JavaClassRegistry {
final Map<JavaClassName, Integer> existingClasses = new HashMap<>(); final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
public JavaClassRegistry(Map<String, Integer> initialNames){ public JavaClassRegistry(Map<String, Integer> initialNames) {
for(String name : initialNames.keySet()){ for (String name : initialNames.keySet()) {
existingClasses.put(new JavaClassName(name), initialNames.get(name)); existingClasses.put(new JavaClassName(name), initialNames.get(name));
} }
} }
public JavaClassName getName(String className) { public JavaClassName getName(String className) {
for(JavaClassName name : existingClasses.keySet()){ for (JavaClassName name : existingClasses.keySet()) {
if(name.equals(new JavaClassName(className)))return name; if (name.equals(new JavaClassName(className)))
return name;
} }
throw new NotImplementedException(); throw new NotImplementedException();
} }
@Override @Override
public String toString(){ public String toString() {
return existingClasses.toString(); return existingClasses.toString();
} }
public List<JavaClassName> getAllFromPackage(String packageName) { public List<JavaClassName> getAllFromPackage(String packageName) {
List<JavaClassName> ret = new ArrayList<>(); List<JavaClassName> ret = new ArrayList<>();
for(JavaClassName className : this.existingClasses.keySet()){ for (JavaClassName className : this.existingClasses.keySet()) {
JavaClassName toCompare = new JavaClassName(packageName + "." + JavaClassName.stripClassName(className.toString())); JavaClassName toCompare = new JavaClassName(
if(toCompare.toString().equals(className.toString())){ packageName + "." + JavaClassName.stripClassName(className.toString()));
if (toCompare.toString().equals(className.toString())) {
ret.add(className); ret.add(className);
} }
} }

View File

@ -1,3 +1,5 @@
import java.lang.Boolean;
class Test{ class Test{
method(){ method(){
if(true)i++; if(true)i++;

View File

@ -12,44 +12,44 @@ import de.dhbwstuttgart.parser.JavaTXParser;
import org.junit.Test; import org.junit.Test;
/** /**
* Dieser Test pr�ft nur, ob .java-Dateien fehlerfrei geparst werden. * Dieser Test pr�ft nur, ob .java-Dateien fehlerfrei geparst werden.
* Der dabei erstellte Syntaxbaum wird nicht kontrolliert. * Der dabei erstellte Syntaxbaum wird nicht kontrolliert.
*
* @author janulrich * @author janulrich
* *
*/ */
public class GeneralParserTest{ public class GeneralParserTest {
private static final String rootDirectory = System.getProperty("user.dir")+"/src/test/java/parser/"; private static final String rootDirectory = System.getProperty("user.dir") + "/src/test/java/parser/";
@Test @Test
public void run(){ public void run() {
List<String> filenames = new ArrayList<String>(); List<String> filenames = new ArrayList<String>();
/* /*
filenames.add("NewTest.jav"); * filenames.add("NewTest.jav");
filenames.add("FieldInitializationTest.jav"); * filenames.add("FieldInitializationTest.jav");
filenames.add("ImportTest.jav"); * filenames.add("ImportTest.jav");
filenames.add("CastTest.jav"); * filenames.add("CastTest.jav");
filenames.add("StatementsTest.jav"); * filenames.add("StatementsTest.jav");
//filenames.add("Methods.jav"); * //filenames.add("Methods.jav");
filenames.add("ImportTestGeneric.jav"); * filenames.add("ImportTestGeneric.jav");
filenames.add("CastTest.jav"); * filenames.add("CastTest.jav");
//filenames.add("BoundedParameter.jav"); * //filenames.add("BoundedParameter.jav");
//filenames.add("GenericFieldVarTest.jav"); * //filenames.add("GenericFieldVarTest.jav");
filenames.add("FieldVarTest.jav"); * filenames.add("FieldVarTest.jav");
filenames.add("StructuralTypes.jav"); * filenames.add("StructuralTypes.jav");
*/ * filenames.add("ExtendsTest.jav");
// filenames.add("ExtendsTest.jav"); * filenames.add("PackageNameTest.jav");
filenames.add("PackageNameTest.jav"); */
try{ filenames.add("AntlrTest.jav");
try {
new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList())); new JavaTXCompiler(filenames.stream().map(s -> new File(rootDirectory + s)).collect(Collectors.toList()));
}catch(Exception exc){ } catch (Exception exc) {
exc.printStackTrace(); exc.printStackTrace();
fail(); fail();
} }
assertTrue("Tests durchlaufen",filenames.size()>0); assertTrue("Tests durchlaufen", filenames.size() > 0);
} }
} }