Merge branch 'bigRefactoring' into sat
This commit is contained in:
commit
57df329751
@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@ -8,6 +9,9 @@ import org.objectweb.asm.ClassWriter;
|
|||||||
import org.objectweb.asm.FieldVisitor;
|
import org.objectweb.asm.FieldVisitor;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Opcodes;
|
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.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
@ -16,6 +20,7 @@ import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
@ -23,7 +28,6 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|||||||
public class BytecodeGen implements ASTVisitor {
|
public class BytecodeGen implements ASTVisitor {
|
||||||
|
|
||||||
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS);
|
||||||
// String methDesc;
|
|
||||||
|
|
||||||
String type;
|
String type;
|
||||||
|
|
||||||
@ -34,6 +38,12 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
|
// 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;
|
byte[] bytecode;
|
||||||
HashMap<String,byte[]> classFiles;
|
HashMap<String,byte[]> classFiles;
|
||||||
|
|
||||||
@ -45,14 +55,19 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(SourceFile sourceFile) {
|
public void visit(SourceFile sourceFile) {
|
||||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
||||||
isInterface = (cl.getModifiers()&512)==512;
|
|
||||||
System.out.println("IS Interface = "+"modifiers= "+cl.getModifiers()+" ->"+(cl.getModifiers()&512) + isInterface);
|
|
||||||
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
BytecodeGen classGen = new BytecodeGen(classFiles, resultSet);
|
||||||
cl.accept(classGen);
|
cl.accept(classGen);
|
||||||
|
System.out.println("In CLASS: "+(cl.getClassName().toString()));
|
||||||
classGen.writeClass(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) {
|
private void writeClass(String name) {
|
||||||
bytecode = cw.toByteArray();
|
bytecode = cw.toByteArray();
|
||||||
classFiles.put(name, bytecode);
|
classFiles.put(name, bytecode);
|
||||||
@ -62,12 +77,30 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
public HashMap<String,byte[]> getClassFiles() {
|
public HashMap<String,byte[]> getClassFiles() {
|
||||||
return classFiles;
|
return classFiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ClassOrInterface classOrInterface) {
|
public void visit(ClassOrInterface classOrInterface) {
|
||||||
className = classOrInterface.getClassName().toString();
|
className = classOrInterface.getClassName().toString();
|
||||||
// access flages??
|
|
||||||
cw.visit(Opcodes.V1_8, classOrInterface.getModifiers()+Opcodes.ACC_SUPER, classOrInterface.getClassName().toString()
|
isInterface = (classOrInterface.getModifiers()&512)==512;
|
||||||
, null, classOrInterface.getSuperClass().toString().replace(".", "/"), null);
|
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 each field in the class
|
||||||
for(Field f : classOrInterface.getFieldDecl()) {
|
for(Field f : classOrInterface.getFieldDecl()) {
|
||||||
@ -85,16 +118,34 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
|
cw.visitSource(classOrInterface.getClassName().toString()+".jav", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Constructor field) {
|
public void visit(Constructor field) {
|
||||||
Descriptor desc = new Descriptor(field, resultSet);
|
field.getParameterList().accept(this);
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc.getDesc(), null, null);
|
|
||||||
|
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();
|
mv.visitCode();
|
||||||
System.out.println("-----Constructor-----");
|
System.out.println("-----Constructor-----");
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,desc.getDesc(),cw,isInterface);
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw,
|
||||||
|
genericsAndBoundsMethod,genericsAndBounds,isInterface);
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
if(!field.getParameterList().iterator().hasNext()) {
|
||||||
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
|
}
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
@ -104,12 +155,49 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
// 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
|
// else it will be stored in pos 1 and this will be stored in pos 0
|
||||||
method.getParameterList().accept(this);
|
method.getParameterList().accept(this);
|
||||||
Descriptor methDesc = new Descriptor(method,resultSet);
|
|
||||||
|
String methDesc = null;
|
||||||
|
|
||||||
|
// Method getModifiers() ?
|
||||||
|
int acc = isInterface?Opcodes.ACC_ABSTRACT:0;
|
||||||
|
|
||||||
System.out.println("-----Method-----");
|
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();
|
mv.visitCode();
|
||||||
|
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,methDesc.getDesc(),cw,isInterface);
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,method, mv,paramsAndLocals,cw,genericsAndBounds,genericsAndBounds,isInterface);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
@ -117,11 +205,13 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(ParameterList formalParameters) {
|
public void visit(ParameterList formalParameters) {
|
||||||
paramsAndLocals = new HashMap<>();
|
paramsAndLocals = new HashMap<>();
|
||||||
|
methodParamsAndTypes = new HashMap<>();
|
||||||
Iterator<FormalParameter> itr = formalParameters.iterator();
|
Iterator<FormalParameter> itr = formalParameters.iterator();
|
||||||
int i = 1;
|
int i = 1;
|
||||||
while(itr.hasNext()) {
|
while(itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
paramsAndLocals.put(fp.getName(), i);
|
paramsAndLocals.put(fp.getName(), i);
|
||||||
|
methodParamsAndTypes.put(fp.getName(), fp.getType());
|
||||||
fp.accept(this);
|
fp.accept(this);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import de.dhbwstuttgart.syntaxtree.Method;
|
|||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.FunN;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
@ -29,12 +30,13 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
private Method m;
|
private Method m;
|
||||||
private MethodVisitor mv;
|
private MethodVisitor mv;
|
||||||
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
private String desc;
|
|
||||||
private String className;
|
private String className;
|
||||||
private int lamCounter;
|
private int lamCounter;
|
||||||
private ClassWriter cw;
|
private ClassWriter cw;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod;
|
||||||
|
private HashMap<String,String> genericsAndBounds;
|
||||||
|
|
||||||
//for tests **
|
//for tests **
|
||||||
private String fieldName;
|
private String fieldName;
|
||||||
@ -46,8 +48,9 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface;
|
||||||
|
|
||||||
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, HashMap<String, Integer> paramsAndLocals,
|
public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
String desc, ClassWriter cw, boolean isInterface) {
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw,
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod, HashMap<String,String> genericsAndBounds, boolean isInterface) {
|
||||||
|
|
||||||
this.where = "<<<<<< NORMAL METHOD >>>>>>";
|
this.where = "<<<<<< NORMAL METHOD >>>>>>";
|
||||||
|
|
||||||
@ -56,29 +59,32 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
this.m = m;
|
this.m = m;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.paramsAndLocals = paramsAndLocals;
|
this.paramsAndLocals = paramsAndLocals;
|
||||||
this.desc = desc;
|
|
||||||
this.cw = cw;
|
this.cw = cw;
|
||||||
|
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||||
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.lamCounter = -1;
|
this.lamCounter = -1;
|
||||||
|
|
||||||
this.varsFunInterface = new ArrayList<>();
|
this.varsFunInterface = new ArrayList<>();
|
||||||
System.out.println("PARAMS = "+this.paramsAndLocals.size());
|
System.out.println("PARAMS = "+this.paramsAndLocals.size());
|
||||||
this.m.block.accept(this);
|
|
||||||
System.out.println("PARAMS = "+this.paramsAndLocals.size());
|
if(!isInterface)
|
||||||
for(int i = 0; i<this.paramsAndLocals.size();i++) {
|
this.m.block.accept(this);
|
||||||
System.out.println(this.paramsAndLocals.keySet().toArray()[i]);
|
|
||||||
}
|
// 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,ResultSet resultSet ,MethodVisitor mv,
|
public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv,
|
||||||
String desc,int indexOfFirstParamLam, boolean isInterface) {
|
int indexOfFirstParamLam, boolean isInterface) {
|
||||||
System.out.println("\t\t++++++IN LAMBDA -------");
|
System.out.println("\t\t++++++IN LAMBDA -------");
|
||||||
|
|
||||||
this.where = "<<<<<< LAMBDA METHOD >>>>>>";
|
this.where = "<<<<<< LAMBDA METHOD >>>>>>";
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.desc = desc;
|
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.lamCounter = -1;
|
this.lamCounter = -1;
|
||||||
this.varsFunInterface = new ArrayList<>();
|
this.varsFunInterface = new ArrayList<>();
|
||||||
@ -94,7 +100,8 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
return resultSet.resolveType(type).resolvedType.toString().replace(".", "/");
|
// return resultSet.resolveType(type).resolvedType.toString().replace(".", "/");
|
||||||
|
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -113,7 +120,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false);
|
// mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", superCall.name, desc,false);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, desc,isInterface);
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@ -150,9 +157,6 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
assign.rightSide.accept(this);
|
assign.rightSide.accept(this);
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -164,7 +168,11 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
System.out.println("\n++ In Lambda: ");
|
System.out.println("\n++ In Lambda: ");
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
Descriptor lamDesc = new Descriptor(lambdaExpression, resultSet);
|
|
||||||
|
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
|
//Call site, which, when invoked, returns an instance of the functional interface to which
|
||||||
//the lambda is being converted
|
//the lambda is being converted
|
||||||
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
|
||||||
@ -174,10 +182,12 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
|
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory",
|
||||||
"metafactory", mt.toMethodDescriptorString(), false);
|
"metafactory", mt.toMethodDescriptorString(), false);
|
||||||
String methodName = "lambda$new$" + this.lamCounter;
|
String methodName = "lambda$new$" + this.lamCounter;
|
||||||
|
// String typeErasure = "(Ljava/lang/Object;)Ljava/lang/Object;";
|
||||||
// Type erasure
|
// Type erasure
|
||||||
Type arg1 = Type.getMethodType(lamDesc.getDesc());
|
// Type arg1 = Type.getMethodType(typeErasure);
|
||||||
|
Type arg1 = Type.getMethodType(lamDesc);
|
||||||
// real Type
|
// real Type
|
||||||
Type arg3 = Type.getMethodType(lamDesc.getDesc());
|
Type arg3 = Type.getMethodType(lamDesc);
|
||||||
|
|
||||||
int staticOrSpecial=0;
|
int staticOrSpecial=0;
|
||||||
int staticOrInstance=0;
|
int staticOrInstance=0;
|
||||||
@ -197,16 +207,16 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName,
|
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName,
|
||||||
arg3.toString(),false);
|
arg3.toString(),false);
|
||||||
// Descriptor of functional interface methode
|
// Descriptor of functional interface methode
|
||||||
Descriptor fiMethodDesc = new Descriptor(kindOfLambda.getArgumentList(), lambdaExpression.getType(),resultSet);
|
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
|
||||||
|
|
||||||
// Desc: (this/nothing)TargetType
|
// Desc: (this/nothing)TargetType
|
||||||
mv.visitInvokeDynamicInsn("apply", fiMethodDesc.getDesc(), bootstrap,
|
String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet));
|
||||||
|
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap,
|
||||||
arg1, arg2,arg3);
|
arg1, arg2,arg3);
|
||||||
|
|
||||||
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC,
|
||||||
methodName, arg3.toString(), null, null);
|
methodName, arg3.toString(), null, null);
|
||||||
|
|
||||||
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,arg3.toString(),indexOfFirstParamLam,isInterface);
|
new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface);
|
||||||
|
|
||||||
mvLambdaBody.visitMaxs(0, 0);
|
mvLambdaBody.visitMaxs(0, 0);
|
||||||
mvLambdaBody.visitEnd();
|
mvLambdaBody.visitEnd();
|
||||||
@ -274,17 +284,20 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
Descriptor mDesc = new Descriptor(methodCall.arglist, methodCall.getType(),resultSet);
|
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
||||||
|
genericsAndBoundsMethod,genericsAndBounds);
|
||||||
|
String mDesc = method.accept(new DescriptorToString(resultSet));
|
||||||
|
|
||||||
System.out.println("is Vars empty: "+varsFunInterface.isEmpty());
|
System.out.println("is Vars empty: "+varsFunInterface.isEmpty());
|
||||||
|
|
||||||
// is methodCall.receiver functional Interface)?
|
// is methodCall.receiver functional Interface)?
|
||||||
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
if(varsFunInterface.contains(methodCall.receiver.getType())) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()),
|
||||||
methodCall.name, mDesc.getDesc(), false);
|
methodCall.name, mDesc, false);
|
||||||
}else {
|
}else {
|
||||||
|
System.out.println("mDesc = " + mDesc);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()),
|
||||||
methodCall.name, mDesc.getDesc(), isInterface);
|
methodCall.name, mDesc, isInterface);
|
||||||
}
|
}
|
||||||
// test
|
// test
|
||||||
// if(!methodCall.getType().toString().equals("V")) {
|
// if(!methodCall.getType().toString().equals("V")) {
|
||||||
@ -303,7 +316,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
String d = "(";
|
String d = "(";
|
||||||
for(Expression e : methodCall.arglist.getArguments()) {
|
for(Expression e : methodCall.arglist.getArguments()) {
|
||||||
d = d + "L"+e.getType().toString().replace(".", "/") + ";";
|
d = d + "L"+getResolvedType(e.getType()) + ";";
|
||||||
}
|
}
|
||||||
d += ")V";
|
d += ")V";
|
||||||
|
|
||||||
@ -339,7 +352,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
System.out.println("In StaticClassName: ");
|
System.out.println("In StaticClassName: ");
|
||||||
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"),
|
||||||
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
// staticClassName.toString(), staticClassName.getType().toString(), false);
|
||||||
mv.visitFieldInsn(Opcodes.GETSTATIC, staticClassName.getType().toString().replace(".", "/"),
|
mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()),
|
||||||
fieldName, fieldDesc);
|
fieldName, fieldDesc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +392,7 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
// value?
|
// value?
|
||||||
mv.visitLdcInsn(literal.getType().toString());
|
mv.visitLdcInsn(getResolvedType(literal.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -393,14 +406,16 @@ public class BytecodeGenMethod implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
|
// temporäre Lösung für testen, bis ich weiss wie man funktionale
|
||||||
|
// interfaces erkennt
|
||||||
if(isRightSideALambda)
|
if(isRightSideALambda)
|
||||||
varsFunInterface.add(assignLeftSide.field.getType());
|
varsFunInterface.add(assignLeftSide.field.getType());
|
||||||
// Loads the an object reference from the local variable
|
// Loads the an object reference from the local variable
|
||||||
// array slot onto the top of the operand stack.
|
// array slot onto the top of the operand stack.
|
||||||
assignLeftSide.field.receiver.accept(this);
|
assignLeftSide.field.receiver.accept(this);
|
||||||
this.rightSideTemp.accept(this);
|
this.rightSideTemp.accept(this);
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, assignLeftSide.field.receiver.getType().toString(),
|
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
||||||
assignLeftSide.field.fieldVarName, assignLeftSide.field.getType().toString());
|
assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,112 +0,0 @@
|
|||||||
package de.dhbwstuttgart.bytecode;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Iterator;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|
||||||
|
|
||||||
public class Descriptor {
|
|
||||||
String desc;
|
|
||||||
|
|
||||||
public Descriptor(Method method, ResultSet resultSet) {
|
|
||||||
desc = "(";
|
|
||||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
|
||||||
}
|
|
||||||
desc = addReturnType(desc,method.getReturnType(), resultSet);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private class TypeToDescriptor implements TypeVisitor<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();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String visit(GenericRefType genericRefType) {
|
|
||||||
return genericRefType.getParsedName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String addReturnType(String desc2, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
|
|
||||||
System.out.println("DescType = "+returnType.toString());
|
|
||||||
if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){
|
|
||||||
desc = desc + ")V";
|
|
||||||
}else {
|
|
||||||
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";";
|
|
||||||
}
|
|
||||||
return desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Descriptor(Constructor constructor, ResultSet resultSet) {
|
|
||||||
desc = "(";
|
|
||||||
Iterator<FormalParameter> itr = constructor.getParameterList().iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";";
|
|
||||||
}
|
|
||||||
desc = desc + ")V";
|
|
||||||
}
|
|
||||||
|
|
||||||
public Descriptor(LambdaExpression lambdaExpr, ResultSet resultSet) {
|
|
||||||
desc = "(";
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpr.params.iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
FormalParameter fp = itr.next();
|
|
||||||
desc = desc + "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "/") + ";";
|
|
||||||
}
|
|
||||||
desc = addReturnType(desc, lambdaExpr.getReturnType(), resultSet);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Descriptor(ArgumentList argList, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
|
|
||||||
desc = "(";
|
|
||||||
for(Expression e : argList.getArguments()) {
|
|
||||||
desc = desc + "L"+resultSet.resolveType(e.getType()).resolvedType.toString().replace(".", "/") + ";";
|
|
||||||
}
|
|
||||||
desc = addReturnType(desc, returnType, resultSet);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Descriptor(List<RefTypeOrTPHOrWildcardOrGeneric> argumentList,RefTypeOrTPHOrWildcardOrGeneric returnType ,ResultSet resultSet) {
|
|
||||||
desc = "(";
|
|
||||||
Iterator<RefTypeOrTPHOrWildcardOrGeneric> itr = argumentList.iterator();
|
|
||||||
while(itr.hasNext()) {
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
|
|
||||||
desc = desc + "L"+resultSet.resolveType(rt).resolvedType.toString().replace(".", "/")+";";
|
|
||||||
}
|
|
||||||
desc = desc + ")"+"L"+resultSet.resolveType(returnType).resolvedType.toString().replace(".", "/")+";";
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDesc() {
|
|
||||||
return this.desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
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);
|
||||||
|
}
|
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.getType();
|
||||||
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -6,6 +6,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSetVisitor;
|
|||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +29,15 @@ public class RefType extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
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
|
@Override
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
|
||||||
class Generics<B> {
|
class Generics<B> {
|
||||||
|
Generics(B b){
|
||||||
|
}
|
||||||
B mt1(B b){
|
B mt1(B b){
|
||||||
return mt1(b);
|
return mt1(b);
|
||||||
}
|
}
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
}
|
7
test/bytecode/InterfaceTest.java
Normal file
7
test/bytecode/InterfaceTest.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
public class InterfaceTest extends JavaTXCompilerTest{
|
||||||
|
public InterfaceTest() {
|
||||||
|
this.fileName = "Interface1";
|
||||||
|
}
|
||||||
|
}
|
@ -25,11 +25,12 @@ public class JavaTXCompilerTest {
|
|||||||
|
|
||||||
private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/";
|
||||||
private static final List<File> filesToTest = new ArrayList<>();
|
private static final List<File> filesToTest = new ArrayList<>();
|
||||||
|
|
||||||
|
protected String fileName = "";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws IOException, java.lang.ClassNotFoundException {
|
public void test() throws IOException, java.lang.ClassNotFoundException {
|
||||||
System.out.println(rootDirectory);
|
System.out.println(rootDirectory);
|
||||||
String fileName = "Generics";
|
|
||||||
filesToTest.add(new File(rootDirectory+fileName+".jav"));
|
filesToTest.add(new File(rootDirectory+fileName+".jav"));
|
||||||
System.out.println(rootDirectory+fileName+".jav");
|
System.out.println(rootDirectory+fileName+".jav");
|
||||||
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
|
JavaTXCompiler compiler = new JavaTXCompiler(filesToTest);
|
||||||
@ -48,7 +49,7 @@ public class JavaTXCompilerTest {
|
|||||||
if(pos != -1) {
|
if(pos != -1) {
|
||||||
name = f.getName().substring(0, pos);
|
name = f.getName().substring(0, pos);
|
||||||
}
|
}
|
||||||
this.writeClassFile(bytecode, name);
|
this.writeClassFile(bytecode);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -61,20 +62,23 @@ public class JavaTXCompilerTest {
|
|||||||
return bytecodeGen.getClassFiles();
|
return bytecodeGen.getClassFiles();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeClassFile(HashMap<String,byte[]> classFiles, String name) {
|
public void writeClassFile(HashMap<String,byte[]> classFiles) {
|
||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
byte[] bytecode = classFiles.get(name);
|
for(String name : classFiles.keySet()) {
|
||||||
try {
|
byte[] bytecode = classFiles.get(name);
|
||||||
System.out.println("generating .class file");
|
try {
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
System.out.println("generating"+name+ ".class file");
|
||||||
output.write(bytecode);
|
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
||||||
output.close();
|
output.write(bytecode);
|
||||||
System.out.println(".class file generated");
|
output.close();
|
||||||
} catch (FileNotFoundException e) {
|
System.out.println(name+".class file generated");
|
||||||
e.printStackTrace();
|
} catch (FileNotFoundException e) {
|
||||||
} catch (IOException e) {
|
e.printStackTrace();
|
||||||
e.printStackTrace();
|
} catch (IOException e) {
|
||||||
}
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static String readFile(String path, Charset encoding)
|
static String readFile(String path, Charset encoding)
|
||||||
|
@ -7,3 +7,7 @@ class LamAssign {
|
|||||||
return lam1;
|
return lam1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Fun1<A,B>{
|
||||||
|
A apply(B b);
|
||||||
|
}
|
||||||
|
7
test/bytecode/LamAssignTest.java
Normal file
7
test/bytecode/LamAssignTest.java
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
public class LamAssignTest extends JavaTXCompilerTest{
|
||||||
|
public LamAssignTest() {
|
||||||
|
this.fileName = "LamAssign";
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user