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/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java
index 425582ad..f1994c20 100644
--- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java
+++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java
@@ -1,6 +1,5 @@
package de.dhbwstuttgart.bytecode;
-import java.awt.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -10,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.*;
@@ -18,37 +20,54 @@ 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;
public class BytecodeGen implements ASTVisitor {
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
-// String methDesc;
String type;
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<>();
+ // 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;
- public BytecodeGen(HashMap classFiles) {
+ public BytecodeGen(HashMap classFiles, ResultSet resultSet) {
this.classFiles = classFiles;
- paramsAndLocals = new HashMap<>();
+ this.resultSet = resultSet;
}
@Override
public void visit(SourceFile sourceFile) {
for(ClassOrInterface cl : sourceFile.getClasses()) {
- BytecodeGen classGen = new BytecodeGen(classFiles);
+ 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);
@@ -58,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(), 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()) {
@@ -81,40 +118,100 @@ public class BytecodeGen implements ASTVisitor {
}
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
}
-
+
@Override
public void visit(Constructor field) {
- Descriptor desc = new Descriptor(field);
- MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc.getDesc(), 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,field, mv,paramsAndLocals,desc.getDesc(),cw);
-
- 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();
}
@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);
+
+ 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.getDesc(), 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,method, mv,paramsAndLocals,methDesc.getDesc(),cw);
+ BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,genericsAndBounds,genericsAndBounds,isInterface);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
@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 d92ebfc3..5368cf93 100644
--- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java
+++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java
@@ -1,12 +1,12 @@
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 java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.objectweb.asm.ClassWriter;
@@ -16,60 +16,95 @@ 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.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
+import de.dhbwstuttgart.typeinference.result.ResultSet;
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;
private String fieldDesc;
private Expression rightSideTemp;
private String where;
+ private boolean isRightSideALambda = false;
+ private KindOfLambda kindOfLambda;
- public BytecodeGenMethod(String className, Method m, MethodVisitor mv, HashMap paramsAndLocals,
- String desc, ClassWriter cw) {
+ private ArrayList varsFunInterface;
+
+ public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
+ HashMap paramsAndLocals, ClassWriter cw,
+ HashMap genericsAndBoundsMethod, HashMap genericsAndBounds, boolean isInterface) {
- this.where = "NORMAL METHOD";
+ this.where = "<<<<<< NORMAL METHOD >>>>>>";
this.className = className;
+ this.resultSet = resultSet;
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.m.block.accept(this);
+ this.varsFunInterface = new ArrayList<>();
+ System.out.println("PARAMS = "+this.paramsAndLocals.size());
+
+ if(!isInterface)
+ this.m.block.accept(this);
+
+// System.out.println("PARAMS = "+this.paramsAndLocals.size());
+// for(int i = 0; i paramsAndLocals, String desc) {
- System.out.println("++++++IN LAMBDA -------");
-
- this.where = "&&&&&&&& LAMBDA METHOD";
+ public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
+ 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(".", "/");
+ return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
+ }
+
+
@Override
public void visit(Block block) {
for(Statement stmt : block.getStatements()) {
@@ -85,26 +120,35 @@ 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, "()V",isInterface);
}
// ??
@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));
}
// ??
@Override
public void visit(LocalVarDecl localVarDecl) {
// Integer i;
- paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
- System.out.println("In localVarDecl");
+// paramsAndLocals.put(localVarDecl.getName(), paramsAndLocals.size()+1);
+ System.out.println("In localVarDecl :: "+localVarDecl.getName());
}
@Override
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;
@@ -113,44 +157,71 @@ public class BytecodeGenMethod implements StatementVisitor{
assign.rightSide.accept(this);
assign.lefSide.accept(this);
}
-
-
-
}
@Override
public void visit(Binary binary) {
- System.out.println("++ In Binary: ");
+ System.out.println("\t++ In Binary: ");
}
@Override
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
//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;
+// String typeErasure = "(Ljava/lang/Object;)Ljava/lang/Object;";
// Type erasure
- Type arg1 = Type.getMethodType("()V");
+// Type arg1 = Type.getMethodType(typeErasure);
+ Type arg1 = Type.getMethodType(lamDesc);
// real Type
- Type arg3 = Type.getMethodType("()V");
- Handle arg2 = new Handle(Opcodes.H_INVOKESTATIC, this.className, methodName,
- arg3.toString(),false);
- mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", bootstrap,
- arg1, arg2,arg3);
-
- MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ Opcodes.ACC_STATIC + Opcodes.ACC_SYNTHETIC,
- methodName, arg3.toString(), null, null);
-// new BytecodeGenLambda(lambdaExpression, mvLambdaBody);
+ Type arg3 = Type.getMethodType(lamDesc);
+
+ 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);
+ // Descriptor of functional interface methode
+ SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
+ // Desc: (this/nothing)TargetType
+ 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);
+
+ new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface);
- new BytecodeGenMethod(lambdaExpression, mvLambdaBody, new HashMap<>(), arg3.toString());
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
@@ -170,12 +241,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(".", "/"),
@@ -202,7 +274,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{
@@ -212,20 +284,31 @@ public class BytecodeGenMethod implements StatementVisitor{
methodCall.receiver.accept(this);
methodCall.arglist.accept(this);
- Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType());
+ MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
+ genericsAndBoundsMethod,genericsAndBounds);
+ String mDesc = method.accept(new DescriptorToString(resultSet));
- 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, 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);
}
+ // 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);
@@ -233,11 +316,11 @@ 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";
- mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "", d, false);
+ mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "", d, isInterface);
}
@Override
@@ -255,6 +338,7 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override
public void visit(Return aReturn) {
+ aReturn.retexpr.accept(this);
mv.visitInsn(Opcodes.ARETURN);
}
@@ -268,7 +352,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);
}
@@ -308,30 +392,41 @@ public class BytecodeGenMethod implements StatementVisitor{
@Override
public void visit(Literal literal) {
// value?
- mv.visitLdcInsn(literal.getType().toString());
+ mv.visitLdcInsn(getResolvedType(literal.getType()));
}
@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
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
// 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
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());
+ // Debug:::
+
}
}
diff --git a/src/de/dhbwstuttgart/bytecode/Descriptor.java b/src/de/dhbwstuttgart/bytecode/Descriptor.java
deleted file mode 100644
index 41f7ab5d..00000000
--- a/src/de/dhbwstuttgart/bytecode/Descriptor.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package de.dhbwstuttgart.bytecode;
-
-import java.awt.List;
-import java.util.Iterator;
-
-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.type.RefTypeOrTPHOrWildcardOrGeneric;
-
-public class Descriptor {
- String desc;
-
- public Descriptor(Method method) {
- 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(".", "/")+";";
- }
-
- }
-
- public Descriptor(Constructor constructor) {
- desc = "(";
- Iterator itr = constructor.getParameterList().iterator();
- while(itr.hasNext()) {
- FormalParameter fp = itr.next();
- desc = desc + "L"+fp.getType().toString().replace(".", "/") + ";";
- }
- desc = desc + ")V";
- }
-
- public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType) {
- desc = "(";
- for(Expression e : argList.getArguments()) {
- desc = desc + "L"+e.getType().toString().replace(".", "/") + ";";
- }
- desc = desc + ")"+returnType.toString();
-
- }
-
- 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..481dbc5d
--- /dev/null
+++ b/src/de/dhbwstuttgart/bytecode/DescriptorToString.java
@@ -0,0 +1,146 @@
+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();
+ 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())+ ";";
+ }
+ }
+
+ 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;
+ }
+
+ @Override
+ public String visit(NormalConstructor constructor) {
+ String desc = "(";
+ Iterator itr = constructor.getParameterList().iterator();
+ while(itr.hasNext()) {
+ FormalParameter fp = itr.next();
+ 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;
+ }
+
+ @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()) + ";";
+ }
+ System.out.println("LamReturnType: "+lambdaExpression.getReturnType().acceptTV(new TypeToString()));
+ 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.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())+ ";";
+ }
+ }
+
+ 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/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/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/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..330b0666
--- /dev/null
+++ b/src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java
@@ -0,0 +1,41 @@
+package de.dhbwstuttgart.bytecode;
+
+import java.util.HashMap;
+
+import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
+import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
+
+public class MethodFromMethodCall {
+ private ArgumentList argList;
+ private RefTypeOrTPHOrWildcardOrGeneric returnType;
+ private HashMap genericsAndBoundsMethod;
+ private HashMap genericsAndBounds;
+
+ 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) {
+ 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..d2174fd4
--- /dev/null
+++ b/src/de/dhbwstuttgart/bytecode/NormalConstructor.java
@@ -0,0 +1,39 @@
+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, 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();
+ }
+
+ 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..16e84cc5
--- /dev/null
+++ b/src/de/dhbwstuttgart/bytecode/NormalMethod.java
@@ -0,0 +1,55 @@
+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, 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() {
+ return method;
+ }
+
+ public ParameterList getParameterList() {
+ return method.getParameterList();
+ }
+
+ public HashMap getGenericsAndBounds(){
+ return genericsAndBounds;
+ }
+
+ public HashMap getGenericsAndBoundsMethod(){
+ return genericsAndBoundsMethod;
+ }
+
+ public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
+ return method.getReturnType();
+ }
+
+ public boolean hasGen() {
+ return this.hasGenerics;
+ }
+
+ 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/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 extends GenericTypeVar> 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 extends RefTypeOrTPHOrWildcardOrGeneric> 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/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/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/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java
index adc160fc..86666a49 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,55 +38,85 @@ 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()){
+ 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));
+ allClasses.addAll(sf.getClasses());
+ }
+
+ final ConstraintSet cons = getConstraints();
+
+ FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
+ System.out.println(finiteClosure);
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);
+ 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;
});
@@ -96,8 +126,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);
+ SourceFile ret = generator.convert(tree, environment.packageCrawler);
return ret;
}
-
-}
+
+}
\ No newline at end of file
diff --git a/src/de/dhbwstuttgart/environment/CompilationEnvironment.java b/src/de/dhbwstuttgart/environment/CompilationEnvironment.java
index 46a60139..7044da6b 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;
@@ -35,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
@@ -52,12 +50,22 @@ public class CompilationEnvironment {
}
}
this.sourceFiles = sourceFiles;
+ this.packageCrawler = new PackageCrawler(librarys);
}
public JavaClassRegistry getRegistry(File forSourceFile) throws ClassNotFoundException, IOException {
- List allNames;
+ Map allNames;
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
- allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
+ allNames = GatherNames.getNames(tree, packageCrawler);
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..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;
@@ -56,14 +53,24 @@ public class PackageCrawler {
return classes;
}
- public List getClassNames(String packageName){
- List nameList = new ArrayList();
+ 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 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/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/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
index 830f9d37..3d9d7aca 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<>();
@@ -71,56 +72,10 @@ 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) 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){
@@ -184,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, superClass);
+ 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());
}
}
@@ -222,7 +177,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);
@@ -266,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, superClass);
+ return new Constructor(Modifier.PUBLIC, className, classType, params, block, classGenerics, offset, fieldInitializations);
}
private RefType convert(Java8Parser.SuperclassContext superclass) {
@@ -424,6 +378,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));
@@ -434,7 +390,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..d54b682a 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;
@@ -42,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){
@@ -77,7 +78,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){
@@ -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()){
+ public static Map getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException {
+ Map ret = new HashMap<>();
+ ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+ ret.putAll(packages.getClassNames("java.lang"));
+ 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/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/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/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){
+
+ }
+}
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/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/writer/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java
new file mode 100644
index 00000000..002e3c7f
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java
@@ -0,0 +1,111 @@
+package de.dhbwstuttgart.sat.asp.writer;
+
+import de.dhbwstuttgart.exceptions.NotImplementedException;
+import de.dhbwstuttgart.parser.scope.JavaClassName;
+import de.dhbwstuttgart.sat.asp.writer.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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ASPGenerator {
+ ASPWriter writer = new ASPWriter();
+ private final String asp;
+
+ 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(List constraintSet, Collection fcClasses){
+ TypeConverter converter = new TypeConverter();
+ for(ClassOrInterface cl : fcClasses){
+ 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()){
+ paramList.add(new ASPGenericType(toConstant(gtv.getName())));
+ }
+ ASPParameterList params = new ASPParameterList(paramList, writer);
+ return new ASPRefType(toConstant(cl.getClassName()), params);
+ }
+
+ 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/writer/ASPWriter.java b/src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java
new file mode 100644
index 00000000..450950d9
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java
@@ -0,0 +1,22 @@
+package de.dhbwstuttgart.sat.asp.writer;
+
+import de.dhbwstuttgart.sat.asp.writer.model.ASPStatement;
+
+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/writer/model/ASPGenericType.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPGenericType.java
new file mode 100644
index 00000000..57619edf
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPGenericType.java
@@ -0,0 +1,15 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+import de.dhbwstuttgart.sat.asp.model.ASPRule;
+
+public class ASPGenericType implements ASPType{
+ private final String name;
+
+ public ASPGenericType(String name){
+ this.name = name;
+ }
+
+ public String toString(){
+ return ASPRule.ASP_GENERIC_TYPE_NAME + "(" + name + ")";
+ }
+}
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java
new file mode 100644
index 00000000..662f995c
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java
@@ -0,0 +1,21 @@
+package de.dhbwstuttgart.sat.asp.writer.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/writer/model/ASPPairEquals.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java
new file mode 100644
index 00000000..8806f2ce
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java
@@ -0,0 +1,14 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+import de.dhbwstuttgart.sat.asp.model.ASPRule;
+
+public class ASPPairEquals extends ASPPair{
+ public ASPPairEquals(ASPType ls, ASPType rs){
+ super(ls, rs);
+ }
+
+ @Override
+ protected String getRuleName() {
+ return ASPRule.ASP_PAIR_EQUALS_NAME.toString();
+ }
+}
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java
new file mode 100644
index 00000000..f57170f6
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmaller.java
@@ -0,0 +1,16 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+import de.dhbwstuttgart.sat.asp.model.ASPRule;
+
+import java.util.Map;
+
+public class ASPPairSmaller extends ASPPair{
+ public ASPPairSmaller(ASPType ls, ASPType rs){
+ super(ls, rs);
+ }
+
+ @Override
+ protected String getRuleName() {
+ return ASPRule.ASP_PAIR_SMALLER_NAME.toString();
+ }
+}
\ No newline at end of file
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java
new file mode 100644
index 00000000..e8482bfc
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairSmallerDot.java
@@ -0,0 +1,14 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+import de.dhbwstuttgart.sat.asp.model.ASPRule;
+
+public class ASPPairSmallerDot extends ASPPair{
+ public ASPPairSmallerDot(ASPType ls, ASPType rs){
+ super(ls, rs);
+ }
+
+ @Override
+ protected String getRuleName() {
+ return ASPRule.ASP_PAIR_SMALLER_DOT_NAME.toString();
+ }
+}
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java
new file mode 100644
index 00000000..3c176e49
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPParameterList.java
@@ -0,0 +1,45 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+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.Iterator;
+import java.util.List;
+
+public class ASPParameterList {
+ 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 = ASPRule.ASP_PARAMLIST_END_POINTER.toString();
+ }else{
+ name = newName();
+ String nextPointer = name;
+ Iterator it = types.iterator();
+ while(it.hasNext()){
+ ASPType t = it.next();
+ String param = nextPointer + "," + t.toString() + ",";
+ nextPointer = newName();
+ if(! it.hasNext())nextPointer = ASPRule.ASP_PARAMLIST_END_POINTER.toString();
+ param += nextPointer;
+ 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 + ")"));
+ }
+ }
+ }
+
+ private String newName() {
+ return ASPGenerator.toConstant(NameGenerator.makeNewName());
+ }
+
+ public String toString(){
+ return name;
+ }
+}
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java
new file mode 100644
index 00000000..6491ff33
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java
@@ -0,0 +1,21 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+import de.dhbwstuttgart.sat.asp.model.ASPRule;
+
+public class ASPRefType implements ASPType {
+ 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 ASPRule.ASP_TYPE + "(" + name +"," + params.name + ")";
+ }
+}
diff --git a/src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java
new file mode 100644
index 00000000..76bb63e8
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java
@@ -0,0 +1,27 @@
+package de.dhbwstuttgart.sat.asp.writer.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/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/writer/model/ASPTypeVar.java b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java
new file mode 100644
index 00000000..4b07d30b
--- /dev/null
+++ b/src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java
@@ -0,0 +1,14 @@
+package de.dhbwstuttgart.sat.asp.writer.model;
+
+public class ASPTypeVar implements ASPType{
+ 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/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..8a66629b 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
@@ -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);
@@ -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/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..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,
- GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations, RefType superClass) {
- super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset);
+ public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, ParameterList parameterList, Block codeInsideConstructor,
+ GenericDeclarationList gtvDeclarations, Token offset, List fieldInitializations) {
+ super(modifier, name, returnType, 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/Field.java b/src/de/dhbwstuttgart/syntaxtree/Field.java
index 421f0ff3..8a4230e3 100644
--- a/src/de/dhbwstuttgart/syntaxtree/Field.java
+++ b/src/de/dhbwstuttgart/syntaxtree/Field.java
@@ -6,7 +6,8 @@ import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
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 implements TypeScope{
super(offset);
this.name = name;
this.type = type;
+ this.modifier = modifier;
}
public String getName(){
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/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java
index 3686fb4e..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 extends Field implements IItemWithOffset
+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,11 +53,20 @@ public class Method extends Field implements IItemWithOffset
@Override
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
- return this.getType();
+ return this.returnType;
}
@Override
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
+
+ @Override
+ public Token getOffset() {
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
}
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/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 extends GenericTypeVar> getGenerics();
diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java
index b3f628a7..6acb4214 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 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!)
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(modifier, name,returnType, 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();
@@ -105,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){
@@ -182,6 +185,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..a962c2bc 100644
--- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
+++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
@@ -6,37 +6,36 @@ 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;
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.PairTPHequalRefType;
+import de.dhbwstuttgart.typeinference.result.PairTPHEqualTPH;
+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 {
- public static FiniteClosure generateFC(List fromAvailableClasses){
- 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));
- }
- return new FiniteClosure(pairs);
+ public static FiniteClosure generateFC(List fromClasses) throws ClassNotFoundException {
+ /*
+ 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
+ */
+ return new FiniteClosure(FCGenerator.toFC(fromClasses));
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
@@ -105,7 +104,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){
@@ -121,6 +120,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)
@@ -148,12 +151,19 @@ 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");
- 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{
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/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..d5abd93b 100644
--- a/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java
+++ b/src/de/dhbwstuttgart/syntaxtree/type/ExtendsWildcardType.java
@@ -40,6 +40,11 @@ public class ExtendsWildcardType extends WildcardType{
visitor.visit(this);
}
+ @Override
+ public A acceptTV(TypeVisitor visitor) {
+ return visitor.visit(this);
+ }
+
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
diff --git a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java
index 121a6c99..a5d394aa 100644
--- a/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java
+++ b/src/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java
@@ -20,7 +20,7 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
return name;
}
- public String getUniqueIdentifier(){
+ public String getParsedName(){
return name.toString();
}
@@ -29,6 +29,11 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric
visitor.visit(this);
}
+ @Override
+ public A acceptTV(TypeVisitor visitor) {
+ return visitor.visit(this);
+ }
+
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java
index b2876119..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
@@ -100,6 +109,11 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
visitor.visit(this);
}
+ @Override
+ public A acceptTV(TypeVisitor visitor) {
+ return visitor.visit(this);
+ }
+
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java
index 75638712..8a573d16 100644
--- a/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java
+++ b/src/de/dhbwstuttgart/syntaxtree/type/RefTypeOrTPHOrWildcardOrGeneric.java
@@ -13,5 +13,6 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
@Override
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 3fc8ffb9..f630583e 100644
--- a/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java
+++ b/src/de/dhbwstuttgart/syntaxtree/type/SuperWildcardType.java
@@ -50,6 +50,11 @@ public class SuperWildcardType extends WildcardType{
visitor.visit(this);
}
+ @Override
+ public A acceptTV(TypeVisitor visitor) {
+ return visitor.visit(this);
+ }
+
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
diff --git a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java
index 99a34cd5..ab4414fd 100644
--- a/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java
+++ b/src/de/dhbwstuttgart/syntaxtree/type/TypePlaceholder.java
@@ -73,6 +73,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
visitor.visit(this);
}
+ @Override
+ public A acceptTV(TypeVisitor visitor) {
+ return visitor.visit(this);
+ }
+
@Override
public void accept(ResultSetVisitor visitor) {
visitor.visit(this);
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..d56c39d8 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;
@@ -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/typedeployment/TypeInsertFactory.java b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java
index b9eea3c6..29492c31 100644
--- a/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java
+++ b/src/de/dhbwstuttgart/typedeployment/TypeInsertFactory.java
@@ -100,7 +100,12 @@ class TypeToInsertString implements ResultSetVisitor{
}
@Override
- public void visit(PairTPHequalRefType p) {
+ public void visit(PairTPHequalRefTypeOrWildcardType p) {
+
+ }
+
+ @Override
+ public void visit(PairTPHEqualTPH p) {
}
diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java
index 88b2bd4a..62867a26 100644
--- a/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java
+++ b/src/de/dhbwstuttgart/typeinference/assumptions/FieldAssumption.java
@@ -1,24 +1,31 @@
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 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() {
- 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/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;
+ }
+}
diff --git a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java
index bbeff0d7..066c3246 100644
--- a/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java
+++ b/src/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java
@@ -1,20 +1,27 @@
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.FunN;
+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;
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 +29,14 @@ public class MethodAssumption extends Assumption{
this.params = params;
}
+ /*
public RefType getReceiverType() {
+
+ return receiver;
+ }
+ */
+
+ public ClassOrInterface getReceiver(){
return receiver;
}
@@ -30,7 +44,35 @@ 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;
+ if(receiver instanceof FunNClass){
+ receiverType = new FunN(params);
+ }else{
+ receiverType = new RefType(receiver.getClassName(), params, new NullToken());
+ }
+
+ return receiverType;
}
}
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
deleted file mode 100644
index 3d1058da..00000000
--- a/src/de/dhbwstuttgart/typeinference/constraints/ConstraintsFactory.java
+++ /dev/null
@@ -1,58 +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 {
-
- 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/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/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/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);
+ }
+}
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/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 f3c81b55..19701d7b 100644
--- a/src/de/dhbwstuttgart/typeinference/result/ResultSet.java
+++ b/src/de/dhbwstuttgart/typeinference/result/ResultSet.java
@@ -1,16 +1,10 @@
package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException;
-import de.dhbwstuttgart.syntaxtree.ASTVisitor;
-import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
+import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
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 {
@@ -22,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)return new ResolvedType(type, new HashSet<>());
if(type instanceof RefType){
RelatedTypeWalker related = new RelatedTypeWalker(null, this);
type.accept(related);
@@ -49,6 +44,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);
}
@@ -70,7 +70,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);
@@ -79,6 +79,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) {
@@ -134,7 +139,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;
@@ -146,6 +151,11 @@ class TPHResolver implements ResultSetVisitor {
}
}
+ @Override
+ public void visit(PairTPHEqualTPH p) {
+ //ignorieren. Wird vom Resolver behandelt
+ }
+
@Override
public void visit(RefType refType) {
@@ -209,12 +219,17 @@ class RelatedTypeWalker implements ResultSetVisitor {
}
@Override
- public void visit(PairTPHequalRefType p) {
+ public void visit(PairTPHequalRefTypeOrWildcardType p) {
if(p.getLeft().equals(toResolve)){
p.getRight().accept(this);
}
}
+ @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 3f21ae31..bed742dd 100644
--- a/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java
+++ b/src/de/dhbwstuttgart/typeinference/result/ResultSetVisitor.java
@@ -4,7 +4,8 @@ import de.dhbwstuttgart.syntaxtree.type.*;
public interface ResultSetVisitor {
void visit(PairTPHsmallerTPH p);
- void visit(PairTPHequalRefType 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);
+
}
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 bf063d71..3448e8e3 100644
--- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
+++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
@@ -6,15 +6,14 @@ 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.FunNClass;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
import de.dhbwstuttgart.typeinference.constraints.*;
@@ -36,14 +35,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) {
@@ -64,11 +64,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));
@@ -80,8 +80,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
@@ -113,15 +113,21 @@ 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));
+ */
+ 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)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
+
+ //Wegen dem Problem oben:
+ throw new NotImplementedException();
}
@Override
@@ -156,8 +162,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());
@@ -191,9 +196,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.SMALLERDOT));
}
@Override
@@ -213,9 +216,15 @@ public class TYPEStmt implements StatementVisitor{
@Override
public void visit(This aThis) {
- constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
- aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
- createNullTypeScope(), getResolverInstance()));
+ //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(new Pair(
+ aThis.getType(), thisType, PairOperator.EQUALSDOT));
}
private static TypeScope createNullTypeScope() {
@@ -280,10 +289,20 @@ 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(),
- PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
- methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(),
- PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
+ ClassOrInterface receiverCl = assumption.getReceiver();
+ /*
+ List params = new ArrayList<>();
+ for(GenericTypeVar gtv : receiverCl.getGenerics()){
+ //Die Generics werden alle zu TPHs umgewandelt.
+ params.add(resolver.resolve(gtv.getParsedName()));
+ }
+
+ RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
+ */
+ 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));
return methodConstraint;
}
@@ -293,8 +312,9 @@ public class TYPEStmt implements StatementVisitor{
Set ret = new HashSet<>();
for(int i = 0;i 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 extends GenericTypeVar> getGenerics() {
@@ -324,9 +345,9 @@ 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.getType(), retType, convertParams(m.getParameterList(),info),
+ ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m)));
}
}
@@ -361,7 +382,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)));
}
}
@@ -373,8 +394,8 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint 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;
}
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