forked from JavaTX/JavaCompilerCore
Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into plugin
This commit is contained in:
commit
1437788f5a
@ -17,6 +17,7 @@ import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
|||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
@ -28,6 +29,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
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.GenericInsertPair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
import de.dhbwstuttgart.typeinference.result.ResultPair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
@ -43,6 +45,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private int indexOfFirstParam = 0;
|
private int indexOfFirstParam = 0;
|
||||||
|
|
||||||
|
private String superClass;
|
||||||
|
|
||||||
// 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
|
// stores generics and their bounds of class
|
||||||
@ -50,6 +54,9 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// stores generics and their bounds of method
|
// stores generics and their bounds of method
|
||||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||||
|
|
||||||
|
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
||||||
|
private ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
|
|
||||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
|
||||||
byte[] bytecode;
|
byte[] bytecode;
|
||||||
HashMap<String,byte[]> classFiles;
|
HashMap<String,byte[]> classFiles;
|
||||||
@ -90,6 +97,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ClassOrInterface classOrInterface) {
|
public void visit(ClassOrInterface classOrInterface) {
|
||||||
|
|
||||||
className = classOrInterface.getClassName().toString();
|
className = classOrInterface.getClassName().toString();
|
||||||
|
|
||||||
cw.visitSource(className +".jav", null);
|
cw.visitSource(className +".jav", null);
|
||||||
@ -97,27 +105,42 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
isInterface = (classOrInterface.getModifiers()&512)==512;
|
isInterface = (classOrInterface.getModifiers()&512)==512;
|
||||||
|
|
||||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
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);
|
|
||||||
sig = signature.toString();
|
|
||||||
}
|
|
||||||
// needs implemented Interfaces?
|
|
||||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
|
||||||
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
|
||||||
|
|
||||||
for(Field f : classOrInterface.getFieldDecl()) {
|
|
||||||
f.accept(this);
|
|
||||||
}
|
|
||||||
// resultSet = listOfResultSets.get(0);
|
// resultSet = listOfResultSets.get(0);
|
||||||
boolean isConsWithNoParamsVisited = false;
|
boolean isConsWithNoParamsVisited = false;
|
||||||
|
boolean isVisited = false;
|
||||||
for(ResultSet rs : listOfResultSets) {
|
for(ResultSet rs : listOfResultSets) {
|
||||||
|
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
||||||
resultSet = rs;
|
resultSet = rs;
|
||||||
|
// Nur einmal ausführen!!
|
||||||
|
if(!isVisited) {
|
||||||
|
TPHExtractor tphExtractor = new TPHExtractor();
|
||||||
|
classOrInterface.accept(tphExtractor);
|
||||||
|
|
||||||
|
getCommonTPHS(tphExtractor);
|
||||||
|
ListOfMethodsAndTph = tphExtractor.ListOfMethodsAndTph;
|
||||||
|
String sig = null;
|
||||||
|
/* if class has generics then creates signature
|
||||||
|
* Signature looks like:
|
||||||
|
* <E:Ljava/...>Superclass
|
||||||
|
*/
|
||||||
|
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty()) {
|
||||||
|
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs);
|
||||||
|
sig = signature.toString();
|
||||||
|
System.out.println("Signature: => " + sig);
|
||||||
|
}
|
||||||
|
|
||||||
|
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
||||||
|
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||||
|
|
||||||
|
isVisited = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Field f : classOrInterface.getFieldDecl()) {
|
||||||
|
f.accept(this);
|
||||||
|
}
|
||||||
|
|
||||||
for(Constructor c : classOrInterface.getConstructors()) {
|
for(Constructor c : classOrInterface.getConstructors()) {
|
||||||
if(!isConsWithNoParamsVisited)
|
if(!isConsWithNoParamsVisited)
|
||||||
c.accept(this);
|
c.accept(this);
|
||||||
@ -133,6 +156,36 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void getCommonTPHS(TPHExtractor tphExtractor) {
|
||||||
|
// Gemeinsame TPHs
|
||||||
|
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>();
|
||||||
|
// Alle TPHs der Felder speichern
|
||||||
|
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) {
|
||||||
|
if(!tphExtractor.allTPHS.get(tph))
|
||||||
|
cTPHs.add(tph);
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<MethodAndTPH> tphsMethod = tphExtractor.ListOfMethodsAndTph;
|
||||||
|
// Für jede Methode speichere die gemeinsame TPHs:
|
||||||
|
// -> Für jedes Pair prüfe ob, auf der rechten Seite ein TPH steht, der
|
||||||
|
// in der Liste der TPHs der Methode enthalten ist.
|
||||||
|
// Wenn ja -> gemeinsamer TPH
|
||||||
|
for(MethodAndTPH m:tphsMethod){
|
||||||
|
for(GenericInsertPair p : m.getPairs()){
|
||||||
|
if(!m.getTphs().contains(p.TA2))
|
||||||
|
cTPHs.add(p.TA2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TypePlaceholder tph : cTPHs) {
|
||||||
|
for(GenericInsertPair p : tphExtractor.allPairs) {
|
||||||
|
if(p.contains(tph))
|
||||||
|
commonPairs.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Constructor field) {
|
public void visit(Constructor field) {
|
||||||
field.getParameterList().accept(this);
|
field.getParameterList().accept(this);
|
||||||
@ -156,7 +209,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
desc = constructor.accept(new DescriptorToString(resultSet));
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,resultSet,field, mv,paramsAndLocals,cw,
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
|
||||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
||||||
if(!field.getParameterList().iterator().hasNext()) {
|
if(!field.getParameterList().iterator().hasNext()) {
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
@ -215,11 +268,18 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
/* if method has generics or return type is TPH, create signature */
|
/* if method has generics or return type is TPH, create signature */
|
||||||
// zwite operand muss weggelassen werden
|
// zwite operand muss weggelassen werden
|
||||||
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
|
if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) {
|
||||||
// resultset hier zum testen
|
ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||||
Signature signature = new Signature(method, genericsAndBoundsMethod, methodParamsAndTypes,resultSet);
|
for(MethodAndTPH m : ListOfMethodsAndTph) {
|
||||||
|
if(m.getName().equals(method.name)) {
|
||||||
|
pairs = m.getPairs();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
// System.out.println(sig);
|
System.out.println(method.getName()+" ==> "+sig);
|
||||||
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
||||||
methDesc = meth.accept(new DescriptorToString(resultSet));
|
methDesc = meth.accept(new DescriptorToString(resultSet));
|
||||||
|
|
||||||
@ -227,7 +287,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
|
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,cw,
|
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw,
|
||||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
@ -475,5 +535,49 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
public void visit(UnaryExpr unaryExpr) {
|
public void visit(UnaryExpr unaryExpr) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TPHExtractor extends AbstractASTWalker{
|
||||||
|
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||||
|
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||||
|
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
||||||
|
MethodAndTPH methodAndTph;
|
||||||
|
Boolean inMethod = false;
|
||||||
|
final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
|
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(TypePlaceholder tph) {
|
||||||
|
if(resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
|
||||||
|
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
|
||||||
|
if(inMethod)
|
||||||
|
methodAndTph.getTphs().add(resolvedTPH);
|
||||||
|
|
||||||
|
allTPHS.put(resolvedTPH,inMethod);
|
||||||
|
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{
|
||||||
|
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
|
||||||
|
if(inMethod)
|
||||||
|
methodAndTph.getPairs().add(ag);
|
||||||
|
allPairs.add(ag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
||||||
|
for(int i=0; i<pairs.size();++i) {
|
||||||
|
GenericInsertPair p = pairs.get(i);
|
||||||
|
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void visit(Method method) {
|
||||||
|
inMethod = true;
|
||||||
|
methodAndTph = new MethodAndTPH(method.name);
|
||||||
|
super.visit(method);
|
||||||
|
inMethod = false;
|
||||||
|
ListOfMethodsAndTph.add(methodAndTph);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -29,15 +29,18 @@ import org.objectweb.asm.signature.SignatureWriter;
|
|||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
|
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
import de.dhbwstuttgart.syntaxtree.StatementVisitor;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
public class BytecodeGenMethod implements StatementVisitor {
|
public class BytecodeGenMethod implements StatementVisitor {
|
||||||
@ -50,10 +53,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
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> genericsAndBoundsMethod;
|
||||||
private HashMap<String, String> genericsAndBounds;
|
private HashMap<String, String> genericsAndBounds;
|
||||||
private boolean isBinaryExp = false;
|
private boolean isBinaryExp = false;
|
||||||
|
private String superClass;
|
||||||
|
|
||||||
private IStatement statement = null;
|
private IStatement statement = null;
|
||||||
|
|
||||||
// for tests **
|
// for tests **
|
||||||
@ -67,11 +71,12 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
private ArrayList<RefTypeOrTPHOrWildcardOrGeneric> varsFunInterface = new ArrayList<>();;
|
||||||
|
|
||||||
public BytecodeGenMethod(String className, ResultSet resultSet, Method m, MethodVisitor mv,
|
public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv,
|
||||||
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
HashMap<String, Integer> paramsAndLocals, ClassWriter cw, HashMap<String, String> genericsAndBoundsMethod,
|
||||||
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
HashMap<String, String> genericsAndBounds, boolean isInterface, HashMap<String, byte[]> classFiles) {
|
||||||
|
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
this.superClass = superClass;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.m = m;
|
this.m = m;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
@ -104,7 +109,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
lambdaExpression.methodBody.accept(this);
|
lambdaExpression.methodBody.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void isBinary(boolean isBinary) {
|
||||||
|
this.isBinaryExp =isBinary;
|
||||||
|
}
|
||||||
|
|
||||||
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
@ -120,7 +129,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
superCall.receiver.accept(this);
|
superCall.receiver.accept(this);
|
||||||
superCall.arglist.accept(this);
|
superCall.arglist.accept(this);
|
||||||
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V",
|
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, this.superClass, superCall.name, "()V",
|
||||||
isInterface);
|
isInterface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,6 +176,11 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
doBoxing(binaryType);
|
doBoxing(binaryType);
|
||||||
isBinaryExp = false;
|
isBinaryExp = false;
|
||||||
}
|
}
|
||||||
|
System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType()));
|
||||||
|
String typeOfRightSide = getResolvedType(assign.rightSide.getType());
|
||||||
|
if(typeOfRightSide.contains("<")) {
|
||||||
|
mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<')));
|
||||||
|
}
|
||||||
assign.lefSide.accept(this);
|
assign.lefSide.accept(this);
|
||||||
|
|
||||||
statement = null;
|
statement = null;
|
||||||
@ -621,14 +635,15 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
|
||||||
|
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
|
|
||||||
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
||||||
genericsAndBoundsMethod, genericsAndBounds);
|
genericsAndBoundsMethod, genericsAndBounds);
|
||||||
String mDesc = method.accept(new DescriptorToString(resultSet));
|
String mDesc = method.accept(new DescriptorToString(resultSet));
|
||||||
|
System.out.println("Methodcall Desc : " + mDesc);
|
||||||
// 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()), methodCall.name,
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name,
|
||||||
@ -641,6 +656,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// if(!methodCall.getType().toString().equals("V")) {
|
// if(!methodCall.getType().toString().equals("V")) {
|
||||||
// mv.visitInsn(Opcodes.POP);
|
// mv.visitInsn(Opcodes.POP);
|
||||||
// }
|
// }
|
||||||
|
if(isBinaryExp) {
|
||||||
|
doUnboxing(getResolvedType(methodCall.getType()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -799,7 +817,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
statement = new LoopStmt(whileStmt.expr, whileStmt.loopBlock);
|
statement = new LoopStmt(whileStmt.expr, whileStmt.loopBlock);
|
||||||
isBinaryExp = statement.isExprBinary();
|
isBinaryExp = statement.isExprBinary();
|
||||||
whileStmt.expr.accept(this);
|
whileStmt.expr.accept(this);
|
||||||
isBinaryExp = false;
|
// isBinaryExp = false;
|
||||||
statement = null;
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1040,13 +1058,18 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
String var = assignLeftSide.localVar.name;
|
String var = assignLeftSide.localVar.name;
|
||||||
if (!paramsAndLocals.containsKey(var)) {
|
if (!paramsAndLocals.containsKey(var)) {
|
||||||
paramsAndLocals.put(var, index + 1);
|
paramsAndLocals.put(var, index + 1);
|
||||||
} else {
|
}
|
||||||
paramsAndLocals.put(var, index);
|
|
||||||
|
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(var));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TPHEx extends AbstractASTWalker{
|
||||||
|
// Liste enthält alle tph der Methode
|
||||||
|
ArrayList<TypePlaceholder> allTPHS = new ArrayList<>();
|
||||||
|
@Override
|
||||||
|
public void visit(TypePlaceholder tph) {
|
||||||
|
allTPHS.add(tph);
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size());
|
|
||||||
// Debug:::
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ public class LoopStmt extends AStatement {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
||||||
|
bytecodeGenMethod.isBinary(false);
|
||||||
this.loopBlock.accept(bytecodeGenMethod);
|
this.loopBlock.accept(bytecodeGenMethod);
|
||||||
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
mv.visitJumpInsn(Opcodes.GOTO, endLabel);
|
||||||
mv.visitLabel(branchLabel);
|
mv.visitLabel(branchLabel);
|
||||||
|
@ -2,6 +2,8 @@ package de.dhbwstuttgart.bytecode.descriptor;
|
|||||||
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
import de.dhbwstuttgart.bytecode.utilities.Lambda;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
|
||||||
@ -49,7 +51,8 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
||||||
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||||
desc += "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
// Bound ist immer Object
|
||||||
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
} else {
|
} else {
|
||||||
desc += "L"+resType+ ";";
|
desc += "L"+resType+ ";";
|
||||||
}
|
}
|
||||||
@ -76,7 +79,8 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
}else {
|
}else {
|
||||||
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resType.subSequence(0, 4).equals("TPH ")) {
|
if(resType.subSequence(0, 4).equals("TPH ")) {
|
||||||
desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
// desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
|
||||||
|
desc += ")" + "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
} else {
|
} else {
|
||||||
desc += ")" + "L"+resType+ ";";
|
desc += ")" + "L"+resType+ ";";
|
||||||
}
|
}
|
||||||
@ -141,26 +145,34 @@ public class DescriptorToString implements DescriptorVisitor{
|
|||||||
public String visit(MethodFromMethodCall methodFromMethodCall) {
|
public String visit(MethodFromMethodCall methodFromMethodCall) {
|
||||||
String desc = "(";
|
String desc = "(";
|
||||||
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
|
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
|
||||||
String d = e.getType().acceptTV(new TypeToDescriptor());
|
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
|
|
||||||
desc += "L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(d)+ ";";
|
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) {
|
||||||
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(d)) {
|
desc += "L"+Type.getInternalName(Object.class)+ ";";
|
||||||
desc += "L"+methodFromMethodCall.getGenericsAndBounds().get(d)+ ";";
|
|
||||||
}else {
|
}else {
|
||||||
desc += "L"+resultSet.resolveType(e.getType()).resolvedType.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())+ ";";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
if(resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.toString().equals("void")) {
|
System.out.println("DescriptorToString retType = " + retType);
|
||||||
|
if(retType.equals("void")) {
|
||||||
desc += ")V";
|
desc += ")V";
|
||||||
|
}else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){
|
||||||
|
desc += ")L"+Type.getInternalName(Object.class)+ ";";
|
||||||
}else {
|
}else {
|
||||||
String ret = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
|
||||||
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(ret)) {
|
desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(retType)+ ";";
|
||||||
desc += ")L"+methodFromMethodCall.getGenericsAndBoundsMethod().get(ret)+ ";";
|
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(retType)){
|
||||||
}else if(methodFromMethodCall.getGenericsAndBounds().containsKey(ret)){
|
desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(retType)+ ";";
|
||||||
desc += ")L"+methodFromMethodCall.getGenericsAndBounds().get(ret)+ ";";
|
|
||||||
}else {
|
}else {
|
||||||
desc += ")" + "L"+resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
|
desc += ")" + "L"+retType+ ";";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);
|
// desc = addReturnType(desc, methodFromMethodCall.getReturnType(), resultSet);
|
||||||
|
@ -19,7 +19,9 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visit(SuperWildcardType superWildcardType) {
|
public String visit(SuperWildcardType superWildcardType) {
|
||||||
throw new NotImplementedException();
|
System.out.println("\nWILDCARD ="+superWildcardType.getInnerType().toString().replace(".", "/"));
|
||||||
|
return superWildcardType.getInnerType().toString().replace(".", "/");
|
||||||
|
//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -29,6 +31,7 @@ public class TypeToDescriptor implements TypeVisitor<String>{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
|
System.out.println("\nWILDCARD extends ="+extendsWildcardType.getInnerType().toString().replace(".", "/"));
|
||||||
return extendsWildcardType.getInnerType().toString().replace(".", "/");
|
return extendsWildcardType.getInnerType().toString().replace(".", "/");
|
||||||
//throw new NotImplementedException();
|
//throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package de.dhbwstuttgart.bytecode.signature;
|
package de.dhbwstuttgart.bytecode.signature;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
@ -8,6 +9,7 @@ import org.objectweb.asm.signature.SignatureVisitor;
|
|||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
@ -15,6 +17,8 @@ import de.dhbwstuttgart.syntaxtree.Method;
|
|||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
||||||
|
|
||||||
public class Signature {
|
public class Signature {
|
||||||
@ -26,10 +30,13 @@ public class Signature {
|
|||||||
private Method method;
|
private Method method;
|
||||||
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
|
private ArrayList<GenericInsertPair> commonPairs;
|
||||||
|
private ArrayList<GenericInsertPair> methodPairs;
|
||||||
|
|
||||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds) {
|
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) {
|
||||||
this.classOrInterface = classOrInterface;
|
this.classOrInterface = classOrInterface;
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
|
this.commonPairs = commonPairs;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForClassOrInterface();
|
createSignatureForClassOrInterface();
|
||||||
}
|
}
|
||||||
@ -42,12 +49,14 @@ public class Signature {
|
|||||||
createSignatureForConsOrMethod(this.constructor,true);
|
createSignatureForConsOrMethod(this.constructor,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,
|
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet) {
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet, ArrayList<GenericInsertPair> methodPairs) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||||
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
|
this.methodPairs = methodPairs;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForConsOrMethod(this.method,false);
|
createSignatureForConsOrMethod(this.method,false);
|
||||||
}
|
}
|
||||||
@ -92,28 +101,62 @@ public class Signature {
|
|||||||
GenericTypeVar g = itr.next();
|
GenericTypeVar g = itr.next();
|
||||||
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
||||||
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
||||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
if(ret.substring(0,4).equals("TPH ")) {
|
if(ret.substring(0,4).equals("TPH ")) {
|
||||||
String g = ret.substring(4)+"$";
|
String g = ret.substring(4)+"$";
|
||||||
sw.visitFormalTypeParameter(g);
|
if(genericsAndBounds.containsKey(g)) {
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
genericsAndBoundsMethod.put(g, genericsAndBounds.get(g));
|
||||||
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
|
}else {
|
||||||
sw.visitClassBound().visitEnd();
|
sw.visitFormalTypeParameter(g);
|
||||||
|
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||||
|
genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
|
||||||
|
sw.visitClassBound().visitEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Parameters
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||||
String pT = t.acceptTV(new TypeToSignature());
|
String pT = t.acceptTV(new TypeToSignature());
|
||||||
// S.o
|
// S.o
|
||||||
if(pT.substring(0,4).equals("TPH ") && !genericsAndBoundsMethod.containsKey(pT)) {
|
if(pT.substring(0,4).equals("TPH ")) {
|
||||||
String gP = pT.substring(4)+"$";
|
String gP = pT.substring(4)+"$";
|
||||||
sw.visitFormalTypeParameter(gP);
|
if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) {
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
sw.visitFormalTypeParameter(gP);
|
||||||
genericsAndBoundsMethod.put(gP, Type.getInternalName(Object.class));
|
String bound = Type.getInternalName(Object.class);
|
||||||
sw.visitClassBound().visitEnd();
|
boolean isTypeVar = false;
|
||||||
|
for(GenericInsertPair pair : methodPairs) {
|
||||||
|
if(pT.substring(4).equals(pair.TA1.getName())) {
|
||||||
|
bound = pair.TA2.getName()+"$";
|
||||||
|
isTypeVar = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isTypeVar) {
|
||||||
|
sw.visitClassBound().visitTypeVariable(bound);
|
||||||
|
}else {
|
||||||
|
sw.visitClassBound().visitClassType(bound);
|
||||||
|
sw.visitClassBound().visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
genericsAndBoundsMethod.put(gP, bound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// methodPairs.forEach(p->{
|
||||||
|
// String name = p.TA2.getName() + "$";
|
||||||
|
// if(!genericsAndBoundsMethod.containsKey(name)) {
|
||||||
|
// sw.visitFormalTypeParameter(name);
|
||||||
|
// String bound = Type.getInternalName(Object.class);
|
||||||
|
// sw.visitClassBound().visitClassType(bound);
|
||||||
|
// sw.visitClassBound().visitEnd();
|
||||||
|
// genericsAndBoundsMethod.put(name, bound);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit each method-parameter to create the signature
|
// visit each method-parameter to create the signature
|
||||||
@ -125,15 +168,6 @@ public class Signature {
|
|||||||
if(isConstructor) {
|
if(isConstructor) {
|
||||||
sw.visitReturnType().visitBaseType('V');
|
sw.visitReturnType().visitBaseType('V');
|
||||||
}else {
|
}else {
|
||||||
// String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
|
||||||
// if(ret.substring(0,4).equals("TPH ")) {
|
|
||||||
// String g = ret.substring(4);
|
|
||||||
// if(!genericsAndBoundsMethod.containsKey(g)) {
|
|
||||||
// genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class));
|
|
||||||
// } else {
|
|
||||||
// genericsAndBoundsMethod.put(g+"_", Type.getInternalName(Object.class));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
|
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
|
||||||
// return type deswegen ist false
|
// return type deswegen ist false
|
||||||
doVisitParamsOrReturn(returnType, false);
|
doVisitParamsOrReturn(returnType, false);
|
||||||
@ -194,7 +228,34 @@ public class Signature {
|
|||||||
GenericTypeVar g = itr.next();
|
GenericTypeVar g = itr.next();
|
||||||
getBoundsOfTypeVar(g,genericsAndBounds);
|
getBoundsOfTypeVar(g,genericsAndBounds);
|
||||||
}
|
}
|
||||||
|
if(!commonPairs.isEmpty()) {
|
||||||
|
ArrayList<TypePlaceholder> types = new ArrayList<>();
|
||||||
|
ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
|
||||||
|
|
||||||
|
for(GenericInsertPair p : commonPairs) {
|
||||||
|
types.add(p.TA1);
|
||||||
|
superTypes.add(p.TA2);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(GenericInsertPair p : commonPairs) {
|
||||||
|
String t = p.TA1.getName()+"$";
|
||||||
|
String bound = p.TA2.getName()+"$";
|
||||||
|
sw.visitFormalTypeParameter(t);
|
||||||
|
sw.visitClassBound().visitTypeVariable(bound);
|
||||||
|
genericsAndBounds.put(t, bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(GenericInsertPair p : commonPairs) {
|
||||||
|
if(!types.contains(p.TA2)) {
|
||||||
|
String t = p.TA2.getName()+"$";
|
||||||
|
String bound = Type.getInternalName(Object.class);
|
||||||
|
sw.visitFormalTypeParameter(t);
|
||||||
|
sw.visitClassBound().visitClassType(bound);
|
||||||
|
genericsAndBounds.put(t, bound);
|
||||||
|
sw.visitClassBound().visitEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
sw.visitSuperclass().visitClassType(classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()));;
|
sw.visitSuperclass().visitClassType(classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()));;
|
||||||
sw.visitEnd();
|
sw.visitEnd();
|
||||||
}
|
}
|
||||||
|
29
src/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java
Normal file
29
src/de/dhbwstuttgart/bytecode/utilities/MethodAndTPH.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
|
||||||
|
|
||||||
|
public class MethodAndTPH {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private final ArrayList<TypePlaceholder> tphs = new ArrayList<>();
|
||||||
|
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
|
||||||
|
|
||||||
|
public MethodAndTPH(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<TypePlaceholder> getTphs() {
|
||||||
|
return tphs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayList<GenericInsertPair> getPairs(){
|
||||||
|
return pairs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
}
|
@ -37,8 +37,8 @@ public class FacTest {
|
|||||||
@Test
|
@Test
|
||||||
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class);
|
Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class);
|
||||||
Integer result = (Integer) getFac.invoke(instanceOfClass,3);
|
Double result = (Double) getFac.invoke(instanceOfClass,3);
|
||||||
assertEquals(result, 6);
|
assertEquals(result, 6.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
41
test/bytecode/Tph2Test.java
Normal file
41
test/bytecode/Tph2Test.java
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class Tph2Test {
|
||||||
|
|
||||||
|
private static String path;
|
||||||
|
private static File fileToTest;
|
||||||
|
private static JavaTXCompiler compiler;
|
||||||
|
private static ClassLoader loader;
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static String pathToClassFile;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Tph2.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Tph2");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
fail("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
test/bytecode/TphTest.java
Normal file
40
test/bytecode/TphTest.java
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class TphTest {
|
||||||
|
private static String path;
|
||||||
|
private static File fileToTest;
|
||||||
|
private static JavaTXCompiler compiler;
|
||||||
|
private static ClassLoader loader;
|
||||||
|
private static Class<?> classToTest;
|
||||||
|
private static String pathToClassFile;
|
||||||
|
private static Object instanceOfClass;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setUpBeforeClass() throws Exception {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Tph.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode();
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Tph");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
fail("Not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,14 +2,15 @@ import java.lang.Integer;
|
|||||||
|
|
||||||
class Faculty {
|
class Faculty {
|
||||||
|
|
||||||
Integer mul(Integer x, Integer y) {
|
|
||||||
return x;
|
|
||||||
}
|
|
||||||
|
|
||||||
m () {
|
m () {
|
||||||
|
|
||||||
var fact = (Integer x) -> {
|
var fact = (Integer x) -> {
|
||||||
return mul(x, x);
|
if (x == 1) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return x * fact.apply(x-1);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return fact;
|
return fact;
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
public class IfTest{
|
public class IfTest{
|
||||||
Integer m1(Boolean b) {
|
Integer m1(Boolean b) {
|
||||||
Integer i;
|
Integer i;
|
||||||
|
@ -6,6 +6,6 @@ public class Lambda {
|
|||||||
var lam1 = (Integer x) -> {
|
var lam1 = (Integer x) -> {
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
return lam1;
|
return lam1.apply(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,24 +2,24 @@ import java.util.Vector;
|
|||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
|
|
||||||
class Matrix extends Vector<Vector<Integer>> {
|
public class Matrix extends Vector<Vector<Integer>> {
|
||||||
mul(m) {
|
mul(m) {
|
||||||
var ret = new Matrix();
|
var ret = new Matrix();
|
||||||
var i = 0;
|
var i = 0;
|
||||||
while(i < size()) {
|
while(i < size()) {
|
||||||
// var v1 = this.elementAt(i);
|
var v1 = this.elementAt(i);
|
||||||
// var v2 = new Vector<Integer>();
|
var v2 = new Vector<Integer>();
|
||||||
// var j = 0;
|
var j = 0;
|
||||||
// while(j < v1.size()) {
|
while(j < v1.size()) {
|
||||||
// var erg = 0;
|
// var erg = 0;
|
||||||
// var k = 0;
|
// var k = 0;
|
||||||
// while(k < v1.size()) {
|
// while(k < v1.size()) {
|
||||||
// erg = erg + v1.elementAt(k)
|
// erg = erg + v1.elementAt(k)
|
||||||
// * m.elementAt(k).elementAt(j);
|
// * m.elementAt(k).elementAt(j);
|
||||||
// k++; }
|
// k++; }
|
||||||
// v2.addElement(new Integer(erg));
|
// v2.addElement(new Integer(erg));
|
||||||
// j++; }
|
j++; }
|
||||||
// ret.addElement(v2);
|
ret.addElement(v2);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
11
test/bytecode/javFiles/Tph.jav
Normal file
11
test/bytecode/javFiles/Tph.jav
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
public class Tph {
|
||||||
|
|
||||||
|
m(a,b){
|
||||||
|
var c = m2(b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
m2(b){
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
10
test/bytecode/javFiles/Tph2.jav
Normal file
10
test/bytecode/javFiles/Tph2.jav
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
public class Tph2 {
|
||||||
|
m(a,b){
|
||||||
|
var c = m2(a,b);
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
m2(a,b){
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
}
|
@ -7,7 +7,7 @@ public class Lambda {
|
|||||||
var lam1 = (x) -> {
|
var lam1 = (x) -> {
|
||||||
return x;
|
return x;
|
||||||
};
|
};
|
||||||
return lam1;
|
return lam1.apply(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,12 @@ public class UnifyTest {
|
|||||||
execute(new File(rootDirectory+"fc.jav"));
|
execute(new File(rootDirectory+"fc.jav"));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
@Test
|
@Test
|
||||||
public void lambda() throws IOException, ClassNotFoundException {
|
public void lambda() throws IOException, ClassNotFoundException {
|
||||||
execute(new File(rootDirectory+"Lambda.jav"));
|
execute(new File(rootDirectory+"Lambda.jav"));
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/*
|
/*
|
||||||
@Test
|
@Test
|
||||||
public void lambda2() throws IOException, ClassNotFoundException {
|
public void lambda2() throws IOException, ClassNotFoundException {
|
||||||
@ -74,6 +74,7 @@ public class UnifyTest {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void matrix() throws IOException, ClassNotFoundException {
|
public void matrix() throws IOException, ClassNotFoundException {
|
||||||
@ -81,6 +82,7 @@ public class UnifyTest {
|
|||||||
//JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"Matrix.jav"));
|
//JavaTXCompiler compiler = new JavaTXCompiler(new File(rootDirectory+"Matrix.jav"));
|
||||||
//compiler.generateBytecode();
|
//compiler.generateBytecode();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@Test
|
@Test
|
||||||
|
Loading…
Reference in New Issue
Block a user