From b372c6ac1cb7e4e6f3d9f7c355700de049a80613 Mon Sep 17 00:00:00 2001 From: Daniel Holle Date: Tue, 24 Oct 2023 15:17:13 +0200 Subject: [PATCH] More work on static, references to other classes --- resources/bytecode/javFiles/Static.jav | 6 +++- .../de/dhbwstuttgart/bytecode/Codegen.java | 4 +-- .../de/dhbwstuttgart/core/JavaTXCompiler.java | 31 ++++++++++--------- .../StatementGenerator.java | 3 +- .../SyntaxTreeGenerator.java | 30 +++++++++++------- .../syntaxtree/ClassOrInterface.java | 6 ++-- .../de/dhbwstuttgart/syntaxtree/Record.java | 2 +- .../dhbwstuttgart/syntaxtree/SourceFile.java | 8 ++--- .../typeinference/typeAlgo/TYPE.java | 2 +- .../typeinference/typeAlgo/TYPEStmt.java | 2 +- 10 files changed, 53 insertions(+), 41 deletions(-) diff --git a/resources/bytecode/javFiles/Static.jav b/resources/bytecode/javFiles/Static.jav index 98166abb..aa0c3373 100644 --- a/resources/bytecode/javFiles/Static.jav +++ b/resources/bytecode/javFiles/Static.jav @@ -1,5 +1,9 @@ import java.lang.Integer; +class Other { + static field = 20; +} + public class Static { static i = 20; @@ -9,6 +13,6 @@ public class Static { } static m() { - return i; + return i + Other.field; } } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java index 535c1ad7..83c019c5 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/Codegen.java @@ -1296,9 +1296,7 @@ public class Codegen { 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)); + generate(state, constructor.block()); mv.visitInsn(RETURN); mv.visitMaxs(0, 0); diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index e161f7a2..9a36f871 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -70,8 +70,6 @@ public class JavaTXCompiler { final CompilationEnvironment environment; Boolean resultmodel = false; public final Map sourceFiles = new HashMap<>(); - // TODO We might want to incorporate this into the class registry instead - public final Map classes = new HashMap<>(); Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+""/logFiles/"" geschrieben werden soll? public volatile UnifyTaskModel usedTasks = new UnifyTaskModel(); @@ -106,20 +104,22 @@ public class JavaTXCompiler { classPath = contextPath; for (File s : sources) { - addSourceFile(s, parse(s)); + parse(s); } // 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); + for (var sf : sourceFiles.values()) { + for (var clazz : sf.KlassenVektor) { + if (clazz.getClassName().equals(name)) return clazz; + } + } + return null; } public ConstraintSet getConstraints() throws ClassNotFoundException, IOException { @@ -645,8 +645,12 @@ public class JavaTXCompiler { SourceFileContext tree = JavaTXParser.parse(sourceFile); environment.addClassesToRegistry(classRegistry, tree, sourceFile, this); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null)); - SourceFile ret = generator.convert(tree, environment.packageCrawler); - return ret; + var classes = new ArrayList(); + 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 */ public boolean loadJavaTXClass(JavaClassName name) { - if (classRegistry.contains(name.getClassName())) { - return true; - } - var file = findFileForClass(name); if (file != null) { 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? environment.addClassesToRegistry(classRegistry, tree, file, this); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(this, classRegistry, new GenericsRegistry(null)); - addSourceFile(file, generator.convert(tree, environment.packageCrawler)); + var classes = new ArrayList(); + var sf = new SourceFile(generator.pkgName, classes, generator.imports); + addSourceFile(file, sf); + generator.convert(classes, tree, environment.packageCrawler); return true; } catch (Exception e) { throw new RuntimeException(e); diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java index 56d03576..31e5d8ed 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/StatementGenerator.java @@ -808,7 +808,8 @@ public class StatementGenerator { receiver = generateLocalOrFieldVarOrClassName(part, offset); } else { 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); } diff --git a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 209b5ba9..95dfec33 100644 --- a/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -87,8 +87,8 @@ import javax.swing.text.html.Option; public class SyntaxTreeGenerator { private JavaClassRegistry reg; private final GenericsRegistry globalGenerics; - private String pkgName = ""; - Set imports = new HashSet<>(); + public String pkgName = ""; + public Set imports = new HashSet<>(); HashMap allmodifiers = new HashMap<>(); // PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH // bekommen @@ -138,13 +138,12 @@ public class SyntaxTreeGenerator { return ctx.getText(); } - public SourceFile convert(Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException { + public void convert(List classes, Java17Parser.SourceFileContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException, NotImplementedException { SrcfileContext srcfile; - List classes = new ArrayList<>(); if (ctx instanceof Java17Parser.SrcfileContext) { srcfile = (SrcfileContext) ctx; } else { - return new SourceFile(this.pkgName, classes, this.imports); + return; } if (srcfile.packageDeclaration() != null) 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 + staticFieldInitializations = new ArrayList<>(); if (!Objects.isNull(clsoif.classDeclaration())) { newClass = convertClass(clsoif.classDeclaration(), modifiers); } else if (!Objects.isNull(clsoif.interfaceDeclaration())) { @@ -176,9 +176,7 @@ public class SyntaxTreeGenerator { } classes.add(newClass); } - if (classes.size() > 0) { - return new SourceFile(this.pkgName, classes, this.imports); - } else { + if (classes.isEmpty()) { 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 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); } @@ -290,7 +288,7 @@ public class SyntaxTreeGenerator { if (!Objects.isNull(recordDeclaration.IMPLEMENTS())) { 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); } @@ -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()); } @@ -475,6 +473,13 @@ public class SyntaxTreeGenerator { */); } + private Method generateStaticConstructor(String className, List 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) { ClassOrInterfaceTypeContext supertypecontext = typeType.classOrInterfaceType(); 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) { StatementGenerator statementGenerator = new StatementGenerator(superClass, compiler, reg, generics, fields, new HashMap<>()); var assignment = statementGenerator.generateFieldAssignment(ctx, typeOfField); - if (isStatic) + if (isStatic) { staticFieldInitializations.add(assignment); + } else fieldInitializations.add(assignment); } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index f1eb5290..fa319e49 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -23,7 +23,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope { protected JavaClassName name; private List fields = new ArrayList<>(); private Optional fieldInitializations; // PL 2018-11-24: Noetig, um Bytecode fuer initializators nur einmal zu erzeugen - private Optional staticInitializer; + private Optional staticInitializer; private List methods = new ArrayList<>(); private GenericDeclarationList genericClassParameters; private RefType superClass; @@ -32,7 +32,7 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope { private List permittedSubtypes; private List constructors; - public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, Optional staticInitializer, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, List permittedSubtypes, Token offset) { + public ClassOrInterface(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, Optional staticInitializer, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, List permittedSubtypes, Token offset) { super(offset); if (isInterface) { 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(); } - public Optional getStaticInitializer() { + public Optional getStaticInitializer() { return staticInitializer; } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java b/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java index 7b1bdc80..462c5c79 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/Record.java @@ -13,7 +13,7 @@ import javax.swing.text.html.Option; public class Record extends ClassOrInterface { - public Record(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, Optional staticInitializer, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, Token offset) { + public Record(int modifiers, JavaClassName name, List fielddecl, Optional fieldInitializations, Optional staticInitializer, List methods, List constructors, GenericDeclarationList genericClassParameters, RefType superClass, Boolean isInterface, List implementedInterfaces, Token offset) { super(modifiers, name, fielddecl, fieldInitializations, staticInitializer, methods, constructors, genericClassParameters, superClass, isInterface, implementedInterfaces, new ArrayList<>(), offset); } } diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/main/java/de/dhbwstuttgart/syntaxtree/SourceFile.java index 252e7cc5..6745d53f 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -21,11 +21,11 @@ public class SourceFile extends SyntaxTreeNode { */ public SourceFile(String pkgName, List classDefinitions, Set imports) { 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 - } else { - this.KlassenVektor = null; // es handelt sich um ein "Java Module" - } + //} else { + // this.KlassenVektor = null; // es handelt sich um ein "Java Module" + //} this.pkgName = pkgName; this.imports = imports; } diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java index 73a9e868..d8de982e 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPE.java @@ -46,7 +46,7 @@ public class TYPE { ret.addAll(getConstraintsConstructor(cl.getfieldInitializations().get(), info, cl)); } if (cl.getStaticInitializer().isPresent()) { - ret.addAll(getConstraintsConstructor(cl.getStaticInitializer().get(), info, cl)); + ret.addAll(getConstraintsMethod(cl.getStaticInitializer().get(), info, cl)); } return ret; diff --git a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index ffbed416..a9d1051c 100644 --- a/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -345,7 +345,7 @@ public class TYPEStmt implements StatementVisitor { } } 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); } 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)) {