forked from JavaTX/JavaCompilerCore
Static but no static blocks yet
This commit is contained in:
parent
892ba5fff0
commit
eaef00ff54
9
resources/bytecode/javFiles/Static.jav
Normal file
9
resources/bytecode/javFiles/Static.jav
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class Static {
|
||||||
|
static i = 20;
|
||||||
|
|
||||||
|
static m() {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
@ -599,7 +599,7 @@ public class Codegen {
|
|||||||
switch (op) {
|
switch (op) {
|
||||||
case TargetUnaryOp.Add add ->
|
case TargetUnaryOp.Add add ->
|
||||||
// This literally does nothing
|
// This literally does nothing
|
||||||
generate(state, add.expr());
|
generate(state, add.expr());
|
||||||
case TargetUnaryOp.Negate negate -> {
|
case TargetUnaryOp.Negate negate -> {
|
||||||
generate(state, negate.expr());
|
generate(state, negate.expr());
|
||||||
if (negate.type().equals(TargetType.Double))
|
if (negate.type().equals(TargetType.Double))
|
||||||
@ -834,7 +834,8 @@ public class Codegen {
|
|||||||
}
|
}
|
||||||
case TargetFieldVar dot -> {
|
case TargetFieldVar dot -> {
|
||||||
var fieldType = dot.type();
|
var fieldType = dot.type();
|
||||||
generate(state, dot.left());
|
if (!(dot.left() instanceof TargetThis && dot.isStatic()))
|
||||||
|
generate(state, dot.left());
|
||||||
generate(state, assign.right());
|
generate(state, assign.right());
|
||||||
convertTo(state, assign.right().type(), fieldType);
|
convertTo(state, assign.right().type(), fieldType);
|
||||||
boxPrimitive(state, fieldType);
|
boxPrimitive(state, fieldType);
|
||||||
@ -1290,6 +1291,20 @@ public class Codegen {
|
|||||||
cw.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
cw.visitField(access, field.name(), field.type().toSignature(), field.type().toDescriptor(), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void generateStaticConstructor(TargetMethod constructor) {
|
||||||
|
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", "()V", null, null);
|
||||||
|
mv.visitCode();
|
||||||
|
|
||||||
|
var state = new State(null, mv, 0);
|
||||||
|
var stmts = constructor.block().statements();
|
||||||
|
for (var i = 1; i < stmts.size(); i++)
|
||||||
|
generate(state, stmts.get(i));
|
||||||
|
|
||||||
|
mv.visitInsn(RETURN);
|
||||||
|
mv.visitMaxs(0, 0);
|
||||||
|
mv.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
private void generateConstructor(TargetConstructor constructor) {
|
private void generateConstructor(TargetConstructor constructor) {
|
||||||
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||||
if (constructor.txGenerics() != null)
|
if (constructor.txGenerics() != null)
|
||||||
@ -1407,6 +1422,9 @@ public class Codegen {
|
|||||||
clazz.constructors().forEach(this::generateConstructor);
|
clazz.constructors().forEach(this::generateConstructor);
|
||||||
clazz.methods().forEach(this::generateMethod);
|
clazz.methods().forEach(this::generateMethod);
|
||||||
|
|
||||||
|
if (clazz.staticConstructor() != null)
|
||||||
|
generateStaticConstructor(clazz.staticConstructor());
|
||||||
|
|
||||||
if (clazz instanceof TargetRecord)
|
if (clazz instanceof TargetRecord)
|
||||||
generateRecordMethods();
|
generateRecordMethods();
|
||||||
|
|
||||||
|
@ -70,6 +70,9 @@ public class JavaTXCompiler {
|
|||||||
final CompilationEnvironment environment;
|
final CompilationEnvironment environment;
|
||||||
Boolean resultmodel = false;
|
Boolean resultmodel = false;
|
||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||||
|
// TODO We might want to incorporate this into the class registry instead
|
||||||
|
public final Map<JavaClassName, ClassOrInterface> classes = new HashMap<>();
|
||||||
|
|
||||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll?
|
||||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||||
private final DirectoryClassLoader classLoader;
|
private final DirectoryClassLoader classLoader;
|
||||||
@ -103,11 +106,22 @@ public class JavaTXCompiler {
|
|||||||
classPath = contextPath;
|
classPath = contextPath;
|
||||||
|
|
||||||
for (File s : sources) {
|
for (File s : sources) {
|
||||||
sourceFiles.put(s, parse(s));
|
addSourceFile(s, parse(s));
|
||||||
}
|
}
|
||||||
// INSTANCE = this;
|
// INSTANCE = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addSourceFile(File file, SourceFile sf) {
|
||||||
|
sourceFiles.put(file, sf);
|
||||||
|
for (var clazz : sf.KlassenVektor) {
|
||||||
|
classes.put(clazz.getClassName(), clazz);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassOrInterface getClass(JavaClassName name) {
|
||||||
|
return classes.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
|
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
|
||||||
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
|
||||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||||
@ -630,8 +644,8 @@ public class JavaTXCompiler {
|
|||||||
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
||||||
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
SourceFileContext tree = JavaTXParser.parse(sourceFile);
|
||||||
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
|
environment.addClassesToRegistry(classRegistry, tree, sourceFile, this);
|
||||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(classRegistry, new GenericsRegistry(null));
|
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
|
||||||
SourceFile ret = generator.convert(tree, environment.packageCrawler, this);
|
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -651,8 +665,8 @@ public class JavaTXCompiler {
|
|||||||
var tree = JavaTXParser.parse(file);
|
var tree = JavaTXParser.parse(file);
|
||||||
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
|
classRegistry.addName(name.toString(), 0); // TODO This gets overwritten later, is it bad if we don't know this right away?
|
||||||
environment.addClassesToRegistry(classRegistry, tree, file, this);
|
environment.addClassesToRegistry(classRegistry, tree, file, this);
|
||||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(classRegistry, new GenericsRegistry(null));
|
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
|
||||||
sourceFiles.put(file, generator.convert(tree, environment.packageCrawler, this));
|
addSourceFile(file, generator.convert(tree, environment.packageCrawler));
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
|
||||||
|
public record FieldEntry(String name, RefTypeOrTPHOrWildcardOrGeneric type, int modifiers) {
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -8,6 +9,7 @@ import java.util.Map;
|
|||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.Void;
|
import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
@ -134,17 +136,24 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
|
|
||||||
public class StatementGenerator {
|
public class StatementGenerator {
|
||||||
|
|
||||||
private JavaClassRegistry reg;
|
private final JavaClassRegistry reg;
|
||||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields; // PL 2018-11-01 fields eingefuegt, damit die fields
|
|
||||||
// immer die gleiche TPH bekommen
|
|
||||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
|
||||||
private GenericsRegistry generics;
|
|
||||||
|
|
||||||
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
|
private final Map<String, FieldEntry> fields; // PL 2018-11-01 fields eingefuegt, damit die fields
|
||||||
|
// immer die gleiche TPH bekommen
|
||||||
|
private final Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
||||||
|
private final GenericsRegistry generics;
|
||||||
|
private final JavaTXCompiler compiler;
|
||||||
|
|
||||||
|
private final RefType superClass;
|
||||||
|
|
||||||
|
// TODO How about instead of passing all of these types we just pass an instance of the SyntaxTreeGenerator?
|
||||||
|
public StatementGenerator(RefType superType, JavaTXCompiler compiler, JavaClassRegistry reg, GenericsRegistry generics, Map<String, FieldEntry> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars) {
|
||||||
this.reg = reg;
|
this.reg = reg;
|
||||||
this.generics = generics;
|
this.generics = generics;
|
||||||
this.fields = fields;
|
this.fields = fields;
|
||||||
this.localVars = localVars;
|
this.localVars = localVars;
|
||||||
|
this.compiler = compiler;
|
||||||
|
this.superClass = superType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
|
public ParameterList convert(Java17Parser.FormalParameterListContext formalParameterListContext) {
|
||||||
@ -574,7 +583,8 @@ public class StatementGenerator {
|
|||||||
} else {
|
} else {
|
||||||
initValue = convert(varDecl.variableInitializer().expression());
|
initValue = convert(varDecl.variableInitializer().expression());
|
||||||
}
|
}
|
||||||
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
var fieldEntry = fields.get(name.getText());
|
||||||
|
return (new Assign(new AssignToField(new FieldVar(new This(varDecl.getStart()), (fieldEntry.modifiers() & Modifier.STATIC) != 0, name.getText(), type, varDecl.getStart())), initValue, name.getStart()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Statement convert(Java17Parser.BreakstmtContext stmt) {
|
private Statement convert(Java17Parser.BreakstmtContext stmt) {
|
||||||
@ -760,7 +770,8 @@ public class StatementGenerator {
|
|||||||
return new LocalVar(expression, localVars.get(expression), offset);
|
return new LocalVar(expression, localVars.get(expression), offset);
|
||||||
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
} else if (fields.get(expression) != null) {// PL 2018-11-01 fields eingefuegt, damit die fields immer die
|
||||||
// gleiche TPH bekommen
|
// gleiche TPH bekommen
|
||||||
return new FieldVar(new This(offset), expression, fields.get(expression), offset);
|
var field = fields.get(expression);
|
||||||
|
return new FieldVar(new This(offset), Modifier.isStatic(field.modifiers()), expression, fields.get(expression).type(), offset);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
// lokale Variable wurde ohne "var"-Keyword deklariert und direkt mit Wert versehen
|
||||||
@ -783,16 +794,23 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
whole += ".";
|
whole += ".";
|
||||||
}
|
}
|
||||||
|
var fieldName = parts[parts.length - 1];
|
||||||
|
|
||||||
|
var isStatic = false;
|
||||||
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
if (parts.length < 2 || parts[0].contentEquals("this")) {
|
||||||
receiver = new This(offset);
|
receiver = new This(offset);
|
||||||
|
isStatic = Modifier.isStatic(fields.get(fieldName).modifiers());
|
||||||
} else if (parts[0].contentEquals("super")) {
|
} else if (parts[0].contentEquals("super")) {
|
||||||
receiver = new Super(offset);
|
receiver = new Super(offset);
|
||||||
|
isStatic = Modifier.isStatic(compiler.getClass(new JavaClassName(superClass.getName().toString())).getField(fieldName).orElseThrow().modifier);
|
||||||
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
} else if (receiver == null) { // Handelt es sich um keinen Statischen Klassennamen:
|
||||||
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
String part = expression.substring(0, expression.length() - (1 + parts[parts.length - 1].length()));
|
||||||
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
receiver = generateLocalOrFieldVarOrClassName(part, offset);
|
||||||
|
} else {
|
||||||
|
StaticClassName cname = (StaticClassName) receiver;
|
||||||
|
isStatic = Modifier.isStatic(compiler.getClass(reg.getName(cname.getType().toString())).getField(fieldName).orElseThrow().modifier);
|
||||||
}
|
}
|
||||||
return new FieldVar(receiver, parts[parts.length - 1], TypePlaceholder.fresh(offset), offset);
|
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
private Expression convert(Java17Parser.ArrayaccessexpressionContext arrayaccess) {
|
||||||
@ -1063,7 +1081,7 @@ public class StatementGenerator {
|
|||||||
if (!(param instanceof FormalParameter fp)) throw new IllegalArgumentException();
|
if (!(param instanceof FormalParameter fp)) throw new IllegalArgumentException();
|
||||||
lambdaLocals.put(fp.getName(), fp.getType());
|
lambdaLocals.put(fp.getName(), fp.getType());
|
||||||
}
|
}
|
||||||
StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, fields, lambdaLocals);
|
StatementGenerator lambdaGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, lambdaLocals);
|
||||||
|
|
||||||
Block block;
|
Block block;
|
||||||
if (expression.lambdaBody().expression() != null) {
|
if (expression.lambdaBody().expression() != null) {
|
||||||
|
@ -13,6 +13,7 @@ import java.util.Set;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.Record;
|
import de.dhbwstuttgart.syntaxtree.Record;
|
||||||
import org.antlr.v4.runtime.CommonToken;
|
import org.antlr.v4.runtime.CommonToken;
|
||||||
@ -91,11 +92,15 @@ public class SyntaxTreeGenerator {
|
|||||||
HashMap<String, Integer> allmodifiers = new HashMap<>();
|
HashMap<String, Integer> allmodifiers = new HashMap<>();
|
||||||
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
|
// PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH
|
||||||
// bekommen
|
// bekommen
|
||||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>();
|
private final Map<String, FieldEntry> fields = new HashMap<>();
|
||||||
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
|
// PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
|
||||||
List<Statement> fieldInitializations = new ArrayList<>();
|
List<Statement> fieldInitializations = new ArrayList<>();
|
||||||
|
List<Statement> staticFieldInitializations = new ArrayList<>();
|
||||||
|
|
||||||
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics) {
|
private final JavaTXCompiler compiler;
|
||||||
|
private RefType superClass;
|
||||||
|
|
||||||
|
public SyntaxTreeGenerator(JavaTXCompiler compiler, 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,
|
||||||
// da diese mit der Methode oder Klasse, in welcher sie deklariert 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
|
// verknüpft sein müssen. Dennoch werden die Namen aller Generics in einer
|
||||||
@ -118,6 +123,8 @@ public class SyntaxTreeGenerator {
|
|||||||
this.allmodifiers.put("non-sealed", 8192);
|
this.allmodifiers.put("non-sealed", 8192);
|
||||||
this.allmodifiers.put("default", 16384);
|
this.allmodifiers.put("default", 16384);
|
||||||
this.allmodifiers.put("strictfp", 32768);
|
this.allmodifiers.put("strictfp", 32768);
|
||||||
|
|
||||||
|
this.compiler = compiler;
|
||||||
}
|
}
|
||||||
|
|
||||||
public JavaClassRegistry getReg() {
|
public JavaClassRegistry getReg() {
|
||||||
@ -131,7 +138,7 @@ public class SyntaxTreeGenerator {
|
|||||||
return ctx.getText();
|
return ctx.getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler, JavaTXCompiler compiler) throws ClassNotFoundException, NotImplementedException {
|
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException {
|
||||||
SrcfileContext srcfile;
|
SrcfileContext srcfile;
|
||||||
List<ClassOrInterface> classes = new ArrayList<>();
|
List<ClassOrInterface> classes = new ArrayList<>();
|
||||||
if (ctx instanceof Java17Parser.SrcfileContext) {
|
if (ctx instanceof Java17Parser.SrcfileContext) {
|
||||||
@ -200,6 +207,7 @@ public class SyntaxTreeGenerator {
|
|||||||
} else {
|
} else {
|
||||||
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
|
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
|
||||||
}
|
}
|
||||||
|
this.superClass = superClass;
|
||||||
List<Field> fielddecl = new ArrayList<>();
|
List<Field> fielddecl = new ArrayList<>();
|
||||||
List<Method> methods = new ArrayList<>();
|
List<Method> methods = new ArrayList<>();
|
||||||
List<Constructor> constructors = new ArrayList<>();
|
List<Constructor> constructors = new ArrayList<>();
|
||||||
@ -225,11 +233,14 @@ public class SyntaxTreeGenerator {
|
|||||||
throw new NotImplementedException("Invalid sealed class declaration");
|
throw new NotImplementedException("Invalid sealed class declaration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ClassOrInterface(modifiers, name, fielddecl, Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), name, superClass, genericClassParameters, offset)), methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, offset));
|
||||||
|
var staticCtor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||||
|
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) {
|
private de.dhbwstuttgart.syntaxtree.Record convertRecord(RecordDeclarationContext recordDeclaration, int modifiers) {
|
||||||
|
this.superClass = new RefType(new JavaClassName("java.lang.Record"), new NullToken());
|
||||||
String identifier = recordDeclaration.identifier().getText();
|
String identifier = recordDeclaration.identifier().getText();
|
||||||
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + identifier;
|
String className = this.pkgName + (this.pkgName.length() > 0 ? "." : "") + identifier;
|
||||||
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
|
JavaClassName name = reg.getName(className); // Holt den Package Namen mit dazu
|
||||||
@ -264,7 +275,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
fielddecl.add(new Field(fieldname, fieldtype, fieldmodifiers, fieldoffset));
|
||||||
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
constructorParameters.add(new FormalParameter(fieldname, fieldtype, fieldoffset));
|
||||||
FieldVar fieldvar = new FieldVar(new This(offset), fieldname, fieldtype, fieldoffset);
|
FieldVar fieldvar = new FieldVar(new This(offset), false, fieldname, fieldtype, fieldoffset);
|
||||||
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
constructorStatements.add(new Assign(new AssignToField(fieldvar), new LocalVar(fieldname, fieldtype, fieldoffset), offset));
|
||||||
Statement returnStatement = new Return(fieldvar, offset);
|
Statement returnStatement = new Return(fieldvar, offset);
|
||||||
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
methods.add(new Method(allmodifiers.get("public"), fieldname, fieldtype, new ParameterList(new ArrayList<>(), offset), new Block(Arrays.asList(returnStatement), offset), new GenericDeclarationList(new ArrayList<>(), offset), offset));
|
||||||
@ -279,7 +290,8 @@ public class SyntaxTreeGenerator {
|
|||||||
if (!Objects.isNull(recordDeclaration.IMPLEMENTS())) {
|
if (!Objects.isNull(recordDeclaration.IMPLEMENTS())) {
|
||||||
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
|
implementedInterfaces.addAll(convert(recordDeclaration.typeList(), generics));
|
||||||
}
|
}
|
||||||
return new Record(modifiers, name, fielddecl, initializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
var staticCtor = Optional.of(this.generatePseudoConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
|
||||||
|
return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
|
private void convert(ClassBodyDeclarationContext classBody, List<Field> fields, List<Constructor> constructors, List<Method> methods, JavaClassName name, RefType superClass, GenericsRegistry generics) {
|
||||||
@ -319,6 +331,7 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext ctx, int modifiers) {
|
private ClassOrInterface convertInterface(Java17Parser.InterfaceDeclarationContext ctx, int modifiers) {
|
||||||
|
this.superClass = new RefType(new JavaClassName("java.lang.Object"), new NullToken());
|
||||||
String className = this.pkgName.length() > 0 ? this.pkgName + "." : "" + ctx.identifier().getText();
|
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?
|
||||||
@ -391,7 +404,9 @@ public class SyntaxTreeGenerator {
|
|||||||
throw new NotImplementedException("Invalid sealed class declaration");
|
throw new NotImplementedException("Invalid sealed class declaration");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart());
|
|
||||||
|
var staticCtor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart()));
|
||||||
|
return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
private GenericDeclarationList createEmptyGenericDeclarationList(Token classNameIdentifier) {
|
||||||
@ -419,7 +434,7 @@ public class SyntaxTreeGenerator {
|
|||||||
retType = new Void(bodydeclaration.refType().getStart());
|
retType = new Void(bodydeclaration.refType().getStart());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementGenerator stmtgen = new StatementGenerator(reg, generics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(bodydeclaration.formalParameters().formalParameterList());
|
||||||
MethodBodyContext body = bodydeclaration.methodBody();
|
MethodBodyContext body = bodydeclaration.methodBody();
|
||||||
Block block = null;
|
Block block = null;
|
||||||
@ -447,10 +462,10 @@ public class SyntaxTreeGenerator {
|
|||||||
/*
|
/*
|
||||||
* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert
|
* fieldInitializations werden in einem Psedokonstruktor in der abstrakten Syntax gespeichert
|
||||||
*/
|
*/
|
||||||
private Constructor generatePseudoConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset) {
|
private Constructor generatePseudoConstructor(String className, List<Statement> initializations, GenericDeclarationList classGenerics, Token offset) {
|
||||||
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<>(fieldInitializations), offset);
|
Block block = new Block(new ArrayList<>(initializations), offset);
|
||||||
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
|
return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset /*
|
||||||
* fieldInitializations geloescht PL 2018-11-24
|
* fieldInitializations geloescht PL 2018-11-24
|
||||||
*/);
|
*/);
|
||||||
@ -512,7 +527,7 @@ public class SyntaxTreeGenerator {
|
|||||||
retType = new Void(header.refType().getStart());
|
retType = new Void(header.refType().getStart());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(header.formalParameters().formalParameterList());
|
||||||
MethodBodyContext body = methoddeclaration.methodBody();
|
MethodBodyContext body = methoddeclaration.methodBody();
|
||||||
Block block = null;
|
Block block = null;
|
||||||
@ -552,13 +567,13 @@ public class SyntaxTreeGenerator {
|
|||||||
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), constructordeclaration.getStart());
|
gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), constructordeclaration.getStart());
|
||||||
}
|
}
|
||||||
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
RefTypeOrTPHOrWildcardOrGeneric retType = TypeGenerator.convertTypeName(name, constructordeclaration.getStart(), reg, localgenerics);
|
||||||
StatementGenerator stmtgen = new StatementGenerator(reg, localgenerics, fields, new HashMap<>());
|
StatementGenerator stmtgen = new StatementGenerator(superClass, compiler, reg, localgenerics, fields, new HashMap<>());
|
||||||
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
ParameterList paramlist = stmtgen.convert(constructordeclaration.formalParameters().formalParameterList());
|
||||||
Block block = stmtgen.convert(constructordeclaration.constructorBody, true);
|
Block block = stmtgen.convert(constructordeclaration.constructorBody, true);
|
||||||
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
return new Constructor(modifiers, name, retType, paramlist, block, gtvDeclarations, constructordeclaration.getStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) {
|
List<? extends Field> convert(Java17Parser.FieldDeclarationContext fieldDeclContext, int modifiers, GenericsRegistry generics) {
|
||||||
List<Field> ret = new ArrayList<>();
|
List<Field> ret = new ArrayList<>();
|
||||||
RefTypeOrTPHOrWildcardOrGeneric fieldType;
|
RefTypeOrTPHOrWildcardOrGeneric fieldType;
|
||||||
if (fieldDeclContext.typeType() != null) {
|
if (fieldDeclContext.typeType() != null) {
|
||||||
@ -570,9 +585,9 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
for (Java17Parser.VariableDeclaratorContext varDecl : fieldDeclContext.variableDeclarators().variableDeclarator()) {
|
||||||
String fieldName = varDecl.variableDeclaratorId().getText();
|
String fieldName = varDecl.variableDeclaratorId().getText();
|
||||||
this.fields.put(fieldName, fieldType);
|
this.fields.put(fieldName, new FieldEntry(fieldName, fieldType, modifiers));
|
||||||
if (varDecl.variableInitializer() != null) {
|
if (varDecl.variableInitializer() != null) {
|
||||||
initializeField(varDecl, fieldType, generics);
|
initializeField(varDecl, Modifier.isStatic(modifiers), fieldType, generics);
|
||||||
}
|
}
|
||||||
ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart()));
|
ret.add(new Field(fieldName, fieldType, modifiers, varDecl.getStart()));
|
||||||
}
|
}
|
||||||
@ -584,9 +599,12 @@ public class SyntaxTreeGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a field by creating implicit constructor.
|
// Initialize a field by creating implicit constructor.
|
||||||
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
|
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, boolean isStatic, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
|
||||||
StatementGenerator statementGenerator = new StatementGenerator(reg, generics, fields, new HashMap<>());
|
StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
|
||||||
fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField));
|
var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField);
|
||||||
|
if (isStatic)
|
||||||
|
staticFieldInitializations.add(assignment);
|
||||||
|
else fieldInitializations.add(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int convertModifier(String modifier) {
|
public int convertModifier(String modifier) {
|
||||||
|
@ -1,18 +1,11 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree;
|
package de.dhbwstuttgart.syntaxtree;
|
||||||
|
|
||||||
import de.dhbwstuttgart.core.IItemWithOffset;
|
|
||||||
import de.dhbwstuttgart.exceptions.DebugException;
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.syntaxtree.visual.ASTPrinter;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Constraint;
|
|
||||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
|
||||||
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation;
|
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@ -30,6 +23,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
protected JavaClassName name;
|
protected JavaClassName name;
|
||||||
private List<Field> fields = new ArrayList<>();
|
private List<Field> fields = new ArrayList<>();
|
||||||
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
|
private Optional<Constructor> fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen
|
||||||
|
private Optional<Constructor> staticInitializer;
|
||||||
private List<Method> methods = new ArrayList<>();
|
private List<Method> methods = new ArrayList<>();
|
||||||
private GenericDeclarationList genericClassParameters;
|
private GenericDeclarationList genericClassParameters;
|
||||||
private RefType superClass;
|
private RefType superClass;
|
||||||
@ -38,7 +32,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
private List<RefType> permittedSubtypes;
|
private List<RefType> permittedSubtypes;
|
||||||
private List<Constructor> constructors;
|
private List<Constructor> constructors;
|
||||||
|
|
||||||
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
|
public ClassOrInterface(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Constructor> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, List<RefType> permittedSubtypes, Token offset) {
|
||||||
super(offset);
|
super(offset);
|
||||||
if (isInterface) {
|
if (isInterface) {
|
||||||
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
|
modifiers |= Modifier.INTERFACE | Modifier.ABSTRACT;
|
||||||
@ -47,6 +41,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
this.name = name;
|
this.name = name;
|
||||||
this.fields = fielddecl;
|
this.fields = fielddecl;
|
||||||
this.fieldInitializations = fieldInitializations;
|
this.fieldInitializations = fieldInitializations;
|
||||||
|
this.staticInitializer = staticInitializer;
|
||||||
this.genericClassParameters = genericClassParameters;
|
this.genericClassParameters = genericClassParameters;
|
||||||
this.superClass = superClass;
|
this.superClass = superClass;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
@ -65,6 +60,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
this.name = cl.name;
|
this.name = cl.name;
|
||||||
this.fields = new ArrayList<>(cl.fields);
|
this.fields = new ArrayList<>(cl.fields);
|
||||||
this.fieldInitializations = cl.fieldInitializations;
|
this.fieldInitializations = cl.fieldInitializations;
|
||||||
|
this.staticInitializer = cl.staticInitializer;
|
||||||
this.genericClassParameters = cl.genericClassParameters;
|
this.genericClassParameters = cl.genericClassParameters;
|
||||||
this.superClass = cl.superClass;
|
this.superClass = cl.superClass;
|
||||||
this.isInterface = cl.isInterface;
|
this.isInterface = cl.isInterface;
|
||||||
@ -73,6 +69,15 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
|
|||||||
this.constructors = new ArrayList<>(cl.constructors);
|
this.constructors = new ArrayList<>(cl.constructors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Optional<Field> getField(String name) {
|
||||||
|
// TODO This should be a map
|
||||||
|
return fields.stream().filter(field -> field.getName().equals(name)).findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Optional<Constructor> getStaticInitializer() {
|
||||||
|
return staticInitializer;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isInterface() {
|
public boolean isInterface() {
|
||||||
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
return (Modifier.INTERFACE & this.getModifiers()) != 0;
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,11 @@ import org.antlr.v4.runtime.Token;
|
|||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
|
|
||||||
|
import javax.swing.text.html.Option;
|
||||||
|
|
||||||
public class Record extends ClassOrInterface {
|
public class Record extends ClassOrInterface {
|
||||||
|
|
||||||
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
|
public Record(int modifiers, JavaClassName name, List<Field> fielddecl, Optional<Constructor> fieldInitializations, Optional<Constructor> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
|
||||||
super(modifiers, name, fielddecl, fieldInitializations, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset);
|
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,7 +141,7 @@ public class ASTFactory {
|
|||||||
|
|
||||||
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
Token offset = new NullToken(); // Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||||
|
|
||||||
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, methoden, konstruktoren, genericDeclarationList, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
var cinf = new ClassOrInterface(modifier, name, felder, Optional.empty() /* eingefuegt PL 2018-11-24 */, Optional.empty(), methoden, konstruktoren, genericDeclarationList, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
|
||||||
cache.put(jreClass, cinf);
|
cache.put(jreClass, cinf);
|
||||||
return cinf;
|
return cinf;
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,13 @@ public class FieldVar extends Expression {
|
|||||||
|
|
||||||
public final String fieldVarName;
|
public final String fieldVarName;
|
||||||
public final Expression receiver;
|
public final Expression receiver;
|
||||||
|
public final boolean isStatic;
|
||||||
|
|
||||||
public FieldVar(Expression receiver, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
public FieldVar(Expression receiver, boolean isStatic, String fieldVarName, RefTypeOrTPHOrWildcardOrGeneric type, Token offset) {
|
||||||
super(type, offset);
|
super(type, offset);
|
||||||
this.fieldVarName = fieldVarName;
|
this.fieldVarName = fieldVarName;
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
|
this.isStatic = isStatic;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -144,11 +144,15 @@ public class ASTToTargetAST {
|
|||||||
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
var fields = input.getFieldDecl().stream().map(this::convert).toList();
|
||||||
var methods = groupOverloads(input.getMethods()).stream().map(this::convert).flatMap(List::stream).toList();
|
var methods = groupOverloads(input.getMethods()).stream().map(this::convert).flatMap(List::stream).toList();
|
||||||
|
|
||||||
|
TargetMethod staticConstructor = null;
|
||||||
|
if (input.getStaticInitializer().isPresent())
|
||||||
|
staticConstructor = this.convert(input.getStaticInitializer().get()).get(0);
|
||||||
|
|
||||||
if (input instanceof Record)
|
if (input instanceof Record)
|
||||||
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
return new TargetRecord(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
else if (input.isInterface())
|
else if (input.isInterface())
|
||||||
return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces);
|
return new TargetInterface(input.getModifiers(), input.getClassName(), javaGenerics, txGenerics, methods, superInterfaces, staticConstructor);
|
||||||
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, fields, methods);
|
else return new TargetClass(input.getModifiers(), input.getClassName(), convert(input.getSuperClass(), generics.javaGenerics), javaGenerics, txGenerics, superInterfaces, constructors, staticConstructor, fields, methods);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
private List<MethodParameter> convert(ParameterList input, GenerateGenerics generics) {
|
||||||
|
@ -134,7 +134,7 @@ public class StatementToTargetExpression implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), false, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
|
result = new TargetFieldVar(converter.convert(fieldVar.getType()), converter.convert(fieldVar.receiver.getType()), fieldVar.isStatic, converter.convert(fieldVar.receiver), fieldVar.fieldVarName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,13 +11,13 @@ import java.util.List;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetClass(int modifiers, JavaClassName qualifiedName, TargetType superType, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces,
|
public record TargetClass(int modifiers, JavaClassName qualifiedName, TargetType superType, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces,
|
||||||
List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
List<TargetConstructor> constructors, TargetMethod staticConstructor, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
||||||
|
|
||||||
public TargetClass(int modifiers, JavaClassName qualifiedName) {
|
public TargetClass(int modifiers, JavaClassName qualifiedName) {
|
||||||
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), new ArrayList<>(), new ArrayList<>(), null, new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
public TargetClass(int modifiers, JavaClassName qualifiedName, List<TargetType> implementingInterfaces) {
|
public TargetClass(int modifiers, JavaClassName qualifiedName, List<TargetType> implementingInterfaces) {
|
||||||
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), implementingInterfaces, new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
|
this(modifiers, qualifiedName, TargetType.Object, new HashSet<>(), new HashSet<>(), implementingInterfaces, new ArrayList<>(), null, new ArrayList<>(), new ArrayList<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addField(int access, TargetRefType type, String name) {
|
public void addField(int access, TargetRefType type, String name) {
|
||||||
|
@ -6,7 +6,7 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetInterface(int modifiers, JavaClassName qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetMethod> methods, List<TargetType> implementingInterfaces) implements TargetStructure {
|
public record TargetInterface(int modifiers, JavaClassName qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetMethod> methods, List<TargetType> implementingInterfaces, TargetMethod staticConstructor) implements TargetStructure {
|
||||||
@Override
|
@Override
|
||||||
public TargetType superType() {
|
public TargetType superType() {
|
||||||
return null;
|
return null;
|
||||||
|
@ -7,7 +7,7 @@ import de.dhbwstuttgart.target.tree.type.TargetType;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public record TargetRecord(int modifiers, JavaClassName qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces, List<TargetConstructor> constructors, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
public record TargetRecord(int modifiers, JavaClassName qualifiedName, Set<TargetGeneric> generics, Set<TargetGeneric> txGenerics, List<TargetType> implementingInterfaces, List<TargetConstructor> constructors, TargetMethod staticConstructor, List<TargetField> fields, List<TargetMethod> methods) implements TargetStructure {
|
||||||
|
|
||||||
public static final TargetType RECORD = new TargetRefType("java.lang.Record");
|
public static final TargetType RECORD = new TargetRefType("java.lang.Record");
|
||||||
public TargetType superType() {
|
public TargetType superType() {
|
||||||
|
@ -15,6 +15,9 @@ public interface TargetStructure {
|
|||||||
Set<TargetGeneric> txGenerics();
|
Set<TargetGeneric> txGenerics();
|
||||||
List<TargetType> implementingInterfaces();
|
List<TargetType> implementingInterfaces();
|
||||||
List<TargetConstructor> constructors();
|
List<TargetConstructor> constructors();
|
||||||
|
|
||||||
|
TargetMethod staticConstructor();
|
||||||
|
|
||||||
List<TargetField> fields();
|
List<TargetField> fields();
|
||||||
List<TargetMethod> methods();
|
List<TargetMethod> methods();
|
||||||
|
|
||||||
|
@ -15,13 +15,14 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
|
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
|
import javax.swing.text.html.Option;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class FunNClass extends ClassOrInterface {
|
public class FunNClass extends ClassOrInterface {
|
||||||
public FunNClass(List<GenericRefType> funNParams) {
|
public FunNClass(List<GenericRefType> funNParams) {
|
||||||
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
super(0, new JavaClassName("Fun" + (funNParams.size() - 1)), new ArrayList<>(), Optional.empty(), Optional.empty() /* eingefuegt PL 2018-11-24 */, createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), ASTFactory.createObjectType(), true, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,10 @@ public class TYPE {
|
|||||||
if (cl.getfieldInitializations().isPresent()) {
|
if (cl.getfieldInitializations().isPresent()) {
|
||||||
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
|
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
|
||||||
}
|
}
|
||||||
|
if (cl.getStaticInitializer().isPresent()) {
|
||||||
|
ret.addAll(getConstraintsConstructor(cl.getStaticInitializer().get(), info, cl));
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -719,6 +719,12 @@ public class TestComplete {
|
|||||||
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Interfaces.jav");
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Interfaces.jav");
|
||||||
var clazz = classFiles.get("Interfaces");
|
var clazz = classFiles.get("Interfaces");
|
||||||
var instance = clazz.getDeclaredConstructor().newInstance();
|
var instance = clazz.getDeclaredConstructor().newInstance();
|
||||||
System.out.println(Arrays.toString(clazz.getInterfaces()));
|
}
|
||||||
|
@Test
|
||||||
|
public void testStatic() throws Exception {
|
||||||
|
var classFiles = generateClassFiles(new ByteArrayClassLoader(), "Static.jav");
|
||||||
|
var clazz = classFiles.get("Static");
|
||||||
|
var m = clazz.getDeclaredMethod("m");
|
||||||
|
assertEquals(m.invoke(null), 20);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,17 +8,13 @@ import de.dhbwstuttgart.parser.scope.JavaClassName;
|
|||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
||||||
import de.dhbwstuttgart.target.tree.TargetClass;
|
|
||||||
import de.dhbwstuttgart.target.tree.TargetStructure;
|
import de.dhbwstuttgart.target.tree.TargetStructure;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
import org.junit.Ignore;
|
import org.junit.Ignore;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Vector;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
@ -26,7 +22,7 @@ public class ASTToTypedTargetAST {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emptyClass() {
|
public void emptyClass() {
|
||||||
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), java.util.Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
ClassOrInterface emptyClass = new ClassOrInterface(0, new JavaClassName("EmptyClass"), new ArrayList<>(), Optional.empty(), Optional.empty(), new ArrayList<>(), new ArrayList<>(), new GenericDeclarationList(new ArrayList<>(), new NullToken()), new RefType(new JavaClassName("Object"), new NullToken()), false, new ArrayList<>(), new ArrayList<>(), new NullToken());
|
||||||
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
ResultSet emptyResultSet = new ResultSet(new HashSet<>());
|
||||||
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
TargetStructure emptyTargetClass = new ASTToTargetAST(List.of(emptyResultSet)).convert(emptyClass);
|
||||||
assert emptyTargetClass.getName().equals("EmptyClass");
|
assert emptyTargetClass.getName().equals("EmptyClass");
|
||||||
|
Loading…
Reference in New Issue
Block a user