From ae02ee247ac913e893e4b1c6819e50ae92cde674 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 17 Aug 2017 15:08:07 +0200 Subject: [PATCH 01/42] SAT Package erstellen --- src/de/dhbwstuttgart/sat/CNF/CNF.java | 8 ++++++++ src/de/dhbwstuttgart/sat/CNF/Writer.java | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/de/dhbwstuttgart/sat/CNF/CNF.java create mode 100644 src/de/dhbwstuttgart/sat/CNF/Writer.java diff --git a/src/de/dhbwstuttgart/sat/CNF/CNF.java b/src/de/dhbwstuttgart/sat/CNF/CNF.java new file mode 100644 index 00000000..e5d9b3d0 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/CNF/CNF.java @@ -0,0 +1,8 @@ +package de.dhbwstuttgart.sat.CNF; + +public class CNF { + /* + Baut die CNF Datei. + Hier muss man überlegen, in welchem Form die Constraints gebaut werden + */ +} diff --git a/src/de/dhbwstuttgart/sat/CNF/Writer.java b/src/de/dhbwstuttgart/sat/CNF/Writer.java new file mode 100644 index 00000000..c366686a --- /dev/null +++ b/src/de/dhbwstuttgart/sat/CNF/Writer.java @@ -0,0 +1,12 @@ +package de.dhbwstuttgart.sat.CNF; + +import java.io.*; + +/** + * Schreibt CNFs in eine Datei im DIMACS CNF Format + */ +public class Writer { + public Writer(FileWriter output){ + + } +} From 1d767a769675f2c1d65533952107a73c45e5c553 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 3 Nov 2017 13:56:04 +0100 Subject: [PATCH 02/42] Matrix Test --- test/javFiles/Matrix.jav | 14 +++++++++++++- test/typeinference/JavaTXCompilerTest.java | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/test/javFiles/Matrix.jav b/test/javFiles/Matrix.jav index 65dc465a..e6aa84cd 100644 --- a/test/javFiles/Matrix.jav +++ b/test/javFiles/Matrix.jav @@ -1,5 +1,16 @@ import java.util.Vector; +class Matrix extends Vector> { + + methode(Matrix m) { + Vector> i; + methode(i); + } + } + +/* +import java.util.Vector; + class Matrix extends Vector> { Matrix mul_rec(Matrix m) { @@ -39,4 +50,5 @@ class Matrix extends Vector> { } return ret; } -} \ No newline at end of file +} +*/ \ No newline at end of file diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index 4b79b8c5..8e60c803 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -37,6 +37,7 @@ public class JavaTXCompilerTest { //filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"test.jav")); filesToTest.add(new File(rootDirectory+"EmptyMethod.jav")); + //filesToTest.add(new File(rootDirectory+"fc.jav")); //filesToTest.add(new File(rootDirectory+"Lambda.jav")); //filesToTest.add(new File(rootDirectory+"Lambda2.jav")); //filesToTest.add(new File(rootDirectory+"Lambda3.jav")); From 5a026a431c98093f905206349d82f3bfbde05175 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Fri, 3 Nov 2017 14:17:36 +0100 Subject: [PATCH 03/42] kleine Aenderung --- src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java | 4 +++- test/bytecode/JavaTXCompilerTest.java | 2 +- test/typeinference/FiniteClosureTest.java | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c65e691c..debcd8e4 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -175,8 +175,10 @@ public class BytecodeGenMethod implements StatementVisitor{ MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); // new BytecodeGenLambda(lambdaExpression, mvLambdaBody); + HashMap paramsAndLocalsLambda = new HashMap<>(); + new BytecodeGenMethod(lambdaExpression, mvLambdaBody, paramsAndLocalsLambda, arg3.toString()); - new BytecodeGenMethod(lambdaExpression, mvLambdaBody, new HashMap<>(), arg3.toString()); + mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocalsLambda.size()); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); } diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 9ca91abb..228a4851 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -51,7 +51,7 @@ public class JavaTXCompilerTest { byte[] bytecode = classFiles.get(name); try { System.out.println("generating .class file"); - output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/" +name+".class")); + output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); output.write(bytecode); output.close(); System.out.println(".class file generated"); diff --git a/test/typeinference/FiniteClosureTest.java b/test/typeinference/FiniteClosureTest.java index d3e1fdb0..8b62e4e5 100644 --- a/test/typeinference/FiniteClosureTest.java +++ b/test/typeinference/FiniteClosureTest.java @@ -4,6 +4,6 @@ import java.io.File; public class FiniteClosureTest extends JavaTXCompilerTest{ public FiniteClosureTest() { - this.fileToTest = new File(rootDirectory+"fc.jav"); +// this.fileToTest = new File(rootDirectory+"fc.jav"); } } \ No newline at end of file From 01703a73c544e707af7884ba9c42880da353253c Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Tue, 7 Nov 2017 10:55:33 +0100 Subject: [PATCH 04/42] generiert Bytecode fuer einfachen Lambda --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 9 ++- .../bytecode/BytecodeGenMethod.java | 72 +++++++++++++------ test/bytecode/Interface1.jav | 3 + test/bytecode/JavaTXCompilerTest.java | 13 +++- test/bytecode/LamRunnable.jav | 9 +++ test/bytecode/VoidMeth.jav | 5 ++ 6 files changed, 84 insertions(+), 27 deletions(-) create mode 100644 test/bytecode/Interface1.jav create mode 100644 test/bytecode/LamRunnable.jav create mode 100644 test/bytecode/VoidMeth.jav diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 425582ad..dbdb1dc2 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -29,6 +29,7 @@ public class BytecodeGen implements ASTVisitor { String type; String className; + private boolean isInterface; // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... HashMap paramsAndLocals;// = new HashMap<>(); @@ -43,6 +44,8 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(SourceFile sourceFile) { for(ClassOrInterface cl : sourceFile.getClasses()) { + isInterface = (cl.getModifiers()&512)==512; + System.out.println("IS Interface = "+"modifiers= "+cl.getModifiers()+" ->"+(cl.getModifiers()&512) + isInterface); BytecodeGen classGen = new BytecodeGen(classFiles); cl.accept(classGen); classGen.writeClass(cl.getClassName().toString()); @@ -88,9 +91,9 @@ public class BytecodeGen implements ASTVisitor { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc.getDesc(), null, null); mv.visitCode(); System.out.println("-----Constructor-----"); - BytecodeGenMethod gen = new BytecodeGenMethod(className,field, mv,paramsAndLocals,desc.getDesc(),cw); + BytecodeGenMethod gen = new BytecodeGenMethod(className,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface); - mv.visitInsn(Opcodes.RETURN); +// mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } @@ -103,7 +106,7 @@ public class BytecodeGen implements ASTVisitor { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc.getDesc(), null, null); mv.visitCode(); - BytecodeGenMethod gen = new BytecodeGenMethod(className,method, mv,paramsAndLocals,methDesc.getDesc(),cw); + BytecodeGenMethod gen = new BytecodeGenMethod(className,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface); mv.visitMaxs(0, 0); mv.visitEnd(); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 7547abc5..ff9c8faa 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -1,11 +1,10 @@ package de.dhbwstuttgart.bytecode; -import java.io.PrintStream; import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.security.GeneralSecurityException; +import java.util.ArrayList; import java.util.HashMap; import de.dhbwstuttgart.syntaxtree.statement.*; @@ -31,17 +30,21 @@ public class BytecodeGenMethod implements StatementVisitor{ private String className; private int lamCounter; private ClassWriter cw; + private boolean isInterface; //for tests ** private String fieldName; private String fieldDesc; private Expression rightSideTemp; private String where; + private boolean isRightSideALambda = false; + + private ArrayList varsFunInterface; public BytecodeGenMethod(String className, Method m, MethodVisitor mv, HashMap paramsAndLocals, - String desc, ClassWriter cw) { + String desc, ClassWriter cw, boolean isInterface) { - this.where = "NORMAL METHOD"; + this.where = "<<<<<< NORMAL METHOD >>>>>>"; this.className = className; this.m = m; @@ -49,23 +52,27 @@ public class BytecodeGenMethod implements StatementVisitor{ this.paramsAndLocals = paramsAndLocals; this.desc = desc; this.cw = cw; + this.isInterface = isInterface; this.lamCounter = -1; + this.varsFunInterface = new ArrayList<>(); + this.m.block.accept(this); } public BytecodeGenMethod(LambdaExpression lambdaExpression, MethodVisitor mv, - HashMap paramsAndLocals, String desc) { - System.out.println("++++++IN LAMBDA -------"); + HashMap paramsAndLocals, String desc,boolean isInterface) { + System.out.println("\t\t++++++IN LAMBDA -------"); - this.where = "&&&&&&&& LAMBDA METHOD"; + this.where = "<<<<<< LAMBDA METHOD >>>>>>"; this.mv = mv; this.paramsAndLocals = paramsAndLocals; this.desc = desc; - + this.isInterface = isInterface; this.lamCounter = -1; + this.varsFunInterface = new ArrayList<>(); lambdaExpression.methodBody.accept(this); } @@ -85,19 +92,20 @@ public class BytecodeGenMethod implements StatementVisitor{ superCall.receiver.accept(this); superCall.arglist.accept(this); // mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, desc,false); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, desc,isInterface); } // ?? @Override public void visit(LocalVar localVar) { System.out.println("in Local Var"); + mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); } // ?? @Override public void visit(LocalVarDecl localVarDecl) { // Integer i; - paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); +// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); System.out.println("In localVarDecl"); } @@ -105,6 +113,14 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(Assign assign) { System.out.println("Assign : \nright = "+assign.rightSide + "\nLeft = " + assign.lefSide); + // if the right side is a lambda => the left side must be a functional interface + if(assign.rightSide.getClass().equals(LambdaExpression.class)) { + isRightSideALambda = true; + }else { + isRightSideALambda = false; + } + + System.out.println("\t isRight Side lambda: " + isRightSideALambda); if(assign.lefSide.getClass().equals(AssignToField.class)) { // load_0, ldc or .. then putfield this.rightSideTemp = assign.rightSide; @@ -120,7 +136,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Binary binary) { - System.out.println("++ In Binary: "); + System.out.println("\t++ In Binary: "); } @Override @@ -148,11 +164,12 @@ public class BytecodeGenMethod implements StatementVisitor{ methodName, arg3.toString(), null, null); // new BytecodeGenLambda(lambdaExpression, mvLambdaBody); HashMap paramsAndLocalsLambda = new HashMap<>(); - new BytecodeGenMethod(lambdaExpression, mvLambdaBody, paramsAndLocalsLambda, arg3.toString()); + new BytecodeGenMethod(lambdaExpression, mvLambdaBody, paramsAndLocalsLambda, arg3.toString(),isInterface); - mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocalsLambda.size()); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); + cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", + Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); } @Override @@ -204,7 +221,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(MethodCall methodCall) { System.out.println(" In Methodcall: (" +methodCall.name+")" ); - System.out.print(" Method-Receiver: "); + System.out.print("\t\tMethod-Receiver: "); if(methodCall.receiver instanceof ExpressionReceiver){ System.out.print(((ExpressionReceiver) methodCall.receiver).expr + "\n"); }else{ @@ -216,18 +233,26 @@ public class BytecodeGenMethod implements StatementVisitor{ Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType()); - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.getType().toString(), - methodCall.name, mDesc.getDesc(), false); - // test - if(!methodCall.getType().toString().equals("V")) { - mv.visitInsn(Opcodes.POP); + System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); + + // is methodCall.receiver functional Interface)? + if(varsFunInterface.contains(methodCall.receiver.getType())) { + mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, methodCall.receiver.getType().toString().replace(".", "/"), + methodCall.name, mDesc.getDesc(), false); + }else { + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.getType().toString().replace(".", "/"), + methodCall.name, mDesc.getDesc(), isInterface); } + // test +// if(!methodCall.getType().toString().equals("V")) { +// mv.visitInsn(Opcodes.POP); +// } } @Override public void visit(NewClass methodCall) { System.out.println("In NewClass: "); - System.out.println("name: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver); + System.out.println("\t\tname: " + methodCall.name + " *** " + "Receiver: " + methodCall.receiver); mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/")); mv.visitInsn(Opcodes.DUP); @@ -239,7 +264,7 @@ public class BytecodeGenMethod implements StatementVisitor{ } d += ")V"; - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "", d, false); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "", d, isInterface); } @Override @@ -322,6 +347,8 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(AssignToField assignLeftSide) { + if(isRightSideALambda) + varsFunInterface.add(assignLeftSide.field.getType()); // Loads the an object reference from the local variable // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); @@ -332,6 +359,9 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(AssignToLocal assignLeftSide) { + System.out.println("In Assign To Local: "); + if(isRightSideALambda) + varsFunInterface.add(assignLeftSide.localVar.getType()); paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1); mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size()); } diff --git a/test/bytecode/Interface1.jav b/test/bytecode/Interface1.jav new file mode 100644 index 00000000..b741819c --- /dev/null +++ b/test/bytecode/Interface1.jav @@ -0,0 +1,3 @@ +public interface Interface1{ + public void test(); +} \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 228a4851..5c3e0a87 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -21,19 +21,26 @@ import static org.junit.Assert.*; public class JavaTXCompilerTest { - private static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/"; + private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; private static final List filesToTest = new ArrayList<>(); @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - filesToTest.add(new File(rootDirectory+"EmptyClass.jav")); + String fileName = "LamRunnable"; + filesToTest.add(new File(rootDirectory+fileName+".jav")); + System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); System.out.println("test"); for(File f : filesToTest){ String content = readFile(f.getPath(), StandardCharsets.UTF_8); HashMap bytecode = this.getBytecode(compiler.sourceFiles.get(f)); - this.writeClassFile(bytecode, "EmptyClass"); + String name = ""; + int pos = f.getName().lastIndexOf("."); + if(pos != -1) { + name = f.getName().substring(0, pos); + } + this.writeClassFile(bytecode, name); } } diff --git a/test/bytecode/LamRunnable.jav b/test/bytecode/LamRunnable.jav new file mode 100644 index 00000000..451858f2 --- /dev/null +++ b/test/bytecode/LamRunnable.jav @@ -0,0 +1,9 @@ +public class LamRunnable{ + + public LamRunnable(){ + + Runnable lam = () -> {System.out.println("lambda");}; + lam.run(); + } +} + \ No newline at end of file diff --git a/test/bytecode/VoidMeth.jav b/test/bytecode/VoidMeth.jav new file mode 100644 index 00000000..bdbf2545 --- /dev/null +++ b/test/bytecode/VoidMeth.jav @@ -0,0 +1,5 @@ +public class VoidMeth{ + public void test(){ + System.out.print(""); + } +} \ No newline at end of file From fea86460e85ce984894396d2c9e2c0c04c5f13b5 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 9 Nov 2017 19:41:53 +0100 Subject: [PATCH 05/42] =?UTF-8?q?=C3=84nderungen=20an=20der=20FC=20generie?= =?UTF-8?q?rung=20und=20an=20dem=20Verhalten=20von=20GTVs=20im=20Type=20Al?= =?UTF-8?q?gorithmus=20UNVOLLST=C3=84NDIG.=20Kleines=20Backup,=20da=20gro?= =?UTF-8?q?=C3=9Fe=20=C3=84nderung=20am=20Type-Algorithmus=20noch=20ansteh?= =?UTF-8?q?t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environment/CompilationEnvironment.java | 9 +++ .../environment/PackageCrawler.java | 10 +++ .../SyntaxTreeGenerator.java | 8 +-- .../SyntaxTreeGenerator/TypeGenerator.java | 2 +- .../parser/scope/GenericTypeName.java | 4 ++ .../syntaxtree/ClassOrInterface.java | 8 ++- .../dhbwstuttgart/syntaxtree/Constructor.java | 6 +- .../syntaxtree/GenericTypeVar.java | 9 +++ .../dhbwstuttgart/syntaxtree/TypeScope.java | 2 + .../syntaxtree/factory/ASTFactory.java | 19 ++++-- .../syntaxtree/factory/UnifyTypeFactory.java | 68 +++++++++++++++++-- .../assumptions/FieldAssumption.java | 11 +-- .../assumptions/MethodAssumption.java | 12 +++- .../assumptions/TypeInferenceInformation.java | 3 +- .../constraints/ConstraintsFactory.java | 12 ++++ .../typeinference/typeAlgo/TYPEStmt.java | 39 ++++++++--- .../unify/model/FiniteClosure.java | 45 ++++++------ .../typeinference/unify/model/TypeParams.java | 10 ++- 18 files changed, 216 insertions(+), 61 deletions(-) diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 46a60139..9a632674 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -60,4 +60,13 @@ public class CompilationEnvironment { allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); return new JavaClassRegistry(allNames); } + + public List getAllAvailableClasses() { + List ret = new ArrayList<>(); + for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){ + ret.add(ASTFactory.createClass(c)); + } + return ret; + } + } diff --git a/src/de/dhbwstuttgart/environment/PackageCrawler.java b/src/de/dhbwstuttgart/environment/PackageCrawler.java index 47b58128..cec63562 100644 --- a/src/de/dhbwstuttgart/environment/PackageCrawler.java +++ b/src/de/dhbwstuttgart/environment/PackageCrawler.java @@ -56,6 +56,16 @@ public class PackageCrawler { return classes; } + public Set> getAllAvailableClasses(){ + Reflections reflections = new Reflections(new ConfigurationBuilder() + .setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner()) + .setUrls(urls)); + + Set> classes = reflections.getSubTypesOf(Object.class); + + return classes; + } + public List getClassNames(String packageName){ List nameList = new ArrayList(); Set> classes = getClassesInPackage(packageName); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index 830f9d37..ed9d82e2 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -184,7 +184,7 @@ public class SyntaxTreeGenerator{ block = stmtGen.convert(body.block()); } if(parentClass.equals(new JavaClassName(name))){ - return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass); + return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); }else{ return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); } @@ -222,7 +222,7 @@ public class SyntaxTreeGenerator{ if(ctx.superclass() != null){ superClass = convert(ctx.superclass()); }else{ - superClass = ASTFactory.createObjectClass().getType(); + superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart()); } List fielddecl = convertFields(ctx.classBody(), generics); List methods = convertMethods(ctx.classBody(), name, superClass, generics); @@ -269,7 +269,7 @@ public class SyntaxTreeGenerator{ int modifiers = 0; ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset); - return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass); + return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations); } private RefType convert(Java8Parser.SuperclassContext superclass) { @@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{ }else{ genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); } - RefType superClass = ASTFactory.createObjectClass().getType(); + RefType superClass = ASTFactory.createObjectType(); List fields = convertFields(ctx.interfaceBody()); List methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index c60ae322..b5042fba 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -77,7 +77,7 @@ public class TypeGenerator { public static List convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { List ret = new ArrayList<>(); if(typeBoundContext == null){ - ret.add(ASTFactory.createObjectClass().getType()); + ret.add(ASTFactory.createObjectType()); return ret; } if(typeBoundContext.typeVariable() != null){ diff --git a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java index 0cee932f..c5355ebd 100644 --- a/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java +++ b/src/de/dhbwstuttgart/parser/scope/GenericTypeName.java @@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName { + DELIMITER + methodName + DELIMITER + super.toString(); } + + public JavaClassName getParentClass() { + return parentClass; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java index 540bc993..5d5fc3e2 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java +++ b/src/de/dhbwstuttgart/syntaxtree/ClassOrInterface.java @@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return this.methods; } + /* public RefType getType() { return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); } - + */ + //TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern List params = new ArrayList<>(); @@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{ return new RefType(name, params, offset); } + /** + * Die Superklasse im Kontext dieser ClassOrInterface + * Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind + */ public RefType getSuperClass() { return superClass; } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index 2fdfb04e..bb48be40 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -15,8 +15,8 @@ public class Constructor extends Method { //TODO: Constructor braucht ein super-Statement public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, - GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations, RefType superClass) { - super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset); + GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { + super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); } @@ -25,7 +25,7 @@ public class Constructor extends Method { * welche die Felder der zugehörigen Klasse dieses * Konstruktor initialisieren */ - protected static Block prepareBlock(Block constructorBlock, List fieldInitializations, RefType superClass){ + protected static Block prepareBlock(Block constructorBlock, List fieldInitializations){ List statements = constructorBlock.getStatements(); statements.add(0, new SuperCall(constructorBlock.getOffset())); return new Block(statements, constructorBlock.getOffset()); diff --git a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java index c43fe068..02042ca3 100644 --- a/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/GenericTypeVar.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.parser.scope.GenericTypeName; +import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import org.antlr.v4.runtime.Token; @@ -53,6 +54,14 @@ public class GenericTypeVar extends SyntaxTreeNode return name; } + public String getParsedName(){ + return name.toString(); + } + + public JavaClassName definingClass(){ + return name.getParentClass(); + } + @Override public void accept(ASTVisitor visitor) { visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java index 3631eb2e..f651648b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/TypeScope.java +++ b/src/de/dhbwstuttgart/syntaxtree/TypeScope.java @@ -2,6 +2,8 @@ package de.dhbwstuttgart.syntaxtree; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import java.util.Collection; + public interface TypeScope { Iterable getGenerics(); diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index b3f628a7..046b97b8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -5,6 +5,7 @@ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.List; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.scope.GenericTypeName; @@ -45,7 +46,11 @@ public class ASTFactory { java.lang.Class superjreClass = jreClass.getSuperclass(); RefType superClass; if(superjreClass != null){ - superClass = (RefType) createType(superjreClass, name, ""); + List params = new ArrayList<>(); + for(TypeVariable tv : superjreClass.getTypeParameters()){ + params.add(new RefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken())); + } + superClass = new RefType(new JavaClassName(superjreClass.getName()), params, new NullToken()); }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) superClass = (RefType) createType(java.lang.Object.class, name, ""); } @@ -83,13 +88,12 @@ public class ASTFactory { return null; } - return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(), - createType(inClass.getSuperclass())); + return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); } - private static RefType createType(Class classType) { - return createClass(classType).getType(); - } + //private static RefType createType(Class classType) { + // return createClass(classType).getType(); + //} public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ String name = jreMethod.getName(); @@ -182,6 +186,9 @@ public class ASTFactory { public static ClassOrInterface createObjectClass() { return createClass(Object.class); } + public static RefType createObjectType() { + return new RefType(createClass(Object.class).getClassName(), new NullToken()); + } /* public Constructor createEmptyConstructor(Class parent){ diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index c154e86f..7ad15acc 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.util.*; import java.util.stream.Collectors; +import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; @@ -26,19 +28,73 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType; import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.UnifyType; - public class UnifyTypeFactory { - public static FiniteClosure generateFC(List fromAvailableClasses){ + public static FiniteClosure generateFC(List fromClasses) throws ClassNotFoundException { + /* + TODO: Generics werden zu TPHs + Die transitive Hülle muss funktionieren. + Man darf schreiben List extends AL + und Vector extends List + hier muss dann aber dennoch die Vererbung V < L < AL + hergestellt werden. + In einem solchen Vererbungsbaum dürfen die TPH auch die gleichen Namen haben. + Generell dürfen sie immer die gleichen Namen haben. + TODO: die transitive Hülle bilden + */ HashSet pairs = new HashSet<>(); - for(ClassOrInterface cl : fromAvailableClasses){ - UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); - UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass()); - pairs.add(generateSmallerPair(t1, t2)); + for(ClassOrInterface cly : fromClasses){ + pairs.addAll(getSuperTypes(cly, fromClasses)); } return new FiniteClosure(pairs); } + /** + * Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ + * Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss. + * Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH + * @param forType + * @return + */ + private static List getSuperTypes(ClassOrInterface forType, List availableClasses) throws ClassNotFoundException { + return getSuperTypes(forType, availableClasses, new HashMap<>()); + } + + private static List getSuperTypes(ClassOrInterface forType, List availableClasses, HashMap gtvs) throws ClassNotFoundException { + List params = new ArrayList<>(); + //Generics mit gleichem Namen müssen den selben TPH bekommen + for(GenericTypeVar gtv : forType.getGenerics()){ + if(!gtvs.containsKey(gtv.getParsedName())) + gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder()); + params.add(gtvs.get(gtv.getParsedName())); + } + Optional hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny(); + ClassOrInterface superClass; + if(!hasSuperclass.isPresent()) //TODO: Wenn es die Object-Klasse ist, dann ist es in Ordnung, ansonsten Fehler ausgeben: + { + superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString())); + }else{ + superClass = hasSuperclass.get(); + } + List superTypes; + if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){ + superTypes = Arrays.asList(generateSmallerPair(convert(ASTFactory.createObjectType()), convert(ASTFactory.createObjectType()))); + }else{ + superTypes = getSuperTypes(superClass, availableClasses, gtvs); + } + + TypeParams paramList = new TypeParams(params); + UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList); + UnifyType t2 = superTypes.get(0).getLhsType(); + + UnifyPair ret = generateSmallerPair(t1, t2); + List retList = new ArrayList<>(); + retList.add(ret); + retList.addAll(superTypes); + + return retList; + } + public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ return new UnifyPair(tl, tr, PairOperator.SMALLER); } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java index 88b2bd4a..2e568e48 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java @@ -1,21 +1,22 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class FieldAssumption extends Assumption{ - private RefTypeOrTPHOrWildcardOrGeneric receiverType; + private ClassOrInterface receiverClass; private RefTypeOrTPHOrWildcardOrGeneric type; - public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, + public FieldAssumption(ClassOrInterface receiverType, RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ super(scope); this.type = type; - this.receiverType = receiverType; + this.receiverClass = receiverType; } - public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { - return receiverType; + public ClassOrInterface getReceiverClass() { + return receiverClass; } public RefTypeOrTPHOrWildcardOrGeneric getType() { diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index bbeff0d7..af8d6fb7 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.statement.Assign; @@ -10,11 +11,11 @@ import java.util.List; import java.util.stream.Collectors; public class MethodAssumption extends Assumption{ - private RefType receiver; + private ClassOrInterface receiver; private RefTypeOrTPHOrWildcardOrGeneric retType; List params; - public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, + public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType, List params, TypeScope scope){ super(scope); this.receiver = receiver; @@ -22,7 +23,14 @@ public class MethodAssumption extends Assumption{ this.params = params; } + /* public RefType getReceiverType() { + + return receiver; + } + */ + + public ClassOrInterface getReceiver(){ return receiver; } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java index 90548e6d..737cd0c4 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/TypeInferenceInformation.java @@ -46,7 +46,8 @@ public class TypeInferenceInformation { for(ClassOrInterface cl : classes){ for(Field m : cl.getFieldDecl()){ if(m.getName().equals(name)){ - ret.add(new FieldAssumption(cl.getType(), checkGTV(m.getType()), new TypeScopeContainer(cl, m))); + + ret.add(new FieldAssumption(cl, checkGTV(m.getType()), new TypeScopeContainer(cl, m))); } } } diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java index 3d1058da..043af210 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java @@ -17,6 +17,17 @@ import java.util.Map; public class ConstraintsFactory { + /** + * Erstellt ein Pair Element für den Unify. + * Die Methode löst gleichzeitig GTVs in den Typen t1 und t2 auf. + * @param t1 + * @param t2 + * @param equalsdot + * @param currentScope + * @param additionalScope + * @param resolver + * @return + */ public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2, PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope, GenericsResolver resolver){ @@ -30,6 +41,7 @@ public class ConstraintsFactory { return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver); } + private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, TypeScope currentScope, TypeScope additionalScope, GenericsResolver resolver){ diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index bf063d71..8062e173 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -6,14 +6,12 @@ import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; -import de.dhbwstuttgart.syntaxtree.type.FunN; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; @@ -113,8 +111,10 @@ public class TYPEStmt implements StatementVisitor{ for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ Constraint constraint = new Constraint(); GenericsResolver resolver = getResolverInstance(); + /*TODO Hier muss der Typ der Klasse ermittelt werden. In diesem müssen Generics mit TPHs ausgetauscht werden constraint.add(ConstraintsFactory.createPair( fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); + */ constraint.add(ConstraintsFactory.createPair( fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); oderConstraints.add(constraint); @@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{ if(oderConstraints.size() == 0) throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); constraintsSet.addOderConstraint(oderConstraints); + + //Wegen dem Problem oben: + throw new NotImplementedException(); } @Override @@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{ @Override public void visit(This aThis) { + //Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden. + ClassOrInterface currentClass = info.getCurrentClass(); + List params = new ArrayList<>(); + for(GenericTypeVar gtv : currentClass.getGenerics()){ + params.add(new GenericRefType(gtv.getName(), aThis.getOffset())); + } + RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset()); constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), + aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); } @@ -280,7 +290,18 @@ public class TYPEStmt implements StatementVisitor{ protected Constraint generateConstraint(MethodCall forMethod, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), + ClassOrInterface receiverCl = assumption.getReceiver(); + List params = new ArrayList<>(); + for(GenericTypeVar gtv : receiverCl.getGenerics()){ + //if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){ + // params.add(new GenericRefType(gtv.getName(), forMethod.getOffset())); + //}else{ + //Die Generics werden alle zu TPHs umgewandelt. + params.add(TypePlaceholder.fresh(forMethod.getOffset())); + //} + } + RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset()); + methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), receiverType, PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); @@ -302,6 +323,7 @@ public class TYPEStmt implements StatementVisitor{ public static List getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { List ret = new ArrayList<>(); + /* if(name.equals("apply")){ List funNParams = new ArrayList<>(); for(int i = 0; i< numArgs + 1 ; i++){ @@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{ } })); } + */ for(ClassOrInterface cl : info.getAvailableClasses()){ for(Method m : cl.getMethods()){ if(m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs){ RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); - ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info), + ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info), createTypeScope(cl, m))); } } @@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{ if(cl.getClassName().equals(ofType.getName())){ for(Method m : cl.getConstructors()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ - ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(), + ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(), info), createTypeScope(cl, m))); } } diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java index 9ace0e51..aba3d3f6 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java @@ -17,17 +17,18 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify; * @author Florian Steurer */ public class FiniteClosure implements IFiniteClosure { - + /** * A map that maps every type to the node in the inheritance graph that contains that type. - */ + */ private HashMap> inheritanceGraph; /** * A map that maps every typename to the nodes of the inheritance graph that contain a type with that name. */ private HashMap>> strInheritanceGraph; - + + /** * The initial pairs of that define the inheritance tree */ @@ -38,7 +39,7 @@ public class FiniteClosure implements IFiniteClosure { */ public FiniteClosure(Set pairs) { this.pairs = new HashSet<>(pairs); - inheritanceGraph = new HashMap>(); + inheritanceGraph = new HashMap>(); // Build the transitive closure of the inheritance tree for(UnifyPair pair : pairs) { @@ -46,7 +47,7 @@ public class FiniteClosure implements IFiniteClosure { continue; // Add nodes if not already in the graph - if(!inheritanceGraph.containsKey(pair.getLhsType())) + if(!inheritanceGraph.containsKey(pair.getLhsType())) inheritanceGraph.put(pair.getLhsType(), new Node(pair.getLhsType())); if(!inheritanceGraph.containsKey(pair.getRhsType())) inheritanceGraph.put(pair.getRhsType(), new Node(pair.getRhsType())); @@ -61,7 +62,7 @@ public class FiniteClosure implements IFiniteClosure { parentNode.getPredecessors().stream().forEach(x -> x.addDescendant(childNode)); childNode.getDescendants().stream().forEach(x -> x.addPredecessor(parentNode)); } - + // Build the alternative representation with strings as keys strInheritanceGraph = new HashMap<>(); for(UnifyType key : inheritanceGraph.keySet()) { @@ -75,7 +76,7 @@ public class FiniteClosure implements IFiniteClosure { /** * Returns all types of the finite closure that are subtypes of the argument. * @return The set of subtypes of the argument. - */ + */ @Override public Set smaller(UnifyType type) { if(type instanceof FunNType) @@ -156,7 +157,7 @@ public class FiniteClosure implements IFiniteClosure { /** * Returns all types of the finite closure that are supertypes of the argument. * @return The set of supertypes of the argument. - */ + */ @Override public Set greater(UnifyType type) { if(type instanceof FunNType) @@ -240,7 +241,7 @@ public class FiniteClosure implements IFiniteClosure { return type.grArg(this); } - @Override + @Override public Set grArg(ReferenceType type) { Set result = new HashSet(); result.add(type); @@ -249,7 +250,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(FunNType type) { Set result = new HashSet(); result.add(type); @@ -267,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -276,11 +277,11 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set grArg(PlaceholderType type) { HashSet result = new HashSet<>(); result.add(type); - return result; + return result; } @Override @@ -288,12 +289,12 @@ public class FiniteClosure implements IFiniteClosure { return type.smArg(this); } - @Override + @Override public Set smArg(ReferenceType type) { Set result = new HashSet(); result.add(type); return result; - } + } @Override public Set smArg(FunNType type) { @@ -316,7 +317,7 @@ public class FiniteClosure implements IFiniteClosure { } - @Override + @Override public Set smArg(SuperType type) { Set result = new HashSet(); result.add(type); @@ -329,20 +330,20 @@ public class FiniteClosure implements IFiniteClosure { return result; } - @Override + @Override public Set smArg(PlaceholderType type) { HashSet result = new HashSet<>(); - result.add(type); + result.add(type); return result; } - @Override - public Set getAllTypesByName(String typeName) { + @Override + public Set getAllTypesByName(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) return new HashSet<>(); return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new)); } - + @Override public Optional getLeftHandedType(String typeName) { if(!strInheritanceGraph.containsKey(typeName)) @@ -392,7 +393,7 @@ public class FiniteClosure implements IFiniteClosure { * @param result Set of all permutations found so far * @param current The permutation of type params that is currently explored */ - protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { + protected void permuteParams(ArrayList> candidates, int idx, Set result, UnifyType[] current) { if(candidates.size() == idx) { result.add(new TypeParams(Arrays.copyOf(current, current.length))); return; diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index fd87eecc..f40ecb2f 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -24,8 +24,10 @@ public final class TypeParams implements Iterable{ */ public TypeParams(List types){ typeParams = new UnifyType[types.size()]; - for(int i=0;i{ if(other.size() != this.size()) return false; - + + for(int i = 0; i < this.size(); i++){ + if(this.get(i) == null) + System.out.print("s"); + } for(int i = 0; i < this.size(); i++) if(!(this.get(i).equals(other.get(i)))) return false; From 48dc76646bf5bafaf806676e4ee8ce722a4a3b0f Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 14 Nov 2017 19:28:46 +0100 Subject: [PATCH 06/42] =?UTF-8?q?createPair=20Methode=20entfernen.=20Die?= =?UTF-8?q?=20Generics=20k=C3=B6nnen=20nicht=20generell=20aufgel=C3=B6st?= =?UTF-8?q?=20werden.=20(unvollst=C3=A4ndiger=20Zustand)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constraints/ConstraintsFactory.java | 70 ------------------- .../typeinference/typeAlgo/TYPEStmt.java | 8 +-- 2 files changed, 4 insertions(+), 74 deletions(-) delete mode 100644 src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java diff --git a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java b/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java deleted file mode 100644 index 043af210..00000000 --- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.dhbwstuttgart.typeinference.constraints; - -import de.dhbwstuttgart.exceptions.DebugException; -import de.dhbwstuttgart.syntaxtree.GenericTypeVar; -import de.dhbwstuttgart.syntaxtree.TypeScope; -import de.dhbwstuttgart.syntaxtree.type.GenericRefType; -import de.dhbwstuttgart.syntaxtree.type.RefType; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.unify.model.PairOperator; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -public class ConstraintsFactory { - - /** - * Erstellt ein Pair Element für den Unify. - * Die Methode löst gleichzeitig GTVs in den Typen t1 und t2 auf. - * @param t1 - * @param t2 - * @param equalsdot - * @param currentScope - * @param additionalScope - * @param resolver - * @return - */ - public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2, - PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope, - GenericsResolver resolver){ - //Check whether Generics are in the same class and resolve all other generics: - return new Pair(checkGeneric(t1, currentScope, additionalScope,resolver), - checkGeneric(t2, currentScope,additionalScope, resolver), equalsdot); - } - public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, - RefTypeOrTPHOrWildcardOrGeneric t2, TypeScope currentScope, TypeScope additionalScope, - GenericsResolver resolver){ - return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver); - } - - - private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, - TypeScope currentScope, TypeScope additionalScope, - GenericsResolver resolver){ - if(type instanceof GenericRefType){ - //TODO: Für Generics müssen auch noch Constraints generiert werden - for(GenericTypeVar genericTypeVar : currentScope.getGenerics()){ - if(genericTypeVar.getName().toString().equals(((GenericRefType)type).getName().toString())){ - return new RefType(((GenericRefType)type).getName(),type.getOffset()); - } - } - //Nicht in den Generics in diesem Kontext enthalten: - TypePlaceholder ret = null; - for(GenericTypeVar genericTypeVar : additionalScope.getGenerics()){ - if(genericTypeVar.getName().equals(((GenericRefType)type).getName())){ - ret = resolver.resolve(genericTypeVar); - } - } - if(ret == null) - throw new DebugException("Der Generic " + ((GenericRefType) type).getName() + " kommt in keine TypeScope vor!"); - return ret; - }else{ - return type; - } - } - -} diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 8062e173..e45f7326 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -301,10 +301,10 @@ public class TYPEStmt implements StatementVisitor{ //} } RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset()); - methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), receiverType, - PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); - methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), - PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); + methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, + PairOperator.SMALLERDOT); + methodConstraint.add(new Pair(assumption.getReturnType(), forMethod.getType(), + PairOperator.EQUALSDOT)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); return methodConstraint; } From b51d8356b720e49b9a1c4cc9c573650fb03be000 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 15 Nov 2017 17:58:15 +0100 Subject: [PATCH 07/42] =?UTF-8?q?Unvollst=C3=A4ndiger=20Zustand;=20Verkn?= =?UTF-8?q?=C3=BCpfung=20zwischen=20GTVs=20und=20TPH=20ge=C3=A4ndert.=20?= =?UTF-8?q?=C3=84nderungen=20in=20TypeStmt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dhbwstuttgart/syntaxtree/ASTVisitor.java | 2 + .../syntaxtree/AbstractASTWalker.java | 4 +- .../syntaxtree/factory/UnifyTypeFactory.java | 3 +- .../syntaxtree/statement/Assign.java | 1 - .../syntaxtree/statement/FieldVar.java | 1 - .../syntaxtree/statement/MethodCall.java | 1 - .../syntaxtree/statement/NewClass.java | 1 - .../syntaxtree/statement/Return.java | 3 - .../syntaxtree/statement/This.java | 7 -- .../syntaxtree/type/ExtendsWildcardType.java | 4 +- .../syntaxtree/type/GenericRefType.java | 6 +- .../syntaxtree/type/RefType.java | 4 +- .../type/RefTypeOrTPHOrWildcardOrGeneric.java | 5 +- .../syntaxtree/type/SuperWildcardType.java | 4 +- .../syntaxtree/type/TypePlaceholder.java | 4 +- .../syntaxtree/type/TypeVisitor.java | 13 ++++ .../syntaxtree/visual/OutputGenerator.java | 2 +- .../assumptions/FieldAssumption.java | 10 ++- .../assumptions/MethodAssumption.java | 32 ++++++++- .../constraints/GenericsResolver.java | 4 +- .../typeAlgo/GenericsResolverSameName.java | 56 ++++++++++++++++ .../typeinference/typeAlgo/TYPEStmt.java | 66 +++++++++---------- 22 files changed, 162 insertions(+), 71 deletions(-) create mode 100644 src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java create mode 100644 src/de/dhbwstuttgart/typeinference/typeAlgo/GenericsResolverSameName.java diff --git a/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java b/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java index 9d3a7f6d..cecbc6cb 100644 --- a/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java +++ b/src/de/dhbwstuttgart/syntaxtree/ASTVisitor.java @@ -6,6 +6,8 @@ import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.constraints.Constraint; +import java.lang.reflect.Type; + public interface ASTVisitor extends StatementVisitor{ void visit(SourceFile sourceFile); diff --git a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index 50b4b470..d771bd93 100644 --- a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -37,7 +37,7 @@ public abstract class AbstractASTWalker implements ASTVisitor{ @Override public void visit(FormalParameter formalParameter) { - formalParameter.getType().accept(this); + formalParameter.getType().accept((ASTVisitor) this); } @Override @@ -105,7 +105,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{ @Override public void visit(TypePlaceholder typePlaceholder) { - } @Override @@ -115,7 +114,6 @@ public abstract class AbstractASTWalker implements ASTVisitor{ @Override public void visit(GenericRefType genericRefType) { - } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 7ad15acc..7cd7ca9c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -3,7 +3,6 @@ package de.dhbwstuttgart.syntaxtree.factory; import java.util.*; import java.util.stream.Collectors; -import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; @@ -161,7 +160,7 @@ public class UnifyTypeFactory { } public static UnifyType convert(GenericRefType t){ - return new ReferenceType(t.getUniqueIdentifier()); + return new ReferenceType(t.getParsedName()); } public static UnifyType convert(WildcardType t){ diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java index ed385c25..3af2de6f 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Assign.java @@ -4,7 +4,6 @@ package de.dhbwstuttgart.syntaxtree.statement; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import org.antlr.v4.runtime.Token; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/FieldVar.java b/src/de/dhbwstuttgart/syntaxtree/statement/FieldVar.java index ba56fc5a..9380e951 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/FieldVar.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/FieldVar.java @@ -7,7 +7,6 @@ import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import org.antlr.v4.runtime.Token; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 771423d8..435b1b65 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -8,7 +8,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java index 258da2e5..d29f3d53 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/NewClass.java @@ -15,7 +15,6 @@ import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import org.antlr.v4.runtime.Token; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java index 434f1ce9..5a6a5312 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Return.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Return.java @@ -1,9 +1,6 @@ package de.dhbwstuttgart.syntaxtree.statement; import de.dhbwstuttgart.syntaxtree.StatementVisitor; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; import org.antlr.v4.runtime.Token; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/This.java b/src/de/dhbwstuttgart/syntaxtree/statement/This.java index 81899052..d35e7797 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/This.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/This.java @@ -3,14 +3,7 @@ package de.dhbwstuttgart.syntaxtree.statement; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; -import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceInformation; -import de.dhbwstuttgart.typeinference.constraints.ConstraintsFactory; -import de.dhbwstuttgart.typeinference.constraints.Pair; -import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.atn.SemanticContext; import de.dhbwstuttgart.exceptions.NotImplementedException; public class This extends Expression diff --git a/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java index 1852b323..dbf76815 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java @@ -36,8 +36,8 @@ public class ExtendsWildcardType extends WildcardType{ @Override - public void accept(ASTVisitor visitor) { - visitor.visit(this); + public A acceptTV(TypeVisitor visitor) { + return visitor.visit(this); } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java index 121a6c99..b5698be8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java @@ -20,13 +20,13 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric return name; } - public String getUniqueIdentifier(){ + public String getParsedName(){ return name.toString(); } @Override - public void accept(ASTVisitor visitor) { - visitor.visit(this); + public A acceptTV(TypeVisitor visitor) { + return visitor.visit(this); } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index b2876119..10842d24 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -96,8 +96,8 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric @Override - public void accept(ASTVisitor visitor) { - visitor.visit(this); + public A acceptTV(TypeVisitor visitor) { + return visitor.visit(this); } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java index 75638712..1dcdefc0 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java @@ -11,7 +11,10 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{ } @Override - public abstract void accept(ASTVisitor visitor); + public void accept(ASTVisitor visitor){ + this.acceptTV((TypeVisitor)visitor); + } + public abstract A acceptTV(TypeVisitor visitor); public abstract void accept(ResultSetVisitor visitor); } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java index 3fc8ffb9..e7a19b5a 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java @@ -46,8 +46,8 @@ public class SuperWildcardType extends WildcardType{ } @Override - public void accept(ASTVisitor visitor) { - visitor.visit(this); + public A acceptTV(TypeVisitor visitor) { + return visitor.visit(this); } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java index 99a34cd5..af79fa39 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java @@ -69,8 +69,8 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric } @Override - public void accept(ASTVisitor visitor) { - visitor.visit(this); + public A acceptTV(TypeVisitor visitor) { + return visitor.visit(this); } @Override diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java b/src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java new file mode 100644 index 00000000..a3b7796f --- /dev/null +++ b/src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java @@ -0,0 +1,13 @@ +package de.dhbwstuttgart.syntaxtree.type; + +public interface TypeVisitor { + A visit(RefType refType); + + A visit(SuperWildcardType superWildcardType); + + A visit(TypePlaceholder typePlaceholder); + + A visit(ExtendsWildcardType extendsWildcardType); + + A visit(GenericRefType genericRefType); +} diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index 4b4ac7dc..e760e458 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -11,7 +11,7 @@ import de.dhbwstuttgart.syntaxtree.type.*; import java.lang.reflect.Modifier; import java.util.Iterator; -public class OutputGenerator implements ASTVisitor { +public class OutputGenerator implements ASTVisitor{ private static final String TAB = " "; String tabs = ""; protected final StringBuilder out; diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java index 2e568e48..62867a26 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference.assumptions; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; public class FieldAssumption extends Assumption{ private ClassOrInterface receiverClass; @@ -19,7 +20,12 @@ public class FieldAssumption extends Assumption{ return receiverClass; } - public RefTypeOrTPHOrWildcardOrGeneric getType() { - return type; + public RefTypeOrTPHOrWildcardOrGeneric getType(GenericsResolver resolver) { + return resolver.resolve(type); + } + + public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) { + + return null; } } diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index af8d6fb7..f6805564 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -1,12 +1,17 @@ package de.dhbwstuttgart.typeinference.assumptions; +import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.statement.Assign; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -38,7 +43,30 @@ public class MethodAssumption extends Assumption{ return retType; } - public List getArgTypes() { - return params; + public List getArgTypes(GenericsResolver resolver) { + List ret = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric param : params){ + if(param instanceof GenericRefType){ //Generics in den Assumptions müssen umgewandelt werden. + param = resolver.resolve((GenericRefType) param); + } + ret.add(param); + } + return ret; + } + + /** + * + * @param resolver + * @return + */ + public RefTypeOrTPHOrWildcardOrGeneric getReceiverType(GenericsResolver resolver) { + List params = new ArrayList<>(); + for(GenericTypeVar gtv : receiver.getGenerics()){ + //Die Generics werden alle zu TPHs umgewandelt. + params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken()))); + } + + RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(receiver.getClassName(), params, new NullToken()); + return receiverType; } } diff --git a/src/de/dhbwstuttgart/typeinference/constraints/GenericsResolver.java b/src/de/dhbwstuttgart/typeinference/constraints/GenericsResolver.java index d72b6835..59bcd4b4 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/GenericsResolver.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/GenericsResolver.java @@ -1,6 +1,8 @@ package de.dhbwstuttgart.typeinference.constraints; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; /** @@ -8,5 +10,5 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; * TODO: Erklörung! */ public interface GenericsResolver { - public TypePlaceholder resolve(GenericTypeVar generic); + public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic); } diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/GenericsResolverSameName.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/GenericsResolverSameName.java new file mode 100644 index 00000000..f8754e63 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/GenericsResolverSameName.java @@ -0,0 +1,56 @@ +package de.dhbwstuttgart.typeinference.typeAlgo; + +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.*; +import de.dhbwstuttgart.typeinference.constraints.GenericsResolver; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +/** + * Ein GenericsResolver, welcher Generics mit dem selben Namen den selben TPH zuordnet + */ +public class GenericsResolverSameName implements GenericsResolver, TypeVisitor{ + + HashMap map = new HashMap<>(); + + @Override + public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic) { + return generic.acceptTV(this); + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { + List params = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ + params.add(param.acceptTV(this)); + } + RefType ret = new RefType(refType.getName(), params, refType.getOffset()); + return ret; + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) { + return new SuperWildcardType(superWildcardType.getInnerType().acceptTV(this), superWildcardType.getOffset()); + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) { + return typePlaceholder; + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) { + return new SuperWildcardType(extendsWildcardType.getInnerType().acceptTV(this), extendsWildcardType.getOffset()); + } + + @Override + public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) { + String name = genericRefType.getParsedName(); + if(!map.containsKey(name)){ + map.put(name, TypePlaceholder.fresh(genericRefType.getOffset())); + } + return map.get(name); + } +} diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index e45f7326..da712f1e 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -34,14 +34,15 @@ public class TYPEStmt implements StatementVisitor{ return constraintsSet; } + /** + * Erstellt einen neuen GenericResolver + * Die Idee dieser Datenstruktur ist es, GTVs einen eindeutigen TPH zuzuweisen. + * Bei Methodenaufrufen oder anderen Zugriffen, bei denen alle benutzten GTVs jeweils einen einheitlichen TPH bekommen müssen + * kann diese Klasse eingesetzt werden. Wichtig ist, dass hierfür jeweils eine frische Instanz benutzt wird. + * @return + */ private static GenericsResolver getResolverInstance(){ - Map map = new HashMap<>(); - return generic -> { - if(map.containsKey(generic))return map.get(generic); - TypePlaceholder ret = TypePlaceholder.fresh(generic.getOffset()); - map.put(generic, ret); - return ret; - }; + return new GenericsResolverSameName(); } private static TypeScope createTypeScope(ClassOrInterface cl, Method method) { @@ -62,11 +63,11 @@ public class TYPEStmt implements StatementVisitor{ //lambdaParams.add(tphRetType); lambdaParams.add(0,tphRetType); constraintsSet.addUndConstraint( - ConstraintsFactory.createPair(lambdaExpression.getType(), - new FunN(lambdaParams),PairOperator.EQUALSDOT,info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); + new Pair(lambdaExpression.getType(), + new FunN(lambdaParams),PairOperator.EQUALSDOT)); constraintsSet.addUndConstraint( - ConstraintsFactory.createPair(lambdaExpression.getReturnType(), - tphRetType,info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); + new Pair(lambdaExpression.getReturnType(), + tphRetType,PairOperator.EQUALSDOT)); //Constraints des Bodys generieren: TYPEStmt lambdaScope = new TYPEStmt(new TypeInferenceBlockInformation(info, lambdaExpression)); @@ -78,8 +79,8 @@ public class TYPEStmt implements StatementVisitor{ public void visit(Assign assign) { assign.lefSide.accept(this); assign.rightSide.accept(this); - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT, info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); + constraintsSet.addUndConstraint(new Pair( + assign.rightSide.getType(), assign.lefSide.getType(), PairOperator.SMALLERDOT)); } @Override @@ -115,8 +116,9 @@ public class TYPEStmt implements StatementVisitor{ constraint.add(ConstraintsFactory.createPair( fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); */ - constraint.add(ConstraintsFactory.createPair( - fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); + constraint.add(new Pair(fieldVar.receiver.getType(), fieldAssumption.getReceiverType(resolver), PairOperator.EQUALSDOT)); + constraint.add(new Pair( + fieldVar.getType(), fieldAssumption.getType(resolver), PairOperator.EQUALSDOT)); oderConstraints.add(constraint); } if(oderConstraints.size() == 0) @@ -159,8 +161,7 @@ public class TYPEStmt implements StatementVisitor{ Set methodConstraints = new HashSet<>(); for(MethodAssumption m : this.getMethods(methodCall.name, methodCall.arglist, info)){ GenericsResolver resolver = getResolverInstance(); - TypeScope additionalScope = m.getTypeScope(); - methodConstraints.add(generateConstraint(methodCall, m, info, getResolverInstance())); + methodConstraints.add(generateConstraint(methodCall, m, info, resolver)); } if(methodConstraints.size()<1){ throw new TypeinferenceException("Methode "+methodCall.name+" ist nicht vorhanden!",methodCall.getOffset()); @@ -194,9 +195,7 @@ public class TYPEStmt implements StatementVisitor{ @Override public void visit(Return returnExpr) { returnExpr.retexpr.accept(this); - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT, - info.getCurrentTypeScope(), createNullTypeScope(), getResolverInstance())); + constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT)); } @Override @@ -223,9 +222,8 @@ public class TYPEStmt implements StatementVisitor{ params.add(new GenericRefType(gtv.getName(), aThis.getOffset())); } RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset()); - constraintsSet.addUndConstraint(ConstraintsFactory.createPair( - aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(), - createNullTypeScope(), getResolverInstance())); + constraintsSet.addUndConstraint(new Pair( + aThis.getType(), thisType, PairOperator.EQUALSDOT)); } private static TypeScope createNullTypeScope() { @@ -291,18 +289,17 @@ public class TYPEStmt implements StatementVisitor{ TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); ClassOrInterface receiverCl = assumption.getReceiver(); + /* List params = new ArrayList<>(); for(GenericTypeVar gtv : receiverCl.getGenerics()){ - //if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){ - // params.add(new GenericRefType(gtv.getName(), forMethod.getOffset())); - //}else{ //Die Generics werden alle zu TPHs umgewandelt. - params.add(TypePlaceholder.fresh(forMethod.getOffset())); - //} + params.add(resolver.resolve(gtv.getParsedName())); } + RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset()); - methodConstraint.add(new Pair(forMethod.receiver.getType(), receiverType, - PairOperator.SMALLERDOT); + */ + methodConstraint.add(new Pair(forMethod.receiver.getType(), assumption.getReceiverType(resolver), + PairOperator.SMALLERDOT)); methodConstraint.add(new Pair(assumption.getReturnType(), forMethod.getType(), PairOperator.EQUALSDOT)); methodConstraint.addAll(generateParameterConstraints(forMethod, assumption, info, resolver)); @@ -314,8 +311,9 @@ public class TYPEStmt implements StatementVisitor{ Set ret = new HashSet<>(); for(int i = 0;i generateConstructorConstraint(NewClass forConstructor, MethodAssumption assumption, TypeInferenceBlockInformation info, GenericsResolver resolver){ Constraint methodConstraint = new Constraint(); - methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forConstructor.getType(), - PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); + methodConstraint.add(new Pair(assumption.getReturnType(), forConstructor.getType(), + PairOperator.SMALLERDOT)); methodConstraint.addAll(generateParameterConstraints(forConstructor, assumption, info, resolver)); return methodConstraint; } From 16e14f9363d1cad3fc9f791d33f894999ef0b1fe Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 16 Nov 2017 15:10:08 +0100 Subject: [PATCH 08/42] =?UTF-8?q?Finite=20CLosure=20TEst=20l=C3=A4uft=20wi?= =?UTF-8?q?eder=20halbwegs.=20Sonst=20unfertiger=20Zustand?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 2 +- .../dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java | 5 +++++ src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java | 5 +++++ src/de/dhbwstuttgart/syntaxtree/type/RefType.java | 5 +++++ .../syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java | 4 +--- .../dhbwstuttgart/syntaxtree/type/SuperWildcardType.java | 5 +++++ src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java | 5 +++++ src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java | 1 + test/javFiles/fc.jav | 7 ++++--- 9 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index adc160fc..4ec0e2c3 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -70,7 +70,7 @@ public class JavaTXCompiler { xConsSet.addAll(constraint); } - //System.out.println(xConsSet); + System.out.println(xConsSet); Set> result = unify.unify(xConsSet, finiteClosure); //System.out.println("RESULT: " + result); results.addAll(result); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java index dbf76815..d5abd93b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java @@ -35,6 +35,11 @@ public class ExtendsWildcardType extends WildcardType{ } + @Override + public void accept(ASTVisitor visitor) { + visitor.visit(this); + } + @Override public A acceptTV(TypeVisitor visitor) { return visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java index b5698be8..a5d394aa 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java @@ -24,6 +24,11 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric return name.toString(); } + @Override + public void accept(ASTVisitor visitor) { + visitor.visit(this); + } + @Override public A acceptTV(TypeVisitor visitor) { return visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 10842d24..002e792d 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -95,6 +95,11 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric } + @Override + public void accept(ASTVisitor visitor) { + visitor.visit(this); + } + @Override public A acceptTV(TypeVisitor visitor) { return visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java index 1dcdefc0..8a573d16 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java @@ -11,9 +11,7 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{ } @Override - public void accept(ASTVisitor visitor){ - this.acceptTV((TypeVisitor)visitor); - } + public abstract void accept(ASTVisitor visitor); public abstract A acceptTV(TypeVisitor visitor); public abstract void accept(ResultSetVisitor visitor); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java index e7a19b5a..f630583e 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java @@ -45,6 +45,11 @@ public class SuperWildcardType extends WildcardType{ return true; } + @Override + public void accept(ASTVisitor visitor) { + visitor.visit(this); + } + @Override public A acceptTV(TypeVisitor visitor) { return visitor.visit(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java index af79fa39..ab4414fd 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java @@ -68,6 +68,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric return name; } + @Override + public void accept(ASTVisitor visitor) { + visitor.visit(this); + } + @Override public A acceptTV(TypeVisitor visitor) { return visitor.visit(this); diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index da712f1e..d710ed3e 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -321,6 +321,7 @@ public class TYPEStmt implements StatementVisitor{ public static List getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { List ret = new ArrayList<>(); + //TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken) /* if(name.equals("apply")){ List funNParams = new ArrayList<>(); diff --git a/test/javFiles/fc.jav b/test/javFiles/fc.jav index cb8c1799..a3278cbc 100644 --- a/test/javFiles/fc.jav +++ b/test/javFiles/fc.jav @@ -1,13 +1,14 @@ -import java.util.*; +import java.util.List; class Test{ methode(param1, param2, param3) { - return param1.meth(param2.add(param3)); + param2.add(param3); + return param1.meth(param2); } } interface Klasse1{ - Klasse1 meth(Klasse1 p); + Klasse1 meth(List p); Klasse1 meth(Klasse2 p); } From 9a886ed223eb2412665a9d0d4794d5190b7b81b3 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 16 Nov 2017 16:56:12 +0100 Subject: [PATCH 09/42] =?UTF-8?q?Typdeklarationen=20wie=20List,=20werden?= =?UTF-8?q?=20jetzt=20automatisch=20TPHs=20eingesetzt.=20(Als=20h=C3=A4tte?= =?UTF-8?q?=20man=20den=20Diamond-Operator=20benutzt)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../environment/CompilationEnvironment.java | 7 +--- .../environment/PackageCrawler.java | 11 ++---- .../SyntaxTreeGenerator/TypeGenerator.java | 7 +++- .../parser/scope/GatherNames.java | 38 ++++++++++++------- .../parser/scope/JavaClassName.java | 2 + .../parser/scope/JavaClassRegistry.java | 22 +++++------ test/javFiles/LambdaRunnable.jav | 11 ++++++ test/typeinference/RunnableTest.java | 9 +++++ 8 files changed, 69 insertions(+), 38 deletions(-) create mode 100644 test/javFiles/LambdaRunnable.jav create mode 100644 test/typeinference/RunnableTest.java diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 9a632674..2f04423f 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -5,10 +5,7 @@ import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; +import java.util.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.SourceFile; @@ -55,7 +52,7 @@ public class CompilationEnvironment { } public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException { - List allNames; + Map allNames; CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); return new JavaClassRegistry(allNames); diff --git a/src/de/dhbwstuttgart/environment/PackageCrawler.java b/src/de/dhbwstuttgart/environment/PackageCrawler.java index cec63562..7c63a0b6 100644 --- a/src/de/dhbwstuttgart/environment/PackageCrawler.java +++ b/src/de/dhbwstuttgart/environment/PackageCrawler.java @@ -1,10 +1,7 @@ package de.dhbwstuttgart.environment; import java.net.URL; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Set; +import java.util.*; import org.reflections.Reflections; import org.reflections.scanners.ResourcesScanner; @@ -66,14 +63,14 @@ public class PackageCrawler { return classes; } - public List getClassNames(String packageName){ - List nameList = new ArrayList(); + public Map getClassNames(String packageName){ + Map nameList = new HashMap<>(); Set> classes = getClassesInPackage(packageName); if(packageName.equals("java.lang") && ! classes.contains(Object.class)) { classes.add(Object.class); } for(Class c : classes){ - nameList.add(c.getName()); + nameList.put(c.getName(), c.getTypeParameters().length); } return nameList; } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index b5042fba..2cf41b43 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -14,6 +14,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import org.antlr.v4.runtime.Token; import java.util.ArrayList; @@ -131,7 +132,11 @@ public class TypeGenerator { } } if(typeArguments == null){ - return new RefType(reg.getName(name), offset); + List params = new ArrayList<>(); + for(int i = 0; i getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ - List ret = new ArrayList<>(); + public static Map getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{ + Map ret = new HashMap<>(); String pkgName = getPackageName(ctx); String nameString = ""; for (Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ @@ -26,6 +28,8 @@ public class GatherNames { else{ nameString = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().Identifier().toString(); } + int numGenerics = typeDecl.interfaceDeclaration().normalInterfaceDeclaration().typeParameters()!=null? + typeDecl.interfaceDeclaration().normalInterfaceDeclaration().typeParameters().typeParameterList().typeParameter().size():0; //Die Generic TypeParameter Definitionen Nicht! an die JavaClassName-Registry anfügen: /* //Diese gelängen dadurch in den globalen Scope, was sie schließlich nicht sind if(typeDecl.classDeclaration().normalClassDeclaration().typeParameters() != null){ @@ -34,7 +38,7 @@ public class GatherNames { } } */ - ret.add(nameString); + ret.put(nameString, numGenerics); } } else{ @@ -53,30 +57,36 @@ public class GatherNames { } } */ - ret.add(nameString); + int numGenerics = typeDecl.classDeclaration().normalClassDeclaration().typeParameters()!=null? + typeDecl.classDeclaration().normalClassDeclaration().typeParameters().typeParameterList().typeParameter().size():0; + + ret.put(nameString, numGenerics); } } } - ret.addAll(getImports(ctx, packages)); + ret.putAll(getImports(ctx, packages)); return ret; } - private static List getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { - List ret = new ArrayList(); - ret.addAll(packages.getClassNames("java.lang")); - for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ + private static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { + Map ret = new HashMap<>(); + ret.putAll(packages.getClassNames("java.lang")); + ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ if(importDeclCtx.singleTypeImportDeclaration() != null){ - ret.add(importDeclCtx.singleTypeImportDeclaration().typeName().getText()); + Class cl = classLoader.loadClass(importDeclCtx.singleTypeImportDeclaration().typeName().getText()); + ret.put(cl.getName(), cl.getTypeParameters().length); } else if(importDeclCtx.typeImportOnDemandDeclaration() != null){ - ret.addAll(packages.getClassNames(importDeclCtx.typeImportOnDemandDeclaration().packageOrTypeName().getText())); + ret.putAll(packages.getClassNames(importDeclCtx.typeImportOnDemandDeclaration().packageOrTypeName().getText())); } else if(importDeclCtx.singleStaticImportDeclaration() != null){ - ret.add(importDeclCtx.singleStaticImportDeclaration().typeName().getText()+"."+importDeclCtx.singleStaticImportDeclaration().Identifier().getText()); - } + Class cl = classLoader.loadClass(importDeclCtx.singleStaticImportDeclaration().typeName().getText()+"."+importDeclCtx.singleStaticImportDeclaration().Identifier().getText()); + ret.put(cl.getName(), cl.getTypeParameters().length); + } else{ - ret.addAll(packages.getClassNames(importDeclCtx.staticImportOnDemandDeclaration().typeName().getText())); + ret.putAll(packages.getClassNames(importDeclCtx.staticImportOnDemandDeclaration().typeName().getText())); } } return ret; diff --git a/src/de/dhbwstuttgart/parser/scope/JavaClassName.java b/src/de/dhbwstuttgart/parser/scope/JavaClassName.java index a20ce2e7..b87ff719 100644 --- a/src/de/dhbwstuttgart/parser/scope/JavaClassName.java +++ b/src/de/dhbwstuttgart/parser/scope/JavaClassName.java @@ -49,8 +49,10 @@ public class JavaClassName { final int prime = 31; int result = 1; result = prime * result + ((name == null) ? 0 : name.hashCode()); + /* result = prime * result + ((packageName == null) ? 0 : packageName.hashCode()); //PackageName does not infect hashCode + */ return result; } diff --git a/src/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java b/src/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java index a0cfacbf..d9ab804c 100644 --- a/src/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java +++ b/src/de/dhbwstuttgart/parser/scope/JavaClassRegistry.java @@ -8,20 +8,16 @@ import java.util.*; * Speichert die Klassen f�r einen bestimmten Projektscope */ public class JavaClassRegistry { - final List existingClasses = new ArrayList<>(); + final Map existingClasses = new HashMap<>(); - public JavaClassRegistry(List initialNames){ - for(String name : initialNames){ - existingClasses.add(new JavaClassName(name)); + public JavaClassRegistry(Map initialNames){ + for(String name : initialNames.keySet()){ + existingClasses.put(new JavaClassName(name), initialNames.get(name)); } } - - public void add(String className){ - existingClasses.add(new JavaClassName(className)); - } public JavaClassName getName(String className) { - for(JavaClassName name : existingClasses){ + for(JavaClassName name : existingClasses.keySet()){ if(name.equals(new JavaClassName(className)))return name; } throw new NotImplementedException(); @@ -34,7 +30,7 @@ public class JavaClassRegistry { public List getAllFromPackage(String packageName) { List ret = new ArrayList<>(); - for(JavaClassName className : this.existingClasses){ + for(JavaClassName className : this.existingClasses.keySet()){ JavaClassName toCompare = new JavaClassName(packageName + "." + JavaClassName.stripClassName(className.toString())); if(toCompare.toString().equals(className.toString())){ ret.add(className); @@ -44,6 +40,10 @@ public class JavaClassRegistry { } public boolean contains(String whole) { - return existingClasses.contains(new JavaClassName(whole)); + return existingClasses.containsKey(new JavaClassName(whole)); + } + + public int getNumberOfGenerics(String name) { + return existingClasses.get(new JavaClassName(name)); } } diff --git a/test/javFiles/LambdaRunnable.jav b/test/javFiles/LambdaRunnable.jav new file mode 100644 index 00000000..982680c3 --- /dev/null +++ b/test/javFiles/LambdaRunnable.jav @@ -0,0 +1,11 @@ + +public class LamRunnable{ + + public LamRunnable(){ + + + Runnable lam = () -> {System.out.println("lambda");}; + lam.run(); + } +} + diff --git a/test/typeinference/RunnableTest.java b/test/typeinference/RunnableTest.java new file mode 100644 index 00000000..bc0c52ad --- /dev/null +++ b/test/typeinference/RunnableTest.java @@ -0,0 +1,9 @@ +package typeinference; + +import java.io.File; + +public class RunnableTest extends JavaTXCompilerTest{ + public RunnableTest() { + this.fileToTest = new File(rootDirectory+"LambdaRunnable.jav"); + } +} \ No newline at end of file From 928396927ee7e17183522222dc5c65d14691fe7c Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 16 Nov 2017 17:28:50 +0100 Subject: [PATCH 10/42] Faculty Test geht wieder --- .../typeinference/assumptions/MethodAssumption.java | 8 +++++++- src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java | 5 ++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java index f6805564..066c3246 100644 --- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java +++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java @@ -6,6 +6,7 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.statement.Assign; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; @@ -65,8 +66,13 @@ public class MethodAssumption extends Assumption{ //Die Generics werden alle zu TPHs umgewandelt. params.add(resolver.resolve(new GenericRefType(gtv.getName(), new NullToken()))); } + RefTypeOrTPHOrWildcardOrGeneric receiverType; + if(receiver instanceof FunNClass){ + receiverType = new FunN(params); + }else{ + receiverType = new RefType(receiver.getClassName(), params, new NullToken()); + } - RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(receiver.getClassName(), params, new NullToken()); return receiverType; } } diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index d710ed3e..9d302ccd 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -13,6 +13,7 @@ import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; +import de.dhbwstuttgart.typeinference.assumptions.FunNClass; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.constraints.*; @@ -322,13 +323,12 @@ public class TYPEStmt implements StatementVisitor{ public static List getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { List ret = new ArrayList<>(); //TODO: apply Methoden wieder anfügen. Diese könnten möglicherweise auch in den Assumptions auftauchen (überdenken) - /* if(name.equals("apply")){ List funNParams = new ArrayList<>(); for(int i = 0; i< numArgs + 1 ; i++){ funNParams.add(TypePlaceholder.fresh(new NullToken())); } - ret.add(new MethodAssumption(new FunN(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size()), + ret.add(new MethodAssumption(new FunNClass(funNParams), funNParams.get(0), funNParams.subList(1, funNParams.size()), new TypeScope() { @Override public Iterable getGenerics() { @@ -341,7 +341,6 @@ public class TYPEStmt implements StatementVisitor{ } })); } - */ for(ClassOrInterface cl : info.getAvailableClasses()){ for(Method m : cl.getMethods()){ if(m.getName().equals(name) && From b55d0779e98f9041ec368fb3fb4d3e2ef50372aa Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 22 Nov 2017 06:49:11 +0100 Subject: [PATCH 11/42] =?UTF-8?q?ResultPairs=20des=20Unify=20Algorithmus?= =?UTF-8?q?=20k=C3=B6nnnen=20nun=20auch=20Wildcard-Typen=20enthalten?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../syntaxtree/factory/UnifyTypeFactory.java | 23 ++++++++----------- .../typedeployment/TypeInsertFactory.java | 2 +- ...=> PairTPHequalRefTypeOrWildcardType.java} | 6 ++--- .../typeinference/result/ResultSet.java | 13 +++-------- .../result/ResultSetVisitor.java | 2 +- 5 files changed, 18 insertions(+), 28 deletions(-) rename src/de/dhbwstuttgart/typeinference/result/{PairTPHequalRefType.java => PairTPHequalRefTypeOrWildcardType.java} (68%) diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 7cd7ca9c..325e453f 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -11,21 +11,13 @@ import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.Void; +import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.Pair; -import de.dhbwstuttgart.typeinference.result.PairTPHequalRefType; +import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType; import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH; import de.dhbwstuttgart.typeinference.result.ResultPair; -import de.dhbwstuttgart.typeinference.unify.model.ExtendsType; -import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; -import de.dhbwstuttgart.typeinference.unify.model.FunNType; -import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; -import de.dhbwstuttgart.typeinference.unify.model.PairOperator; -import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; -import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; -import de.dhbwstuttgart.typeinference.unify.model.SuperType; -import de.dhbwstuttgart.typeinference.unify.model.TypeParams; -import de.dhbwstuttgart.typeinference.unify.model.UnifyType; +import de.dhbwstuttgart.typeinference.unify.model.*; public class UnifyTypeFactory { @@ -205,10 +197,15 @@ public class UnifyTypeFactory { if(tr instanceof TypePlaceholder) { if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) throw new DebugException("TPH =. TPH ist ein ungültiges Ergebnis"); + //Einfach ignorieren TODO: Das hier muss ausgebessert werden: + //return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); else return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr); - } - return new PairTPHequalRefType((TypePlaceholder)tl, (RefType) tr); + }else if(tr instanceof RefType){ + return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr); + }else if(tr instanceof WildcardType){ + return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (WildcardType) tr); + }else throw new NotImplementedException(); }else throw new NotImplementedException(); } diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index b9eea3c6..290fd984 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -100,7 +100,7 @@ class TypeToInsertString implements ResultSetVisitor{ } @Override - public void visit(PairTPHequalRefType p) { + public void visit(PairTPHequalRefTypeOrWildcardType p) { } diff --git a/src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefType.java b/src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefTypeOrWildcardType.java similarity index 68% rename from src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefType.java rename to src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefTypeOrWildcardType.java index bf29ce52..ef6dd00a 100644 --- a/src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefType.java +++ b/src/de/dhbwstuttgart/typeinference/result/PairTPHequalRefTypeOrWildcardType.java @@ -7,11 +7,11 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; /** * Steht für A =. RefType */ -public class PairTPHequalRefType extends ResultPair{ +public class PairTPHequalRefTypeOrWildcardType extends ResultPair{ public final TypePlaceholder left; - public final RefType right; + public final RefTypeOrTPHOrWildcardOrGeneric right; - public PairTPHequalRefType(TypePlaceholder left, RefType right){ + public PairTPHequalRefTypeOrWildcardType(TypePlaceholder left, RefTypeOrTPHOrWildcardOrGeneric right){ super(left, right); this.left = left; this.right = right; diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java index f3c81b55..1d0bd32d 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java @@ -1,16 +1,9 @@ package de.dhbwstuttgart.typeinference.result; import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.syntaxtree.ASTVisitor; -import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.type.*; -import de.dhbwstuttgart.typeinference.constraints.Pair; -import javax.xml.transform.Result; -import java.lang.reflect.Type; -import java.util.ArrayList; import java.util.HashSet; -import java.util.List; import java.util.Set; public class ResultSet { @@ -70,7 +63,7 @@ class Resolver implements ResultSetVisitor { } @Override - public void visit(PairTPHequalRefType p) { + public void visit(PairTPHequalRefTypeOrWildcardType p) { if(p.left.equals(toResolve)){ resolved = p.right; RelatedTypeWalker related = new RelatedTypeWalker(null, result); @@ -134,7 +127,7 @@ class TPHResolver implements ResultSetVisitor { } @Override - public void visit(PairTPHequalRefType p) { + public void visit(PairTPHequalRefTypeOrWildcardType p) { TypePlaceholder otherSide = null; if(p.right.equals(tph)){ otherSide = p.left; @@ -209,7 +202,7 @@ class RelatedTypeWalker implements ResultSetVisitor { } @Override - public void visit(PairTPHequalRefType p) { + public void visit(PairTPHequalRefTypeOrWildcardType p) { if(p.getLeft().equals(toResolve)){ p.getRight().accept(this); } diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java b/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java index 3f21ae31..fbf241c1 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java @@ -4,7 +4,7 @@ import de.dhbwstuttgart.syntaxtree.type.*; public interface ResultSetVisitor { void visit(PairTPHsmallerTPH p); - void visit(PairTPHequalRefType p); + void visit(PairTPHequalRefTypeOrWildcardType p); void visit(RefType refType); From dbe47f41c1698465c86baa75e5d7749307820d2c Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 22 Nov 2017 13:12:21 +0100 Subject: [PATCH 12/42] =?UTF-8?q?FunNClass=20anf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../typeinference/assumptions/FunNClass.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java new file mode 100644 index 00000000..0eba225d --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java @@ -0,0 +1,43 @@ +package de.dhbwstuttgart.typeinference.assumptions; + +import com.sun.org.apache.regexp.internal.RE; +import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; +import de.dhbwstuttgart.parser.scope.GenericTypeName; +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import org.antlr.v4.runtime.Token; + +import java.util.ArrayList; +import java.util.List; + +public class FunNClass extends ClassOrInterface { + public FunNClass(List funNParams) { + super(0, new JavaClassName("Fun"+(funNParams.size()-1)), new ArrayList<>(), + createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), + ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken()); + + + } + + private static GenericDeclarationList createGenerics(List funNParams) { + List generics = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric param : funNParams){ + generics.add(new GenericTypeVar(new GenericTypeName(new GenericContext( + new JavaClassName("Fun"+(funNParams.size()-1)), null), NameGenerator.makeNewName()), + new ArrayList<>(), new NullToken(), new NullToken())); + } + return new GenericDeclarationList(generics, new NullToken()); + } + + private static List createMethods(List funNParams) { + return null; + } +} From e702f745c3eba9fab3b382413841c3ff24ac3423 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 29 Nov 2017 14:31:07 +0100 Subject: [PATCH 13/42] Dirty fix --- src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 325e453f..e99713fb 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -196,9 +196,9 @@ public class UnifyTypeFactory { if(tl instanceof TypePlaceholder){ if(tr instanceof TypePlaceholder) { if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) - throw new DebugException("TPH =. TPH ist ein ungültiges Ergebnis"); + //throw new DebugException("TPH =. TPH ist ein ungültiges Ergebnis"); //Einfach ignorieren TODO: Das hier muss ausgebessert werden: - //return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); + return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); else return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr); }else if(tr instanceof RefType){ From a8274bdc698316f8523cdba423e5c1634056d58b Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 29 Nov 2017 14:45:15 +0100 Subject: [PATCH 14/42] erzeugt bytecode fuer lambda --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 26 ++--- .../bytecode/BytecodeGenMethod.java | 94 ++++++++++++++----- src/de/dhbwstuttgart/bytecode/Descriptor.java | 55 ++++++++--- ...tecodeGenLambda.java => KindOfLambda.java} | 52 +++++----- test/bytecode/DuMethod.jav | 11 +++ test/bytecode/EmptyMethod.jav | 8 ++ test/bytecode/Faculty.jav | 14 +++ test/bytecode/Faculty2.jav | 10 ++ test/bytecode/JavaTXCompilerTest.java | 16 +++- test/bytecode/LamAssign.jav | 9 ++ test/bytecode/Lambda.jav | 18 ++++ test/bytecode/Lambda2.jav | 32 +++++++ test/bytecode/Lambda3.jav | 23 +++++ test/bytecode/ReturnMethod.jav | 6 ++ testBytecode/LamRun.java | 2 +- testBytecode/TestMyTest.java | 3 +- testBytecode/manually/Fac1.java | 6 ++ testBytecode/manually/Fac2.java | 14 +++ testBytecode/manually/LamAssign.java | 10 ++ testBytecode/manually/LamAssignWithM.java | 12 +++ testBytecode/manually/LamWithAnField.java | 14 +++ testBytecode/manually/LamWithField.java | 14 +++ testBytecode/manually/ReturnM1.java | 6 ++ 23 files changed, 378 insertions(+), 77 deletions(-) rename src/de/dhbwstuttgart/bytecode/{BytecodeGenLambda.java => KindOfLambda.java} (75%) create mode 100644 test/bytecode/DuMethod.jav create mode 100644 test/bytecode/EmptyMethod.jav create mode 100644 test/bytecode/Faculty.jav create mode 100644 test/bytecode/Faculty2.jav create mode 100644 test/bytecode/LamAssign.jav create mode 100644 test/bytecode/Lambda.jav create mode 100644 test/bytecode/Lambda2.jav create mode 100644 test/bytecode/Lambda3.jav create mode 100644 test/bytecode/ReturnMethod.jav create mode 100644 testBytecode/manually/Fac1.java create mode 100644 testBytecode/manually/Fac2.java create mode 100644 testBytecode/manually/LamAssign.java create mode 100644 testBytecode/manually/LamAssignWithM.java create mode 100644 testBytecode/manually/LamWithAnField.java create mode 100644 testBytecode/manually/LamWithField.java create mode 100644 testBytecode/manually/ReturnM1.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index dbdb1dc2..a1bd4ae5 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -1,7 +1,5 @@ package de.dhbwstuttgart.bytecode; -import java.awt.List; -import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -20,6 +18,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.result.ResultSet; public class BytecodeGen implements ASTVisitor { @@ -30,15 +29,17 @@ public class BytecodeGen implements ASTVisitor { String className; private boolean isInterface; + private ResultSet resultSet; + private int indexOfFirstParam = 0; // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... - HashMap paramsAndLocals;// = new HashMap<>(); + HashMap paramsAndLocals = new HashMap<>(); byte[] bytecode; HashMap classFiles; - public BytecodeGen(HashMap classFiles) { + public BytecodeGen(HashMap classFiles, ResultSet resultSet) { this.classFiles = classFiles; - paramsAndLocals = new HashMap<>(); + this.resultSet = resultSet; } @Override @@ -46,7 +47,7 @@ public class BytecodeGen implements ASTVisitor { for(ClassOrInterface cl : sourceFile.getClasses()) { isInterface = (cl.getModifiers()&512)==512; System.out.println("IS Interface = "+"modifiers= "+cl.getModifiers()+" ->"+(cl.getModifiers()&512) + isInterface); - BytecodeGen classGen = new BytecodeGen(classFiles); + BytecodeGen classGen = new BytecodeGen(classFiles, resultSet); cl.accept(classGen); classGen.writeClass(cl.getClassName().toString()); } @@ -87,32 +88,35 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Constructor field) { - Descriptor desc = new Descriptor(field); + Descriptor desc = new Descriptor(field, resultSet); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc.getDesc(), null, null); mv.visitCode(); System.out.println("-----Constructor-----"); - BytecodeGenMethod gen = new BytecodeGenMethod(className,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface); -// mv.visitInsn(Opcodes.RETURN); + mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); } @Override public void visit(Method method) { + // TODO: check if the method is static => if static then the first param will be stored in pos 0 + // else it will be stored in pos 1 and this will be stored in pos 0 method.getParameterList().accept(this); - Descriptor methDesc = new Descriptor(method); + Descriptor methDesc = new Descriptor(method,resultSet); System.out.println("-----Method-----"); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc.getDesc(), null, null); mv.visitCode(); - BytecodeGenMethod gen = new BytecodeGenMethod(className,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface); mv.visitMaxs(0, 0); mv.visitEnd(); } @Override public void visit(ParameterList formalParameters) { + paramsAndLocals = new HashMap<>(); Iterator itr = formalParameters.iterator(); int i = 1; while(itr.hasNext()) { diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index ff9c8faa..c2acaba0 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -6,6 +6,7 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.HashMap; +import java.util.Iterator; import de.dhbwstuttgart.syntaxtree.statement.*; import org.objectweb.asm.ClassWriter; @@ -15,11 +16,13 @@ import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; public class BytecodeGenMethod implements StatementVisitor{ @@ -30,6 +33,7 @@ public class BytecodeGenMethod implements StatementVisitor{ private String className; private int lamCounter; private ClassWriter cw; + private ResultSet resultSet; private boolean isInterface; //for tests ** @@ -37,16 +41,18 @@ public class BytecodeGenMethod implements StatementVisitor{ private String fieldDesc; private Expression rightSideTemp; private String where; - private boolean isRightSideALambda = false; + private boolean isRightSideALambda = false; + private KindOfLambda kindOfLambda; private ArrayList varsFunInterface; - public BytecodeGenMethod(String className, Method m, MethodVisitor mv, HashMap paramsAndLocals, + public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, String desc, ClassWriter cw, boolean isInterface) { this.where = "<<<<<< NORMAL METHOD >>>>>>"; this.className = className; + this.resultSet = resultSet; this.m = m; this.mv = mv; this.paramsAndLocals = paramsAndLocals; @@ -56,27 +62,42 @@ public class BytecodeGenMethod implements StatementVisitor{ this.lamCounter = -1; this.varsFunInterface = new ArrayList<>(); - + System.out.println("PARAMS = "+this.paramsAndLocals.size()); this.m.block.accept(this); + System.out.println("PARAMS = "+this.paramsAndLocals.size()); + for(int i = 0; i paramsAndLocals, String desc,boolean isInterface) { + public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv, + String desc,int indexOfFirstParamLam, boolean isInterface) { System.out.println("\t\t++++++IN LAMBDA -------"); this.where = "<<<<<< LAMBDA METHOD >>>>>>"; - + this.resultSet = resultSet; this.mv = mv; - this.paramsAndLocals = paramsAndLocals; this.desc = desc; this.isInterface = isInterface; this.lamCounter = -1; this.varsFunInterface = new ArrayList<>(); - + + Iterator itr = lambdaExpression.params.iterator(); + int i = indexOfFirstParamLam; + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + this.paramsAndLocals.put(fp.getName(), i); + i++; + } lambdaExpression.methodBody.accept(this); } + private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { + return resultSet.resolveType(type).resolvedType.toString().replace(".", "/"); + } + + @Override public void visit(Block block) { for(Statement stmt : block.getStatements()) { @@ -98,7 +119,7 @@ public class BytecodeGenMethod implements StatementVisitor{ // ?? @Override public void visit(LocalVar localVar) { - System.out.println("in Local Var"); + System.out.println("in Local Var: " + localVar.name); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); } // ?? @@ -106,7 +127,7 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(LocalVarDecl localVarDecl) { // Integer i; // paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1); - System.out.println("In localVarDecl"); + System.out.println("In localVarDecl :: "+localVarDecl.getName()); } @Override @@ -143,28 +164,49 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(LambdaExpression lambdaExpression) { System.out.println("\n++ In Lambda: "); this.lamCounter++; + Descriptor lamDesc = new Descriptor(lambdaExpression, resultSet); //Call site, which, when invoked, returns an instance of the functional interface to which //the lambda is being converted MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, MethodType.class, MethodHandle.class, MethodType.class); + Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false); String methodName = "lambda$new$" + this.lamCounter; // Type erasure - Type arg1 = Type.getMethodType("()V"); + Type arg1 = Type.getMethodType(lamDesc.getDesc()); // real Type - Type arg3 = Type.getMethodType("()V"); - Handle arg2 = new Handle(Opcodes.H_INVOKESTATIC, this.className, methodName, + Type arg3 = Type.getMethodType(lamDesc.getDesc()); + + int staticOrSpecial=0; + int staticOrInstance=0; + int indexOfFirstParamLam = 0; + this.kindOfLambda = new KindOfLambda(lambdaExpression); + + if(kindOfLambda.isInstanceCapturingLambda()) { + mv.visitVarInsn(Opcodes.ALOAD, 0); + staticOrSpecial = Opcodes.H_INVOKESPECIAL; + indexOfFirstParamLam = 1; + }else { + staticOrSpecial = Opcodes.H_INVOKESTATIC; + staticOrInstance = Opcodes.ACC_STATIC; + } + + // first check if capturing lambda then invokestatic or invokespecial + Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(),false); - mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bootstrap, + // Descriptor of functional interface methode + Descriptor fiMethodDesc = new Descriptor(kindOfLambda.getArgumentList(), lambdaExpression.getType(),resultSet); + + // Desc: (this/nothing)TargetType + mv.visitInvokeDynamicInsn("apply", fiMethodDesc.getDesc(), bootstrap, arg1, arg2,arg3); - MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC, + MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); -// new BytecodeGenLambda(lambdaExpression, mvLambdaBody); - HashMap paramsAndLocalsLambda = new HashMap<>(); - new BytecodeGenMethod(lambdaExpression, mvLambdaBody, paramsAndLocalsLambda, arg3.toString(),isInterface); + + new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,arg3.toString(),indexOfFirstParamLam,isInterface); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); @@ -189,12 +231,13 @@ public class BytecodeGenMethod implements StatementVisitor{ System.out.println("in fieldVar " + fieldVar.fieldVarName + " ** receiver: "+fieldVar.receiver); fieldName = fieldVar.fieldVarName; - fieldDesc = fieldVar.getType().toString(); + fieldDesc = "L"+getResolvedType(fieldVar.getType())+";"; fieldVar.receiver.accept(this); // test (if) if(!fieldVar.receiver.getClass().equals(StaticClassName.class)) { - mv.visitFieldInsn(Opcodes.GETFIELD,fieldVar.getType().toString(),fieldName ,fieldDesc); + mv.visitFieldInsn(Opcodes.GETFIELD,getResolvedType(fieldVar.receiver.getType()), + fieldName ,fieldDesc); } // mv.visitFieldInsn(Opcodes.GETSTATIC, fieldVar.receiver.getType().toString().replace(".", "/"), @@ -231,16 +274,16 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.receiver.accept(this); methodCall.arglist.accept(this); - Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType()); + Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType(),resultSet); System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); // is methodCall.receiver functional Interface)? if(varsFunInterface.contains(methodCall.receiver.getType())) { - mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, methodCall.receiver.getType().toString().replace(".", "/"), + mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name, mDesc.getDesc(), false); }else { - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, methodCall.receiver.getType().toString().replace(".", "/"), + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name, mDesc.getDesc(), isInterface); } // test @@ -282,6 +325,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Return aReturn) { + aReturn.retexpr.accept(this); mv.visitInsn(Opcodes.ARETURN); } @@ -340,9 +384,11 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(ArgumentList argumentList) { + System.out.println("in ArgumentList: "); for(Expression al : argumentList.getArguments()) { al.accept(this); } + System.out.println("out from Argumentlist"); } @Override @@ -364,6 +410,8 @@ public class BytecodeGenMethod implements StatementVisitor{ varsFunInterface.add(assignLeftSide.localVar.getType()); paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1); mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size()); + // Debug::: + } } diff --git a/src/de/dhbwstuttgart/bytecode/Descriptor.java b/src/de/dhbwstuttgart/bytecode/Descriptor.java index 41f7ab5d..fb57e682 100644 --- a/src/de/dhbwstuttgart/bytecode/Descriptor.java +++ b/src/de/dhbwstuttgart/bytecode/Descriptor.java @@ -1,6 +1,6 @@ package de.dhbwstuttgart.bytecode; -import java.awt.List; +import java.util.List; import java.util.Iterator; import de.dhbwstuttgart.syntaxtree.Constructor; @@ -8,45 +8,74 @@ import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; public class Descriptor { String desc; - public Descriptor(Method method) { + public Descriptor(Method method, ResultSet resultSet) { desc = "("; Iterator itr = method.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+fp.getType().toString().replace(".", "/") + ";"; - } - if(method.getReturnType().toString().equals("void")){ - desc = desc + ")V"; - }else { - desc = desc + ")" + "L"+method.getReturnType().toString().replace(".", "/")+";"; + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; } + desc = addReturnType(desc,method.getReturnType(), resultSet); + } - public Descriptor(Constructor constructor) { + private String addReturnType(String desc2, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { + System.out.println("DescType = "+returnType.toString()); + if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ + desc = desc + ")V"; + }else { + desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; + } + return desc; + } + + public Descriptor(Constructor constructor, ResultSet resultSet) { desc = "("; Iterator itr = constructor.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+fp.getType().toString().replace(".", "/") + ";"; + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; } desc = desc + ")V"; } - public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType) { + public Descriptor(LambdaExpression lambdaExpr, ResultSet resultSet) { + desc = "("; + Iterator itr = lambdaExpr.params.iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; + } + desc = addReturnType(desc, lambdaExpr.getReturnType(), resultSet); + } + + public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { desc = "("; for(Expression e : argList.getArguments()) { - desc = desc + "L"+e.getType().toString().replace(".", "/") + ";"; + desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.toString().replace(".", "/") + ";"; } - desc = desc + ")"+returnType.toString(); + desc = addReturnType(desc, returnType, resultSet); } + public Descriptor(List argumentList,RefTypeOrTPHOrWildcardOrGeneric returnType ,ResultSet resultSet) { + desc = "("; + Iterator itr = argumentList.iterator(); + while(itr.hasNext()) { + RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); + desc = desc + "L"+resultSet.resolveType(rt).resolvedType.toString().replace(".", "/")+";"; + } + desc = desc + ")"+"L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; + } + public String getDesc() { return this.desc; } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java b/src/de/dhbwstuttgart/bytecode/KindOfLambda.java similarity index 75% rename from src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java rename to src/de/dhbwstuttgart/bytecode/KindOfLambda.java index 679a1365..36a28ce6 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenLambda.java +++ b/src/de/dhbwstuttgart/bytecode/KindOfLambda.java @@ -1,24 +1,33 @@ package de.dhbwstuttgart.bytecode; import de.dhbwstuttgart.syntaxtree.statement.*; -import org.objectweb.asm.MethodVisitor; + +import java.util.ArrayList; +import java.util.List; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; -public class BytecodeGenLambda implements StatementVisitor{ - private LambdaExpression lambdaExpression; - private MethodVisitor mv; +public class KindOfLambda implements StatementVisitor{ + private boolean isInstanceCapturingLambda = false; + private List argumentList = new ArrayList<>(); - public BytecodeGenLambda(LambdaExpression lambdaExpression, MethodVisitor mv) { - this.lambdaExpression = lambdaExpression; - this.mv = mv; - + public KindOfLambda(LambdaExpression lambdaExpression) { + lambdaExpression.methodBody.accept(this); } - + + public boolean isInstanceCapturingLambda() { + return this.isInstanceCapturingLambda; + } + + public List getArgumentList() { + return argumentList; + } + @Override public void visit(ArgumentList argumentList) { // TODO Auto-generated method stub @@ -27,14 +36,12 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(LambdaExpression lambdaExpression) { - // TODO Auto-generated method stub } @Override public void visit(Assign assign) { - // TODO Auto-generated method stub - + assign.rightSide.accept(this); } @Override @@ -45,8 +52,9 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(Block block) { - // TODO Auto-generated method stub - + for(Statement stmt : block.getStatements()) { + stmt.accept(this); + } } @Override @@ -63,8 +71,7 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(FieldVar fieldVar) { - // TODO Auto-generated method stub - + fieldVar.receiver.accept(this); } @Override @@ -99,8 +106,7 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(MethodCall methodCall) { - // TODO Auto-generated method stub - + methodCall.receiver.accept(this); } @Override @@ -117,14 +123,12 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(ExpressionReceiver receiver) { - // TODO Auto-generated method stub - + receiver.expr.accept(this); } @Override public void visit(Return aReturn) { - // TODO Auto-generated method stub - + aReturn.retexpr.accept(this); } @Override @@ -147,8 +151,8 @@ public class BytecodeGenLambda implements StatementVisitor{ @Override public void visit(This aThis) { - // TODO Auto-generated method stub - + this.isInstanceCapturingLambda = true; + this.argumentList.add(aThis.getType()); } @Override diff --git a/test/bytecode/DuMethod.jav b/test/bytecode/DuMethod.jav new file mode 100644 index 00000000..b56f6c55 --- /dev/null +++ b/test/bytecode/DuMethod.jav @@ -0,0 +1,11 @@ +public class DuMethod{ + + method(a){ + return a; + } + + method(a){ + return a; + } + +} \ No newline at end of file diff --git a/test/bytecode/EmptyMethod.jav b/test/bytecode/EmptyMethod.jav new file mode 100644 index 00000000..961989df --- /dev/null +++ b/test/bytecode/EmptyMethod.jav @@ -0,0 +1,8 @@ +public class EmptyMethod{ + + public void m1(){ + System.out.println("test"); + } + + public void m2(){} +} diff --git a/test/bytecode/Faculty.jav b/test/bytecode/Faculty.jav new file mode 100644 index 00000000..5742d720 --- /dev/null +++ b/test/bytecode/Faculty.jav @@ -0,0 +1,14 @@ +class Faculty { + + Integer mul(Integer x, Integer y) { + return x; + } + + m () { + + var fact = (Integer x) -> { + return mul(x, x); + }; + return fact; + } +} diff --git a/test/bytecode/Faculty2.jav b/test/bytecode/Faculty2.jav new file mode 100644 index 00000000..828f06f5 --- /dev/null +++ b/test/bytecode/Faculty2.jav @@ -0,0 +1,10 @@ +class Faculty2 { + + m () { + + var fact = (Integer x) -> { + return x; + }; + return fact; + } +} \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 5c3e0a87..4dfdf92e 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -3,6 +3,8 @@ package bytecode; import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.syntaxtree.SourceFile; +import de.dhbwstuttgart.typeinference.result.ResultPair; +import de.dhbwstuttgart.typeinference.result.ResultSet; import org.junit.Test; import java.io.File; @@ -27,14 +29,20 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "LamRunnable"; + String fileName = "DuMethod"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); System.out.println("test"); for(File f : filesToTest){ String content = readFile(f.getPath(), StandardCharsets.UTF_8); - HashMap bytecode = this.getBytecode(compiler.sourceFiles.get(f)); + List typeinferenceResult = compiler.typeInference(); + HashMap bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0)); + + for(ResultPair ep : typeinferenceResult.get(0).results) { + System.out.println(ep.getLeft() + " ->" + ep.getRight()); + } + String name = ""; int pos = f.getName().lastIndexOf("."); if(pos != -1) { @@ -46,9 +54,9 @@ public class JavaTXCompilerTest { } - public HashMap getBytecode(SourceFile sf) { + public HashMap getBytecode(SourceFile sf, ResultSet resultSet) { HashMap classFiles = new HashMap<>(); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles); + BytecodeGen bytecodeGen = new BytecodeGen(classFiles,resultSet); bytecodeGen.visit(sf); return bytecodeGen.getClassFiles(); } diff --git a/test/bytecode/LamAssign.jav b/test/bytecode/LamAssign.jav new file mode 100644 index 00000000..e522bd3b --- /dev/null +++ b/test/bytecode/LamAssign.jav @@ -0,0 +1,9 @@ +class LamAssign { + + m () { + var lam1 = (Integer x) -> { + return x; + }; + return lam1; + } +} diff --git a/test/bytecode/Lambda.jav b/test/bytecode/Lambda.jav new file mode 100644 index 00000000..378eb4d3 --- /dev/null +++ b/test/bytecode/Lambda.jav @@ -0,0 +1,18 @@ +class Lambda{ + +methode(){ + return ((f) -> f); +} +} +/* +interface Fun0{ + A apply(); +} + +interface Fun1{ + A apply(B b); +} +*/ +interface Fun2{ + A apply(B b, C c); +} \ No newline at end of file diff --git a/test/bytecode/Lambda2.jav b/test/bytecode/Lambda2.jav new file mode 100644 index 00000000..fbcdaf55 --- /dev/null +++ b/test/bytecode/Lambda2.jav @@ -0,0 +1,32 @@ + +public class Lambda2 +{ + public static void main(List args){ + var listOfStrings = new List(); + var listOfObjects; + listOfObjects = map(listOfStrings, (a) -> a); +} + +public map(a , b){ + b.apply(a); + return a; +} + +/* +public static List map(List input, Function func) { + List output; + output = new List(); + output.add(func.apply(input.get())); + return output; +} +*/ +} + +class List{ + A get(); + void add(A); +} + +class Function{ + B apply(A a); +} \ No newline at end of file diff --git a/test/bytecode/Lambda3.jav b/test/bytecode/Lambda3.jav new file mode 100644 index 00000000..9c4e960c --- /dev/null +++ b/test/bytecode/Lambda3.jav @@ -0,0 +1,23 @@ + +public class Lambda2 +{ + /* + public static List map(List input, + Function func){ + input.add(func.apply(input.get())); + } + */ + public map(input,func){ + input.add(func.apply(input.get())); + return map(new List(), func); + } +} + +class List{ + A get(); + void add(A); +} + +class Function{ + B apply(A a); +} \ No newline at end of file diff --git a/test/bytecode/ReturnMethod.jav b/test/bytecode/ReturnMethod.jav new file mode 100644 index 00000000..38386d0d --- /dev/null +++ b/test/bytecode/ReturnMethod.jav @@ -0,0 +1,6 @@ +class ReturnMethod{ + Integer r; + Integer mul(Integer x, Integer y) { + return r; + } +} \ No newline at end of file diff --git a/testBytecode/LamRun.java b/testBytecode/LamRun.java index f4920700..fdaf0852 100644 --- a/testBytecode/LamRun.java +++ b/testBytecode/LamRun.java @@ -1,6 +1,6 @@ public class LamRun{ - public LamRun(){ + public void mRun(){ Runnable lam = () -> System.out.println("lambda"); lam.run(); diff --git a/testBytecode/TestMyTest.java b/testBytecode/TestMyTest.java index 1b3db588..e1305f76 100644 --- a/testBytecode/TestMyTest.java +++ b/testBytecode/TestMyTest.java @@ -5,6 +5,7 @@ public static void main(String[] a){ //test if statement //new TestIf(new Boolean(true)); // test lambda - new TestClass(); + //new TestClass(); + new LamRun(); } } diff --git a/testBytecode/manually/Fac1.java b/testBytecode/manually/Fac1.java new file mode 100644 index 00000000..e36ad3ae --- /dev/null +++ b/testBytecode/manually/Fac1.java @@ -0,0 +1,6 @@ +class Fuc1{ + + Integer mul(Integer x, Integer y) { + return x; + } +} diff --git a/testBytecode/manually/Fac2.java b/testBytecode/manually/Fac2.java new file mode 100644 index 00000000..dbf307b8 --- /dev/null +++ b/testBytecode/manually/Fac2.java @@ -0,0 +1,14 @@ +import java.util.function.Function; +class Fac2 { + + Integer mul(Integer x, Integer y) { + return x; + } + + Function m () { + Function fact = (Integer x) -> { + return mul(x, x); + }; + return fact; + } +} diff --git a/testBytecode/manually/LamAssign.java b/testBytecode/manually/LamAssign.java new file mode 100644 index 00000000..8d45a641 --- /dev/null +++ b/testBytecode/manually/LamAssign.java @@ -0,0 +1,10 @@ +import java.util.function.Function; +class LamAssign { + + Function m () { + Function lam1 = (Integer x) -> { + return x; + }; + return lam1; + } +} diff --git a/testBytecode/manually/LamAssignWithM.java b/testBytecode/manually/LamAssignWithM.java new file mode 100644 index 00000000..61077d27 --- /dev/null +++ b/testBytecode/manually/LamAssignWithM.java @@ -0,0 +1,12 @@ +import java.util.function.Function; +class LamAssignWithM { + Integer mul(Integer x, Integer y) { + return x; + } + Function m () { + Function lam1 = (Integer x) -> { + return mul(x,x); + }; + return lam1; + } +} diff --git a/testBytecode/manually/LamWithAnField.java b/testBytecode/manually/LamWithAnField.java new file mode 100644 index 00000000..ae6da4fc --- /dev/null +++ b/testBytecode/manually/LamWithAnField.java @@ -0,0 +1,14 @@ +import java.util.function.Function; +class LamWithAnField { + Integer mul(Integer x, Integer y) { + return x; + } + LamWithField temp= new LamWithField(); + Function m () { + Function lam1 = (Integer x) -> { + return temp.res*x; + }; + return lam1; + } +} + diff --git a/testBytecode/manually/LamWithField.java b/testBytecode/manually/LamWithField.java new file mode 100644 index 00000000..dacdca8b --- /dev/null +++ b/testBytecode/manually/LamWithField.java @@ -0,0 +1,14 @@ +import java.util.function.Function; +class LamWithField { + Integer mul(Integer x, Integer y) { + return x; + } + Integer res = new Integer(5); + Function m () { + Function lam1 = (Integer x) -> { + return res*x; + }; + return lam1; + } +} + diff --git a/testBytecode/manually/ReturnM1.java b/testBytecode/manually/ReturnM1.java new file mode 100644 index 00000000..3f89147d --- /dev/null +++ b/testBytecode/manually/ReturnM1.java @@ -0,0 +1,6 @@ +class ReturnM1{ + Integer r; + Integer mul(Integer x, Integer y) { + return r; + } +} From eddac2c8ed90e00fb4254592503706acb71d35c0 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 13 Dec 2017 13:15:11 +0100 Subject: [PATCH 15/42] VoidMeth Test korrigieren --- test/bytecode/JavaTXCompilerTest.java | 2 +- test/bytecode/VoidMeth.jav | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 4dfdf92e..d6846204 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "DuMethod"; + String fileName = "VoidMeth"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); diff --git a/test/bytecode/VoidMeth.jav b/test/bytecode/VoidMeth.jav index bdbf2545..6b3ab212 100644 --- a/test/bytecode/VoidMeth.jav +++ b/test/bytecode/VoidMeth.jav @@ -1,5 +1,4 @@ public class VoidMeth{ public void test(){ - System.out.print(""); } } \ No newline at end of file From fd8df92c031a54e1195bae20ac2061a4fceb47d5 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 13 Dec 2017 13:32:00 +0100 Subject: [PATCH 16/42] =?UTF-8?q?generatedBC-Directory=20anf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- testBytecode/generatedBC/.gitignore | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 testBytecode/generatedBC/.gitignore diff --git a/testBytecode/generatedBC/.gitignore b/testBytecode/generatedBC/.gitignore new file mode 100644 index 00000000..5e7d2734 --- /dev/null +++ b/testBytecode/generatedBC/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore From 5e675b9a93a0289260d4aad730f8f04ba5f22333 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 13 Dec 2017 13:34:22 +0100 Subject: [PATCH 17/42] =?UTF-8?q?Test=20anf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/bytecode/JavaTXCompilerTest.java | 2 +- test/bytecode/RecursiveMeth.jav | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 test/bytecode/RecursiveMeth.jav diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index d6846204..35c2ea3f 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "VoidMeth"; + String fileName = "RecursiveMeth"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); diff --git a/test/bytecode/RecursiveMeth.jav b/test/bytecode/RecursiveMeth.jav new file mode 100644 index 00000000..fd2851b0 --- /dev/null +++ b/test/bytecode/RecursiveMeth.jav @@ -0,0 +1,5 @@ +public class VoidMeth{ + public Integer test(){ + return this.test(); + } +} \ No newline at end of file From eb8db0e0eb901afd5f4502ee4f7769a394b23422 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 14 Dec 2017 17:44:43 +0100 Subject: [PATCH 18/42] =?UTF-8?q?TPH=20=3D=20TPH=20ist=20jetzt=20auch=20im?= =?UTF-8?q?=20ResultSet=20m=C3=B6glich.=20Anpassungen=20an=20der=20Generie?= =?UTF-8?q?rung=20der=20Imports=20einer=20SourceFile;=20l=C3=A4uft=20noch?= =?UTF-8?q?=20nicht=20fehlerfrei?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 2 +- .../environment/CompilationEnvironment.java | 4 +++- .../SyntaxTreeGenerator.java | 22 +++++++++++-------- .../parser/scope/GatherNames.java | 4 ++-- .../dhbwstuttgart/syntaxtree/SourceFile.java | 6 ++--- .../syntaxtree/factory/UnifyTypeFactory.java | 8 ++++--- .../typedeployment/TypeInsertFactory.java | 5 +++++ .../typeinference/result/ResultPair.java | 12 +++++----- .../typeinference/result/ResultSet.java | 20 +++++++++++++++++ .../result/ResultSetVisitor.java | 2 ++ 10 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 4ec0e2c3..80afb800 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -96,7 +96,7 @@ public class JavaTXCompiler { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null)); - SourceFile ret = generator.convert(tree); + SourceFile ret = generator.convert(tree,environment.packageCrawler); return ret; } diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java index 2f04423f..7044da6b 100644 --- a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java +++ b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java @@ -32,6 +32,7 @@ import de.dhbwstuttgart.parser.scope.JavaClassRegistry; public class CompilationEnvironment { private final List librarys; private final List sourceFiles; + public final PackageCrawler packageCrawler; /** * Imitiert die Environment beim Aufruf des JavaCompilers auf einer Menge von java-Dateien @@ -49,12 +50,13 @@ public class CompilationEnvironment { } } this.sourceFiles = sourceFiles; + this.packageCrawler = new PackageCrawler(librarys); } public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException { Map allNames; CompilationUnitContext tree = JavaTXParser.parse(forSourceFile); - allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); + allNames = GatherNames.getNames(tree, packageCrawler); return new JavaClassRegistry(allNames); } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index ed9d82e2..bae6e9b9 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -1,10 +1,12 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator; +import de.dhbwstuttgart.environment.PackageCrawler; import de.dhbwstuttgart.exceptions.NotImplementedException; import java.lang.ClassNotFoundException; import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.parser.antlr.Java8Parser; +import de.dhbwstuttgart.parser.scope.GatherNames; import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassRegistry; @@ -17,9 +19,8 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import java.lang.reflect.Modifier; import java.sql.Ref; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; +import java.util.*; +import java.util.stream.Collectors; //import jdk.internal.dynalink.support.TypeConverterFactory; import org.antlr.v4.runtime.CommonToken; @@ -30,7 +31,7 @@ public class SyntaxTreeGenerator{ private JavaClassRegistry reg; private final GenericsRegistry globalGenerics; private String pkgName = ""; - List imports = new ArrayList(); + Set imports = new HashSet(); List fieldInitializations = new ArrayList<>(); @@ -70,7 +71,8 @@ public class SyntaxTreeGenerator{ } return ret; } - + + /* public void setImports(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException { List newImports = new ArrayList(); for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ @@ -89,7 +91,7 @@ public class SyntaxTreeGenerator{ } this.imports.addAll(newImports); } - + private JavaClassName convertSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) throws ClassNotFoundException{ String typeName = convertTypeName(ctx.typeName()); JavaClassName ret = reg.getName(typeName); @@ -107,7 +109,8 @@ public class SyntaxTreeGenerator{ private List convertStaticImportOnDemandDeclaration(Java8Parser.StaticImportOnDemandDeclarationContext ctx){ return reg.getAllFromPackage(ctx.typeName().getText()); } - + + */ private String getPackageFromClass(String cls){ String ret = ""; String[] parts = cls.split("\\."); @@ -118,9 +121,10 @@ public class SyntaxTreeGenerator{ return ret; } - public SourceFile convert(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException{ + public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException{ List classes = new ArrayList<>(); - this.setImports(ctx); + Map imports = GatherNames.getImports(ctx, packageCrawler); + this.imports = imports.keySet().stream().map(name -> reg.getName(name)).collect(Collectors.toSet()); for(Java8Parser.TypeDeclarationContext typeDecl : ctx.typeDeclaration()){ ClassOrInterface newClass; if(typeDecl.classDeclaration() != null){ diff --git a/src/de/dhbwstuttgart/parser/scope/GatherNames.java b/src/de/dhbwstuttgart/parser/scope/GatherNames.java index 466d228b..cd508cde 100644 --- a/src/de/dhbwstuttgart/parser/scope/GatherNames.java +++ b/src/de/dhbwstuttgart/parser/scope/GatherNames.java @@ -69,10 +69,10 @@ public class GatherNames { } - private static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { + public static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException { Map ret = new HashMap<>(); - ret.putAll(packages.getClassNames("java.lang")); ClassLoader classLoader = ClassLoader.getSystemClassLoader(); + ret.putAll(packages.getClassNames("java.lang")); for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ if(importDeclCtx.singleTypeImportDeclaration() != null){ Class cl = classLoader.loadClass(importDeclCtx.singleTypeImportDeclaration().typeName().getText()); diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 439a3a8c..945ee5d8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -13,13 +13,13 @@ public class SourceFile extends SyntaxTreeNode{ private String pkgName; public final List KlassenVektor; - public final List imports; + public final Set imports; /** * Die SourceFile repräsntiert eine zu einem Syntaxbaum eingelesene Java-Datei. * SourceFile stellt dabei den Wurzelknoten des Syntaxbaumes dar. */ - public SourceFile(String pkgName, List classDefinitions, List imports){ + public SourceFile(String pkgName, List classDefinitions, Set imports){ super(new NullToken()); this.KlassenVektor = classDefinitions; this.pkgName = pkgName; @@ -31,7 +31,7 @@ public class SourceFile extends SyntaxTreeNode{ } // Get imports (to test implementation) - public List getImports(){ + public Set getImports(){ return this.imports; } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 325e453f..66b750a4 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -14,6 +14,7 @@ import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH; import de.dhbwstuttgart.typeinference.result.PairTPHequalRefTypeOrWildcardType; import de.dhbwstuttgart.typeinference.result.PairTPHsmallerTPH; import de.dhbwstuttgart.typeinference.result.ResultPair; @@ -195,12 +196,13 @@ public class UnifyTypeFactory { RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs); if(tl instanceof TypePlaceholder){ if(tr instanceof TypePlaceholder) { - if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) - throw new DebugException("TPH =. TPH ist ein ungültiges Ergebnis"); + if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) { + return new PairTPHEqualTPH((TypePlaceholder)tl, (TypePlaceholder)tr); //Einfach ignorieren TODO: Das hier muss ausgebessert werden: //return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); - else + }else{ return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr); + } }else if(tr instanceof RefType){ return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr); }else if(tr instanceof WildcardType){ diff --git a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java index 290fd984..29492c31 100644 --- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java +++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java @@ -104,6 +104,11 @@ class TypeToInsertString implements ResultSetVisitor{ } + @Override + public void visit(PairTPHEqualTPH p) { + + } + @Override public void visit(RefType resolved) { insert = resolved.getName().toString(); diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultPair.java b/src/de/dhbwstuttgart/typeinference/result/ResultPair.java index 4c754198..4415a939 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultPair.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultPair.java @@ -5,22 +5,22 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; /** * Paare, welche das Unifikationsergebnis darstellen */ -public abstract class ResultPair { - private final RefTypeOrTPHOrWildcardOrGeneric left; - private final RefTypeOrTPHOrWildcardOrGeneric right; +public abstract class ResultPair { + private final A left; + private final B right; public abstract void accept(ResultSetVisitor visitor); - public ResultPair(RefTypeOrTPHOrWildcardOrGeneric left, RefTypeOrTPHOrWildcardOrGeneric right){ + public ResultPair(A left, B right){ this.left = left; this.right = right; } - public RefTypeOrTPHOrWildcardOrGeneric getLeft() { + public A getLeft() { return left; } - public RefTypeOrTPHOrWildcardOrGeneric getRight() { + public B getRight() { return right; } } diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java index 1d0bd32d..9c1982ce 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java @@ -42,6 +42,11 @@ class Resolver implements ResultSetVisitor { public ResolvedType resolve(TypePlaceholder tph){ toResolve = tph; resolved = null; + for(ResultPair resultPair : result.results){ + if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){ + return resolve(((PairTPHEqualTPH) resultPair).getRight()); + } + } for(ResultPair resultPair : result.results){ resultPair.accept(this); } @@ -72,6 +77,11 @@ class Resolver implements ResultSetVisitor { } } + @Override + public void visit(PairTPHEqualTPH p) { + //Do nothing. Dieser Fall wird in der resolve-Methode abgefangen + } + @Override public void visit(RefType refType) { @@ -139,6 +149,11 @@ class TPHResolver implements ResultSetVisitor { } } + @Override + public void visit(PairTPHEqualTPH p) { + //ignorieren. Wird vom Resolver behandelt + } + @Override public void visit(RefType refType) { @@ -208,6 +223,11 @@ class RelatedTypeWalker implements ResultSetVisitor { } } + @Override + public void visit(PairTPHEqualTPH p) { + //Kann ignoriert werden. Diese Fälle werden vom Resolver behandelt + } + /* Die folgenden Funktionen fügen alle TPHs an die relatedTPHs an, denen sie begegnen: Das wird verwendet, wenn alle relatedTPHs aus den Parametern eines RefTypes angefügt werden sollen diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java b/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java index fbf241c1..bed742dd 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java @@ -5,6 +5,7 @@ import de.dhbwstuttgart.syntaxtree.type.*; public interface ResultSetVisitor { void visit(PairTPHsmallerTPH p); void visit(PairTPHequalRefTypeOrWildcardType p); + void visit(PairTPHEqualTPH p); void visit(RefType refType); @@ -15,4 +16,5 @@ public interface ResultSetVisitor { void visit(TypePlaceholder typePlaceholder); void visit(ExtendsWildcardType extendsWildcardType); + } From fb0ef510b23f5fc92d7cc7cf3f41f17c461f52b4 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 15 Dec 2017 00:05:30 +0100 Subject: [PATCH 19/42] Fehlende Klasse --- .../typeinference/result/PairTPHEqualTPH.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/de/dhbwstuttgart/typeinference/result/PairTPHEqualTPH.java diff --git a/src/de/dhbwstuttgart/typeinference/result/PairTPHEqualTPH.java b/src/de/dhbwstuttgart/typeinference/result/PairTPHEqualTPH.java new file mode 100644 index 00000000..64d0ce0b --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/result/PairTPHEqualTPH.java @@ -0,0 +1,15 @@ +package de.dhbwstuttgart.typeinference.result; + +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; + +public class PairTPHEqualTPH extends ResultPair { + public PairTPHEqualTPH(TypePlaceholder tl, TypePlaceholder tr) { + super(tl, tr); + } + + @Override + public void accept(ResultSetVisitor visitor) { + visitor.visit(this); + } +} From 9919ecd083ba248ece1730128bcc0320ff84d43a Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 15 Dec 2017 00:06:57 +0100 Subject: [PATCH 20/42] Anfangen mit Masterarbeit --- .../dhbwstuttgart/sat/asp/ASPGenerator.java | 24 +++++++++++++++++++ .../dhbwstuttgart/sat/asp/model/ASPType.java | 9 +++++++ 2 files changed, 33 insertions(+) create mode 100644 src/de/dhbwstuttgart/sat/asp/ASPGenerator.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPType.java diff --git a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java new file mode 100644 index 00000000..26ab0957 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java @@ -0,0 +1,24 @@ +package de.dhbwstuttgart.sat.asp; + +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; + +import java.util.Collection; + +public class ASPGenerator { + public static String toASP(ConstraintSet constraintSet, Collection fcClasses){ + String ret = ""; + for(ClassOrInterface cl : fcClasses){ + String className = toConstant(cl.getClassName()); + String superClassName = toConstant(cl.getSuperClass().getName()); + + } + return ret; + } + + + public static String toConstant(JavaClassName name){ + return "c" + name.toString().replace(".", "_"); + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPType.java new file mode 100644 index 00000000..4de8759d --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPType.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.sat.asp.model; + +import java.util.List; + +public class ASPType { + public ASPType(String name, List params){ + + } +} From 3a444c0172ef5e53aa0a74ce69c07e6d1f9a2cf3 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 15 Dec 2017 13:12:18 +0100 Subject: [PATCH 21/42] =?UTF-8?q?Aufr=C3=A4umen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 3 +- .../SyntaxTreeGenerator.java | 49 ------------------- 2 files changed, 2 insertions(+), 50 deletions(-) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 80afb800..51974ce8 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -52,6 +52,7 @@ public class JavaTXCompiler { //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(File forSourceFile : sourceFiles.keySet()) for(JavaClassName name : sourceFiles.get(forSourceFile).getImports()){ + //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet ClassOrInterface importedClass = ASTFactory.createClass( ClassLoader.getSystemClassLoader().loadClass(name.toString())); importedClasses.add(importedClass); @@ -96,7 +97,7 @@ public class JavaTXCompiler { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null)); - SourceFile ret = generator.convert(tree,environment.packageCrawler); + SourceFile ret = generator.convert(tree, environment.packageCrawler); return ret; } diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index bae6e9b9..b5ade811 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -71,55 +71,6 @@ public class SyntaxTreeGenerator{ } return ret; } - - /* - public void setImports(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException { - List newImports = new ArrayList(); - for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){ - if(importDeclCtx.singleTypeImportDeclaration() != null){ - newImports.add(convertSingleTypeImportDeclaration(importDeclCtx.singleTypeImportDeclaration())); - } - else if(importDeclCtx.typeImportOnDemandDeclaration() != null){ - newImports.addAll(convertTypeImportOnDemandDeclaration(importDeclCtx.typeImportOnDemandDeclaration())); - } - else if(importDeclCtx.singleStaticImportDeclaration() != null){ - newImports.add(convertSingleStaticImportDeclaration(importDeclCtx.singleStaticImportDeclaration())); - } - else{ - newImports.addAll(convertStaticImportOnDemandDeclaration(importDeclCtx.staticImportOnDemandDeclaration())); - } - } - this.imports.addAll(newImports); - } - - private JavaClassName convertSingleTypeImportDeclaration(Java8Parser.SingleTypeImportDeclarationContext ctx) throws ClassNotFoundException{ - String typeName = convertTypeName(ctx.typeName()); - JavaClassName ret = reg.getName(typeName); - return ret; - } - - private List convertTypeImportOnDemandDeclaration(Java8Parser.TypeImportOnDemandDeclarationContext ctx){ - return reg.getAllFromPackage(ctx.packageOrTypeName().getText()); - } - - private JavaClassName convertSingleStaticImportDeclaration(Java8Parser.SingleStaticImportDeclarationContext ctx){ - throw new NotImplementedException(); - } - - private List convertStaticImportOnDemandDeclaration(Java8Parser.StaticImportOnDemandDeclarationContext ctx){ - return reg.getAllFromPackage(ctx.typeName().getText()); - } - - */ - private String getPackageFromClass(String cls){ - String ret = ""; - String[] parts = cls.split("\\."); - for(int i = 0; i < parts.length - 1; i++){ - ret = ret + "." + parts[i]; - } - ret = ret.substring(1); - return ret; - } public SourceFile convert(Java8Parser.CompilationUnitContext ctx, PackageCrawler packageCrawler) throws ClassNotFoundException{ List classes = new ArrayList<>(); From e8757a179f41da93452422678cf26ec6f0e3ff99 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 18 Dec 2017 14:43:03 +0100 Subject: [PATCH 22/42] ASP-Generierung: parameterListe --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 73 +++++++++++++------ .../SyntaxTreeGenerator/TypeGenerator.java | 2 +- .../dhbwstuttgart/sat/asp/ASPGenerator.java | 41 +++++++++-- src/de/dhbwstuttgart/sat/asp/ASPWriter.java | 24 ++++++ .../sat/asp/model/ASPGenericType.java | 7 ++ .../dhbwstuttgart/sat/asp/model/ASPPair.java | 21 ++++++ .../sat/asp/model/ASPPairEquals.java | 13 ++++ .../sat/asp/model/ASPPairSmaller.java | 13 ++++ .../sat/asp/model/ASPParameterList.java | 40 ++++++++++ .../sat/asp/model/ASPRefType.java | 20 +++++ .../sat/asp/model/ASPStatement.java | 27 +++++++ .../dhbwstuttgart/sat/asp/model/ASPType.java | 7 +- .../sat/asp/model/ASPTypeVar.java | 7 ++ .../typeinference/unify/model/TypeParams.java | 4 +- test/asp/typeinference/ASPTest.java | 68 +++++++++++++++++ test/asp/typeinference/VectorTest.java | 9 +++ test/typeinference/JavaTXCompilerTest.java | 26 ++++++- 17 files changed, 358 insertions(+), 44 deletions(-) create mode 100644 src/de/dhbwstuttgart/sat/asp/ASPWriter.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPPair.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java create mode 100644 test/asp/typeinference/ASPTest.java create mode 100644 test/asp/typeinference/VectorTest.java diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 51974ce8..cce81107 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -29,7 +29,7 @@ import java.util.stream.Collectors; public class JavaTXCompiler { - final CompilationEnvironment environment; + final CompilationEnvironment environment; public final Map sourceFiles = new HashMap<>(); public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { @@ -38,56 +38,83 @@ public class JavaTXCompiler { public JavaTXCompiler(List sources) throws IOException, ClassNotFoundException { environment = new CompilationEnvironment(sources); - for(File s : sources){ - sourceFiles.put(s,parse(s)); + for (File s : sources) { + sourceFiles.put(s, parse(s)); } } - public List typeInference() throws ClassNotFoundException { + public ConstraintSet getConstraints() throws ClassNotFoundException { List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); - for(SourceFile sf : sourceFiles.values()){ + for (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses()); } List importedClasses = new ArrayList<>(); //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC - for(File forSourceFile : sourceFiles.keySet()) - for(JavaClassName name : sourceFiles.get(forSourceFile).getImports()){ - //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet + for (File forSourceFile : sourceFiles.keySet()) + for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) { + //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet ClassOrInterface importedClass = ASTFactory.createClass( ClassLoader.getSystemClassLoader().loadClass(name.toString())); importedClasses.add(importedClass); } allClasses.addAll(importedClasses); - FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); - final ConstraintSet cons = new TYPE(sourceFiles.values(), allClasses).getConstraints(); + return new TYPE(sourceFiles.values(), allClasses).getConstraints(); + } + + public List getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException { + List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); + for (SourceFile sf : sourceFiles.values()) { + allClasses.addAll(sf.getClasses()); + } + List importedClasses = new ArrayList<>(); + for (JavaClassName name : forSourceFile.getImports()) { + //TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet + ClassOrInterface importedClass = ASTFactory.createClass( + ClassLoader.getSystemClassLoader().loadClass(name.toString())); + importedClasses.add(importedClass); + allClasses.addAll(importedClasses); + } + return allClasses; + } + + public List typeInference() throws ClassNotFoundException { + List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); + //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC + for(SourceFile sf : this.sourceFiles.values()) { + allClasses.addAll(getAvailableClasses(sf)); + } + + final ConstraintSet cons = getConstraints(); + + FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); TypeUnify unify = new TypeUnify(); Set> results = new HashSet<>(); - for(List> xCons : unifyCons.cartesianProduct()){ + for (List> xCons : unifyCons.cartesianProduct()) { Set xConsSet = new HashSet<>(); - for(Constraint constraint : xCons){ + for (Constraint constraint : xCons) { xConsSet.addAll(constraint); } - System.out.println(xConsSet); + //System.out.println(xConsSet); Set> result = unify.unify(xConsSet, finiteClosure); //System.out.println("RESULT: " + result); results.addAll(result); } return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList()); - } + } - private Map generateTPHMap(ConstraintSet constraints){ + private Map generateTPHMap(ConstraintSet constraints) { HashMap ret = new HashMap<>(); - constraints.map((Pair p)->{ - if(p.TA1 instanceof TypePlaceholder){ - ret.put(((TypePlaceholder)p.TA1).getName(), (TypePlaceholder) p.TA1); + constraints.map((Pair p) -> { + if (p.TA1 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1); } - if(p.TA2 instanceof TypePlaceholder){ - ret.put(((TypePlaceholder)p.TA2).getName(), (TypePlaceholder) p.TA2); + if (p.TA2 instanceof TypePlaceholder) { + ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2); } return null; }); @@ -97,8 +124,8 @@ public class JavaTXCompiler { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { CompilationUnitContext tree = JavaTXParser.parse(sourceFile); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null)); - SourceFile ret = generator.convert(tree, environment.packageCrawler); + SourceFile ret = generator.convert(tree, environment.packageCrawler); return ret; } - -} + +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java index 2cf41b43..d54b682a 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java @@ -43,7 +43,7 @@ public class TypeGenerator { throw new NotImplementedException(); }else if(unannTypeContext.unannReferenceType().unannArrayType()!=null){ - System.out.println(unannTypeContext.getText()); + //System.out.println(unannTypeContext.getText()); throw new NotImplementedException(); }else if(unannTypeContext.unannReferenceType().unannTypeVariable()!=null){ diff --git a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java index 26ab0957..07e0e8dd 100644 --- a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java +++ b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java @@ -1,24 +1,49 @@ package de.dhbwstuttgart.sat.asp; import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.sat.asp.model.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import java.util.ArrayList; import java.util.Collection; +import java.util.List; +import java.util.Optional; public class ASPGenerator { - public static String toASP(ConstraintSet constraintSet, Collection fcClasses){ - String ret = ""; - for(ClassOrInterface cl : fcClasses){ - String className = toConstant(cl.getClassName()); - String superClassName = toConstant(cl.getSuperClass().getName()); + ASPWriter writer = new ASPWriter(); + private final String asp; - } - return ret; + public ASPGenerator(ConstraintSet constraints, Collection fcClasses){ + asp = toASP(constraints, fcClasses); } + public String getASP(){ + return asp; + } - public static String toConstant(JavaClassName name){ + private String toASP(ConstraintSet constraintSet, Collection fcClasses){ + for(ClassOrInterface cl : fcClasses){ + Optional superClass = + fcClasses.stream().filter(c -> c.getSuperClass().getName().equals(cl.getClassName())).findAny(); + //Für den Fall das es keinen Supertyp in den fcClasses gibt, wird die Klasse immer noch als ihr eigener Subtyp angefügt: + ASPPairSmaller fcEntry = new ASPPairSmaller(convert(cl), convert(superClass.orElse(cl))); + writer.add(new ASPStatement(fcEntry.toASP())); + } + return writer.getASPFile(); + } + + private ASPType convert(ClassOrInterface cl){ + List paramList = new ArrayList<>(); + for(GenericTypeVar gtv : cl.getGenerics()){ + paramList.add(new ASPGenericType(toConstant(gtv.getName()))); + } + ASPParameterList params = new ASPParameterList(paramList, writer); + return new ASPRefType(toConstant(cl.getClassName()), params); + } + + private String toConstant(JavaClassName name){ return "c" + name.toString().replace(".", "_"); } } diff --git a/src/de/dhbwstuttgart/sat/asp/ASPWriter.java b/src/de/dhbwstuttgart/sat/asp/ASPWriter.java new file mode 100644 index 00000000..4d33cbbf --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/ASPWriter.java @@ -0,0 +1,24 @@ +package de.dhbwstuttgart.sat.asp; + +import de.dhbwstuttgart.sat.asp.model.ASPRefType; +import de.dhbwstuttgart.sat.asp.model.ASPStatement; +import de.dhbwstuttgart.sat.asp.model.ASPType; + +import java.util.HashSet; + +public class ASPWriter { + + private HashSet content = new HashSet<>(); + + public void add(ASPStatement stmt){ + content.add(stmt); + } + + public String getASPFile(){ + String ret = ""; + for(ASPStatement statement : content){ + ret += statement.getASP() + ".\n"; + } + return ret; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java new file mode 100644 index 00000000..729d678a --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPGenericType implements ASPType{ + public ASPGenericType(String name){ + + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPair.java b/src/de/dhbwstuttgart/sat/asp/model/ASPPair.java new file mode 100644 index 00000000..bbd3ff3f --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPPair.java @@ -0,0 +1,21 @@ +package de.dhbwstuttgart.sat.asp.model; + +public abstract class ASPPair { + public final ASPType leftSide; + public final ASPType rightSide; + + public ASPPair(ASPType ls, ASPType rs){ + this.leftSide = ls; + this.rightSide = rs; + } + + public String toASP(){ + return this.getRuleName() + "(" + leftSide + ","+ rightSide + ")"; + } + + public String toString(){ + return toASP(); + } + + protected abstract String getRuleName(); +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java b/src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java new file mode 100644 index 00000000..b67920bd --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java @@ -0,0 +1,13 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPPairEquals extends ASPPair{ + private final static String ASP_PAIR_EQUALS_NAME = "equals"; + public ASPPairEquals(ASPType ls, ASPType rs){ + super(ls, rs); + } + + @Override + protected String getRuleName() { + return ASP_PAIR_EQUALS_NAME; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java b/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java new file mode 100644 index 00000000..882054cc --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java @@ -0,0 +1,13 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPPairSmaller extends ASPPair{ + private final static String ASP_PAIR_SMALLER_NAME = "smaller"; + public ASPPairSmaller(ASPType ls, ASPType rs){ + super(ls, rs); + } + + @Override + protected String getRuleName() { + return ASP_PAIR_SMALLER_NAME; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java new file mode 100644 index 00000000..b38f8a38 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java @@ -0,0 +1,40 @@ +package de.dhbwstuttgart.sat.asp.model; + +import de.dhbwstuttgart.sat.asp.ASPWriter; +import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +public class ASPParameterList { + private final static String ASP_PARAMLIST_NAME = "param"; + private final static String ASP_PARAMLIST_END_POINTER = "null"; + public final String name; + private final List types; + + public ASPParameterList(List types, ASPWriter writer){ + this.types = types; + if(types.size() == 0){ + name = ASP_PARAMLIST_END_POINTER; + }else{ + name = NameGenerator.makeNewName(); + String nextPointer = name; + Iterator it = types.iterator(); + while(it.hasNext()){ + ASPType t = it.next(); + String param = nextPointer + "," + t.toString() + ","; + nextPointer = NameGenerator.makeNewName(); + if(! it.hasNext())nextPointer = ASP_PARAMLIST_END_POINTER; + param += nextPointer; + writer.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); + //paramDefinitions.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); + } + } + } + + public String toString(){ + return name; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java new file mode 100644 index 00000000..ba318876 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java @@ -0,0 +1,20 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPRefType implements ASPType { + public static final String ASP_TYPE = "type"; + private final ASPParameterList params; + private final String name; + + public ASPRefType(String name, ASPParameterList params){ + this.name = name; + this.params = params; + } + + public ASPParameterList getParams() { + return params; + } + + public String toString(){ + return ASP_TYPE + "(" + name +"," + params.name + ")"; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java b/src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java new file mode 100644 index 00000000..8e4a1d35 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java @@ -0,0 +1,27 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPStatement { + private final String stmt; + public ASPStatement(String stmt) { + this.stmt = stmt; + } + + public String toString(){ + return stmt; + } + + @Override + public int hashCode() { + return stmt.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof ASPStatement)return stmt.equals(((ASPStatement) obj).stmt); + return false; + } + + public String getASP() { + return stmt; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPType.java index 4de8759d..e703596c 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPType.java +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPType.java @@ -1,9 +1,4 @@ package de.dhbwstuttgart.sat.asp.model; -import java.util.List; - -public class ASPType { - public ASPType(String name, List params){ - - } +public interface ASPType { } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java b/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java new file mode 100644 index 00000000..16b79f91 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPTypeVar implements ASPType{ + public ASPTypeVar(String name){ + + } +} diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java index f40ecb2f..dc90847b 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/TypeParams.java @@ -153,8 +153,8 @@ public final class TypeParams implements Iterable{ return false; for(int i = 0; i < this.size(); i++){ - if(this.get(i) == null) - System.out.print("s"); + //if(this.get(i) == null) + //System.out.print("s"); } for(int i = 0; i < this.size(); i++) if(!(this.get(i).equals(other.get(i)))) diff --git a/test/asp/typeinference/ASPTest.java b/test/asp/typeinference/ASPTest.java new file mode 100644 index 00000000..5074e4f3 --- /dev/null +++ b/test/asp/typeinference/ASPTest.java @@ -0,0 +1,68 @@ +package asp.typeinference; + +import de.dhbwstuttgart.core.JavaTXCompiler; +import de.dhbwstuttgart.sat.asp.ASPGenerator; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.SourceFile; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import org.junit.Test; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; + +public class ASPTest { + + public static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/"; + private static final List filesToTest = new ArrayList<>(); + protected File fileToTest = null; + + public ASPTest(){ + } + + + @Test + public void test() throws IOException, ClassNotFoundException { + if(fileToTest != null)filesToTest.add(fileToTest); + else return; + //filesToTest.add(new File(rootDirectory+"Faculty.jav")); + //filesToTest.add(new File(rootDirectory+"mathStruc.jav")); + //filesToTest.add(new File(rootDirectory+"test.jav")); + filesToTest.add(new File(rootDirectory+"EmptyMethod.jav")); + //filesToTest.add(new File(rootDirectory+"fc.jav")); + //filesToTest.add(new File(rootDirectory+"Lambda.jav")); + //filesToTest.add(new File(rootDirectory+"Lambda2.jav")); + //filesToTest.add(new File(rootDirectory+"Lambda3.jav")); + //filesToTest.add(new File(rootDirectory+"Vector.jav")); + //filesToTest.add(new File(rootDirectory+"Generics.jav")); + //filesToTest.add(new File(rootDirectory+"MethodsEasy.jav")); + //filesToTest.add(new File(rootDirectory+"Matrix.jav")); + //filesToTest.add(new File(rootDirectory+"Import.jav")); + JavaTXCompiler compiler = new JavaTXCompiler(fileToTest); + List allClasses = new ArrayList<>(); + for(SourceFile sf : compiler.sourceFiles.values()) { + //allClasses.addAll(compiler.getAvailableClasses(sf)); + } + for(SourceFile sf : compiler.sourceFiles.values()) { + allClasses.addAll(sf.getClasses()); + } + + final ConstraintSet cons = compiler.getConstraints(); + ASPGenerator generator = new ASPGenerator(cons, allClasses); + System.out.println(generator.getASP()); + } + + static String readFile(String path, Charset encoding) + throws IOException + { + byte[] encoded = Files.readAllBytes(Paths.get(path)); + return new String(encoded, encoding); + } + +} + diff --git a/test/asp/typeinference/VectorTest.java b/test/asp/typeinference/VectorTest.java new file mode 100644 index 00000000..77ff4959 --- /dev/null +++ b/test/asp/typeinference/VectorTest.java @@ -0,0 +1,9 @@ +package asp.typeinference; + +import java.io.File; + +public class VectorTest extends ASPTest { + public VectorTest() { + this.fileToTest = new File(rootDirectory+"Vector.jav"); + } +} \ No newline at end of file diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index 8e60c803..fbbed9af 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -1,11 +1,23 @@ package typeinference; import de.dhbwstuttgart.core.JavaTXCompiler; +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.sat.asp.ASPGenerator; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.SourceFile; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter; import de.dhbwstuttgart.typedeployment.TypeInsert; import de.dhbwstuttgart.typedeployment.TypeInsertFactory; +import de.dhbwstuttgart.typeinference.constraints.Constraint; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.result.ResultSet; +import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; +import de.dhbwstuttgart.typeinference.unify.TypeUnify; +import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; +import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import org.junit.Test; import java.io.File; @@ -17,8 +29,10 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.stream.Collectors; public class JavaTXCompilerTest { @@ -28,11 +42,10 @@ public class JavaTXCompilerTest { public JavaTXCompilerTest(){ } - @Test - public void test() throws IOException, java.lang.ClassNotFoundException { + public void test() throws IOException, ClassNotFoundException { if(fileToTest != null)filesToTest.add(fileToTest); - else return; + else return; //filesToTest.add(new File(rootDirectory+"Faculty.jav")); //filesToTest.add(new File(rootDirectory+"mathStruc.jav")); //filesToTest.add(new File(rootDirectory+"test.jav")); @@ -47,6 +60,7 @@ public class JavaTXCompilerTest { //filesToTest.add(new File(rootDirectory+"Matrix.jav")); //filesToTest.add(new File(rootDirectory+"Import.jav")); JavaTXCompiler compiler = new JavaTXCompiler(fileToTest); + List results = compiler.typeInference(); for(File f : compiler.sourceFiles.keySet()){ @@ -54,14 +68,18 @@ public class JavaTXCompilerTest { System.out.println(ASTTypePrinter.print(sf)); //List results = compiler.typeInference(); PL 2017-10-03 vor die For-Schleife gezogen assert results.size()>0; + Set insertedTypes = new HashSet<>(); for(ResultSet resultSet : results){ Set result = TypeInsertFactory.createTypeInsertPoints(sf, resultSet); assert result.size()>0; String content = readFile(f.getPath(), StandardCharsets.UTF_8); for(TypeInsert tip : result){ - System.out.println(tip.insert(content)); + insertedTypes.add(tip.insert(content)); } } + for(String s : insertedTypes){ + System.out.println(s); + } } } From 09bdaa6a218dbce8bfee4cdd15e9a3bb1a2b808e Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 13:34:34 +0100 Subject: [PATCH 23/42] Generics Test erzeugt falsches ConstraintSet --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 6 +- .../dhbwstuttgart/sat/asp/ASPGenerator.java | 82 +++++++++++++++++-- .../sat/asp/model/ASPGenericType.java | 9 +- .../sat/asp/model/ASPPairSmallerDot.java | 13 +++ .../sat/asp/model/ASPParameterList.java | 9 +- .../sat/asp/model/ASPTypeVar.java | 9 +- .../syntaxtree/factory/UnifyTypeFactory.java | 5 ++ .../typeinference/constraints/Pair.java | 3 + test/asp/typeinference/GenericsTest.java | 9 ++ test/javFiles/Generics.jav | 3 +- test/typeinference/GenericsTest.java | 1 + 11 files changed, 133 insertions(+), 16 deletions(-) create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java create mode 100644 test/asp/typeinference/GenericsTest.java diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index cce81107..bac09f8b 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -82,7 +82,7 @@ public class JavaTXCompiler { List allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : this.sourceFiles.values()) { - allClasses.addAll(getAvailableClasses(sf)); + //allClasses.addAll(getAvailableClasses(sf)); } final ConstraintSet cons = getConstraints(); @@ -98,9 +98,9 @@ public class JavaTXCompiler { xConsSet.addAll(constraint); } - //System.out.println(xConsSet); + System.out.println(xConsSet); Set> result = unify.unify(xConsSet, finiteClosure); - //System.out.println("RESULT: " + result); + System.out.println("RESULT: " + result); results.addAll(result); } return results.stream().map((unifyPairs -> diff --git a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java index 07e0e8dd..1b942ad0 100644 --- a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java +++ b/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java @@ -1,11 +1,19 @@ package de.dhbwstuttgart.sat.asp; +import de.dhbwstuttgart.exceptions.DebugException; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.sat.asp.model.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; +import de.dhbwstuttgart.syntaxtree.type.*; +import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.unify.model.UnifyType; +import java.sql.Ref; import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -15,25 +23,45 @@ public class ASPGenerator { ASPWriter writer = new ASPWriter(); private final String asp; - public ASPGenerator(ConstraintSet constraints, Collection fcClasses){ - asp = toASP(constraints, fcClasses); + public ASPGenerator(ConstraintSet constraints, Collection fcClasses){ + List> constraints1 = constraints.cartesianProduct().iterator().next(); + List constraintPairs = new ArrayList<>(); + for(Constraint constraint : constraints1){ + System.out.println(UnifyTypeFactory.convert(constraint)); + constraintPairs.addAll(constraint); + } + asp = toASP(constraintPairs, fcClasses); } public String getASP(){ return asp; } - private String toASP(ConstraintSet constraintSet, Collection fcClasses){ + private String toASP(List constraintSet, Collection fcClasses){ + TypeConverter converter = new TypeConverter(); for(ClassOrInterface cl : fcClasses){ - Optional superClass = - fcClasses.stream().filter(c -> c.getSuperClass().getName().equals(cl.getClassName())).findAny(); - //Für den Fall das es keinen Supertyp in den fcClasses gibt, wird die Klasse immer noch als ihr eigener Subtyp angefügt: - ASPPairSmaller fcEntry = new ASPPairSmaller(convert(cl), convert(superClass.orElse(cl))); + ASPType superClass = cl.getSuperClass().acceptTV(converter); + ASPPairSmaller fcEntry = new ASPPairSmaller(convert(cl), superClass); writer.add(new ASPStatement(fcEntry.toASP())); } + for(Pair cons : constraintSet){ + writer.add(new ASPStatement(convert(cons).toASP())); + } + return writer.getASPFile(); } + private ASPPair convert(Pair pair){ + TypeConverter converter = new TypeConverter(); + ASPType ls = pair.TA1.acceptTV(converter); + ASPType rs = pair.TA2.acceptTV(converter); + if(pair.OperatorEqual()){ + return new ASPPairEquals(ls, rs); + }else if(pair.OperatorSmallerDot()){ + return new ASPPairSmallerDot(ls, rs); + }else throw new NotImplementedException(); + } + private ASPType convert(ClassOrInterface cl){ List paramList = new ArrayList<>(); for(GenericTypeVar gtv : cl.getGenerics()){ @@ -43,7 +71,45 @@ public class ASPGenerator { return new ASPRefType(toConstant(cl.getClassName()), params); } - private String toConstant(JavaClassName name){ + public static String toConstant(JavaClassName name){ + return toConstant(name.toString().replace(".", "_")); + } + + public static String toConstant(String name){ return "c" + name.toString().replace(".", "_"); } + + private class TypeConverter implements TypeVisitor{ + + @Override + public ASPType visit(RefType type) { + List paramList = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric gtv : type.getParaList()){ + paramList.add(gtv.acceptTV(this)); + } + ASPParameterList params = new ASPParameterList(paramList, writer); + return new ASPRefType(toConstant(type.getName()), params); + } + + @Override + public ASPType visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public ASPType visit(TypePlaceholder typePlaceholder) { + return new ASPTypeVar(toConstant(typePlaceholder.getName())); + } + + @Override + public ASPType visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public ASPType visit(GenericRefType genericRefType) { + return new ASPRefType(toConstant(genericRefType.getName()), + new ASPParameterList(new ArrayList<>(), writer)); + } + } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java index 729d678a..26e6ea02 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java @@ -1,7 +1,14 @@ package de.dhbwstuttgart.sat.asp.model; public class ASPGenericType implements ASPType{ - public ASPGenericType(String name){ + public static final String ASP_GENERIC_TYPE_NAME = "genericType"; + private final String name; + public ASPGenericType(String name){ + this.name = name; + } + + public String toString(){ + return ASP_GENERIC_TYPE_NAME + "(" + name + ")"; } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java b/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java new file mode 100644 index 00000000..0e6598c1 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java @@ -0,0 +1,13 @@ +package de.dhbwstuttgart.sat.asp.model; + +public class ASPPairSmallerDot extends ASPPair{ + private final static String ASP_PAIR_SMALLER_NAME = "smallerDot"; + public ASPPairSmallerDot(ASPType ls, ASPType rs){ + super(ls, rs); + } + + @Override + protected String getRuleName() { + return ASP_PAIR_SMALLER_NAME; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java index b38f8a38..f0c06744 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.sat.asp.model; +import de.dhbwstuttgart.sat.asp.ASPGenerator; import de.dhbwstuttgart.sat.asp.ASPWriter; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; @@ -19,13 +20,13 @@ public class ASPParameterList { if(types.size() == 0){ name = ASP_PARAMLIST_END_POINTER; }else{ - name = NameGenerator.makeNewName(); + name = newName(); String nextPointer = name; Iterator it = types.iterator(); while(it.hasNext()){ ASPType t = it.next(); String param = nextPointer + "," + t.toString() + ","; - nextPointer = NameGenerator.makeNewName(); + nextPointer = newName(); if(! it.hasNext())nextPointer = ASP_PARAMLIST_END_POINTER; param += nextPointer; writer.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); @@ -34,6 +35,10 @@ public class ASPParameterList { } } + private String newName() { + return ASPGenerator.toConstant(NameGenerator.makeNewName()); + } + public String toString(){ return name; } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java b/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java index 16b79f91..e2f87636 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java @@ -1,7 +1,14 @@ package de.dhbwstuttgart.sat.asp.model; public class ASPTypeVar implements ASPType{ - public ASPTypeVar(String name){ + private final String name; + public ASPTypeVar(String name){ + this.name = name; + } + + @Override + public String toString() { + return "typeVar("+ name +")"; } } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 66b750a4..e5eea03c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -12,6 +12,7 @@ import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.WildcardType; +import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH; @@ -169,6 +170,10 @@ public class UnifyTypeFactory { return constraints.map(UnifyTypeFactory::convert); } + public static Constraint convert(Constraint constraint){ + return constraint.stream().map(UnifyTypeFactory::convert).collect(Collectors.toCollection(Constraint::new)); + } + public static UnifyPair convert(Pair p) { if(p.GetOperator().equals(PairOperator.SMALLERDOT)) { UnifyPair ret = generateSmallerDotPair(UnifyTypeFactory.convert(p.TA1) diff --git a/src/de/dhbwstuttgart/typeinference/constraints/Pair.java b/src/de/dhbwstuttgart/typeinference/constraints/Pair.java index c7e1f6b6..ab0cb3ea 100644 --- a/src/de/dhbwstuttgart/typeinference/constraints/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/constraints/Pair.java @@ -104,5 +104,8 @@ public class Pair implements Serializable return eOperator; } + public boolean OperatorSmallerDot() { + return eOperator == PairOperator.SMALLERDOT; + } } // ino.end diff --git a/test/asp/typeinference/GenericsTest.java b/test/asp/typeinference/GenericsTest.java new file mode 100644 index 00000000..b0f0330a --- /dev/null +++ b/test/asp/typeinference/GenericsTest.java @@ -0,0 +1,9 @@ +package asp.typeinference; + +import java.io.File; + +public class GenericsTest extends ASPTest { + public GenericsTest() { + this.fileToTest = new File(rootDirectory+"Generics.jav"); + } +} \ No newline at end of file diff --git a/test/javFiles/Generics.jav b/test/javFiles/Generics.jav index 958025e6..c76b40aa 100644 --- a/test/javFiles/Generics.jav +++ b/test/javFiles/Generics.jav @@ -1,6 +1,7 @@ class Generics { - A mt1(A a, B b){ + // A mt1(A a, B b){ + B mt1(B a, B b){ return mt1(a, a); } } diff --git a/test/typeinference/GenericsTest.java b/test/typeinference/GenericsTest.java index 3811883d..abcef013 100644 --- a/test/typeinference/GenericsTest.java +++ b/test/typeinference/GenericsTest.java @@ -2,6 +2,7 @@ package typeinference; import java.io.File; +//TODO: Hier gibt es einen Fehler. Das erstellte ConstraintSet stimmt nicht public class GenericsTest extends JavaTXCompilerTest{ public GenericsTest() { this.fileToTest = new File(rootDirectory+"Generics.jav"); From 5f731bb09ca0b7c933fd883b6acc5f47db01dbfc Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 20 Dec 2017 13:35:55 +0100 Subject: [PATCH 24/42] letzte tests --- .../syntaxtree/factory/UnifyTypeFactory.java | 9 +-------- test/bytecode/DuMethod.jav | 2 +- test/bytecode/IfTest.jav | 10 ++++++++++ test/bytecode/JavaTXCompilerTest.java | 2 +- 4 files changed, 13 insertions(+), 10 deletions(-) create mode 100644 test/bytecode/IfTest.jav diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index e0a8ddbf..361a7583 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -196,19 +196,12 @@ public class UnifyTypeFactory { RefTypeOrTPHOrWildcardOrGeneric tr = UnifyTypeFactory.convert(mp.getRhsType(), tphs); if(tl instanceof TypePlaceholder){ if(tr instanceof TypePlaceholder) { -<<<<<<< HEAD - if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) - //throw new DebugException("TPH =. TPH ist ein ungültiges Ergebnis"); - //Einfach ignorieren TODO: Das hier muss ausgebessert werden: - return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); - else -======= + if(mp.getPairOp().equals(PairOperator.EQUALSDOT)) { return new PairTPHEqualTPH((TypePlaceholder)tl, (TypePlaceholder)tr); //Einfach ignorieren TODO: Das hier muss ausgebessert werden: //return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, ASTFactory.createObjectType()); }else{ ->>>>>>> eb8db0e0eb901afd5f4502ee4f7769a394b23422 return new PairTPHsmallerTPH((TypePlaceholder)tl, (TypePlaceholder)tr); } }else if(tr instanceof RefType){ diff --git a/test/bytecode/DuMethod.jav b/test/bytecode/DuMethod.jav index 12666893..b56f6c55 100644 --- a/test/bytecode/DuMethod.jav +++ b/test/bytecode/DuMethod.jav @@ -1,6 +1,6 @@ public class DuMethod{ - method(a,b){ + method(a){ return a; } diff --git a/test/bytecode/IfTest.jav b/test/bytecode/IfTest.jav new file mode 100644 index 00000000..806e2157 --- /dev/null +++ b/test/bytecode/IfTest.jav @@ -0,0 +1,10 @@ +public class IfTest{ + Integer m1(Boolean b) { + Integer i; + if(b) { + return i; + } + + return i; + } +} \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 66e60fe1..39413991 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "IfTest"; + String fileName = "LamAssign"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); From d989100b4764c03c77a1231bf73e3ea241f0bc77 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 20 Dec 2017 14:14:05 +0100 Subject: [PATCH 25/42] korrekte bytecode --- src/de/dhbwstuttgart/bytecode/BytecodeGen.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index a1bd4ae5..6f7acd64 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -67,7 +67,7 @@ public class BytecodeGen implements ASTVisitor { className = classOrInterface.getClassName().toString(); // access flages?? cw.visit(Opcodes.V1_8, classOrInterface.getModifiers()+Opcodes.ACC_SUPER, classOrInterface.getClassName().toString() - , null, classOrInterface.getSuperClass().toString(), null); + , null, classOrInterface.getSuperClass().toString().replace(".", "/"), null); // for each field in the class for(Field f : classOrInterface.getFieldDecl()) { From 940c922c80ec235e982ca936c54045746a3c570a Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 15:01:02 +0100 Subject: [PATCH 26/42] =?UTF-8?q?ResultSet=20kann=20GenericRefTypes=20aufl?= =?UTF-8?q?=C3=B6sen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/typeinference/result/ResultSet.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java index 9c1982ce..22da67fc 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.typeinference.result; import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.type.*; import java.util.HashSet; @@ -15,6 +16,7 @@ public class ResultSet { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { if(type instanceof TypePlaceholder) return new Resolver(this).resolve((TypePlaceholder)type); + if(type instanceof GenericRefType)new ResolvedType(type, new HashSet<>()); if(type instanceof RefType){ RelatedTypeWalker related = new RelatedTypeWalker(null, this); type.accept(related); From 01fd396d29b34eba14ebfc2f95df5ba926f4f1c1 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 20 Dec 2017 15:04:03 +0100 Subject: [PATCH 27/42] Test generics --- test/bytecode/Gen.jav | 5 +++++ test/bytecode/Generics.jav | 15 +++++++++++++++ test/bytecode/JavaTXCompilerTest.java | 2 +- 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/bytecode/Gen.jav create mode 100644 test/bytecode/Generics.jav diff --git a/test/bytecode/Gen.jav b/test/bytecode/Gen.jav new file mode 100644 index 00000000..1f873919 --- /dev/null +++ b/test/bytecode/Gen.jav @@ -0,0 +1,5 @@ +public class Gen{ + Vector m(Vector v){ + return v; + } +} \ No newline at end of file diff --git a/test/bytecode/Generics.jav b/test/bytecode/Generics.jav new file mode 100644 index 00000000..2c7a67b6 --- /dev/null +++ b/test/bytecode/Generics.jav @@ -0,0 +1,15 @@ + +class Generics { + B mt1(B b){ + return mt1(b); + } +} + + +/* +Problem: +auto test = new List(); +auto test2 = new List(); +... //code, welcher möglicherweise test und test2 vertauscht +test.add("hallo"); +*/ \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 39413991..f43a0740 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "LamAssign"; + String fileName = "Generics"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); From 55be865ab4fd96d8bbfd84d12dcb324b42d6be16 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 15:06:04 +0100 Subject: [PATCH 28/42] Bugfix --- src/de/dhbwstuttgart/typeinference/result/ResultSet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java index 22da67fc..19701d7b 100644 --- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java @@ -16,7 +16,7 @@ public class ResultSet { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { if(type instanceof TypePlaceholder) return new Resolver(this).resolve((TypePlaceholder)type); - if(type instanceof GenericRefType)new ResolvedType(type, new HashSet<>()); + if(type instanceof GenericRefType)return new ResolvedType(type, new HashSet<>()); if(type instanceof RefType){ RelatedTypeWalker related = new RelatedTypeWalker(null, this); type.accept(related); From 009a638c9a4a6b79d78f92e5674a25c9266b6a42 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 15:27:39 +0100 Subject: [PATCH 29/42] FC ohne java.lang generieren --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index bac09f8b..2abd8b9d 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -83,6 +83,7 @@ public class JavaTXCompiler { //Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf : this.sourceFiles.values()) { //allClasses.addAll(getAvailableClasses(sf)); + allClasses.addAll(sf.getClasses()); } final ConstraintSet cons = getConstraints(); From 90a9273fc25cadd955c24b1a2fdc1cd7f940e5e1 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 15:37:33 +0100 Subject: [PATCH 30/42] TypeToStringVisitor --- src/de/dhbwstuttgart/bytecode/Descriptor.java | 35 +++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/Descriptor.java b/src/de/dhbwstuttgart/bytecode/Descriptor.java index fb57e682..3b024d71 100644 --- a/src/de/dhbwstuttgart/bytecode/Descriptor.java +++ b/src/de/dhbwstuttgart/bytecode/Descriptor.java @@ -3,13 +3,14 @@ package de.dhbwstuttgart.bytecode; import java.util.List; import java.util.Iterator; +import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; -import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.result.ResultSet; public class Descriptor { @@ -20,13 +21,41 @@ public class Descriptor { Iterator itr = method.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; } desc = addReturnType(desc,method.getReturnType(), resultSet); } - + + private class TypeToDescriptor implements TypeVisitor{ + + @Override + public String visit(RefType refType) { + return refType.getName().toString().replace(".", "/"); + } + + @Override + public String visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(TypePlaceholder typePlaceholder) { + return typePlaceholder.toString(); + } + + @Override + public String visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(GenericRefType genericRefType) { + return genericRefType.getParsedName(); + } + } + private String addReturnType(String desc2, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { System.out.println("DescType = "+returnType.toString()); if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ From 719d1a5cedb3141498812a5d50cb262d8af7f1c8 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 15:59:07 +0100 Subject: [PATCH 31/42] Interface Modifier setzen --- .../parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index b5ade811..c5b135e6 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -379,6 +379,8 @@ public class SyntaxTreeGenerator{ modifiers += newModifier; } } + if(!Modifier.isInterface(modifiers))modifiers += Modifier.INTERFACE; + JavaClassName name = reg.getName(ctx.Identifier().getText()); GenericsRegistry generics = createGenerics(ctx.typeParameters(), name, "", reg, new GenericsRegistry(globalGenerics)); From 6ddc4983b02bbf5ebffe5fd562a4bea95a8d1b2a Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 20 Dec 2017 17:12:40 +0100 Subject: [PATCH 32/42] Fehler im Type beheben --- src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 9d302ccd..2152fc65 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -196,7 +196,7 @@ public class TYPEStmt implements StatementVisitor{ @Override public void visit(Return returnExpr) { returnExpr.retexpr.accept(this); - constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.EQUALSDOT)); + constraintsSet.addUndConstraint(new Pair(returnExpr.getType(),info.getCurrentTypeScope().getReturnType(), PairOperator.SMALLERDOT)); } @Override From 01339ca7ec7ec368cf9e6a3fee5e481fc19459f9 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Thu, 28 Dec 2017 10:20:28 +0100 Subject: [PATCH 33/42] Descriptor-Erzeugen neu mit Visitor-pattern implementiert --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 16 ++- .../bytecode/BytecodeGenMethod.java | 36 +++--- src/de/dhbwstuttgart/bytecode/Descriptor.java | 112 ------------------ .../bytecode/DescriptorToString.java | 85 +++++++++++++ .../bytecode/DescriptorVisitor.java | 9 ++ src/de/dhbwstuttgart/bytecode/Lambda.java | 25 ++++ .../bytecode/MethodFromMethodCall.java | 18 +++ .../bytecode/NormalConstructor.java | 20 ++++ .../dhbwstuttgart/bytecode/NormalMethod.java | 29 +++++ src/de/dhbwstuttgart/bytecode/SamMethod.java | 31 +++++ .../bytecode/TypeToDescriptor.java | 37 ++++++ test/bytecode/JavaTXCompilerTest.java | 2 +- 12 files changed, 285 insertions(+), 135 deletions(-) delete mode 100644 src/de/dhbwstuttgart/bytecode/Descriptor.java create mode 100644 src/de/dhbwstuttgart/bytecode/DescriptorToString.java create mode 100644 src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java create mode 100644 src/de/dhbwstuttgart/bytecode/Lambda.java create mode 100644 src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java create mode 100644 src/de/dhbwstuttgart/bytecode/NormalConstructor.java create mode 100644 src/de/dhbwstuttgart/bytecode/NormalMethod.java create mode 100644 src/de/dhbwstuttgart/bytecode/SamMethod.java create mode 100644 src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 6f7acd64..1b6ef47b 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -88,11 +88,12 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(Constructor field) { - Descriptor desc = new Descriptor(field, resultSet); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc.getDesc(), null, null); + NormalConstructor constructor = new NormalConstructor(field); + String desc = constructor.accept(new DescriptorToString(resultSet)); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, null, null); mv.visitCode(); System.out.println("-----Constructor-----"); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc,cw,isInterface); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); @@ -104,12 +105,15 @@ public class BytecodeGen implements ASTVisitor { // TODO: check if the method is static => if static then the first param will be stored in pos 0 // else it will be stored in pos 1 and this will be stored in pos 0 method.getParameterList().accept(this); - Descriptor methDesc = new Descriptor(method,resultSet); + + NormalMethod meth = new NormalMethod(method); + String methDesc = meth.accept(new DescriptorToString(resultSet)); + System.out.println("-----Method-----"); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc.getDesc(), null, null); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc, null, null); mv.visitCode(); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc,cw,isInterface); mv.visitMaxs(0, 0); mv.visitEnd(); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index c2acaba0..ffdf1450 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -94,7 +94,8 @@ public class BytecodeGenMethod implements StatementVisitor{ } private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { - return resultSet.resolveType(type).resolvedType.toString().replace(".", "/"); +// return resultSet.resolveType(type).resolvedType.toString().replace(".", "/"); + return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); } @@ -164,7 +165,9 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(LambdaExpression lambdaExpression) { System.out.println("\n++ In Lambda: "); this.lamCounter++; - Descriptor lamDesc = new Descriptor(lambdaExpression, resultSet); + + Lambda lam = new Lambda(lambdaExpression); + String lamDesc = lam.accept(new DescriptorToString(resultSet)); //Call site, which, when invoked, returns an instance of the functional interface to which //the lambda is being converted MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, @@ -175,9 +178,9 @@ public class BytecodeGenMethod implements StatementVisitor{ "metafactory", mt.toMethodDescriptorString(), false); String methodName = "lambda$new$" + this.lamCounter; // Type erasure - Type arg1 = Type.getMethodType(lamDesc.getDesc()); + Type arg1 = Type.getMethodType(lamDesc); // real Type - Type arg3 = Type.getMethodType(lamDesc.getDesc()); + Type arg3 = Type.getMethodType(lamDesc); int staticOrSpecial=0; int staticOrInstance=0; @@ -197,12 +200,12 @@ public class BytecodeGenMethod implements StatementVisitor{ Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(),false); // Descriptor of functional interface methode - Descriptor fiMethodDesc = new Descriptor(kindOfLambda.getArgumentList(), lambdaExpression.getType(),resultSet); - + SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); // Desc: (this/nothing)TargetType - mv.visitInvokeDynamicInsn("apply", fiMethodDesc.getDesc(), bootstrap, + String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet)); + mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3); - + MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); @@ -274,17 +277,18 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.receiver.accept(this); methodCall.arglist.accept(this); - Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType(),resultSet); + MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType()); + String mDesc = method.accept(new DescriptorToString(resultSet)); System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); // is methodCall.receiver functional Interface)? if(varsFunInterface.contains(methodCall.receiver.getType())) { mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc.getDesc(), false); + methodCall.name, mDesc, false); }else { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc.getDesc(), isInterface); + methodCall.name, mDesc, isInterface); } // test // if(!methodCall.getType().toString().equals("V")) { @@ -303,7 +307,7 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.arglist.accept(this); String d = "("; for(Expression e : methodCall.arglist.getArguments()) { - d = d + "L"+e.getType().toString().replace(".", "/") + ";"; + d = d + "L"+getResolvedType(e.getType()) + ";"; } d += ")V"; @@ -339,7 +343,7 @@ public class BytecodeGenMethod implements StatementVisitor{ System.out.println("In StaticClassName: "); // mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"), // staticClassName.toString(), staticClassName.getType().toString(), false); - mv.visitFieldInsn(Opcodes.GETSTATIC, staticClassName.getType().toString().replace(".", "/"), + mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), fieldName, fieldDesc); } @@ -379,7 +383,7 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Literal literal) { // value? - mv.visitLdcInsn(literal.getType().toString()); + mv.visitLdcInsn(getResolvedType(literal.getType())); } @Override @@ -399,8 +403,8 @@ public class BytecodeGenMethod implements StatementVisitor{ // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); this.rightSideTemp.accept(this); - mv.visitFieldInsn(Opcodes.PUTFIELD, assignLeftSide.field.receiver.getType().toString(), - assignLeftSide.field.fieldVarName, assignLeftSide.field.getType().toString()); + mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), + assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType())); } @Override diff --git a/src/de/dhbwstuttgart/bytecode/Descriptor.java b/src/de/dhbwstuttgart/bytecode/Descriptor.java deleted file mode 100644 index 3b024d71..00000000 --- a/src/de/dhbwstuttgart/bytecode/Descriptor.java +++ /dev/null @@ -1,112 +0,0 @@ -package de.dhbwstuttgart.bytecode; - -import java.util.List; -import java.util.Iterator; - -import de.dhbwstuttgart.exceptions.NotImplementedException; -import de.dhbwstuttgart.syntaxtree.Constructor; -import de.dhbwstuttgart.syntaxtree.FormalParameter; -import de.dhbwstuttgart.syntaxtree.Method; -import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; -import de.dhbwstuttgart.syntaxtree.statement.Expression; -import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; -import de.dhbwstuttgart.syntaxtree.type.*; -import de.dhbwstuttgart.typeinference.result.ResultSet; - -public class Descriptor { - String desc; - - public Descriptor(Method method, ResultSet resultSet) { - desc = "("; - Iterator itr = method.getParameterList().iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; - } - desc = addReturnType(desc,method.getReturnType(), resultSet); - - - } - - private class TypeToDescriptor implements TypeVisitor{ - - @Override - public String visit(RefType refType) { - return refType.getName().toString().replace(".", "/"); - } - - @Override - public String visit(SuperWildcardType superWildcardType) { - throw new NotImplementedException(); - } - - @Override - public String visit(TypePlaceholder typePlaceholder) { - return typePlaceholder.toString(); - } - - @Override - public String visit(ExtendsWildcardType extendsWildcardType) { - throw new NotImplementedException(); - } - - @Override - public String visit(GenericRefType genericRefType) { - return genericRefType.getParsedName(); - } - } - - private String addReturnType(String desc2, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { - System.out.println("DescType = "+returnType.toString()); - if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ - desc = desc + ")V"; - }else { - desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; - } - return desc; - } - - public Descriptor(Constructor constructor, ResultSet resultSet) { - desc = "("; - Iterator itr = constructor.getParameterList().iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = desc + ")V"; - } - - public Descriptor(LambdaExpression lambdaExpr, ResultSet resultSet) { - desc = "("; - Iterator itr = lambdaExpr.params.iterator(); - while(itr.hasNext()) { - FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = addReturnType(desc, lambdaExpr.getReturnType(), resultSet); - } - - public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { - desc = "("; - for(Expression e : argList.getArguments()) { - desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.toString().replace(".", "/") + ";"; - } - desc = addReturnType(desc, returnType, resultSet); - - } - - public Descriptor(List argumentList,RefTypeOrTPHOrWildcardOrGeneric returnType ,ResultSet resultSet) { - desc = "("; - Iterator itr = argumentList.iterator(); - while(itr.hasNext()) { - RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); - desc = desc + "L"+resultSet.resolveType(rt).resolvedType.toString().replace(".", "/")+";"; - } - desc = desc + ")"+"L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";"; - } - - public String getDesc() { - return this.desc; - } - -} diff --git a/src/de/dhbwstuttgart/bytecode/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java new file mode 100644 index 00000000..044218e4 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java @@ -0,0 +1,85 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.Iterator; + +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.statement.Expression; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +public class DescriptorToString implements DescriptorVisitor{ + ResultSet resultSet; + + public DescriptorToString(ResultSet resultSet) { + this.resultSet = resultSet; + } + + private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { + if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ + desc = desc + ")V"; + }else { + desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + return desc; + } + + @Override + public String visit(NormalMethod method) { + + String desc = "("; + Iterator itr = method.getParameterList().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = addReturnType(desc,method.getReturnType(), resultSet); + return desc; + } + + @Override + public String visit(NormalConstructor constructor) { + String desc = "("; + Iterator itr = constructor.getParameterList().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = desc + ")V"; + return desc; + } + + @Override + public String visit(Lambda lambdaExpression) { + String desc = "("; + Iterator itr = lambdaExpression.getParams().iterator(); + while(itr.hasNext()) { + FormalParameter fp = itr.next(); + desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; + } + desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); + return desc; + } + + @Override + public String visit(SamMethod samMethod) { + String desc = "("; + Iterator itr = samMethod.getArgumentList().iterator(); + while(itr.hasNext()) { + RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); + desc = desc + "L"+resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor())+";"; + } + desc = desc + ")"+"L"+resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; + return desc; + } + + @Override + public String visit(MethodFromMethodCall methodFromMethodCall) { + String desc = "("; + for(Expression e : methodFromMethodCall.argList.getArguments()) { + desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + desc = addReturnType(desc, methodFromMethodCall.returnType, resultSet); + return desc; + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java b/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java new file mode 100644 index 00000000..63198828 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java @@ -0,0 +1,9 @@ +package de.dhbwstuttgart.bytecode; + +public interface DescriptorVisitor { + public String visit(NormalMethod method); + public String visit(NormalConstructor constructor); + public String visit(Lambda lambdaExpression); + public String visit(SamMethod samMethod); + public String visit(MethodFromMethodCall methodFromMethodCall); +} diff --git a/src/de/dhbwstuttgart/bytecode/Lambda.java b/src/de/dhbwstuttgart/bytecode/Lambda.java new file mode 100644 index 00000000..283b7393 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/Lambda.java @@ -0,0 +1,25 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class Lambda { + private LambdaExpression lambdaExpression; + + public Lambda(LambdaExpression lambdaExpression) { + this.lambdaExpression = lambdaExpression; + } + + public ParameterList getParams() { + return lambdaExpression.params; + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return lambdaExpression.getReturnType(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java new file mode 100644 index 00000000..034e2abf --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java @@ -0,0 +1,18 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class MethodFromMethodCall { + ArgumentList argList; + RefTypeOrTPHOrWildcardOrGeneric returnType; + + public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType) { + this.argList = argList; + this.returnType = returnType; + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/NormalConstructor.java b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java new file mode 100644 index 00000000..d029d21e --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java @@ -0,0 +1,20 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.ParameterList; + +public class NormalConstructor { + private Constructor constructor; + + public NormalConstructor(Constructor constructor) { + this.constructor = constructor; + } + + public ParameterList getParameterList() { + return constructor.getParameterList(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/NormalMethod.java b/src/de/dhbwstuttgart/bytecode/NormalMethod.java new file mode 100644 index 00000000..2dd81d78 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/NormalMethod.java @@ -0,0 +1,29 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class NormalMethod { + private Method method; + + public NormalMethod(Method method) { + this.method = method; + } + + public Method getMethod() { + return method; + } + + public ParameterList getParameterList() { + return method.getParameterList(); + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return method.getType(); + } + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/SamMethod.java b/src/de/dhbwstuttgart/bytecode/SamMethod.java new file mode 100644 index 00000000..9cf039a2 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/SamMethod.java @@ -0,0 +1,31 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.List; + +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +public class SamMethod { + private List argumentList; + private RefTypeOrTPHOrWildcardOrGeneric returnType; + + public SamMethod(List argumentList, RefTypeOrTPHOrWildcardOrGeneric returnType) { + this.argumentList = argumentList; + this.returnType = returnType; + } + + public List getArgumentList() { + return argumentList; + } + + + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return returnType; + } + + + + public String accept(DescriptorVisitor descVisitor) { + return descVisitor.visit(this); + } +} diff --git a/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java b/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java new file mode 100644 index 00000000..5271e63d --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java @@ -0,0 +1,37 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.TypeVisitor; + +public class TypeToDescriptor implements TypeVisitor{ + + @Override + public String visit(RefType refType) { + return refType.getName().toString().replace(".", "/"); + } + + @Override + public String visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(TypePlaceholder typePlaceholder) { + return typePlaceholder.toString().replace(".", "/"); + } + + @Override + public String visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(GenericRefType genericRefType) { + return genericRefType.getParsedName().replace(".", "/"); + } +} \ No newline at end of file diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index f43a0740..39ff5084 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -29,7 +29,7 @@ public class JavaTXCompilerTest { @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "Generics"; + String fileName = "Faculty"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); From 3c732346d907ae5b59e7aece1975fa29ff40baeb Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Sat, 6 Jan 2018 09:38:53 +0100 Subject: [PATCH 34/42] ASPParameterlist erzeugt auch paramNum --- pom.xml | 5 +++++ src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/pom.xml b/pom.xml index 6b0f2fba..9cce2d99 100644 --- a/pom.xml +++ b/pom.xml @@ -22,6 +22,11 @@ antlr4 4.7 + + commons-io + commons-io + 2.6 + com.google.guava guava diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java index f0c06744..46eed10a 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java @@ -11,11 +11,13 @@ import java.util.Set; public class ASPParameterList { private final static String ASP_PARAMLIST_NAME = "param"; + private final static String ASP_PARAMLISTNUMERATION_NAME = "paramNum"; private final static String ASP_PARAMLIST_END_POINTER = "null"; public final String name; private final List types; public ASPParameterList(List types, ASPWriter writer){ + int paramNum = 0; this.types = types; if(types.size() == 0){ name = ASP_PARAMLIST_END_POINTER; @@ -30,6 +32,8 @@ public class ASPParameterList { if(! it.hasNext())nextPointer = ASP_PARAMLIST_END_POINTER; param += nextPointer; writer.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); + writer.add(new ASPStatement(ASP_PARAMLISTNUMERATION_NAME + "(" + name + "," +t + "," + paramNum + ")")); + paramNum++; //paramDefinitions.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); } } From 19a1ef40244e76c117a7f0ad3bab406bb7f54733 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 10 Jan 2018 10:53:07 +0100 Subject: [PATCH 35/42] =?UTF-8?q?Erste=20lauff=C3=A4hige=20aber=20unvollst?= =?UTF-8?q?=C3=A4ndige=20Version=20des=20UnifyWithoutWildcards?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/sat/asp/Clingo.java | 46 +++++++++++++++++++ .../dhbwstuttgart/sat/asp/model/ASPRule.java | 24 ++++++++++ .../dhbwstuttgart/sat/asp/model/ASPType.java | 4 -- .../sat/asp/parser/ASPParser.java | 17 +++++++ .../asp/parser/model/ParsedASPStatement.java | 7 +++ .../sat/asp/{ => writer}/ASPGenerator.java | 8 +--- .../sat/asp/{ => writer}/ASPWriter.java | 6 +-- .../{ => writer}/model/ASPGenericType.java | 7 +-- .../sat/asp/{ => writer}/model/ASPPair.java | 2 +- .../asp/{ => writer}/model/ASPPairEquals.java | 7 +-- .../{ => writer}/model/ASPPairSmaller.java | 11 +++-- .../{ => writer}/model/ASPPairSmallerDot.java | 7 +-- .../{ => writer}/model/ASPParameterList.java | 20 ++++---- .../asp/{ => writer}/model/ASPRefType.java | 7 +-- .../asp/{ => writer}/model/ASPStatement.java | 2 +- .../sat/asp/writer/model/ASPType.java | 4 ++ .../asp/{ => writer}/model/ASPTypeVar.java | 2 +- test/asp/ClingoTest.java | 46 +++++++++++++++++++ test/asp/typeinference/ASPTest.java | 2 +- test/asp/unifywithoutwildcards/ASPTests.java | 10 ++++ test/typeinference/JavaTXCompilerTest.java | 15 ------ 21 files changed, 193 insertions(+), 61 deletions(-) create mode 100644 src/de/dhbwstuttgart/sat/asp/Clingo.java create mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPRule.java delete mode 100644 src/de/dhbwstuttgart/sat/asp/model/ASPType.java create mode 100644 src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java create mode 100644 src/de/dhbwstuttgart/sat/asp/parser/model/ParsedASPStatement.java rename src/de/dhbwstuttgart/sat/asp/{ => writer}/ASPGenerator.java (94%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/ASPWriter.java (67%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPGenericType.java (53%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPPair.java (90%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPPairEquals.java (55%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPPairSmaller.java (51%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPPairSmallerDot.java (55%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPParameterList.java (59%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPRefType.java (68%) rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPStatement.java (91%) create mode 100644 src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java rename src/de/dhbwstuttgart/sat/asp/{ => writer}/model/ASPTypeVar.java (83%) create mode 100644 test/asp/ClingoTest.java create mode 100644 test/asp/unifywithoutwildcards/ASPTests.java diff --git a/src/de/dhbwstuttgart/sat/asp/Clingo.java b/src/de/dhbwstuttgart/sat/asp/Clingo.java new file mode 100644 index 00000000..85f6dc56 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/Clingo.java @@ -0,0 +1,46 @@ +package de.dhbwstuttgart.sat.asp; + + +import org.apache.commons.io.IOUtils; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class Clingo { + private final List input; + private static final List programFiles = new ArrayList<>(); + static{ + programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/basis.lp")); + programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/subst.lp")); + programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/reduce1.lp")); + programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/reduce2.lp")); + programFiles.add(new File("/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards/unify.lp")); + } + + public Clingo(List inputFiles){ + this.input = inputFiles; + } + + public String runClingo() throws IOException, InterruptedException { + String pathToClingo = + "/home/janulrich/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/clingo-5.2.1-linux-x86_64/clingo"; + List commands = new ArrayList<>(); + commands.add(pathToClingo); + commands.add("--outf=2"); //use JSON-Output + for(File file : input){ + commands.add(file.getPath()); + } + commands.addAll(programFiles.stream().map(f->f.getPath()).collect(Collectors.toList())); + Process clingo = new ProcessBuilder( commands.toArray(new String[0])).start(); + InputStream output = clingo.getInputStream(); + clingo.waitFor(); + String result = IOUtils.toString(output, StandardCharsets.UTF_8); + return result; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPRule.java b/src/de/dhbwstuttgart/sat/asp/model/ASPRule.java new file mode 100644 index 00000000..41237547 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/model/ASPRule.java @@ -0,0 +1,24 @@ +package de.dhbwstuttgart.sat.asp.model; + +public enum ASPRule { + ASP_GENERIC_TYPE_NAME("genericType"), + ASP_PAIR_EQUALS_NAME("equals"), + ASP_PAIR_SMALLER_NAME("smaller"), + ASP_PAIR_SMALLER_DOT_NAME("smallerDot"), + ASP_PARAMLIST_NAME("param"), + ASP_PARAMLISTNUMERATION_NAME("paramNum"), + ASP_PARAMLIST_END_POINTER("null"), + ASP_TYPE("type") + ; + + private final String text; + + private ASPRule(final String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPType.java b/src/de/dhbwstuttgart/sat/asp/model/ASPType.java deleted file mode 100644 index e703596c..00000000 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPType.java +++ /dev/null @@ -1,4 +0,0 @@ -package de.dhbwstuttgart.sat.asp.model; - -public interface ASPType { -} diff --git a/src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java b/src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java new file mode 100644 index 00000000..c7be7dbc --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java @@ -0,0 +1,17 @@ +package de.dhbwstuttgart.sat.asp.parser; + +import de.dhbwstuttgart.typeinference.result.ResultPair; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +import java.util.HashSet; +import java.util.Set; + +public class ASPParser { + ResultSet parse(String result){ + Set ret = new HashSet<>(); + for(String pair : result.split(",")){ + + } + return new ResultSet(ret); + } +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/sat/asp/parser/model/ParsedASPStatement.java b/src/de/dhbwstuttgart/sat/asp/parser/model/ParsedASPStatement.java new file mode 100644 index 00000000..614bddb0 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/parser/model/ParsedASPStatement.java @@ -0,0 +1,7 @@ +package de.dhbwstuttgart.sat.asp.parser.model; + +public class ParsedASPStatement { + public ParsedASPStatement(String statement){ + + } +} diff --git a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java similarity index 94% rename from src/de/dhbwstuttgart/sat/asp/ASPGenerator.java rename to src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java index 1b942ad0..002e3c7f 100644 --- a/src/de/dhbwstuttgart/sat/asp/ASPGenerator.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java @@ -1,9 +1,8 @@ -package de.dhbwstuttgart.sat.asp; +package de.dhbwstuttgart.sat.asp.writer; -import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.scope.JavaClassName; -import de.dhbwstuttgart.sat.asp.model.*; +import de.dhbwstuttgart.sat.asp.writer.model.*; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; @@ -11,13 +10,10 @@ import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.Pair; -import de.dhbwstuttgart.typeinference.unify.model.UnifyType; -import java.sql.Ref; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Optional; public class ASPGenerator { ASPWriter writer = new ASPWriter(); diff --git a/src/de/dhbwstuttgart/sat/asp/ASPWriter.java b/src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java similarity index 67% rename from src/de/dhbwstuttgart/sat/asp/ASPWriter.java rename to src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java index 4d33cbbf..450950d9 100644 --- a/src/de/dhbwstuttgart/sat/asp/ASPWriter.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java @@ -1,8 +1,6 @@ -package de.dhbwstuttgart.sat.asp; +package de.dhbwstuttgart.sat.asp.writer; -import de.dhbwstuttgart.sat.asp.model.ASPRefType; -import de.dhbwstuttgart.sat.asp.model.ASPStatement; -import de.dhbwstuttgart.sat.asp.model.ASPType; +import de.dhbwstuttgart.sat.asp.writer.model.ASPStatement; import java.util.HashSet; diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPGenericType.java similarity index 53% rename from src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPGenericType.java index 26e6ea02..57619edf 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPGenericType.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPGenericType.java @@ -1,7 +1,8 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; + +import de.dhbwstuttgart.sat.asp.model.ASPRule; public class ASPGenericType implements ASPType{ - public static final String ASP_GENERIC_TYPE_NAME = "genericType"; private final String name; public ASPGenericType(String name){ @@ -9,6 +10,6 @@ public class ASPGenericType implements ASPType{ } public String toString(){ - return ASP_GENERIC_TYPE_NAME + "(" + name + ")"; + return ASPRule.ASP_GENERIC_TYPE_NAME + "(" + name + ")"; } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPair.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java similarity index 90% rename from src/de/dhbwstuttgart/sat/asp/model/ASPPair.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java index bbd3ff3f..662f995c 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPPair.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java @@ -1,4 +1,4 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; public abstract class ASPPair { public final ASPType leftSide; diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java similarity index 55% rename from src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java index b67920bd..8806f2ce 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPPairEquals.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java @@ -1,13 +1,14 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; + +import de.dhbwstuttgart.sat.asp.model.ASPRule; public class ASPPairEquals extends ASPPair{ - private final static String ASP_PAIR_EQUALS_NAME = "equals"; public ASPPairEquals(ASPType ls, ASPType rs){ super(ls, rs); } @Override protected String getRuleName() { - return ASP_PAIR_EQUALS_NAME; + return ASPRule.ASP_PAIR_EQUALS_NAME.toString(); } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java similarity index 51% rename from src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java index 882054cc..f57170f6 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmaller.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java @@ -1,13 +1,16 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; + +import de.dhbwstuttgart.sat.asp.model.ASPRule; + +import java.util.Map; public class ASPPairSmaller extends ASPPair{ - private final static String ASP_PAIR_SMALLER_NAME = "smaller"; public ASPPairSmaller(ASPType ls, ASPType rs){ super(ls, rs); } @Override protected String getRuleName() { - return ASP_PAIR_SMALLER_NAME; + return ASPRule.ASP_PAIR_SMALLER_NAME.toString(); } -} +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java similarity index 55% rename from src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java index 0e6598c1..e8482bfc 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPPairSmallerDot.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java @@ -1,13 +1,14 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; + +import de.dhbwstuttgart.sat.asp.model.ASPRule; public class ASPPairSmallerDot extends ASPPair{ - private final static String ASP_PAIR_SMALLER_NAME = "smallerDot"; public ASPPairSmallerDot(ASPType ls, ASPType rs){ super(ls, rs); } @Override protected String getRuleName() { - return ASP_PAIR_SMALLER_NAME; + return ASPRule.ASP_PAIR_SMALLER_DOT_NAME.toString(); } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java similarity index 59% rename from src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java index 46eed10a..3c176e49 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPParameterList.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java @@ -1,18 +1,14 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; -import de.dhbwstuttgart.sat.asp.ASPGenerator; -import de.dhbwstuttgart.sat.asp.ASPWriter; +import de.dhbwstuttgart.sat.asp.model.ASPRule; +import de.dhbwstuttgart.sat.asp.writer.ASPGenerator; +import de.dhbwstuttgart.sat.asp.writer.ASPWriter; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; -import java.util.HashSet; import java.util.Iterator; import java.util.List; -import java.util.Set; public class ASPParameterList { - private final static String ASP_PARAMLIST_NAME = "param"; - private final static String ASP_PARAMLISTNUMERATION_NAME = "paramNum"; - private final static String ASP_PARAMLIST_END_POINTER = "null"; public final String name; private final List types; @@ -20,7 +16,7 @@ public class ASPParameterList { int paramNum = 0; this.types = types; if(types.size() == 0){ - name = ASP_PARAMLIST_END_POINTER; + name = ASPRule.ASP_PARAMLIST_END_POINTER.toString(); }else{ name = newName(); String nextPointer = name; @@ -29,10 +25,10 @@ public class ASPParameterList { ASPType t = it.next(); String param = nextPointer + "," + t.toString() + ","; nextPointer = newName(); - if(! it.hasNext())nextPointer = ASP_PARAMLIST_END_POINTER; + if(! it.hasNext())nextPointer = ASPRule.ASP_PARAMLIST_END_POINTER.toString(); param += nextPointer; - writer.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); - writer.add(new ASPStatement(ASP_PARAMLISTNUMERATION_NAME + "(" + name + "," +t + "," + paramNum + ")")); + writer.add(new ASPStatement(ASPRule.ASP_PARAMLIST_NAME + "(" + param + ")")); + writer.add(new ASPStatement(ASPRule.ASP_PARAMLISTNUMERATION_NAME + "(" + name + "," +t + "," + paramNum + ")")); paramNum++; //paramDefinitions.add(new ASPStatement(ASP_PARAMLIST_NAME + "(" + param + ")")); } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java similarity index 68% rename from src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java index ba318876..6491ff33 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPRefType.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java @@ -1,7 +1,8 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; + +import de.dhbwstuttgart.sat.asp.model.ASPRule; public class ASPRefType implements ASPType { - public static final String ASP_TYPE = "type"; private final ASPParameterList params; private final String name; @@ -15,6 +16,6 @@ public class ASPRefType implements ASPType { } public String toString(){ - return ASP_TYPE + "(" + name +"," + params.name + ")"; + return ASPRule.ASP_TYPE + "(" + name +"," + params.name + ")"; } } diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java similarity index 91% rename from src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java index 8e4a1d35..76bb63e8 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPStatement.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java @@ -1,4 +1,4 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; public class ASPStatement { private final String stmt; diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java new file mode 100644 index 00000000..da694218 --- /dev/null +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java @@ -0,0 +1,4 @@ +package de.dhbwstuttgart.sat.asp.writer.model; + +public interface ASPType { +} diff --git a/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java similarity index 83% rename from src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java rename to src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java index e2f87636..4b07d30b 100644 --- a/src/de/dhbwstuttgart/sat/asp/model/ASPTypeVar.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java @@ -1,4 +1,4 @@ -package de.dhbwstuttgart.sat.asp.model; +package de.dhbwstuttgart.sat.asp.writer.model; public class ASPTypeVar implements ASPType{ private final String name; diff --git a/test/asp/ClingoTest.java b/test/asp/ClingoTest.java new file mode 100644 index 00000000..dbfa70d8 --- /dev/null +++ b/test/asp/ClingoTest.java @@ -0,0 +1,46 @@ +package asp; + +import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.sat.asp.writer.ASPGenerator; +import de.dhbwstuttgart.sat.asp.Clingo; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.unify.model.PairOperator; +import org.junit.Test; + +import java.io.*; +import java.util.*; + +public class ClingoTest { + public static final String rootDirectory = "~/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards"; + public static final String tempDirectory = "/tmp/"; + + @Test + public void test() throws IOException, InterruptedException { + String content = ""; + content = new ASPGenerator(this.getPairs(), this.getFC()).getASP(); + + PrintWriter writer = new PrintWriter(tempDirectory + "test.lp", "UTF-8"); + writer.println(content); + writer.close(); + + Clingo clingo = new Clingo(Arrays.asList(new File(tempDirectory + "test.lp"))); + System.out.println(clingo.runClingo()); + } + + public Collection getFC() { + Set ret = new HashSet<>(); + ret.add(ASTFactory.createObjectClass()); + ret.add(ASTFactory.createClass(java.util.List.class)); + return ret; + } + + public ConstraintSet getPairs() { + ConstraintSet ret = new ConstraintSet<>(); + ret.addUndConstraint(new Pair(TypePlaceholder.fresh(new NullToken()), ASTFactory.createObjectType(), PairOperator.SMALLERDOT)); + return ret; + } +} diff --git a/test/asp/typeinference/ASPTest.java b/test/asp/typeinference/ASPTest.java index 5074e4f3..b41d9405 100644 --- a/test/asp/typeinference/ASPTest.java +++ b/test/asp/typeinference/ASPTest.java @@ -1,7 +1,7 @@ package asp.typeinference; import de.dhbwstuttgart.core.JavaTXCompiler; -import de.dhbwstuttgart.sat.asp.ASPGenerator; +import de.dhbwstuttgart.sat.asp.writer.ASPGenerator; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; diff --git a/test/asp/unifywithoutwildcards/ASPTests.java b/test/asp/unifywithoutwildcards/ASPTests.java new file mode 100644 index 00000000..80e7bb78 --- /dev/null +++ b/test/asp/unifywithoutwildcards/ASPTests.java @@ -0,0 +1,10 @@ +package asp.unifywithoutwildcards; + +import org.junit.Test; + +public class ASPTests { + @Test + public void test(){ + + } +} diff --git a/test/typeinference/JavaTXCompilerTest.java b/test/typeinference/JavaTXCompilerTest.java index fbbed9af..f4622954 100644 --- a/test/typeinference/JavaTXCompilerTest.java +++ b/test/typeinference/JavaTXCompilerTest.java @@ -1,29 +1,15 @@ package typeinference; import de.dhbwstuttgart.core.JavaTXCompiler; -import de.dhbwstuttgart.parser.scope.JavaClassName; -import de.dhbwstuttgart.sat.asp.ASPGenerator; -import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.SourceFile; -import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; -import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter; import de.dhbwstuttgart.typedeployment.TypeInsert; import de.dhbwstuttgart.typedeployment.TypeInsertFactory; -import de.dhbwstuttgart.typeinference.constraints.Constraint; -import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; -import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.result.ResultSet; -import de.dhbwstuttgart.typeinference.typeAlgo.TYPE; -import de.dhbwstuttgart.typeinference.unify.TypeUnify; -import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; -import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import org.junit.Test; import java.io.File; import java.io.IOException; -import java.net.URL; -import java.net.URLClassLoader; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.Files; @@ -32,7 +18,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.stream.Collectors; public class JavaTXCompilerTest { From 268056542b7e3ac368cf9057ceecd679c3a0d62d Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Wed, 10 Jan 2018 11:36:29 +0100 Subject: [PATCH 36/42] =?UTF-8?q?erzeugt=20bytecode=20f=C3=BCr=20generics?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 122 ++++++++++++-- .../bytecode/BytecodeGenMethod.java | 47 ++++-- .../bytecode/DescriptorToString.java | 73 ++++++++- .../bytecode/MethodFromMethodCall.java | 29 +++- .../bytecode/NormalConstructor.java | 21 ++- .../dhbwstuttgart/bytecode/NormalMethod.java | 28 +++- src/de/dhbwstuttgart/bytecode/Signature.java | 155 ++++++++++++++++++ .../dhbwstuttgart/bytecode/TypeToString.java | 38 +++++ test/bytecode/Generics.jav | 2 + test/bytecode/Generics2.jav | 6 + test/bytecode/Generics2Test.java | 7 + test/bytecode/GenericsTest.java | 7 + test/bytecode/InterfaceTest.java | 7 + test/bytecode/JavaTXCompilerTest.java | 36 ++-- test/bytecode/LamAssign.jav | 4 + test/bytecode/LamAssignTest.java | 7 + 16 files changed, 526 insertions(+), 63 deletions(-) create mode 100644 src/de/dhbwstuttgart/bytecode/Signature.java create mode 100644 src/de/dhbwstuttgart/bytecode/TypeToString.java create mode 100644 test/bytecode/Generics2.jav create mode 100644 test/bytecode/Generics2Test.java create mode 100644 test/bytecode/GenericsTest.java create mode 100644 test/bytecode/InterfaceTest.java create mode 100644 test/bytecode/LamAssignTest.java diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index 1b6ef47b..f1994c20 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.bytecode; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -8,6 +9,9 @@ import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; +import org.objectweb.asm.Type; +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.*; @@ -16,6 +20,7 @@ import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -23,7 +28,6 @@ import de.dhbwstuttgart.typeinference.result.ResultSet; public class BytecodeGen implements ASTVisitor { ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); -// String methDesc; String type; @@ -34,6 +38,12 @@ public class BytecodeGen implements ASTVisitor { // stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... HashMap paramsAndLocals = new HashMap<>(); + // stores generics and their bounds of class + HashMap genericsAndBounds = new HashMap<>(); + // stores generics and their bounds of method + HashMap genericsAndBoundsMethod = new HashMap<>(); + + HashMap methodParamsAndTypes = new HashMap<>(); byte[] bytecode; HashMap classFiles; @@ -45,14 +55,19 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(SourceFile sourceFile) { for(ClassOrInterface cl : sourceFile.getClasses()) { - isInterface = (cl.getModifiers()&512)==512; - System.out.println("IS Interface = "+"modifiers= "+cl.getModifiers()+" ->"+(cl.getModifiers()&512) + isInterface); BytecodeGen classGen = new BytecodeGen(classFiles, resultSet); cl.accept(classGen); + System.out.println("In CLASS: "+(cl.getClassName().toString())); classGen.writeClass(cl.getClassName().toString()); } } - + + /** + * Associates the bytecode of the class that was build with the classWriter {@link #cw} + * with the class name in the map {@link #classFiles} + * + * @param name name of the class with which the the bytecode is to be associated + */ private void writeClass(String name) { bytecode = cw.toByteArray(); classFiles.put(name, bytecode); @@ -62,12 +77,30 @@ public class BytecodeGen implements ASTVisitor { public HashMap getClassFiles() { return classFiles; } + + @Override public void visit(ClassOrInterface classOrInterface) { className = classOrInterface.getClassName().toString(); - // access flages?? - cw.visit(Opcodes.V1_8, classOrInterface.getModifiers()+Opcodes.ACC_SUPER, classOrInterface.getClassName().toString() - , null, classOrInterface.getSuperClass().toString().replace(".", "/"), null); + + isInterface = (classOrInterface.getModifiers()&512)==512; + System.out.println("IS Interface = "+"modifiers= "+classOrInterface.getModifiers()+" ->"+(classOrInterface.getModifiers()&512) + isInterface); + + int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER; + String sig = null; + /* if class has generics then creates signature + * Signature looks like: + * Superclass + */ + if(classOrInterface.getGenerics().iterator().hasNext()) { + Signature signature = new Signature(classOrInterface, genericsAndBounds); + + System.out.println(signature.toString()); + sig = signature.toString(); + } + // needs implemented Interfaces? + cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString() + , sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null); // for each field in the class for(Field f : classOrInterface.getFieldDecl()) { @@ -85,17 +118,34 @@ public class BytecodeGen implements ASTVisitor { } cw.visitSource(classOrInterface.getClassName().toString()+".jav", null); } - + @Override public void visit(Constructor field) { - NormalConstructor constructor = new NormalConstructor(field); - String desc = constructor.accept(new DescriptorToString(resultSet)); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, null, null); + field.getParameterList().accept(this); + + String desc = null; + boolean hasGen = false; + for(String paramName : methodParamsAndTypes.keySet()) { + genericsAndBounds.containsKey(paramName); + hasGen = true; + } + String sig = null; + if(hasGen) { + System.out.println("IM IN CONST HAS Gens"); + Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes); + sig = signature.toString(); + System.out.println(sig); + } + NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen); + desc = constructor.accept(new DescriptorToString(resultSet)); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, sig, null); mv.visitCode(); System.out.println("-----Constructor-----"); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc,cw,isInterface); - - mv.visitInsn(Opcodes.RETURN); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw, + genericsAndBoundsMethod,genericsAndBounds,isInterface); + if(!field.getParameterList().iterator().hasNext()) { + mv.visitInsn(Opcodes.RETURN); + } mv.visitMaxs(0, 0); mv.visitEnd(); } @@ -106,14 +156,48 @@ public class BytecodeGen implements ASTVisitor { // else it will be stored in pos 1 and this will be stored in pos 0 method.getParameterList().accept(this); - NormalMethod meth = new NormalMethod(method); - String methDesc = meth.accept(new DescriptorToString(resultSet)); + String methDesc = null; + + // Method getModifiers() ? + int acc = isInterface?Opcodes.ACC_ABSTRACT:0; System.out.println("-----Method-----"); - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, method.getName(), methDesc, null, null); + + boolean hasGenInParameterList = genericsAndBounds.containsKey(method.getReturnType().acceptTV(new TypeToDescriptor())); + if(!hasGenInParameterList) { + for(String paramName : methodParamsAndTypes.keySet()) { + if(genericsAndBounds.containsKey(paramName)) { + hasGenInParameterList = true; + break; + } + } + } + String sig = null; + boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList; + // Wenn ReturnType has Generics?? Fun1<...> wie testet man das generic hat?? + System.out.println(method.getReturnType().acceptTV(new TypeToString())); +// if(method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { +// Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet); +// sig = signature.toString(); +// System.out.println(sig); +// } + /* if method has generics, create signature */ + if(hasGen) { + // resultset hier zum testen + Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet); + sig = signature.toString(); + System.out.println(sig); + + } + + NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen); + methDesc = meth.accept(new DescriptorToString(resultSet)); + System.out.println("methDesc" + methDesc); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null); + mv.visitCode(); - BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc,cw,isInterface); + BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,genericsAndBounds,genericsAndBounds,isInterface); mv.visitMaxs(0, 0); mv.visitEnd(); } @@ -121,11 +205,13 @@ public class BytecodeGen implements ASTVisitor { @Override public void visit(ParameterList formalParameters) { paramsAndLocals = new HashMap<>(); + methodParamsAndTypes = new HashMap<>(); Iterator itr = formalParameters.iterator(); int i = 1; while(itr.hasNext()) { FormalParameter fp = itr.next(); paramsAndLocals.put(fp.getName(), i); + methodParamsAndTypes.put(fp.getName(), fp.getType()); fp.accept(this); i++; } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index ffdf1450..5368cf93 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -21,6 +21,7 @@ import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Null; +import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -29,12 +30,13 @@ public class BytecodeGenMethod implements StatementVisitor{ private Method m; private MethodVisitor mv; private HashMap paramsAndLocals = new HashMap<>(); - private String desc; private String className; private int lamCounter; private ClassWriter cw; private ResultSet resultSet; private boolean isInterface; + HashMap genericsAndBoundsMethod; + private HashMap genericsAndBounds; //for tests ** private String fieldName; @@ -46,8 +48,9 @@ public class BytecodeGenMethod implements StatementVisitor{ private ArrayList varsFunInterface; - public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, - String desc, ClassWriter cw, boolean isInterface) { + public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, + HashMap paramsAndLocals, ClassWriter cw, + HashMap genericsAndBoundsMethod, HashMap genericsAndBounds, boolean isInterface) { this.where = "<<<<<< NORMAL METHOD >>>>>>"; @@ -56,29 +59,32 @@ public class BytecodeGenMethod implements StatementVisitor{ this.m = m; this.mv = mv; this.paramsAndLocals = paramsAndLocals; - this.desc = desc; this.cw = cw; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.genericsAndBounds = genericsAndBounds; this.isInterface = isInterface; this.lamCounter = -1; this.varsFunInterface = new ArrayList<>(); System.out.println("PARAMS = "+this.paramsAndLocals.size()); - this.m.block.accept(this); - System.out.println("PARAMS = "+this.paramsAndLocals.size()); - for(int i = 0; i(); @@ -114,7 +120,7 @@ public class BytecodeGenMethod implements StatementVisitor{ superCall.receiver.accept(this); superCall.arglist.accept(this); // mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, desc,isInterface); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface); } // ?? @@ -151,9 +157,6 @@ public class BytecodeGenMethod implements StatementVisitor{ assign.rightSide.accept(this); assign.lefSide.accept(this); } - - - } @Override @@ -165,7 +168,9 @@ public class BytecodeGenMethod implements StatementVisitor{ public void visit(LambdaExpression lambdaExpression) { System.out.println("\n++ In Lambda: "); this.lamCounter++; - + + System.out.println("Lam Hs Gens: " + lambdaExpression.getGenerics().iterator().hasNext()); + System.out.println("Lam Hs Gens: " + lambdaExpression.getReturnType().acceptTV(new TypeToString())); Lambda lam = new Lambda(lambdaExpression); String lamDesc = lam.accept(new DescriptorToString(resultSet)); //Call site, which, when invoked, returns an instance of the functional interface to which @@ -177,7 +182,9 @@ public class BytecodeGenMethod implements StatementVisitor{ Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", mt.toMethodDescriptorString(), false); String methodName = "lambda$new$" + this.lamCounter; +// String typeErasure = "(Ljava/lang/Object;)Ljava/lang/Object;"; // Type erasure +// Type arg1 = Type.getMethodType(typeErasure); Type arg1 = Type.getMethodType(lamDesc); // real Type Type arg3 = Type.getMethodType(lamDesc); @@ -209,7 +216,7 @@ public class BytecodeGenMethod implements StatementVisitor{ MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); - new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,arg3.toString(),indexOfFirstParamLam,isInterface); + new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface); mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); @@ -277,7 +284,8 @@ public class BytecodeGenMethod implements StatementVisitor{ methodCall.receiver.accept(this); methodCall.arglist.accept(this); - MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType()); + MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), + genericsAndBoundsMethod,genericsAndBounds); String mDesc = method.accept(new DescriptorToString(resultSet)); System.out.println("is Vars empty: "+varsFunInterface.isEmpty()); @@ -287,6 +295,7 @@ public class BytecodeGenMethod implements StatementVisitor{ mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name, mDesc, false); }else { + System.out.println("mDesc = " + mDesc); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name, mDesc, isInterface); } @@ -397,6 +406,8 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(AssignToField assignLeftSide) { +// temporäre Lösung für testen, bis ich weiss wie man funktionale +// interfaces erkennt if(isRightSideALambda) varsFunInterface.add(assignLeftSide.field.getType()); // Loads the an object reference from the local variable diff --git a/src/de/dhbwstuttgart/bytecode/DescriptorToString.java b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java index 044218e4..481dbc5d 100644 --- a/src/de/dhbwstuttgart/bytecode/DescriptorToString.java +++ b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java @@ -30,9 +30,37 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = method.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + if(method.hasGen()) { + String fpDesc = fp.getType().acceptTV(new TypeToDescriptor()); + if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) { + desc += "L"+method.getGenericsAndBoundsMethod().get(fpDesc)+ ";"; + }else if(method.getGenericsAndBounds().containsKey(fpDesc)){ + desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";"; + }else { + desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + }else { + desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } } - desc = addReturnType(desc,method.getReturnType(), resultSet); + + if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals("void")) { + desc += ")V"; + }else { + if(method.hasGen()) { + String ret = method.getReturnType().acceptTV(new TypeToDescriptor()); + if(method.getGenericsAndBoundsMethod().containsKey(ret)) { + desc += ")L"+method.getGenericsAndBoundsMethod().get(ret)+ ";"; + }else if(method.getGenericsAndBounds().containsKey(ret)){ + desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";"; + }else { + desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + }else { + desc += ")" + "L"+resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + } +// desc = addReturnType(desc,method.getReturnType(), resultSet); return desc; } @@ -42,7 +70,19 @@ public class DescriptorToString implements DescriptorVisitor{ Iterator itr = constructor.getParameterList().iterator(); while(itr.hasNext()) { FormalParameter fp = itr.next(); - desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + if(constructor.hasGen()) { + System.out.println("Cons has Gens"); + String fpDesc = fp.getType().acceptTV(new TypeToDescriptor()); + System.out.println(fpDesc); + if(constructor.getGenericsAndBounds().containsKey(fpDesc)){ + desc += "L"+constructor.getGenericsAndBounds().get(fpDesc)+ ";"; + }else { + desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + }else { + System.out.println("Cons has NOT Gens"); + desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } } desc = desc + ")V"; return desc; @@ -56,6 +96,7 @@ public class DescriptorToString implements DescriptorVisitor{ FormalParameter fp = itr.next(); desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";"; } + System.out.println("LamReturnType: "+lambdaExpression.getReturnType().acceptTV(new TypeToString())); desc = addReturnType(desc, lambdaExpression.getReturnType(), resultSet); return desc; } @@ -75,10 +116,30 @@ public class DescriptorToString implements DescriptorVisitor{ @Override public String visit(MethodFromMethodCall methodFromMethodCall) { String desc = "("; - for(Expression e : methodFromMethodCall.argList.getArguments()) { - desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + for(Expression e : methodFromMethodCall.getArgList().getArguments()) { + String d = e.getType().acceptTV(new TypeToDescriptor()); + if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) { + desc += "L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(d)+ ";"; + }else if(methodFromMethodCall.getGenericsAndBounds().containsKey(d)) { + desc += "L"+methodFromMethodCall.getGenericsAndBounds().get(d)+ ";"; + }else { + desc += "L"+resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } } - desc = addReturnType(desc, methodFromMethodCall.returnType, resultSet); + + if(resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.toString().equals("void")) { + desc += ")V"; + }else { + String ret = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); + if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(ret)) { + desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(ret)+ ";"; + }else if(methodFromMethodCall.getGenericsAndBounds().containsKey(ret)){ + desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(ret)+ ";"; + }else { + desc += ")" + "L"+resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; + } + } +// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet); return desc; } diff --git a/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java index 034e2abf..330b0666 100644 --- a/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java +++ b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java @@ -1,15 +1,38 @@ package de.dhbwstuttgart.bytecode; +import java.util.HashMap; + import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class MethodFromMethodCall { - ArgumentList argList; - RefTypeOrTPHOrWildcardOrGeneric returnType; + private ArgumentList argList; + private RefTypeOrTPHOrWildcardOrGeneric returnType; + private HashMap genericsAndBoundsMethod; + private HashMap genericsAndBounds; - public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType) { + public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType, + HashMap genericsAndBoundsMethod,HashMap genericsAndBounds) { this.argList = argList; this.returnType = returnType; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.genericsAndBounds = genericsAndBounds; + } + + public ArgumentList getArgList() { + return argList; + } + + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { + return returnType; + } + + public HashMap getGenericsAndBoundsMethod(){ + return genericsAndBoundsMethod; + } + + public HashMap getGenericsAndBounds(){ + return genericsAndBounds; } public String accept(DescriptorVisitor descVisitor) { diff --git a/src/de/dhbwstuttgart/bytecode/NormalConstructor.java b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java index d029d21e..d2174fd4 100644 --- a/src/de/dhbwstuttgart/bytecode/NormalConstructor.java +++ b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java @@ -1,15 +1,34 @@ package de.dhbwstuttgart.bytecode; +import java.util.HashMap; + import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.ParameterList; public class NormalConstructor { private Constructor constructor; + private HashMap genericsAndBounds; + private boolean hasGenerics; - public NormalConstructor(Constructor constructor) { + public NormalConstructor(Constructor constructor, boolean hasGenerics) { this.constructor = constructor; + this.hasGenerics = hasGenerics; } + public NormalConstructor(Constructor constructor, HashMap genericsAndBounds, boolean hasGenerics) { + this.constructor = constructor; + this.genericsAndBounds = genericsAndBounds; + this.hasGenerics = hasGenerics; + } + + public HashMap getGenericsAndBounds() { + return genericsAndBounds; + } + + public boolean hasGen() { + return hasGenerics; + } + public ParameterList getParameterList() { return constructor.getParameterList(); } diff --git a/src/de/dhbwstuttgart/bytecode/NormalMethod.java b/src/de/dhbwstuttgart/bytecode/NormalMethod.java index 2dd81d78..3f6bf2b4 100644 --- a/src/de/dhbwstuttgart/bytecode/NormalMethod.java +++ b/src/de/dhbwstuttgart/bytecode/NormalMethod.java @@ -1,14 +1,28 @@ package de.dhbwstuttgart.bytecode; +import java.util.HashMap; + import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; public class NormalMethod { private Method method; + private HashMap genericsAndBounds; + private HashMap genericsAndBoundsMethod; + private boolean hasGenerics; - public NormalMethod(Method method) { + public NormalMethod(Method method, boolean hasGenerics) { this.method = method; + this.hasGenerics = hasGenerics; + } + + public NormalMethod(Method method, HashMap genericsAndBounds, + HashMap genericsAndBoundsMethod,boolean hasGenerics) { + this.method = method; + this.genericsAndBounds = genericsAndBounds; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.hasGenerics = hasGenerics; } public Method getMethod() { @@ -19,10 +33,22 @@ public class NormalMethod { return method.getParameterList(); } + public HashMap getGenericsAndBounds(){ + return genericsAndBounds; + } + + public HashMap getGenericsAndBoundsMethod(){ + return genericsAndBoundsMethod; + } + public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { return method.getType(); } + public boolean hasGen() { + return this.hasGenerics; + } + public String accept(DescriptorVisitor descVisitor) { return descVisitor.visit(this); } diff --git a/src/de/dhbwstuttgart/bytecode/Signature.java b/src/de/dhbwstuttgart/bytecode/Signature.java new file mode 100644 index 00000000..362429a3 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/Signature.java @@ -0,0 +1,155 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.HashMap; +import java.util.Iterator; + +import org.objectweb.asm.signature.SignatureVisitor; +import org.objectweb.asm.signature.SignatureWriter; + +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +public class Signature { + private ClassOrInterface classOrInterface; + private HashMap genericsAndBounds; + private HashMap genericsAndBoundsMethod; + private SignatureWriter sw; + private Constructor constructor; + private Method method; + private HashMap methodParamsAndTypes; + private ResultSet resultSet; + + public Signature(ClassOrInterface classOrInterface, HashMap genericsAndBounds) { + this.classOrInterface = classOrInterface; + this.genericsAndBounds = genericsAndBounds; + sw = new SignatureWriter(); + createSignatureForClassOrInterface(); + } + + public Signature(Constructor constructor, HashMap genericsAndBounds, HashMap methodParamsAndTypes) { + this.constructor = constructor; + this.genericsAndBounds = genericsAndBounds; + this.methodParamsAndTypes = methodParamsAndTypes; + sw = new SignatureWriter(); + createSignatureForConsOrMethod(this.constructor,true); + } + + public Signature(Method method, HashMap genericsAndBoundsMethod, + HashMap methodParamsAndTypes, ResultSet resultSet) { + this.method = method; + this.genericsAndBoundsMethod = genericsAndBoundsMethod; + this.methodParamsAndTypes = methodParamsAndTypes; + this.resultSet = resultSet; + sw = new SignatureWriter(); + createSignatureForConsOrMethod(this.method,false); + } + + /** + * Creates signature for a method or constructor with @see {@link SignatureWriter} + * Signature looks like: + * (params L.. OR T.. Or basistape)ReturnType + * + * @param method method or constructor + * @param isConstructor true if constructor + */ + private void createSignatureForConsOrMethod(Method method, boolean isConstructor) { + Iterator itr = method.getGenerics().iterator(); + // visits all formal type parameter and visits their bounds + while(itr.hasNext()) { + GenericTypeVar g = itr.next(); + getBoundsOfTypeVar(g,genericsAndBoundsMethod); + } + // visits each method-parameter to create the signature + for(String paramName : methodParamsAndTypes.keySet()) { + RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName); + // parameter type deswegen ist true + doVisitParamsOrReturn(t,true); + } + if(isConstructor) { + sw.visitReturnType().visitBaseType('V'); + }else { + RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType(); + // return type deswegen ist false + doVisitParamsOrReturn(returnType, false); + } +// sw.visitEnd(); + } + /** + * Visits parameter type or return type with {@link SignatureVisitor} to create + * the method signature + * @param t type of parameter or return type + * @param isParameterType true if t is type of parameter + */ + private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, boolean isParameterType) { + String type = t.acceptTV(new TypeToString()); + SignatureVisitor sv; + if(isParameterType) { + sv = sw.visitParameterType(); + } + else { + sv = sw.visitReturnType(); + } + switch (type) { + case "RT": + sv.visitClassType(t.acceptTV(new TypeToDescriptor())); + break; + case "GRT": + GenericRefType g = (GenericRefType) t; + sv.visitTypeVariable(g.getParsedName()); + break; + case "TPH": + System.out.println(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor())); +// sv.visitInterface().visitClassType(resultSet.resolveType(t).resolvedType.acceptTV(new TypeToDescriptor())+";"); + + break; + default: + if(!isParameterType) + sv.visitBaseType('V'); + break; + } + } + /** + * Creates signature for class or interface with {@link SignatureWriter} + * Signature looks like: + * superclass + */ + private void createSignatureForClassOrInterface() { + Iterator itr = classOrInterface.getGenerics().iterator(); + + while(itr.hasNext()) { + GenericTypeVar g = itr.next(); + getBoundsOfTypeVar(g,genericsAndBounds); + } + + sw.visitSuperclass().visitClassType(classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()));; + sw.visitEnd(); + } + /** + * Get bounds of type variable + * @param g type variable + * @param genAndBounds + */ + private void getBoundsOfTypeVar(GenericTypeVar g, HashMap genAndBounds) { + sw.visitFormalTypeParameter(g.getParsedName()); + + Iterator bItr = g.getBounds().iterator(); + while(bItr.hasNext()) { + RefTypeOrTPHOrWildcardOrGeneric b =bItr.next(); + String boundDesc = b.acceptTV(new TypeToDescriptor()); + // Ensure that <...> extends java.lang.Object OR ... + sw.visitClassBound().visitClassType(boundDesc); + genAndBounds.put(g.getParsedName(), boundDesc); + } + sw.visitClassBound().visitEnd(); + } + + public String toString() { + return sw.toString(); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/TypeToString.java b/src/de/dhbwstuttgart/bytecode/TypeToString.java new file mode 100644 index 00000000..86d4124a --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/TypeToString.java @@ -0,0 +1,38 @@ +package de.dhbwstuttgart.bytecode; + +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.TypeVisitor; + +public class TypeToString implements TypeVisitor{ + + @Override + public String visit(RefType refType) { + return "RT"; + } + + @Override + public String visit(SuperWildcardType superWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(TypePlaceholder typePlaceholder) { + return "TPH"; + } + + @Override + public String visit(ExtendsWildcardType extendsWildcardType) { + throw new NotImplementedException(); + } + + @Override + public String visit(GenericRefType genericRefType) { + return "GRT"; + } + +} diff --git a/test/bytecode/Generics.jav b/test/bytecode/Generics.jav index 2c7a67b6..bb7b2af5 100644 --- a/test/bytecode/Generics.jav +++ b/test/bytecode/Generics.jav @@ -1,5 +1,7 @@ class Generics { + Generics(B b){ + } B mt1(B b){ return mt1(b); } diff --git a/test/bytecode/Generics2.jav b/test/bytecode/Generics2.jav new file mode 100644 index 00000000..52d5caa2 --- /dev/null +++ b/test/bytecode/Generics2.jav @@ -0,0 +1,6 @@ +class Generics2{ + B m1(B b){ + return b; + } + +} \ No newline at end of file diff --git a/test/bytecode/Generics2Test.java b/test/bytecode/Generics2Test.java new file mode 100644 index 00000000..26e52665 --- /dev/null +++ b/test/bytecode/Generics2Test.java @@ -0,0 +1,7 @@ +package bytecode; + +public class Generics2Test extends JavaTXCompilerTest{ + public Generics2Test() { + this.fileName = "Generics2"; + } +} diff --git a/test/bytecode/GenericsTest.java b/test/bytecode/GenericsTest.java new file mode 100644 index 00000000..cca16129 --- /dev/null +++ b/test/bytecode/GenericsTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class GenericsTest extends JavaTXCompilerTest { + public GenericsTest() { + this.fileName = "Generics"; + } +} diff --git a/test/bytecode/InterfaceTest.java b/test/bytecode/InterfaceTest.java new file mode 100644 index 00000000..ed378127 --- /dev/null +++ b/test/bytecode/InterfaceTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class InterfaceTest extends JavaTXCompilerTest{ + public InterfaceTest() { + this.fileName = "Interface1"; + } +} diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java index 39ff5084..f017e23e 100644 --- a/test/bytecode/JavaTXCompilerTest.java +++ b/test/bytecode/JavaTXCompilerTest.java @@ -25,11 +25,12 @@ public class JavaTXCompilerTest { private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; private static final List filesToTest = new ArrayList<>(); - + + protected String fileName = ""; + @Test public void test() throws IOException, java.lang.ClassNotFoundException { System.out.println(rootDirectory); - String fileName = "Faculty"; filesToTest.add(new File(rootDirectory+fileName+".jav")); System.out.println(rootDirectory+fileName+".jav"); JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); @@ -48,7 +49,7 @@ public class JavaTXCompilerTest { if(pos != -1) { name = f.getName().substring(0, pos); } - this.writeClassFile(bytecode, name); + this.writeClassFile(bytecode); } } @@ -61,20 +62,23 @@ public class JavaTXCompilerTest { return bytecodeGen.getClassFiles(); } - public void writeClassFile(HashMap classFiles, String name) { + public void writeClassFile(HashMap classFiles) { FileOutputStream output; - byte[] bytecode = classFiles.get(name); - try { - System.out.println("generating .class file"); - output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); - output.write(bytecode); - output.close(); - System.out.println(".class file generated"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } + for(String name : classFiles.keySet()) { + byte[] bytecode = classFiles.get(name); + try { + System.out.println("generating"+name+ ".class file"); + output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); + output.write(bytecode); + output.close(); + System.out.println(name+".class file generated"); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } static String readFile(String path, Charset encoding) diff --git a/test/bytecode/LamAssign.jav b/test/bytecode/LamAssign.jav index e522bd3b..3df81780 100644 --- a/test/bytecode/LamAssign.jav +++ b/test/bytecode/LamAssign.jav @@ -7,3 +7,7 @@ class LamAssign { return lam1; } } + +interface Fun1{ + A apply(B b); +} diff --git a/test/bytecode/LamAssignTest.java b/test/bytecode/LamAssignTest.java new file mode 100644 index 00000000..3442c1d1 --- /dev/null +++ b/test/bytecode/LamAssignTest.java @@ -0,0 +1,7 @@ +package bytecode; + +public class LamAssignTest extends JavaTXCompilerTest{ + public LamAssignTest() { + this.fileName = "LamAssign"; + } +} From ab86cc32295c46ad2bae473aeaae4c836405d411 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 10 Jan 2018 12:10:01 +0100 Subject: [PATCH 37/42] RefType.toString(): Ausgabe von Parameterliste implementieren --- src/de/dhbwstuttgart/syntaxtree/type/RefType.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 002e792d..4cf85297 100644 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -6,6 +6,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSetVisitor; import org.antlr.v4.runtime.Token; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; @@ -28,7 +29,15 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric @Override public String toString(){ - return this.name.toString(); + String params = "<"; + Iterator it = parameter.iterator(); + while(it.hasNext()){ + RefTypeOrTPHOrWildcardOrGeneric param = it.next(); + params += param.toString(); + if(it.hasNext())params += ", "; + } + params += ">"; + return this.name.toString() + params; } @Override From 1f5071d4e4d2ac7deaa81fd77e8dd0387db1bb6a Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Fri, 19 Jan 2018 15:24:49 +0100 Subject: [PATCH 38/42] =?UTF-8?q?Methode=20soll=20kein=20Feld=20mehr=20sei?= =?UTF-8?q?n.=20Nicht=20lauff=C3=A4hig!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/syntaxtree/Field.java | 2 +- src/de/dhbwstuttgart/syntaxtree/Method.java | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 421f0ff3..4ee1675e 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -5,7 +5,7 @@ import org.antlr.v4.runtime.Token; import java.util.ArrayList; -public class Field extends SyntaxTreeNode implements TypeScope{ +public class Field extends SyntaxTreeNode { private String name; private RefTypeOrTPHOrWildcardOrGeneric type; diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index 3686fb4e..fd4ad180 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -22,7 +22,7 @@ import de.dhbwstuttgart.syntaxtree.statement.Block; * @author janulrich * */ -public class Method extends Field implements IItemWithOffset +public class Method implements IItemWithOffset, TypeScope { public final Block block; private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken()); @@ -54,4 +54,9 @@ public class Method extends Field implements IItemWithOffset public void accept(ASTVisitor visitor) { visitor.visit(this); } + + @Override + public Token getOffset() { + return null; + } } From 8d12821c681fde205636d83f75b57c013eaa7f29 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Sun, 21 Jan 2018 11:38:55 +0100 Subject: [PATCH 39/42] Methode erbt nicht mehr von Feld --- .../dhbwstuttgart/bytecode/NormalMethod.java | 2 +- .../SyntaxTreeGenerator.java | 7 +++---- .../syntaxtree/AbstractASTWalker.java | 2 +- .../dhbwstuttgart/syntaxtree/Constructor.java | 4 ++-- src/de/dhbwstuttgart/syntaxtree/Field.java | 6 ++++-- src/de/dhbwstuttgart/syntaxtree/Method.java | 18 ++++++++++++++---- .../syntaxtree/factory/ASTFactory.java | 5 ++--- .../syntaxtree/visual/OutputGenerator.java | 2 +- .../typeinference/typeAlgo/TYPEStmt.java | 2 +- 9 files changed, 29 insertions(+), 19 deletions(-) diff --git a/src/de/dhbwstuttgart/bytecode/NormalMethod.java b/src/de/dhbwstuttgart/bytecode/NormalMethod.java index 3f6bf2b4..16e84cc5 100644 --- a/src/de/dhbwstuttgart/bytecode/NormalMethod.java +++ b/src/de/dhbwstuttgart/bytecode/NormalMethod.java @@ -42,7 +42,7 @@ public class NormalMethod { } public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { - return method.getType(); + return method.getReturnType(); } public boolean hasGen() { diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java index c5b135e6..3d9d7aca 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java @@ -139,9 +139,9 @@ public class SyntaxTreeGenerator{ block = stmtGen.convert(body.block()); } if(parentClass.equals(new JavaClassName(name))){ - return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); + return new Constructor(modifiers, name, retType, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations); }else{ - return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); + return new Method(modifiers, name, retType, parameterList,block, gtvDeclarations, header.getStart()); } } @@ -221,10 +221,9 @@ public class SyntaxTreeGenerator{ */ private Constructor generateStandardConstructor(String className, JavaClassName parentClass, RefType superClass, GenericDeclarationList classGenerics, Token offset){ RefType classType = ClassOrInterface.generateTypeOfClass(reg.getName(className), classGenerics, offset); - int modifiers = 0; ParameterList params = new ParameterList(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset); - return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations); + return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset, fieldInitializations); } private RefType convert(Java8Parser.SuperclassContext superclass) { diff --git a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java index d771bd93..8a66629b 100644 --- a/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java +++ b/src/de/dhbwstuttgart/syntaxtree/AbstractASTWalker.java @@ -61,7 +61,7 @@ public abstract class AbstractASTWalker implements ASTVisitor{ } private void visitMethod(Method method){ - method.getType().accept(this); + method.getReturnType().accept(this); method.getParameterList().accept(this); if(method.block != null) method.block.accept(this); diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index bb48be40..a99692bb 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -14,9 +14,9 @@ public class Constructor extends Method { //TODO: Constructor braucht ein super-Statement - public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, + public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor, GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) { - super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); + super(modifier, name, returnType, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset); } diff --git a/src/de/dhbwstuttgart/syntaxtree/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java index 4ee1675e..8a4230e3 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Field.java +++ b/src/de/dhbwstuttgart/syntaxtree/Field.java @@ -5,8 +5,9 @@ import org.antlr.v4.runtime.Token; import java.util.ArrayList; -public class Field extends SyntaxTreeNode { - +public class Field extends SyntaxTreeNode implements TypeScope{ + + public final int modifier; private String name; private RefTypeOrTPHOrWildcardOrGeneric type; @@ -14,6 +15,7 @@ public class Field extends SyntaxTreeNode { super(offset); this.name = name; this.type = type; + this.modifier = modifier; } public String getName(){ diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index fd4ad180..99cd3f91 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -22,16 +22,22 @@ import de.dhbwstuttgart.syntaxtree.statement.Block; * @author janulrich * */ -public class Method implements IItemWithOffset, TypeScope +public class Method extends SyntaxTreeNode implements IItemWithOffset, TypeScope { public final Block block; + public final int modifier; + public final String name; private ParameterList parameterlist = new ParameterList(new ArrayList<>(), new NullToken()); private ExceptionList exceptionlist; private GenericDeclarationList generics; + private final RefTypeOrTPHOrWildcardOrGeneric returnType; - public Method(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block block, + public Method(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block block, GenericDeclarationList gtvDeclarations, Token offset) { - super(name, returnType, modifiers, offset); + super(offset); + this.name = name; + this.modifier = modifier; + this.returnType = returnType; this.parameterlist = parameterList; this.block = block; this.generics = gtvDeclarations; @@ -47,7 +53,7 @@ public class Method implements IItemWithOffset, TypeScope @Override public RefTypeOrTPHOrWildcardOrGeneric getReturnType() { - return this.getType(); + return this.returnType; } @Override @@ -59,4 +65,8 @@ public class Method implements IItemWithOffset, TypeScope public Token getOffset() { return null; } + + public String getName() { + return name; + } } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index 046b97b8..59e54385 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -88,7 +88,7 @@ public class ASTFactory { return null; } - return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); + return new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset, new ArrayList<>()); } //private static RefType createType(Class classType) { @@ -109,9 +109,8 @@ public class ASTFactory { Block block = new Block(new ArrayList(), new NullToken()); GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName()); Token offset = new NullToken(); - int modifier = jreMethod.getModifiers(); - return new Method(jreMethod.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset); + return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset); } public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){ diff --git a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java index e760e458..d56c39d8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java +++ b/src/de/dhbwstuttgart/syntaxtree/visual/OutputGenerator.java @@ -81,7 +81,7 @@ public class OutputGenerator implements ASTVisitor{ @Override public void visit(Method method) { - method.getType().accept(this); + method.getReturnType().accept(this); out.append(" " + method.getName()); method.getParameterList().accept(this); if(method.block != null) diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index 2152fc65..3448e8e3 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -345,7 +345,7 @@ public class TYPEStmt implements StatementVisitor{ for(Method m : cl.getMethods()){ if(m.getName().equals(name) && m.getParameterList().getFormalparalist().size() == numArgs){ - RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); + RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getReturnType()); ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info), createTypeScope(cl, m))); From 0610ea8e63c02f2cfda8004e6b5bd95f54527175 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 29 Jan 2018 17:32:25 +0100 Subject: [PATCH 40/42] FC Generator --- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 1 + .../SyntaxTreeGenerator/FCGenerator.java | 148 ++++++++++++++++++ .../syntaxtree/factory/UnifyTypeFactory.java | 53 +------ 3 files changed, 151 insertions(+), 51 deletions(-) create mode 100644 src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 2abd8b9d..86666a49 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -89,6 +89,7 @@ public class JavaTXCompiler { final ConstraintSet cons = getConstraints(); FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); + System.out.println(finiteClosure); ConstraintSet unifyCons = UnifyTypeFactory.convert(cons); TypeUnify unify = new TypeUnify(); diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java new file mode 100644 index 00000000..cbca13ce --- /dev/null +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java @@ -0,0 +1,148 @@ +package de.dhbwstuttgart.parser.SyntaxTreeGenerator; + +import de.dhbwstuttgart.exceptions.DebugException; +import de.dhbwstuttgart.exceptions.NotImplementedException; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; +import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; +import de.dhbwstuttgart.syntaxtree.type.*; +import de.dhbwstuttgart.typeinference.constraints.Pair; +import de.dhbwstuttgart.typeinference.unify.model.*; + +import java.util.*; + +public class FCGenerator { + /** + * Baut die FiniteClosure aus availableClasses. + * Klassen welche nicht in availableClasses vorkommen werden im Java Classpath nachgeschlagen. + * + * @param availableClasses - Alle geparsten Klassen + */ + public static Set toFC(Collection availableClasses) throws ClassNotFoundException { + HashSet pairs = new HashSet<>(); + for(ClassOrInterface cly : availableClasses){ + pairs.addAll(getSuperTypes(cly, availableClasses)); + } + System.out.println(pairs); + return pairs; + } + + /** + * Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ + * Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss. + * Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH + * @param forType + * @return + */ + private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses) throws ClassNotFoundException { + return getSuperTypes(forType, availableClasses, new HashMap<>()); + } + + //TODO: implements Interface auch als superklassen beachten + private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses, HashMap gtvs) throws ClassNotFoundException { + List params = new ArrayList<>(); + //Die GTVs, die in forType hinzukommen: + HashMap newGTVs = new HashMap<>(); + //Generics mit gleichem Namen müssen den selben TPH bekommen + for(GenericTypeVar gtv : forType.getGenerics()){ + if(!gtvs.containsKey(gtv.getParsedName())){ + gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder()); + newGTVs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder()); + } + params.add(gtvs.get(gtv.getParsedName())); + } + + Optional hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny(); + ClassOrInterface superClass; + if(!hasSuperclass.isPresent()) //Wenn es die Klasse in den available Klasses nicht gibt wird sie im Classpath gesucht. Ansonsten Exception + { + superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString())); + }else{ + superClass = hasSuperclass.get(); + } + /* + Die Parameter der superklasse müssen jetzt nach den Angaben in der Subklasse + modifiziert werden + Beispie: Matrix extends Vector> + Den ersten Parameter mit Vector austauschen und dort alle Generics zu den Typplaceholdern in gtvs austauschen + */ + //Hier vermerken, welche Typen im der Superklasse ausgetauscht werden müssen + Iterator itGenParams = superClass.getGenerics().iterator(); + Iterator itSetParams = forType.getSuperClass().getParaList().iterator(); + while(itGenParams.hasNext()){ + RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next(); + //In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen: + UnifyType setSetType = setType.acceptTV(new TypeExchanger(gtvs)); + newGTVs.put(itGenParams.next().getParsedName(), setSetType); + } + + UnifyType superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs)); + + TypeParams paramList = new TypeParams(params); + UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList); + UnifyType t2 = superType; + + UnifyPair ret = UnifyTypeFactory.generateSmallerPair(t1, t2); + + List superTypes; + //Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse: + if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){ + superTypes = Arrays.asList(UnifyTypeFactory.generateSmallerPair(UnifyTypeFactory.convert(ASTFactory.createObjectType()), UnifyTypeFactory.convert(ASTFactory.createObjectType()))); + }else{ + superTypes = getSuperTypes(superClass, availableClasses, newGTVs); + } + + List retList = new ArrayList<>(); + retList.add(ret); + retList.addAll(superTypes); + + return retList; + } + + /** + * Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus. + */ + private static class TypeExchanger implements TypeVisitor{ + + private final HashMap gtvs; + + TypeExchanger(HashMap gtvs){ + this.gtvs = gtvs; + } + + @Override + public UnifyType visit(RefType refType) { + List params = new ArrayList<>(); + for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){ + params.add(param.acceptTV(this)); + } + TypeParams paramList = new TypeParams(params); + UnifyType ret = new ReferenceType(refType.getName().toString(), paramList); + return ret; + } + + @Override + public UnifyType visit(SuperWildcardType superWildcardType) { + throw new DebugException("Dieser Fall darf nicht auftreten"); + } + + @Override + public UnifyType visit(TypePlaceholder typePlaceholder) { + throw new DebugException("Dieser Fall darf nicht auftreten"); + } + + @Override + public UnifyType visit(ExtendsWildcardType extendsWildcardType) { + throw new DebugException("Dieser Fall darf nicht auftreten"); + } + + @Override + public UnifyType visit(GenericRefType genericRefType) { + if(! gtvs.containsKey(genericRefType.getParsedName())) + throw new DebugException("Dieser Fall darf nicht auftreten"); + return gtvs.get(genericRefType.getParsedName()); + } + + } +} diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index 6e48c797..aef8068c 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.NullToken; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator; import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; @@ -35,57 +36,7 @@ public class UnifyTypeFactory { Generell dürfen sie immer die gleichen Namen haben. TODO: die transitive Hülle bilden */ - HashSet pairs = new HashSet<>(); - for(ClassOrInterface cly : fromClasses){ - pairs.addAll(getSuperTypes(cly, fromClasses)); - } - return new FiniteClosure(pairs); - } - - /** - * Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ - * Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss. - * Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH - * @param forType - * @return - */ - private static List getSuperTypes(ClassOrInterface forType, List availableClasses) throws ClassNotFoundException { - return getSuperTypes(forType, availableClasses, new HashMap<>()); - } - - private static List getSuperTypes(ClassOrInterface forType, List availableClasses, HashMap gtvs) throws ClassNotFoundException { - List params = new ArrayList<>(); - //Generics mit gleichem Namen müssen den selben TPH bekommen - for(GenericTypeVar gtv : forType.getGenerics()){ - if(!gtvs.containsKey(gtv.getParsedName())) - gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder()); - params.add(gtvs.get(gtv.getParsedName())); - } - Optional hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny(); - ClassOrInterface superClass; - if(!hasSuperclass.isPresent()) //TODO: Wenn es die Object-Klasse ist, dann ist es in Ordnung, ansonsten Fehler ausgeben: - { - superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString())); - }else{ - superClass = hasSuperclass.get(); - } - List superTypes; - if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){ - superTypes = Arrays.asList(generateSmallerPair(convert(ASTFactory.createObjectType()), convert(ASTFactory.createObjectType()))); - }else{ - superTypes = getSuperTypes(superClass, availableClasses, gtvs); - } - - TypeParams paramList = new TypeParams(params); - UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList); - UnifyType t2 = superTypes.get(0).getLhsType(); - - UnifyPair ret = generateSmallerPair(t1, t2); - List retList = new ArrayList<>(); - retList.add(ret); - retList.addAll(superTypes); - - return retList; + return new FiniteClosure(FCGenerator.toFC(fromClasses)); } public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ From ede55d228e23eeaf7fd054357e1b7b51ada0f6f8 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 29 Jan 2018 17:35:49 +0100 Subject: [PATCH 41/42] Fehler in ASTFactory beheben. GenericRefType statt RefType in den Parameterlisten --- src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index 59e54385..6acb4214 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -48,7 +48,7 @@ public class ASTFactory { if(superjreClass != null){ List params = new ArrayList<>(); for(TypeVariable tv : superjreClass.getTypeParameters()){ - params.add(new RefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken())); + params.add(new GenericRefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken())); } superClass = new RefType(new JavaClassName(superjreClass.getName()), params, new NullToken()); }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) From c7dea4c86bfa9c22567dd9452537bca5518c2b30 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 29 Jan 2018 18:26:14 +0100 Subject: [PATCH 42/42] Matrix Test --- .../syntaxtree/factory/UnifyTypeFactory.java | 1 - .../typeinference/unify/model/UnifyType.java | 10 ++++++++++ test/typeinference/MatrixTest.java | 9 +++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 test/typeinference/MatrixTest.java diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index aef8068c..a962c2bc 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -26,7 +26,6 @@ public class UnifyTypeFactory { public static FiniteClosure generateFC(List fromClasses) throws ClassNotFoundException { /* - TODO: Generics werden zu TPHs Die transitive Hülle muss funktionieren. Man darf schreiben List extends AL und Vector extends List diff --git a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java index 56718198..1080f03b 100644 --- a/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java +++ b/src/de/dhbwstuttgart/typeinference/unify/model/UnifyType.java @@ -96,4 +96,14 @@ public abstract class UnifyType { ret.addAll(typeParams.getInvolvedPlaceholderTypes()); return ret; } + + @Override + public int hashCode() { + return this.toString().hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this.toString().equals(obj.toString()); + } } \ No newline at end of file diff --git a/test/typeinference/MatrixTest.java b/test/typeinference/MatrixTest.java new file mode 100644 index 00000000..8cc587c9 --- /dev/null +++ b/test/typeinference/MatrixTest.java @@ -0,0 +1,9 @@ +package typeinference; + +import java.io.File; + +public class MatrixTest extends JavaTXCompilerTest{ + public MatrixTest() { + this.fileToTest = new File(rootDirectory+"Matrix.jav"); + } +} \ No newline at end of file