forked from JavaTX/JavaCompilerCore
Klassendatei fuer FunN beim Methodaufruf wird erzeugt, wenn der Receiver
den Typ FunN besitzt. Die Loesung vom Duplicate Field Problem wird angepasst.
This commit is contained in:
parent
9ffc74467b
commit
73f412d22d
@ -46,11 +46,11 @@ import de.dhbwstuttgart.typeinference.result.ResultPair;
|
|||||||
import de.dhbwstuttgart.typeinference.result.ResultSet;
|
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 type;
|
String type;
|
||||||
|
|
||||||
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
|
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
|
||||||
String className;
|
String className;
|
||||||
private boolean isInterface;
|
private boolean isInterface;
|
||||||
@ -58,35 +58,38 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private SourceFile sf;
|
private SourceFile sf;
|
||||||
private String path;
|
private String path;
|
||||||
|
|
||||||
private Optional<Constructor> fieldInitializations;
|
private Optional<Constructor> fieldInitializations;
|
||||||
|
|
||||||
private int indexOfFirstParam = 0;
|
private int indexOfFirstParam = 0;
|
||||||
|
|
||||||
private String superClass;
|
private String superClass;
|
||||||
|
|
||||||
private ArrayList<String> tphsClass;
|
private ArrayList<String> tphsClass;
|
||||||
|
|
||||||
// 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
|
||||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||||
|
|
||||||
private int constructorPos = 0;
|
private int constructorPos = 0;
|
||||||
|
|
||||||
private final TPHExtractor tphExtractor = new TPHExtractor();
|
private final TPHExtractor tphExtractor = new TPHExtractor();
|
||||||
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> commonPairs = 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;
|
||||||
|
|
||||||
private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
|
||||||
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
|
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
|
||||||
|
|
||||||
private HashMap<String, SimplifyResult> simplifyResults = new HashMap<>();
|
private HashMap<String, SimplifyResult> simplifyResults = new HashMap<>();
|
||||||
private List<HashMap<String, SimplifyResult>> simplifyResultsList = new ArrayList<>();
|
private List<HashMap<String, SimplifyResult>> simplifyResultsList = new ArrayList<>();
|
||||||
|
|
||||||
|
private final ArrayList<String> fieldNameSignature = new ArrayList<>();
|
||||||
|
|
||||||
public List<HashMap<String, SimplifyResult>> getSimplifyResultsList() {
|
public List<HashMap<String, SimplifyResult>> getSimplifyResultsList() {
|
||||||
return simplifyResultsList;
|
return simplifyResultsList;
|
||||||
}
|
}
|
||||||
@ -95,16 +98,17 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
this.simplifyResultsList = simplifyResultsList;
|
this.simplifyResultsList = simplifyResultsList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets,SourceFile sf ,String path) {
|
public BytecodeGen(HashMap<String, byte[]> classFiles, List<ResultSet> listOfResultSets, SourceFile sf,
|
||||||
|
String path) {
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.listOfResultSets = listOfResultSets;
|
this.listOfResultSets = listOfResultSets;
|
||||||
this.sf = sf;
|
this.sf = sf;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SourceFile sourceFile) {
|
public void visit(SourceFile sourceFile) {
|
||||||
for(ClassOrInterface cl : sourceFile.getClasses()) {
|
for (ClassOrInterface cl : sourceFile.getClasses()) {
|
||||||
System.out.println("in Class: " + cl.getClassName().toString());
|
System.out.println("in Class: " + cl.getClassName().toString());
|
||||||
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path);
|
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path);
|
||||||
cl.accept(classGen);
|
cl.accept(classGen);
|
||||||
@ -112,73 +116,74 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
classGen.writeClass(cl.getClassName().toString());
|
classGen.writeClass(cl.getClassName().toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Associates the bytecode of the class that was build with the classWriter {@link #cw}
|
* Associates the bytecode of the class that was build with the classWriter
|
||||||
* with the class name in the map {@link #classFiles}
|
* {@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
|
* @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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
cw.visitSource(className +".jav", null);
|
|
||||||
|
|
||||||
isInterface = (classOrInterface.getModifiers()&512)==512;
|
|
||||||
|
|
||||||
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER;
|
className = classOrInterface.getClassName().toString();
|
||||||
|
|
||||||
|
cw.visitSource(className + ".jav", null);
|
||||||
|
|
||||||
|
isInterface = (classOrInterface.getModifiers() & 512) == 512;
|
||||||
|
|
||||||
|
int acc = isInterface ? classOrInterface.getModifiers() + Opcodes.ACC_ABSTRACT
|
||||||
|
: classOrInterface.getModifiers() + Opcodes.ACC_SUPER;
|
||||||
|
|
||||||
fieldInitializations = classOrInterface.getfieldInitializations();
|
fieldInitializations = classOrInterface.getfieldInitializations();
|
||||||
|
|
||||||
// resultSet = listOfResultSets.get(0);
|
// resultSet = listOfResultSets.get(0);
|
||||||
boolean isConsWithNoParamsVisited = false;
|
boolean isConsWithNoParamsVisited = false;
|
||||||
boolean isVisited = false;
|
boolean isVisited = false;
|
||||||
for(ResultSet rs : listOfResultSets) {
|
for (ResultSet rs : listOfResultSets) {
|
||||||
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
|
||||||
resultSet = rs;
|
resultSet = rs;
|
||||||
tphExtractor.setResultSet(resultSet);
|
tphExtractor.setResultSet(resultSet);
|
||||||
|
|
||||||
// Nur einmal ausführen!!
|
// Nur einmal ausführen!!
|
||||||
if(!isVisited) {
|
if (!isVisited) {
|
||||||
classOrInterface.accept(tphExtractor);
|
classOrInterface.accept(tphExtractor);
|
||||||
|
|
||||||
getCommonTPHS(tphExtractor);
|
getCommonTPHS(tphExtractor);
|
||||||
|
|
||||||
tphsClass = new ArrayList<>();
|
tphsClass = new ArrayList<>();
|
||||||
for(String t : tphExtractor.allTPHS.keySet()) {
|
for (String t : tphExtractor.allTPHS.keySet()) {
|
||||||
if(!tphExtractor.allTPHS.get(t))
|
if (!tphExtractor.allTPHS.get(t))
|
||||||
tphsClass.add(t);
|
tphsClass.add(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
String sig = null;
|
String sig = null;
|
||||||
/* if class has generics then creates signature
|
/*
|
||||||
* Signature looks like:
|
* if class has generics then creates signature Signature looks like:
|
||||||
* <E:Ljava/...>Superclass
|
* <E:Ljava/...>Superclass
|
||||||
*/
|
*/
|
||||||
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
|
if (classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty()
|
||||||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
|| classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|
||||||
|| !tphsClass.isEmpty()) {
|
|| !tphsClass.isEmpty()) {
|
||||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify
|
||||||
|
.simplifyConstraintsClass(tphExtractor, tphsClass);
|
||||||
ArrayList<TPHConstraint> consClass = new ArrayList<>();
|
ArrayList<TPHConstraint> consClass = new ArrayList<>();
|
||||||
for(TPHConstraint cons : constraints.keySet()) {
|
for (TPHConstraint cons : constraints.keySet()) {
|
||||||
String right = null;
|
String right = null;
|
||||||
boolean isToAdd = false;
|
boolean isToAdd = false;
|
||||||
for(String tph : tphsClass) {
|
for (String tph : tphsClass) {
|
||||||
if(cons.getLeft().equals(tph)) {
|
if (cons.getLeft().equals(tph)) {
|
||||||
|
|
||||||
consClass.add(cons);
|
consClass.add(cons);
|
||||||
try {
|
try {
|
||||||
right = getTPH(cons.getRight());
|
right = getTPH(cons.getRight());
|
||||||
@ -186,14 +191,14 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
} catch (NoSuchElementException e) {
|
} catch (NoSuchElementException e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(isToAdd) {
|
if (isToAdd) {
|
||||||
tphsClass.add(right);
|
tphsClass.add(right);
|
||||||
removeFromMethod(right);
|
removeFromMethod(right);
|
||||||
right = null;
|
right = null;
|
||||||
isToAdd= false;
|
isToAdd = false;
|
||||||
}
|
}
|
||||||
// if(right != null) {
|
// if(right != null) {
|
||||||
// tphsClass.add(right);
|
// tphsClass.add(right);
|
||||||
@ -201,73 +206,74 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// right = null;
|
// right = null;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
|
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
|
||||||
simplifyResults.put(className, sRes);
|
simplifyResults.put(className, sRes);
|
||||||
|
|
||||||
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
|
Signature signature = new Signature(classOrInterface, genericsAndBounds, commonPairs, tphsClass,
|
||||||
|
consClass);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
System.out.println("Signature: => " + sig);
|
System.out.println("Signature: => " + sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
|
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString(), sig,
|
||||||
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
|
||||||
|
|
||||||
isVisited = true;
|
isVisited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Field f : classOrInterface.getFieldDecl()) {
|
for (Field f : classOrInterface.getFieldDecl()) {
|
||||||
f.accept(this);
|
f.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Constructor c : classOrInterface.getConstructors()) {
|
for (Constructor c : classOrInterface.getConstructors()) {
|
||||||
// if(!isConsWithNoParamsVisited) {
|
// if(!isConsWithNoParamsVisited) {
|
||||||
c.accept(this);
|
c.accept(this);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// if(!c.getParameterList().iterator().hasNext())
|
// if(!c.getParameterList().iterator().hasNext())
|
||||||
// isConsWithNoParamsVisited = true;
|
// isConsWithNoParamsVisited = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Method m : classOrInterface.getMethods()) {
|
for (Method m : classOrInterface.getMethods()) {
|
||||||
m.accept(this);
|
m.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeFromMethod(String name) {
|
private void removeFromMethod(String name) {
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
ArrayList<String> toRemove = new ArrayList<>();
|
ArrayList<String> toRemove = new ArrayList<>();
|
||||||
for(String tph : m.getTphs()) {
|
for (String tph : m.getTphs()) {
|
||||||
if(tph.equals(name)) {
|
if (tph.equals(name)) {
|
||||||
toRemove.add(tph);
|
toRemove.add(tph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!toRemove.isEmpty()) {
|
if (!toRemove.isEmpty()) {
|
||||||
m.getTphs().removeAll(toRemove);
|
m.getTphs().removeAll(toRemove);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getTPH(String name) {
|
private String getTPH(String name) {
|
||||||
for(String tph: tphExtractor.allTPHS.keySet()) {
|
for (String tph : tphExtractor.allTPHS.keySet()) {
|
||||||
if(tph.equals(name))
|
if (tph.equals(name))
|
||||||
return tph;
|
return tph;
|
||||||
}
|
}
|
||||||
throw new NoSuchElementException("TPH "+name +" does not exist");
|
throw new NoSuchElementException("TPH " + name + " does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void getCommonTPHS(TPHExtractor tphExtractor) {
|
private void getCommonTPHS(TPHExtractor tphExtractor) {
|
||||||
// Gemeinsame TPHs
|
// Gemeinsame TPHs
|
||||||
ArrayList<String> cTPHs = new ArrayList<>();
|
ArrayList<String> cTPHs = new ArrayList<>();
|
||||||
// Alle TPHs der Felder speichern
|
// Alle TPHs der Felder speichern
|
||||||
for(String tph : tphExtractor.allTPHS.keySet()) {
|
for (String tph : tphExtractor.allTPHS.keySet()) {
|
||||||
if(!tphExtractor.allTPHS.get(tph))
|
if (!tphExtractor.allTPHS.get(tph))
|
||||||
cTPHs.add(tph);
|
cTPHs.add(tph);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -275,157 +281,168 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Constructor field) {
|
public void visit(Constructor field) {
|
||||||
System.out.println("ResultSet: ");
|
System.out.println("ResultSet: ");
|
||||||
resultSet.results.forEach(a->{
|
resultSet.results.forEach(a -> {
|
||||||
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
||||||
});
|
});
|
||||||
System.out.println("---------------");
|
System.out.println("---------------");
|
||||||
|
|
||||||
// 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<>();
|
||||||
|
|
||||||
field.getParameterList().accept(this);
|
field.getParameterList().accept(this);
|
||||||
|
|
||||||
String methParamTypes = field.name+"%%";
|
String methParamTypes = field.name + "%%";
|
||||||
|
|
||||||
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
||||||
while(itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
|
||||||
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
if (methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes);
|
System.out.println("ignore - Method: " + field.name + " , paramsType: " + methParamTypes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
methodNameAndParamsT.add(methParamTypes);
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes);
|
System.out.println("Method: " + field.name + " , paramsType: " + methParamTypes);
|
||||||
|
|
||||||
String desc = null;
|
String desc = null;
|
||||||
boolean hasGen = false;
|
boolean hasGen = false;
|
||||||
|
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||||
System.out.println(typeOfParam);
|
System.out.println(typeOfParam);
|
||||||
if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.contains("$")
|
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) {
|
||||||
|| typeOfParam.contains("<")) {
|
|
||||||
hasGen = true;
|
hasGen = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String sig = null;
|
String sig = null;
|
||||||
if(hasGen) {
|
if (hasGen) {
|
||||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,
|
||||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
tphsClass);
|
||||||
|
Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
if(field.getParameterList().iterator().hasNext())
|
if (field.getParameterList().iterator().hasNext())
|
||||||
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
|
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
|
||||||
|
|
||||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
NormalConstructor constructor = new NormalConstructor(field, genericsAndBounds, hasGen);
|
||||||
desc = constructor.accept(new DescriptorToString(resultSet));
|
desc = constructor.accept(new DescriptorToString(resultSet));
|
||||||
System.out.println("Constructor: " + field.getName() + " Sig: "+ sig + " Desc: " + desc);
|
System.out.println("Constructor: " + field.getName() + " Sig: " + sig + " Desc: " + desc);
|
||||||
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();
|
||||||
|
|
||||||
Block block = fieldInitializations.get().block;
|
Block block = fieldInitializations.get().block;
|
||||||
|
|
||||||
constructorPos += 1;
|
constructorPos += 1;
|
||||||
|
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
|
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw,
|
||||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path, block, constructorPos);
|
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos);
|
||||||
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) {
|
if (!field.getParameterList().iterator().hasNext()
|
||||||
|
&& !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) {
|
||||||
mv.visitInsn(Opcodes.RETURN);
|
mv.visitInsn(Opcodes.RETURN);
|
||||||
}
|
}
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Method method) {
|
public void visit(Method method) {
|
||||||
// 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
|
||||||
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
String methParamTypes = retType+method.name+"%%";
|
String methParamTypes = retType + method.name + "%%";
|
||||||
method.getParameterList().accept(this);
|
method.getParameterList().accept(this);
|
||||||
|
|
||||||
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
Iterator<FormalParameter> itr = method.getParameterList().iterator();
|
||||||
while(itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
|
||||||
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
if (methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
methodNameAndParamsT.add(methParamTypes);
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
System.out.println("Method: " + method.name + " , paramsType: " + methParamTypes);
|
||||||
// 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<>();
|
||||||
String methDesc = null;
|
String methDesc = null;
|
||||||
|
|
||||||
// Method getModifiers() ?
|
// Method getModifiers() ?
|
||||||
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
|
int acc = isInterface ? Opcodes.ACC_ABSTRACT : method.modifier;
|
||||||
System.out.println(acc);
|
System.out.println(acc);
|
||||||
|
|
||||||
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
|
/* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */
|
||||||
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") ||
|
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ")
|
||||||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<");
|
|| resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature())
|
||||||
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
|
.contains("<");
|
||||||
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
|
/*
|
||||||
if(!hasGenInParameterList) {
|
* Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature,
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
* wenn nicht, prüfe, ob einer der Parameter Typ-Variable als Typ hat
|
||||||
|
*/
|
||||||
|
if (!hasGenInParameterList) {
|
||||||
|
for (String paramName : methodParamsAndTypes.keySet()) {
|
||||||
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
|
||||||
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
|
||||||
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.contains("TPH ")||sigOfParam.contains("<")) {
|
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ")
|
||||||
|
|| sigOfParam.contains("<")) {
|
||||||
hasGenInParameterList = true;
|
hasGenInParameterList = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
|
// TODO: Test if the return-type or any of the parameter is a parameterized
|
||||||
//then create the descriptor with the new syntax.
|
// type. (VP)
|
||||||
|
// then create the descriptor with the new syntax.
|
||||||
|
|
||||||
String sig = null;
|
String sig = null;
|
||||||
/* method.getGenerics: <....> RT method(..)
|
/*
|
||||||
* */
|
* method.getGenerics: <....> RT method(..)
|
||||||
|
*/
|
||||||
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
|
||||||
/* 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||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) {
|
if (hasGen || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
|
||||||
|
.equals("TPH")) {
|
||||||
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
||||||
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
|
tphExtractor.allCons.forEach(c -> System.out.println(c.toString()));
|
||||||
System.out.println("----------------");
|
System.out.println("----------------");
|
||||||
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name,
|
||||||
|
tphExtractor, tphsClass);
|
||||||
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
||||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,
|
||||||
|
methodParamsAndTypes, resultSet, constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
if(simplifyResults.containsKey(className)) {
|
if (simplifyResults.containsKey(className)) {
|
||||||
simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints);
|
simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints);
|
||||||
} else {
|
} else {
|
||||||
SimplifyResult sRes = new SimplifyResult(new ArrayList<>(), new ArrayList<>(), new HashMap<>());
|
SimplifyResult sRes = new SimplifyResult(new ArrayList<>(), new ArrayList<>(), new HashMap<>());
|
||||||
sRes.getMethodsConstraints().put(methParamTypes, constraints);
|
sRes.getMethodsConstraints().put(methParamTypes, constraints);
|
||||||
simplifyResults.put(className, sRes);
|
simplifyResults.put(className, sRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
System.out.println(method.getName()+" ==> "+sig);
|
|
||||||
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen);
|
|
||||||
methDesc = meth.accept(new DescriptorToString(resultSet));
|
|
||||||
|
|
||||||
// System.out.println(methDesc);
|
|
||||||
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null);
|
|
||||||
|
|
||||||
mv.visitCode();
|
}
|
||||||
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw,
|
System.out.println(method.getName() + " ==> " + sig);
|
||||||
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path);
|
NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen);
|
||||||
|
methDesc = meth.accept(new DescriptorToString(resultSet));
|
||||||
|
|
||||||
|
// System.out.println(methDesc);
|
||||||
|
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + acc, method.getName(), methDesc, sig, null);
|
||||||
|
|
||||||
|
mv.visitCode();
|
||||||
|
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, method, mv, paramsAndLocals, cw,
|
||||||
|
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path);
|
||||||
|
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<String, SimplifyResult> getSimplifyResults() {
|
public HashMap<String, SimplifyResult> getSimplifyResults() {
|
||||||
return simplifyResults;
|
return simplifyResults;
|
||||||
}
|
}
|
||||||
@ -436,7 +453,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
methodParamsAndTypes = 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(), resultSet.resolveType(fp.getType()).resolvedType);
|
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
|
||||||
@ -444,39 +461,39 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(FormalParameter formalParameter) {
|
public void visit(FormalParameter formalParameter) {
|
||||||
formalParameter.getType().accept(this);
|
formalParameter.getType().accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(RefType refType) {
|
public void visit(RefType refType) {
|
||||||
type = "L"+refType.toString()+";";
|
type = "L" + refType.toString() + ";";
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SuperWildcardType superWildcardType) {
|
public void visit(SuperWildcardType superWildcardType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(TypePlaceholder typePlaceholder) {
|
public void visit(TypePlaceholder typePlaceholder) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ExtendsWildcardType extendsWildcardType) {
|
public void visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GenericRefType genericRefType) {
|
public void visit(GenericRefType genericRefType) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ??
|
// ??
|
||||||
@ -484,48 +501,51 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
System.out.println("In FieldVar ---");
|
System.out.println("In FieldVar ---");
|
||||||
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L" + fieldVar.getType() + ";",
|
||||||
|
null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Field field) {
|
public void visit(Field field) {
|
||||||
System.out.println("In Field ---");
|
System.out.println("In Field ---");
|
||||||
String des = "L";
|
String des = "L";
|
||||||
if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
|
if (resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
|
||||||
des += Type.getInternalName(Object.class);
|
des += Type.getInternalName(Object.class);
|
||||||
} else {
|
} else {
|
||||||
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
}
|
}
|
||||||
des +=";";
|
des += ";";
|
||||||
System.out.println(des);
|
System.out.println(des);
|
||||||
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature());
|
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
System.out.println(sig);
|
System.out.println(sig);
|
||||||
if(sig.charAt(sig.length()-1) != (";").charAt(0)) {
|
if (sig.charAt(sig.length() - 1) != (";").charAt(0)) {
|
||||||
sig +=";";
|
sig += ";";
|
||||||
}
|
}
|
||||||
String nameAndDesc = field.getName() + "%%" + des;
|
String nameAndDesc = field.getName() + "%%" + des;
|
||||||
|
String nameAndSig = field.getName() + "%%" + sig;
|
||||||
if(fieldNameAndParamsT.contains(nameAndDesc))
|
if (fieldNameAndParamsT.contains(nameAndDesc)) {
|
||||||
|
if (fieldNameSignature.contains(nameAndSig)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
|
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
|
||||||
|
}
|
||||||
fieldNameAndParamsT.add(nameAndDesc);
|
fieldNameAndParamsT.add(nameAndDesc);
|
||||||
|
fieldNameSignature.add(nameAndSig);
|
||||||
cw.visitField(field.modifier, field.getName(),
|
|
||||||
des, sig,
|
cw.visitField(field.modifier, field.getName(), des, sig, null);
|
||||||
null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Assign assign) {
|
public void visit(Assign assign) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -536,151 +556,151 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Block block) {
|
public void visit(Block block) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(CastExpr castExpr) {
|
public void visit(CastExpr castExpr) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(EmptyStmt emptyStmt) {
|
public void visit(EmptyStmt emptyStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ForStmt forStmt) {
|
public void visit(ForStmt forStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(InstanceOf instanceOf) {
|
public void visit(InstanceOf instanceOf) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVar localVar) {
|
public void visit(LocalVar localVar) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(LocalVarDecl localVarDecl) {
|
public void visit(LocalVarDecl localVarDecl) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewClass methodCall) {
|
public void visit(NewClass methodCall) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(NewArray newArray) {
|
public void visit(NewArray newArray) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Return aReturn) {
|
public void visit(Return aReturn) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ReturnVoid aReturn) {
|
public void visit(ReturnVoid aReturn) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(StaticClassName staticClassName) {
|
public void visit(StaticClassName staticClassName) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Super aSuper) {
|
public void visit(Super aSuper) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStmt whileStmt) {
|
public void visit(WhileStmt whileStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(DoStmt whileStmt) {
|
public void visit(DoStmt whileStmt) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ???
|
// ???
|
||||||
@Override
|
@Override
|
||||||
public void visit(Literal literal) {
|
public void visit(Literal literal) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ArgumentList argumentList) {
|
public void visit(ArgumentList argumentList) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GenericTypeVar genericTypeVar) {
|
public void visit(GenericTypeVar genericTypeVar) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(GenericDeclarationList genericTypeVars) {
|
public void visit(GenericDeclarationList genericTypeVars) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(AssignToLocal assignLeftSide) {
|
public void visit(AssignToLocal assignLeftSide) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(SuperCall superCall) {
|
public void visit(SuperCall superCall) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -693,6 +713,5 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
public void visit(UnaryExpr unaryExpr) {
|
public void visit(UnaryExpr unaryExpr) {
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -678,7 +678,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
methSig.visitReturnType().visitTypeVariable("R");
|
methSig.visitReturnType().visitTypeVariable("R");
|
||||||
// ")"+lam.getReturn.getBounds
|
// ")"+lam.getReturn.getBounds
|
||||||
Signature sig = new Signature(lambdaExpression, numberOfParams);
|
Signature sig = new Signature(numberOfParams);
|
||||||
String name = "Fun" + numberOfParams + "$$";
|
String name = "Fun" + numberOfParams + "$$";
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
Type.getInternalName(Object.class), null);
|
Type.getInternalName(Object.class), null);
|
||||||
@ -778,9 +778,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
String mDesc = "";
|
String mDesc = "";
|
||||||
|
|
||||||
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet);
|
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
|
||||||
|
|
||||||
boolean isCreated = false;
|
boolean toCreate = false;
|
||||||
|
|
||||||
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
||||||
// This will be used if the class is not standard class (not in API)
|
// This will be used if the class is not standard class (not in API)
|
||||||
@ -799,7 +799,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
String superClass = "";
|
String superClass = "";
|
||||||
// TODO: Test SubMatrix.jav
|
|
||||||
while(true) {
|
while(true) {
|
||||||
try {
|
try {
|
||||||
superClass = helper.getSuperClass(receiverName);
|
superClass = helper.getSuperClass(receiverName);
|
||||||
@ -833,25 +832,29 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(methodRefl == null) {
|
if(methodRefl == null) {
|
||||||
isCreated = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
|
||||||
if(isCreated) {
|
if(toCreate) {
|
||||||
try {
|
try {
|
||||||
mDesc = helper.getDesc(clazz);
|
mDesc = helper.getDesc(clazz);
|
||||||
} catch (NotInCurrentPackageException | NotFoundException e) {
|
} catch (NotInCurrentPackageException | NotFoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
} else if(!helper.isInCurrPkg(clazz)){
|
} else if(!helper.isInCurrPkg(clazz)){
|
||||||
try {
|
if(clazz.contains("$$")) {
|
||||||
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
|
mDesc = helper.generateBCForFunN();
|
||||||
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
|
}else {
|
||||||
System.out.println("Methods of " + receiverName + " ");
|
try {
|
||||||
for(int i = 0; i<methods.length; i++) {
|
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
|
||||||
System.out.println(methods[i]);
|
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
|
||||||
|
System.out.println("Methods of " + receiverName + " ");
|
||||||
|
for(int i = 0; i<methods.length; i++) {
|
||||||
|
System.out.println(methods[i]);
|
||||||
|
}
|
||||||
|
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
|
||||||
|
}
|
||||||
|
catch (Exception e2) {
|
||||||
|
e2.printStackTrace();
|
||||||
}
|
}
|
||||||
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
|
|
||||||
}
|
|
||||||
catch (Exception e2) {
|
|
||||||
e2.printStackTrace();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,12 +80,12 @@ public class Signature {
|
|||||||
createSignatureForConsOrMethod(this.method,false);
|
createSignatureForConsOrMethod(this.method,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signature(LambdaExpression lambdaExpression,int numberOfParams) {
|
public Signature(int numberOfParams) {
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForFunN(lambdaExpression, numberOfParams);
|
createSignatureForFunN(numberOfParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) {
|
private void createSignatureForFunN(int numberOfParams) {
|
||||||
|
|
||||||
// sw.visitClassBound().visitEnd();
|
// sw.visitClassBound().visitEnd();
|
||||||
for(int i = 0;i<numberOfParams;i++) {
|
for(int i = 0;i<numberOfParams;i++) {
|
||||||
|
@ -3,6 +3,10 @@
|
|||||||
*/
|
*/
|
||||||
package de.dhbwstuttgart.bytecode.utilities;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -11,11 +15,17 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import org.objectweb.asm.ClassWriter;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
|
||||||
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.TypeToSignature;
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
@ -23,6 +33,8 @@ import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
|
|||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
import de.dhbwstuttgart.syntaxtree.SourceFile;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
|
||||||
@ -38,16 +50,19 @@ public class MethodCallHelper {
|
|||||||
private MethodCall methCall;
|
private MethodCall methCall;
|
||||||
private SourceFile sourceFile;
|
private SourceFile sourceFile;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
|
private String path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param methCall
|
* @param methCall
|
||||||
* @param sourceFile
|
* @param sourceFile
|
||||||
* @param resultSet
|
* @param resultSet
|
||||||
|
* @param path TODO
|
||||||
*/
|
*/
|
||||||
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet) {
|
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, String path) {
|
||||||
this.methCall = methCall;
|
this.methCall = methCall;
|
||||||
this.sourceFile = sourceFile;
|
this.sourceFile = sourceFile;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
|
this.path = path;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
|
||||||
@ -189,19 +204,52 @@ public class MethodCallHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createDesc(Method m) {
|
public String generateBCForFunN() {
|
||||||
String desc = "(";
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
for (FormalParameter fp : m.getParameterList()) {
|
|
||||||
String typeName = getResolvedType(fp.getType());
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric type = resultSet.resolveType(fp.getType()).resolvedType;
|
|
||||||
if (type instanceof TypePlaceholder) {
|
|
||||||
desc += "L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
} else if (type instanceof GenericRefType) {
|
|
||||||
GenericRefType grt = (GenericRefType) type;
|
|
||||||
|
|
||||||
}
|
SignatureWriter methSig = new SignatureWriter();
|
||||||
|
|
||||||
|
int numberOfParams = 0;
|
||||||
|
SignatureVisitor paramVisitor = methSig.visitParameterType();
|
||||||
|
Iterator<Expression> itr1 = methCall.arglist.getArguments().iterator();
|
||||||
|
String methDesc = "(";
|
||||||
|
while(itr1.hasNext()) {
|
||||||
|
numberOfParams++;
|
||||||
|
// getBounds
|
||||||
|
paramVisitor.visitTypeVariable("T" + numberOfParams);
|
||||||
|
methDesc += "L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
itr1.next();
|
||||||
}
|
}
|
||||||
return null;
|
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
|
||||||
|
methSig.visitReturnType().visitTypeVariable("R");
|
||||||
|
// ")"+lam.getReturn.getBounds
|
||||||
|
Signature sig = new Signature(numberOfParams);
|
||||||
|
String name = "Fun" + numberOfParams + "$$";
|
||||||
|
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
||||||
|
Type.getInternalName(Object.class), null);
|
||||||
|
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
||||||
|
methSig.toString(), null);
|
||||||
|
mvApply.visitEnd();
|
||||||
|
writeClassFile(classWriter.toByteArray(), name);
|
||||||
|
return methDesc;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeClassFile(byte[] bytecode, String name) {
|
||||||
|
FileOutputStream output;
|
||||||
|
try {
|
||||||
|
System.out.println("generating " + name + ".class file...");
|
||||||
|
output = new FileOutputStream(
|
||||||
|
new File(path + name + ".class"));
|
||||||
|
output.write(bytecode);
|
||||||
|
output.close();
|
||||||
|
System.out.println(name + ".class file generated");
|
||||||
|
} catch (FileNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ public class MethodFromMethodCall {
|
|||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public ArgumentList getArgList() {
|
public ArgumentList getArgList() {
|
||||||
return argList;
|
return argList;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user