More work on static, references to other classes

This commit is contained in:
Daniel Holle 2023-10-24 15:17:13 +02:00
parent 124dea2e58
commit b372c6ac1c
10 changed files with 53 additions and 41 deletions

View File

@ -1,5 +1,9 @@
import java.lang.Integer; import java.lang.Integer;
class Other {
static field = 20;
}
public class Static { public class Static {
static i = 20; static i = 20;
@ -9,6 +13,6 @@ public class Static {
} }
static m() { static m() {
return i; return i + Other.field;
} }
} }

View File

@ -1296,9 +1296,7 @@ public class Codegen {
mv.visitCode(); mv.visitCode();
var state = new State(null, mv, 0); var state = new State(null, mv, 0);
var stmts = constructor.block().statements(); generate(state, constructor.block());
for (var i = 1; i < stmts.size(); i++)
generate(state, stmts.get(i));
mv.visitInsn(RETURN); mv.visitInsn(RETURN);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);

View File

@ -70,8 +70,6 @@ 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();
@ -106,20 +104,22 @@ public class JavaTXCompiler {
classPath = contextPath; classPath = contextPath;
for (File s : sources) { for (File s : sources) {
addSourceFile(s, parse(s)); parse(s);
} }
// INSTANCE = this; // INSTANCE = this;
} }
private void addSourceFile(File file, SourceFile sf) { private void addSourceFile(File file, SourceFile sf) {
sourceFiles.put(file, sf); sourceFiles.put(file, sf);
for (var clazz : sf.KlassenVektor) {
classes.put(clazz.getClassName(), clazz);
}
} }
public ClassOrInterface getClass(JavaClassName name) { public ClassOrInterface getClass(JavaClassName name) {
return classes.get(name); for (var sf : sourceFiles.values()) {
for (var clazz : sf.KlassenVektor) {
if (clazz.getClassName().equals(name)) return clazz;
}
}
return null;
} }
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException { public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException, IOException {
@ -645,8 +645,12 @@ public class JavaTXCompiler {
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(this, classRegistry, new GenericsRegistry(null)); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
SourceFile ret = generator.convert(tree, environment.packageCrawler); var classes = new ArrayList<ClassOrInterface>();
return ret; var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(sourceFile, sf);
generator.convert(classes, tree, environment.packageCrawler);
sf.imports.addAll(generator.imports);
return sf;
} }
/** /**
@ -655,10 +659,6 @@ public class JavaTXCompiler {
* @param name * @param name
*/ */
public boolean loadJavaTXClass(JavaClassName name) { public boolean loadJavaTXClass(JavaClassName name) {
if (classRegistry.contains(name.getClassName())) {
return true;
}
var file = findFileForClass(name); var file = findFileForClass(name);
if (file != null) { if (file != null) {
try { try {
@ -666,7 +666,10 @@ public class JavaTXCompiler {
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(this, classRegistry, new GenericsRegistry(null)); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null));
addSourceFile(file, generator.convert(tree, environment.packageCrawler)); var classes = new ArrayList<ClassOrInterface>();
var sf = new SourceFile(generator.pkgName, classes, generator.imports);
addSourceFile(file, sf);
generator.convert(classes, tree, environment.packageCrawler);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);

View File

@ -808,7 +808,8 @@ public class StatementGenerator {
receiver = generateLocalOrFieldVarOrClassName(part, offset); receiver = generateLocalOrFieldVarOrClassName(part, offset);
} else { } else {
StaticClassName cname = (StaticClassName) receiver; StaticClassName cname = (StaticClassName) receiver;
isStatic = Modifier.isStatic(compiler.getClass(reg.getName(cname.getType().toString())).getField(fieldName).orElseThrow().modifier); var javaClassName = reg.getName(cname.getType().toString());
isStatic = Modifier.isStatic(compiler.getClass(javaClassName).getField(fieldName).orElseThrow().modifier);
} }
return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset); return new FieldVar(receiver, isStatic, fieldName, TypePlaceholder.fresh(offset), offset);
} }

View File

@ -87,8 +87,8 @@ import javax.swing.text.html.Option;
public class SyntaxTreeGenerator { public class SyntaxTreeGenerator {
private JavaClassRegistry reg; private JavaClassRegistry reg;
private final GenericsRegistry globalGenerics; private final GenericsRegistry globalGenerics;
private String pkgName = ""; public String pkgName = "";
Set<JavaClassName> imports = new HashSet<>(); public Set<JavaClassName> imports = new HashSet<>();
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
@ -138,13 +138,12 @@ public class SyntaxTreeGenerator {
return ctx.getText(); return ctx.getText();
} }
public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException { public void convert(List<ClassOrInterface> classes, Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException {
SrcfileContext srcfile; SrcfileContext srcfile;
List<ClassOrInterface> classes = new ArrayList<>();
if (ctx instanceof Java17Parser.SrcfileContext) { if (ctx instanceof Java17Parser.SrcfileContext) {
srcfile = (SrcfileContext) ctx; srcfile = (SrcfileContext) ctx;
} else { } else {
return new SourceFile(this.pkgName, classes, this.imports); return;
} }
if (srcfile.packageDeclaration() != null) if (srcfile.packageDeclaration() != null)
this.pkgName = convert(srcfile.packageDeclaration()); this.pkgName = convert(srcfile.packageDeclaration());
@ -165,6 +164,7 @@ public class SyntaxTreeGenerator {
} }
} }
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
staticFieldInitializations = new ArrayList<>();
if (!Objects.isNull(clsoif.classDeclaration())) { if (!Objects.isNull(clsoif.classDeclaration())) {
newClass = convertClass(clsoif.classDeclaration(), modifiers); newClass = convertClass(clsoif.classDeclaration(), modifiers);
} else if (!Objects.isNull(clsoif.interfaceDeclaration())) { } else if (!Objects.isNull(clsoif.interfaceDeclaration())) {
@ -176,9 +176,7 @@ public class SyntaxTreeGenerator {
} }
classes.add(newClass); classes.add(newClass);
} }
if (classes.size() > 0) { if (classes.isEmpty()) {
return new SourceFile(this.pkgName, classes, this.imports);
} else {
throw new NotImplementedException("SourceFile enthält keine Klassen"); throw new NotImplementedException("SourceFile enthält keine Klassen");
} }
} }
@ -234,7 +232,7 @@ public class SyntaxTreeGenerator {
} }
} }
var ctor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), fieldInitializations, genericClassParameters, 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)); var staticCtor = Optional.of(this.generateStaticConstructor(ctx.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset); return new ClassOrInterface(modifiers, name, fielddecl, ctor, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, permittedSubtypes, offset);
} }
@ -290,7 +288,7 @@ 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));
} }
var staticCtor = Optional.of(this.generatePseudoConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset)); var staticCtor = Optional.of(this.generateStaticConstructor(recordDeclaration.identifier().getText(), staticFieldInitializations, genericClassParameters, offset));
return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset); return new Record(modifiers, name, fielddecl, initializations, staticCtor, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, offset);
} }
@ -409,7 +407,7 @@ public class SyntaxTreeGenerator {
} }
} }
var staticCtor = Optional.of(this.generatePseudoConstructor(ctx.identifier().getText(), staticFieldInitializations, genericParams, ctx.getStart())); var staticCtor = Optional.of(this.generateStaticConstructor(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()); return new ClassOrInterface(modifiers, name, fields, Optional.empty(), staticCtor, methods, new ArrayList<>(), genericParams, superClass, true, extendedInterfaces, permittedSubtypes, ctx.getStart());
} }
@ -475,6 +473,13 @@ public class SyntaxTreeGenerator {
*/); */);
} }
private Method generateStaticConstructor(String className, List<Statement> initializations, 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<>(initializations), offset);
return new Method(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset);
}
private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) { private RefType convertSuperType(Java17Parser.TypeTypeContext typeType) {
ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType(); ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType();
if (supertypecontext != null && supertypecontext.DOT().size() > 0) { if (supertypecontext != null && supertypecontext.DOT().size() > 0) {
@ -606,8 +611,9 @@ public class SyntaxTreeGenerator {
private void initializeField(Java17Parser.VariableDeclaratorContext ctx, boolean isStatic, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) { private void initializeField(Java17Parser.VariableDeclaratorContext ctx, boolean isStatic, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics) {
StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>()); StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>());
var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField); var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField);
if (isStatic) if (isStatic) {
staticFieldInitializations.add(assignment); staticFieldInitializations.add(assignment);
}
else fieldInitializations.add(assignment); else fieldInitializations.add(assignment);
} }

View File

@ -23,7 +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 Optional<Method> 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;
@ -32,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, Optional<Constructor> staticInitializer, 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<Method> 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;
@ -74,7 +74,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope {
return fields.stream().filter(field -> field.getName().equals(name)).findFirst(); return fields.stream().filter(field -> field.getName().equals(name)).findFirst();
} }
public Optional<Constructor> getStaticInitializer() { public Optional<Method> getStaticInitializer() {
return staticInitializer; return staticInitializer;
} }

View File

@ -13,7 +13,7 @@ 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, Optional<Constructor> staticInitializer, 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<Method> staticInitializer, List<Method> methods, List<Constructor> constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List<RefType> implementedInterfaces, Token offset) {
super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset); super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset);
} }
} }

View File

@ -21,11 +21,11 @@ public class SourceFile extends SyntaxTreeNode {
*/ */
public SourceFile(String pkgName, List<ClassOrInterface> classDefinitions, Set<JavaClassName> imports) { public SourceFile(String pkgName, List<ClassOrInterface> classDefinitions, Set<JavaClassName> imports) {
super(new NullToken()); super(new NullToken());
if (classDefinitions.size() > 0) { // Enthält die Liste Klassen? //if (classDefinitions.size() > 0) { // Enthält die Liste Klassen?
this.KlassenVektor = classDefinitions; // Klassen werden übernommen this.KlassenVektor = classDefinitions; // Klassen werden übernommen
} else { //} else {
this.KlassenVektor = null; // es handelt sich um ein "Java Module" // this.KlassenVektor = null; // es handelt sich um ein "Java Module"
} //}
this.pkgName = pkgName; this.pkgName = pkgName;
this.imports = imports; this.imports = imports;
} }

View File

@ -46,7 +46,7 @@ public class TYPE {
ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl)); ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl));
} }
if (cl.getStaticInitializer().isPresent()) { if (cl.getStaticInitializer().isPresent()) {
ret.addAll(getConstraintsConstructor(cl.getStaticInitializer().get(), info, cl)); ret.addAll(getConstraintsMethod(cl.getStaticInitializer().get(), info, cl));
} }
return ret; return ret;

View File

@ -345,7 +345,7 @@ public class TYPEStmt implements StatementVisitor {
} }
} }
if (numericAdditionOrStringConcatenation.size() < 1) { if (numericAdditionOrStringConcatenation.size() < 1) {
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset()); throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
} }
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
} else if (binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) { } else if (binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGERTHAN) || binary.operation.equals(BinaryExpr.Operator.LESSTHAN)) {