forked from JavaTX/JavaCompilerCore
Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring
Genauere Fehlermeldung im Unify
This commit is contained in:
commit
29173ba172
5
pom.xml
5
pom.xml
@ -22,6 +22,11 @@
|
||||
<artifactId>antlr4</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
|
@ -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<String, Integer> paramsAndLocals;// = new HashMap<>();
|
||||
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||
// stores generics and their bounds of class
|
||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||
// stores generics and their bounds of method
|
||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||
|
||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
||||
byte[] bytecode;
|
||||
HashMap<String,byte[]> classFiles;
|
||||
|
||||
public BytecodeGen(HashMap<String,byte[]> classFiles) {
|
||||
public BytecodeGen(HashMap<String,byte[]> 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<String,byte[]> 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:
|
||||
* <E:Ljava/...>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, "<init>", 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, "<init>", 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<FormalParameter> 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++;
|
||||
}
|
||||
|
@ -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<String, Integer> paramsAndLocals = new HashMap<>();
|
||||
private String desc;
|
||||
private String className;
|
||||
private int lamCounter;
|
||||
private ClassWriter cw;
|
||||
private ResultSet resultSet;
|
||||
private boolean isInterface;
|
||||
HashMap<String, String> genericsAndBoundsMethod;
|
||||
private HashMap<String,String> 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<String, Integer> paramsAndLocals,
|
||||
String desc, ClassWriter cw) {
|
||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
|
||||
|
||||
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw,
|
||||
HashMap<String, String> genericsAndBoundsMethod, HashMap<String,String> 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<this.paramsAndLocals.size();i++) {
|
||||
// System.out.println(this.paramsAndLocals.keySet().toArray()[i]);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public BytecodeGenMethod(LambdaExpression lambdaExpression, MethodVisitor mv,
|
||||
HashMap<String, Integer> 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<FormalParameter> 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(".", "/"), "<init>", d, false);
|
||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", 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:::
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<FormalParameter> 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<FormalParameter> 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;
|
||||
}
|
||||
|
||||
}
|
146
src/de/dhbwstuttgart/bytecode/DescriptorToString.java
Normal file
146
src/de/dhbwstuttgart/bytecode/DescriptorToString.java
Normal file
@ -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<FormalParameter> 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<FormalParameter> 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<FormalParameter> 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<RefTypeOrTPHOrWildcardOrGeneric> 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;
|
||||
}
|
||||
|
||||
}
|
9
src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java
Normal file
9
src/de/dhbwstuttgart/bytecode/DescriptorVisitor.java
Normal file
@ -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);
|
||||
}
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> 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<RefTypeOrTPHOrWildcardOrGeneric> 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
|
25
src/de/dhbwstuttgart/bytecode/Lambda.java
Normal file
25
src/de/dhbwstuttgart/bytecode/Lambda.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
41
src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java
Normal file
41
src/de/dhbwstuttgart/bytecode/MethodFromMethodCall.java
Normal file
@ -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<String, String> genericsAndBoundsMethod;
|
||||
private HashMap<String,String> genericsAndBounds;
|
||||
|
||||
public MethodFromMethodCall(ArgumentList argList,RefTypeOrTPHOrWildcardOrGeneric returnType,
|
||||
HashMap<String, String> genericsAndBoundsMethod,HashMap<String,String> 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<String, String> getGenericsAndBoundsMethod(){
|
||||
return genericsAndBoundsMethod;
|
||||
}
|
||||
|
||||
public HashMap<String,String> getGenericsAndBounds(){
|
||||
return genericsAndBounds;
|
||||
}
|
||||
|
||||
public String accept(DescriptorVisitor descVisitor) {
|
||||
return descVisitor.visit(this);
|
||||
}
|
||||
}
|
39
src/de/dhbwstuttgart/bytecode/NormalConstructor.java
Normal file
39
src/de/dhbwstuttgart/bytecode/NormalConstructor.java
Normal file
@ -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<String, String> genericsAndBounds;
|
||||
private boolean hasGenerics;
|
||||
|
||||
public NormalConstructor(Constructor constructor, boolean hasGenerics) {
|
||||
this.constructor = constructor;
|
||||
this.hasGenerics = hasGenerics;
|
||||
}
|
||||
|
||||
public NormalConstructor(Constructor constructor, HashMap<String, String> genericsAndBounds, boolean hasGenerics) {
|
||||
this.constructor = constructor;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.hasGenerics = hasGenerics;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getGenericsAndBounds() {
|
||||
return genericsAndBounds;
|
||||
}
|
||||
|
||||
public boolean hasGen() {
|
||||
return hasGenerics;
|
||||
}
|
||||
|
||||
public ParameterList getParameterList() {
|
||||
return constructor.getParameterList();
|
||||
}
|
||||
|
||||
public String accept(DescriptorVisitor descVisitor) {
|
||||
return descVisitor.visit(this);
|
||||
}
|
||||
}
|
55
src/de/dhbwstuttgart/bytecode/NormalMethod.java
Normal file
55
src/de/dhbwstuttgart/bytecode/NormalMethod.java
Normal file
@ -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<String, String> genericsAndBounds;
|
||||
private HashMap<String, String> genericsAndBoundsMethod;
|
||||
private boolean hasGenerics;
|
||||
|
||||
public NormalMethod(Method method, boolean hasGenerics) {
|
||||
this.method = method;
|
||||
this.hasGenerics = hasGenerics;
|
||||
}
|
||||
|
||||
public NormalMethod(Method method, HashMap<String, String> genericsAndBounds,
|
||||
HashMap<String, String> 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<String, String> getGenericsAndBounds(){
|
||||
return genericsAndBounds;
|
||||
}
|
||||
|
||||
public HashMap<String, String> getGenericsAndBoundsMethod(){
|
||||
return genericsAndBoundsMethod;
|
||||
}
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
||||
return method.getReturnType();
|
||||
}
|
||||
|
||||
public boolean hasGen() {
|
||||
return this.hasGenerics;
|
||||
}
|
||||
|
||||
public String accept(DescriptorVisitor descVisitor) {
|
||||
return descVisitor.visit(this);
|
||||
}
|
||||
}
|
31
src/de/dhbwstuttgart/bytecode/SamMethod.java
Normal file
31
src/de/dhbwstuttgart/bytecode/SamMethod.java
Normal file
@ -0,0 +1,31 @@
|
||||
package de.dhbwstuttgart.bytecode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||
|
||||
public class SamMethod {
|
||||
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList;
|
||||
private RefTypeOrTPHOrWildcardOrGeneric returnType;
|
||||
|
||||
public SamMethod(List<RefTypeOrTPHOrWildcardOrGeneric> argumentList, RefTypeOrTPHOrWildcardOrGeneric returnType) {
|
||||
this.argumentList = argumentList;
|
||||
this.returnType = returnType;
|
||||
}
|
||||
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgumentList() {
|
||||
return argumentList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public RefTypeOrTPHOrWildcardOrGeneric getReturnType() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String accept(DescriptorVisitor descVisitor) {
|
||||
return descVisitor.visit(this);
|
||||
}
|
||||
}
|
155
src/de/dhbwstuttgart/bytecode/Signature.java
Normal file
155
src/de/dhbwstuttgart/bytecode/Signature.java
Normal file
@ -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<String, String> genericsAndBounds;
|
||||
private HashMap<String, String> genericsAndBoundsMethod;
|
||||
private SignatureWriter sw;
|
||||
private Constructor constructor;
|
||||
private Method method;
|
||||
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||
private ResultSet resultSet;
|
||||
|
||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds) {
|
||||
this.classOrInterface = classOrInterface;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForClassOrInterface();
|
||||
}
|
||||
|
||||
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds, HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes) {
|
||||
this.constructor = constructor;
|
||||
this.genericsAndBounds = genericsAndBounds;
|
||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||
sw = new SignatureWriter();
|
||||
createSignatureForConsOrMethod(this.constructor,true);
|
||||
}
|
||||
|
||||
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,
|
||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> 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:
|
||||
* <typevaliables (K:Ljava/lang/Object "Bounds")>(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 <T:...;B:...;...>
|
||||
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())+"<Ljava/lang/Integer;Ljava/lang/Integer;>;");
|
||||
|
||||
break;
|
||||
default:
|
||||
if(!isParameterType)
|
||||
sv.visitBaseType('V');
|
||||
break;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates signature for class or interface with {@link SignatureWriter}
|
||||
* Signature looks like:
|
||||
* <typevaliables (K:Ljava/lang/Object "Bounds")>superclass
|
||||
*/
|
||||
private void createSignatureForClassOrInterface() {
|
||||
Iterator<GenericTypeVar> 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<String, String> 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();
|
||||
}
|
||||
|
||||
}
|
37
src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java
Normal file
37
src/de/dhbwstuttgart/bytecode/TypeToDescriptor.java
Normal file
@ -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<String>{
|
||||
|
||||
@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(".", "/");
|
||||
}
|
||||
}
|
38
src/de/dhbwstuttgart/bytecode/TypeToString.java
Normal file
38
src/de/dhbwstuttgart/bytecode/TypeToString.java
Normal file
@ -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<String>{
|
||||
|
||||
@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";
|
||||
}
|
||||
|
||||
}
|
@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
final CompilationEnvironment environment;
|
||||
final CompilationEnvironment environment;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
@ -38,55 +38,85 @@ public class JavaTXCompiler {
|
||||
|
||||
public JavaTXCompiler(List<File> 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<ResultSet> typeInference() throws ClassNotFoundException {
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
for(SourceFile sf : sourceFiles.values()){
|
||||
for (SourceFile sf : sourceFiles.values()) {
|
||||
allClasses.addAll(sf.getClasses());
|
||||
}
|
||||
List<ClassOrInterface> 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<Pair> cons = new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
for (SourceFile sf : sourceFiles.values()) {
|
||||
allClasses.addAll(sf.getClasses());
|
||||
}
|
||||
List<ClassOrInterface> 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<ResultSet> typeInference() throws ClassNotFoundException {
|
||||
List<ClassOrInterface> 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<Pair> cons = getConstraints();
|
||||
|
||||
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
|
||||
System.out.println(finiteClosure);
|
||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
|
||||
|
||||
TypeUnify unify = new TypeUnify();
|
||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
||||
for(List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()){
|
||||
for (List<Constraint<UnifyPair>> xCons : unifyCons.cartesianProduct()) {
|
||||
Set<UnifyPair> xConsSet = new HashSet<>();
|
||||
for(Constraint<UnifyPair> constraint : xCons){
|
||||
for (Constraint<UnifyPair> constraint : xCons) {
|
||||
xConsSet.addAll(constraint);
|
||||
}
|
||||
|
||||
//System.out.println(xConsSet);
|
||||
System.out.println(xConsSet);
|
||||
Set<Set<UnifyPair>> 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<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints){
|
||||
private Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
|
||||
HashMap<String, TypePlaceholder> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -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<URL> librarys;
|
||||
private final List<File> 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<String> allNames;
|
||||
Map<String, Integer> allNames;
|
||||
CompilationUnitContext tree = JavaTXParser.parse(forSourceFile);
|
||||
allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
|
||||
allNames = GatherNames.getNames(tree, packageCrawler);
|
||||
return new JavaClassRegistry(allNames);
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAllAvailableClasses() {
|
||||
List<ClassOrInterface> ret = new ArrayList<>();
|
||||
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
|
||||
ret.add(ASTFactory.createClass(c));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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<String> getClassNames(String packageName){
|
||||
List<String> nameList = new ArrayList();
|
||||
public Set<Class<?>> getAllAvailableClasses(){
|
||||
Reflections reflections = new Reflections(new ConfigurationBuilder()
|
||||
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
|
||||
.setUrls(urls));
|
||||
|
||||
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
public Map<String, Integer> getClassNames(String packageName){
|
||||
Map<String, Integer> nameList = new HashMap<>();
|
||||
Set<Class<?>> 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;
|
||||
}
|
||||
|
148
src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
Normal file
148
src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java
Normal file
@ -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<UnifyPair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
HashSet<UnifyPair> 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<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||
return getSuperTypes(forType, availableClasses, new HashMap<>());
|
||||
}
|
||||
|
||||
//TODO: implements Interface auch als superklassen beachten
|
||||
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, HashMap<String, UnifyType> gtvs) throws ClassNotFoundException {
|
||||
List<UnifyType> params = new ArrayList<>();
|
||||
//Die GTVs, die in forType hinzukommen:
|
||||
HashMap<String, UnifyType> 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<ClassOrInterface> 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<A> extends Vector<Vector<A>>
|
||||
Den ersten Parameter mit Vector<A> austauschen und dort alle Generics zu den Typplaceholdern in gtvs austauschen
|
||||
*/
|
||||
//Hier vermerken, welche Typen im der Superklasse ausgetauscht werden müssen
|
||||
Iterator<GenericTypeVar> itGenParams = superClass.getGenerics().iterator();
|
||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> 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<UnifyPair> 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<UnifyPair> 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<UnifyType>{
|
||||
|
||||
private final HashMap<String, UnifyType> gtvs;
|
||||
|
||||
TypeExchanger(HashMap<String, UnifyType> gtvs){
|
||||
this.gtvs = gtvs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public UnifyType visit(RefType refType) {
|
||||
List<UnifyType> 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());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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<JavaClassName> imports = new ArrayList();
|
||||
Set<JavaClassName> imports = new HashSet();
|
||||
|
||||
List<Statement> fieldInitializations = new ArrayList<>();
|
||||
|
||||
@ -71,56 +72,10 @@ public class SyntaxTreeGenerator{
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void setImports(Java8Parser.CompilationUnitContext ctx) throws ClassNotFoundException {
|
||||
List<JavaClassName> 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<JavaClassName> convertTypeImportOnDemandDeclaration(Java8Parser.TypeImportOnDemandDeclarationContext ctx){
|
||||
return reg.getAllFromPackage(ctx.packageOrTypeName().getText());
|
||||
}
|
||||
|
||||
private JavaClassName convertSingleStaticImportDeclaration(Java8Parser.SingleStaticImportDeclarationContext ctx){
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private List<JavaClassName> 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<ClassOrInterface> classes = new ArrayList<>();
|
||||
this.setImports(ctx);
|
||||
Map<String, Integer> 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<Field> fielddecl = convertFields(ctx.classBody(), generics);
|
||||
List<Method> 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<Field> fields = convertFields(ctx.interfaceBody());
|
||||
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> 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<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
|
||||
for(int i = 0; i<reg.getNumberOfGenerics(name);i++){
|
||||
params.add(TypePlaceholder.fresh(offset));
|
||||
}
|
||||
return new RefType(reg.getName(name), params, offset);
|
||||
}else{
|
||||
return new RefType(reg.getName(name), convert(typeArguments, reg, generics), offset);
|
||||
}
|
||||
|
@ -1,7 +1,9 @@
|
||||
package de.dhbwstuttgart.parser.scope;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import de.dhbwstuttgart.parser.antlr.Java8BaseListener;
|
||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||
@ -13,8 +15,8 @@ import de.dhbwstuttgart.parser.antlr.Java8Parser;
|
||||
|
||||
public class GatherNames {
|
||||
|
||||
public static List<String> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{
|
||||
List<String> ret = new ArrayList<>();
|
||||
public static Map<String, Integer> getNames(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException{
|
||||
Map<String, Integer> 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<String> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException {
|
||||
List<String> ret = new ArrayList();
|
||||
ret.addAll(packages.getClassNames("java.lang"));
|
||||
for(Java8Parser.ImportDeclarationContext importDeclCtx : ctx.importDeclaration()){
|
||||
public static Map<String, Integer> getImports(Java8Parser.CompilationUnitContext ctx, PackageCrawler packages) throws ClassNotFoundException {
|
||||
Map<String, Integer> 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;
|
||||
|
@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName {
|
||||
+ DELIMITER + methodName
|
||||
+ DELIMITER + super.toString();
|
||||
}
|
||||
|
||||
public JavaClassName getParentClass() {
|
||||
return parentClass;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -8,20 +8,16 @@ import java.util.*;
|
||||
* Speichert die Klassen f<EFBFBD>r einen bestimmten Projektscope
|
||||
*/
|
||||
public class JavaClassRegistry {
|
||||
final List<JavaClassName> existingClasses = new ArrayList<>();
|
||||
final Map<JavaClassName, Integer> existingClasses = new HashMap<>();
|
||||
|
||||
public JavaClassRegistry(List<String> initialNames){
|
||||
for(String name : initialNames){
|
||||
existingClasses.add(new JavaClassName(name));
|
||||
public JavaClassRegistry(Map<String, Integer> 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<JavaClassName> getAllFromPackage(String packageName) {
|
||||
List<JavaClassName> 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));
|
||||
}
|
||||
}
|
||||
|
8
src/de/dhbwstuttgart/sat/CNF/CNF.java
Normal file
8
src/de/dhbwstuttgart/sat/CNF/CNF.java
Normal file
@ -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
|
||||
*/
|
||||
}
|
12
src/de/dhbwstuttgart/sat/CNF/Writer.java
Normal file
12
src/de/dhbwstuttgart/sat/CNF/Writer.java
Normal file
@ -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){
|
||||
|
||||
}
|
||||
}
|
46
src/de/dhbwstuttgart/sat/asp/Clingo.java
Normal file
46
src/de/dhbwstuttgart/sat/asp/Clingo.java
Normal file
@ -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<File> input;
|
||||
private static final List<File> 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<File> 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<String> 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;
|
||||
}
|
||||
}
|
24
src/de/dhbwstuttgart/sat/asp/model/ASPRule.java
Normal file
24
src/de/dhbwstuttgart/sat/asp/model/ASPRule.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
17
src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java
Normal file
17
src/de/dhbwstuttgart/sat/asp/parser/ASPParser.java
Normal file
@ -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<ResultPair> ret = new HashSet<>();
|
||||
for(String pair : result.split(",")){
|
||||
|
||||
}
|
||||
return new ResultSet(ret);
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package de.dhbwstuttgart.sat.asp.parser.model;
|
||||
|
||||
public class ParsedASPStatement {
|
||||
public ParsedASPStatement(String statement){
|
||||
|
||||
}
|
||||
}
|
111
src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java
Normal file
111
src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java
Normal file
@ -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<Pair> constraints, Collection<ClassOrInterface> fcClasses){
|
||||
List<Constraint<Pair>> constraints1 = constraints.cartesianProduct().iterator().next();
|
||||
List<Pair> constraintPairs = new ArrayList<>();
|
||||
for(Constraint<Pair> constraint : constraints1){
|
||||
System.out.println(UnifyTypeFactory.convert(constraint));
|
||||
constraintPairs.addAll(constraint);
|
||||
}
|
||||
asp = toASP(constraintPairs, fcClasses);
|
||||
}
|
||||
|
||||
public String getASP(){
|
||||
return asp;
|
||||
}
|
||||
|
||||
private String toASP(List<Pair> constraintSet, Collection<ClassOrInterface> 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<ASPType> 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<ASPType>{
|
||||
|
||||
@Override
|
||||
public ASPType visit(RefType type) {
|
||||
List<ASPType> 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));
|
||||
}
|
||||
}
|
||||
}
|
22
src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java
Normal file
22
src/de/dhbwstuttgart/sat/asp/writer/ASPWriter.java
Normal file
@ -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<ASPStatement> 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;
|
||||
}
|
||||
}
|
@ -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 + ")";
|
||||
}
|
||||
}
|
21
src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java
Normal file
21
src/de/dhbwstuttgart/sat/asp/writer/model/ASPPair.java
Normal file
@ -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();
|
||||
}
|
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java
Normal file
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPPairEquals.java
Normal file
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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<ASPType> types;
|
||||
|
||||
public ASPParameterList(List<ASPType> 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<ASPType> 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;
|
||||
}
|
||||
}
|
21
src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java
Normal file
21
src/de/dhbwstuttgart/sat/asp/writer/model/ASPRefType.java
Normal file
@ -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 + ")";
|
||||
}
|
||||
}
|
27
src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java
Normal file
27
src/de/dhbwstuttgart/sat/asp/writer/model/ASPStatement.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
4
src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java
Normal file
4
src/de/dhbwstuttgart/sat/asp/writer/model/ASPType.java
Normal file
@ -0,0 +1,4 @@
|
||||
package de.dhbwstuttgart.sat.asp.writer.model;
|
||||
|
||||
public interface ASPType {
|
||||
}
|
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java
Normal file
14
src/de/dhbwstuttgart/sat/asp/writer/model/ASPTypeVar.java
Normal file
@ -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 +")";
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> 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;
|
||||
}
|
||||
|
@ -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<Statement> 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<Statement> 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<Statement> fieldInitializations, RefType superClass){
|
||||
protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations){
|
||||
List<Statement> statements = constructorBlock.getStatements();
|
||||
statements.add(0, new SuperCall(constructorBlock.getOffset()));
|
||||
return new Block(statements, constructorBlock.getOffset());
|
||||
|
@ -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(){
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -13,13 +13,13 @@ public class SourceFile extends SyntaxTreeNode{
|
||||
private String pkgName;
|
||||
|
||||
public final List<ClassOrInterface> KlassenVektor;
|
||||
public final List<JavaClassName> imports;
|
||||
public final Set<JavaClassName> 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<ClassOrInterface> classDefinitions, List<JavaClassName> imports){
|
||||
public SourceFile(String pkgName, List<ClassOrInterface> classDefinitions, Set<JavaClassName> 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<JavaClassName> getImports(){
|
||||
public Set<JavaClassName> getImports(){
|
||||
return this.imports;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> 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<Statement>(), 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){
|
||||
|
@ -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<ClassOrInterface> fromAvailableClasses){
|
||||
HashSet<UnifyPair> 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<ClassOrInterface> fromClasses) throws ClassNotFoundException {
|
||||
/*
|
||||
Die transitive Hülle muss funktionieren.
|
||||
Man darf schreiben List<A> extends AL<A>
|
||||
und Vector<B> extends List<B>
|
||||
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<UnifyPair> convert(Constraint<Pair> 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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -40,6 +40,11 @@ public class ExtendsWildcardType extends WildcardType{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@ -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> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> 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> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@ -13,5 +13,6 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
||||
@Override
|
||||
public abstract void accept(ASTVisitor visitor);
|
||||
|
||||
public abstract <A> A acceptTV(TypeVisitor<A> visitor);
|
||||
public abstract void accept(ResultSetVisitor visitor);
|
||||
}
|
||||
|
@ -50,6 +50,11 @@ public class SuperWildcardType extends WildcardType{
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@ -73,6 +73,11 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A> A acceptTV(TypeVisitor<A> visitor) {
|
||||
return visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
13
src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java
Normal file
13
src/de/dhbwstuttgart/syntaxtree/type/TypeVisitor.java
Normal file
@ -0,0 +1,13 @@
|
||||
package de.dhbwstuttgart.syntaxtree.type;
|
||||
|
||||
public interface TypeVisitor<A> {
|
||||
A visit(RefType refType);
|
||||
|
||||
A visit(SuperWildcardType superWildcardType);
|
||||
|
||||
A visit(TypePlaceholder typePlaceholder);
|
||||
|
||||
A visit(ExtendsWildcardType extendsWildcardType);
|
||||
|
||||
A visit(GenericRefType genericRefType);
|
||||
}
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> 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<RefTypeOrTPHOrWildcardOrGeneric> funNParams) {
|
||||
List<GenericTypeVar> 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<Method> createMethods(List<RefTypeOrTPHOrWildcardOrGeneric> funNParams) {
|
||||
return null;
|
||||
}
|
||||
}
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric> params;
|
||||
|
||||
public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
|
||||
public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> 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<RefTypeOrTPHOrWildcardOrGeneric> getArgTypes() {
|
||||
return params;
|
||||
public List<RefTypeOrTPHOrWildcardOrGeneric> getArgTypes(GenericsResolver resolver) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> 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<RefTypeOrTPHOrWildcardOrGeneric> 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;
|
||||
}
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
@ -104,5 +104,8 @@ public class Pair implements Serializable
|
||||
return eOperator;
|
||||
}
|
||||
|
||||
public boolean OperatorSmallerDot() {
|
||||
return eOperator == PairOperator.SMALLERDOT;
|
||||
}
|
||||
}
|
||||
// ino.end
|
||||
|
@ -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<TypePlaceholder, TypePlaceholder> {
|
||||
public PairTPHEqualTPH(TypePlaceholder tl, TypePlaceholder tr) {
|
||||
super(tl, tr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(ResultSetVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
}
|
@ -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;
|
@ -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<A extends RefTypeOrTPHOrWildcardOrGeneric,B extends RefTypeOrTPHOrWildcardOrGeneric> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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<RefTypeOrTPHOrWildcardOrGeneric>{
|
||||
|
||||
HashMap<String, TypePlaceholder> map = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric resolve(RefTypeOrTPHOrWildcardOrGeneric generic) {
|
||||
return generic.acceptTV(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> 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);
|
||||
}
|
||||
}
|
@ -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<GenericTypeVar, TypePlaceholder> 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<Constraint> 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<RefTypeOrTPHOrWildcardOrGeneric> 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<Pair> 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<RefTypeOrTPHOrWildcardOrGeneric> 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<Pair> ret = new HashSet<>();
|
||||
for(int i = 0;i<foMethod.arglist.getArguments().size();i++){
|
||||
foMethod.arglist.getArguments().get(i).accept(this);
|
||||
ret.add(ConstraintsFactory.createPair(foMethod.arglist.getArguments().get(i).getType(),
|
||||
assumption.getArgTypes().get(i), PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
|
||||
RefTypeOrTPHOrWildcardOrGeneric argType = foMethod.arglist.getArguments().get(i).getType();
|
||||
RefTypeOrTPHOrWildcardOrGeneric assType = assumption.getArgTypes(resolver).get(i);
|
||||
ret.add(new Pair(argType, assType, PairOperator.SMALLERDOT));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -302,12 +322,13 @@ public class TYPEStmt implements StatementVisitor{
|
||||
|
||||
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
|
||||
List<MethodAssumption> 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<RefTypeOrTPHOrWildcardOrGeneric> 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<Pair> 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;
|
||||
}
|
||||
|
@ -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<UnifyType, Node<UnifyType>> inheritanceGraph;
|
||||
|
||||
/**
|
||||
* A map that maps every typename to the nodes of the inheritance graph that contain a type with that name.
|
||||
*/
|
||||
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The initial pairs of that define the inheritance tree
|
||||
*/
|
||||
@ -38,7 +39,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
*/
|
||||
public FiniteClosure(Set<UnifyPair> pairs) {
|
||||
this.pairs = new HashSet<>(pairs);
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
|
||||
|
||||
// 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<UnifyType>(pair.getLhsType()));
|
||||
if(!inheritanceGraph.containsKey(pair.getRhsType()))
|
||||
inheritanceGraph.put(pair.getRhsType(), new Node<UnifyType>(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<UnifyType> 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<UnifyType> greater(UnifyType type) {
|
||||
if(type instanceof FunNType)
|
||||
@ -240,7 +241,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return type.grArg(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> grArg(ReferenceType type) {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
@ -249,7 +250,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> grArg(FunNType type) {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
@ -267,7 +268,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> grArg(SuperType type) {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
@ -276,11 +277,11 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> grArg(PlaceholderType type) {
|
||||
HashSet<UnifyType> 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<UnifyType> smArg(ReferenceType type) {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> smArg(FunNType type) {
|
||||
@ -316,7 +317,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> smArg(SuperType type) {
|
||||
Set<UnifyType> result = new HashSet<UnifyType>();
|
||||
result.add(type);
|
||||
@ -329,20 +330,20 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Override
|
||||
public Set<UnifyType> smArg(PlaceholderType type) {
|
||||
HashSet<UnifyType> result = new HashSet<>();
|
||||
result.add(type);
|
||||
result.add(type);
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<UnifyType> getAllTypesByName(String typeName) {
|
||||
@Override
|
||||
public Set<UnifyType> getAllTypesByName(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
return new HashSet<>();
|
||||
return strInheritanceGraph.get(typeName).stream().map(x -> x.getContent()).collect(Collectors.toCollection(HashSet::new));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Optional<UnifyType> getLeftHandedType(String typeName) {
|
||||
if(!strInheritanceGraph.containsKey(typeName))
|
||||
@ -392,7 +393,7 @@ public class FiniteClosure implements IFiniteClosure {
|
||||
* @param result Set of all permutations found so far
|
||||
* @param current The permutation of type params that is currently explored
|
||||
*/
|
||||
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
protected void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
|
||||
if(candidates.size() == idx) {
|
||||
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
|
||||
return;
|
||||
|
@ -24,8 +24,10 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
*/
|
||||
public TypeParams(List<UnifyType> types){
|
||||
typeParams = new UnifyType[types.size()];
|
||||
for(int i=0;i<types.size();i++)
|
||||
for(int i=0;i<types.size();i++){
|
||||
typeParams[i] = types.get(i);
|
||||
if(types.get(i)==null)throw new NullPointerException();
|
||||
}
|
||||
|
||||
// Hashcode calculation is expensive and must be cached.
|
||||
hashCode = Arrays.deepHashCode(typeParams);
|
||||
@ -149,7 +151,11 @@ public final class TypeParams implements Iterable<UnifyType>{
|
||||
|
||||
if(other.size() != this.size())
|
||||
return false;
|
||||
|
||||
|
||||
for(int i = 0; i < this.size(); i++){
|
||||
//if(this.get(i) == null)
|
||||
//System.out.print("s");
|
||||
}
|
||||
for(int i = 0; i < this.size(); i++)
|
||||
if(!(this.get(i).equals(other.get(i))))
|
||||
return false;
|
||||
|
@ -96,4 +96,14 @@ public abstract class UnifyType {
|
||||
ret.addAll(typeParams.getInvolvedPlaceholderTypes());
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.toString().hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
return this.toString().equals(obj.toString());
|
||||
}
|
||||
}
|
46
test/asp/ClingoTest.java
Normal file
46
test/asp/ClingoTest.java
Normal file
@ -0,0 +1,46 @@
|
||||
package asp;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPGenerator;
|
||||
import de.dhbwstuttgart.sat.asp.Clingo;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ClingoTest {
|
||||
public static final String rootDirectory = "~/Sync/HiwiJob/ResearchPapers/MasterarbeitStadelmeier/asp/unifyWithoutWildcards";
|
||||
public static final String tempDirectory = "/tmp/";
|
||||
|
||||
@Test
|
||||
public void test() throws IOException, InterruptedException {
|
||||
String content = "";
|
||||
content = new ASPGenerator(this.getPairs(), this.getFC()).getASP();
|
||||
|
||||
PrintWriter writer = new PrintWriter(tempDirectory + "test.lp", "UTF-8");
|
||||
writer.println(content);
|
||||
writer.close();
|
||||
|
||||
Clingo clingo = new Clingo(Arrays.asList(new File(tempDirectory + "test.lp")));
|
||||
System.out.println(clingo.runClingo());
|
||||
}
|
||||
|
||||
public Collection<ClassOrInterface> getFC() {
|
||||
Set<ClassOrInterface> ret = new HashSet<>();
|
||||
ret.add(ASTFactory.createObjectClass());
|
||||
ret.add(ASTFactory.createClass(java.util.List.class));
|
||||
return ret;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getPairs() {
|
||||
ConstraintSet<Pair> ret = new ConstraintSet<>();
|
||||
ret.addUndConstraint(new Pair(TypePlaceholder.fresh(new NullToken()), ASTFactory.createObjectType(), PairOperator.SMALLERDOT));
|
||||
return ret;
|
||||
}
|
||||
}
|
68
test/asp/typeinference/ASPTest.java
Normal file
68
test/asp/typeinference/ASPTest.java
Normal file
@ -0,0 +1,68 @@
|
||||
package asp.typeinference;
|
||||
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.sat.asp.writer.ASPGenerator;
|
||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ASPTest {
|
||||
|
||||
public static final String rootDirectory = System.getProperty("user.dir")+"/test/javFiles/";
|
||||
private static final List<File> filesToTest = new ArrayList<>();
|
||||
protected File fileToTest = null;
|
||||
|
||||
public ASPTest(){
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void test() throws IOException, ClassNotFoundException {
|
||||
if(fileToTest != null)filesToTest.add(fileToTest);
|
||||
else return;
|
||||
//filesToTest.add(new File(rootDirectory+"Faculty.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"mathStruc.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"test.jav"));
|
||||
filesToTest.add(new File(rootDirectory+"EmptyMethod.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"fc.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Lambda.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Lambda2.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Lambda3.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Vector.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Generics.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"MethodsEasy.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Matrix.jav"));
|
||||
//filesToTest.add(new File(rootDirectory+"Import.jav"));
|
||||
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
|
||||
List<ClassOrInterface> allClasses = new ArrayList<>();
|
||||
for(SourceFile sf : compiler.sourceFiles.values()) {
|
||||
//allClasses.addAll(compiler.getAvailableClasses(sf));
|
||||
}
|
||||
for(SourceFile sf : compiler.sourceFiles.values()) {
|
||||
allClasses.addAll(sf.getClasses());
|
||||
}
|
||||
|
||||
final ConstraintSet<Pair> cons = compiler.getConstraints();
|
||||
ASPGenerator generator = new ASPGenerator(cons, allClasses);
|
||||
System.out.println(generator.getASP());
|
||||
}
|
||||
|
||||
static String readFile(String path, Charset encoding)
|
||||
throws IOException
|
||||
{
|
||||
byte[] encoded = Files.readAllBytes(Paths.get(path));
|
||||
return new String(encoded, encoding);
|
||||
}
|
||||
|
||||
}
|
||||
|
9
test/asp/typeinference/GenericsTest.java
Normal file
9
test/asp/typeinference/GenericsTest.java
Normal file
@ -0,0 +1,9 @@
|
||||
package asp.typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class GenericsTest extends ASPTest {
|
||||
public GenericsTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Generics.jav");
|
||||
}
|
||||
}
|
9
test/asp/typeinference/VectorTest.java
Normal file
9
test/asp/typeinference/VectorTest.java
Normal file
@ -0,0 +1,9 @@
|
||||
package asp.typeinference;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class VectorTest extends ASPTest {
|
||||
public VectorTest() {
|
||||
this.fileToTest = new File(rootDirectory+"Vector.jav");
|
||||
}
|
||||
}
|
10
test/asp/unifywithoutwildcards/ASPTests.java
Normal file
10
test/asp/unifywithoutwildcards/ASPTests.java
Normal file
@ -0,0 +1,10 @@
|
||||
package asp.unifywithoutwildcards;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class ASPTests {
|
||||
@Test
|
||||
public void test(){
|
||||
|
||||
}
|
||||
}
|
11
test/bytecode/DuMethod.jav
Normal file
11
test/bytecode/DuMethod.jav
Normal file
@ -0,0 +1,11 @@
|
||||
public class DuMethod{
|
||||
|
||||
method(a){
|
||||
return a;
|
||||
}
|
||||
|
||||
method(a){
|
||||
return a;
|
||||
}
|
||||
|
||||
}
|
8
test/bytecode/EmptyMethod.jav
Normal file
8
test/bytecode/EmptyMethod.jav
Normal file
@ -0,0 +1,8 @@
|
||||
public class EmptyMethod{
|
||||
|
||||
public void m1(){
|
||||
System.out.println("test");
|
||||
}
|
||||
|
||||
public void m2(){}
|
||||
}
|
14
test/bytecode/Faculty.jav
Normal file
14
test/bytecode/Faculty.jav
Normal file
@ -0,0 +1,14 @@
|
||||
class Faculty {
|
||||
|
||||
Integer mul(Integer x, Integer y) {
|
||||
return x;
|
||||
}
|
||||
|
||||
m () {
|
||||
|
||||
var fact = (Integer x) -> {
|
||||
return mul(x, x);
|
||||
};
|
||||
return fact;
|
||||
}
|
||||
}
|
10
test/bytecode/Faculty2.jav
Normal file
10
test/bytecode/Faculty2.jav
Normal file
@ -0,0 +1,10 @@
|
||||
class Faculty2 {
|
||||
|
||||
m () {
|
||||
|
||||
var fact = (Integer x) -> {
|
||||
return x;
|
||||
};
|
||||
return fact;
|
||||
}
|
||||
}
|
5
test/bytecode/Gen.jav
Normal file
5
test/bytecode/Gen.jav
Normal file
@ -0,0 +1,5 @@
|
||||
public class Gen{
|
||||
Vector<Integer> m(Vector<Integer> v){
|
||||
return v;
|
||||
}
|
||||
}
|
17
test/bytecode/Generics.jav
Normal file
17
test/bytecode/Generics.jav
Normal file
@ -0,0 +1,17 @@
|
||||
|
||||
class Generics<B> {
|
||||
Generics(B b){
|
||||
}
|
||||
B mt1(B b){
|
||||
return mt1(b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Problem:
|
||||
auto test = new List<String>();
|
||||
auto test2 = new List<Integer>();
|
||||
... //code, welcher möglicherweise test und test2 vertauscht
|
||||
test.add("hallo");
|
||||
*/
|
6
test/bytecode/Generics2.jav
Normal file
6
test/bytecode/Generics2.jav
Normal file
@ -0,0 +1,6 @@
|
||||
class Generics2<B extends String>{
|
||||
<B extends Integer> B m1(B b){
|
||||
return b;
|
||||
}
|
||||
|
||||
}
|
7
test/bytecode/Generics2Test.java
Normal file
7
test/bytecode/Generics2Test.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class Generics2Test extends JavaTXCompilerTest{
|
||||
public Generics2Test() {
|
||||
this.fileName = "Generics2";
|
||||
}
|
||||
}
|
7
test/bytecode/GenericsTest.java
Normal file
7
test/bytecode/GenericsTest.java
Normal file
@ -0,0 +1,7 @@
|
||||
package bytecode;
|
||||
|
||||
public class GenericsTest extends JavaTXCompilerTest {
|
||||
public GenericsTest() {
|
||||
this.fileName = "Generics";
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user