Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring

This commit is contained in:
pl@gohorb.ba-horb.de 2019-04-27 09:51:22 +02:00
commit 4a7c124fd6
26 changed files with 912 additions and 342 deletions

View File

@ -17,6 +17,7 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
@ -45,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;
@ -57,34 +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<TypePlaceholder> 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;
ArrayList<String> methodNameAndParamsT = new ArrayList<>(); private final ArrayList<String> methodNameAndParamsT = 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;
} }
@ -93,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);
@ -110,149 +116,164 @@ 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(TypePlaceholder 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()) {
TypePlaceholder right = null; String right = null;
for(TypePlaceholder tph : tphsClass) { boolean isToAdd = false;
if(cons.getLeft().equals(tph.getName())) { for (String tph : tphsClass) {
if (cons.getLeft().equals(tph)) {
consClass.add(cons); consClass.add(cons);
right = getTPH(cons.getRight()); try {
right = getTPH(cons.getRight());
isToAdd = true;
} catch (NoSuchElementException e) {
continue;
}
} }
} }
if(right != null) { if (isToAdd) {
tphsClass.add(right); tphsClass.add(right);
removeFromMethod(right.getName()); removeFromMethod(right);
right = null; right = null;
isToAdd = false;
} }
// if(right != null) {
// tphsClass.add(right);
// removeFromMethod(right);
// 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 TypePlaceholder getTPH(String name) { private String getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) { for (String tph : tphExtractor.allTPHS.keySet()) {
if(tph.getName().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<TypePlaceholder> cTPHs = new ArrayList<>(); ArrayList<String> cTPHs = new ArrayList<>();
// Alle TPHs der Felder speichern // Alle TPHs der Felder speichern
for(TypePlaceholder 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);
} }
} }
@ -260,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;
} }
@ -421,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);
@ -429,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
} }
// ?? // ??
@ -469,41 +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 += ";";
} }
cw.visitField(field.modifier, field.getName(), String nameAndDesc = field.getName() + "%%" + des;
des, sig, String nameAndSig = field.getName() + "%%" + sig;
null); if (fieldNameAndParamsT.contains(nameAndDesc)) {
if (fieldNameSignature.contains(nameAndSig)) {
return;
}
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
}
fieldNameAndParamsT.add(nameAndDesc);
fieldNameSignature.add(nameAndSig);
cw.visitField(field.modifier, field.getName(), des, sig, 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
@ -514,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
@ -671,6 +713,5 @@ public class BytecodeGen implements ASTVisitor {
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

View File

@ -33,12 +33,14 @@ import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
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.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature; 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.MethodCallHelper;
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;
@ -52,6 +54,7 @@ import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
public class BytecodeGenMethod implements StatementVisitor { public class BytecodeGenMethod implements StatementVisitor {
@ -675,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);
@ -763,7 +766,7 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(InstanceOf instanceOf) { public void visit(InstanceOf instanceOf) {
} }
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
boolean parentBinary = isParentBinary; boolean parentBinary = isParentBinary;
@ -772,100 +775,102 @@ public class BytecodeGenMethod implements StatementVisitor {
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
java.lang.reflect.Method methodRefl = null; java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", "."); String clazz = receiverName.replace("/", ".");
// if(!receiverName.equals(className)) {
ClassLoader cLoader = ClassLoader.getSystemClassLoader(); String mDesc = "";
// This will be used if the class is not standard class (not in API)
ClassLoader cLoader2; MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()); boolean toCreate = false;
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
try { ClassLoader cLoader = ClassLoader.getSystemClassLoader();
if(receiverName.contains("<")) { // This will be used if the class is not standard class (not in API)
clazz = clazz.substring(0, receiverName.indexOf("<")); ClassLoader cLoader2;
}
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
System.out.println("Methods of " + receiverName + " "); try {
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methods); if (receiverName.contains("<")) {
clazz = clazz.substring(0, receiverName.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
System.out.println("Methods of " + receiverName + " ");
methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods);
} catch (Exception e) { } catch (Exception e) {
// try {
// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
// 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) {
String superClass = ""; String superClass = "";
// TODO: Test SubMatrix.jav
while(true) { while(true) {
for(ClassOrInterface cl : sf.getClasses()) {
if(receiverName.equals(cl.getClassName().toString())) {
superClass = cl.getSuperClass().getName().toString();
break;
}
}
System.out.println(superClass);
if(superClass.equals(""))
break;
try { try {
String superClazz = superClass.replace("/", "."); superClass = helper.getSuperClass(receiverName);
if(superClass.contains("<")) {
superClazz = superClazz.substring(0, superClass.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
System.out.println("Methods of " + superClass + " ");
for(java.lang.reflect.Method m : methods) { try {
if(methodCall.name.equals(m.getName())) { String superClazz = superClass.replace("/", ".");
methodRefl = m; if(superClass.contains("<")) {
break; superClazz = superClazz.substring(0, superClass.indexOf("<"));
} }
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
System.out.println("Methods of " + superClass + " ");
for(java.lang.reflect.Method m : methods) {
if(methodCall.name.equals(m.getName())) {
methodRefl = m;
break;
}
}
break;
} catch (Exception e3) {
receiverName = superClass;
continue;
} }
} catch (NotInCurrentPackageException e2) {
break; break;
} catch (Exception e3) {
receiverName = superClass;
continue;
} }
} }
// }
} }
if(methodRefl == null) { if(methodRefl == null) {
try { toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); if(toCreate) {
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); try {
System.out.println("Methods of " + receiverName + " "); mDesc = helper.getDesc(clazz);
for(int i = 0; i<methods.length; i++) { } catch (NotInCurrentPackageException | NotFoundException e) {
System.out.println(methods[i]); e.printStackTrace();
}
} else if(!helper.isInCurrPkg(clazz)){
if(clazz.contains("$$")) {
mDesc = helper.generateBCForFunN();
}else {
try {
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
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) {
System.out.println("");
//do nothing
} }
} }
// }
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
String mDesc = "";
List<Boolean> argListMethCall = new LinkedList<>(); List<Boolean> argListMethCall = new LinkedList<>();
String receiverRefl=""; String receiverRefl="";
if(methodRefl == null) { if(methodRefl == null && receiverName.equals(className)) {
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
receiverName, genericsAndBoundsMethod, genericsAndBounds); receiverName, genericsAndBoundsMethod, genericsAndBounds);
mDesc = method.accept(new DescriptorToString(resultSet)); mDesc = method.accept(new DescriptorToString(resultSet));
methodCall.arglist.accept(this); methodCall.arglist.accept(this);
} else { } else if(methodRefl != null) {
System.out.println(methodCall.name + " -> Refl != null"); System.out.println(methodCall.name + " -> Refl != null");
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString(); receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
for(Parameter p:methodRefl.getParameters()) { for(Parameter p:methodRefl.getParameters()) {
@ -880,6 +885,8 @@ public class BytecodeGenMethod implements StatementVisitor {
al.accept(argV); al.accept(argV);
statement = null; statement = null;
} }
} else {
methodCall.arglist.accept(this);
} }
System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc); System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc);
@ -917,6 +924,19 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
private String getDescForMethInCurrPkg(String name) {
// TODO Auto-generated method stub
return null;
}
private boolean isInCurrPkg(String superClass) {
for(ClassOrInterface cl : sf.KlassenVektor) {
if(superClass.equals(cl.getClassName().toString()))
return true;
}
return false;
}
private String[] getTypes(List<Expression> arguments) { private String[] getTypes(List<Expression> arguments) {
String[] types = new String[arguments.size()]; String[] types = new String[arguments.size()];
for(int i = 0; i<arguments.size(); ++i) { for(int i = 0; i<arguments.size(); ++i) {
@ -1252,10 +1272,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitBooleanLiteral((Boolean) value); visitBooleanLiteral((Boolean) value);
break; break;
case "java/lang/Byte": case "java/lang/Byte":
visitByteLiteral(((Double) value).byteValue(), false); if(value instanceof Double)
visitByteLiteral(((Double) value).byteValue(), false);
if(value instanceof Integer)
visitByteLiteral(((Integer) value).byteValue(), false);
break; break;
case "java/lang/Short": case "java/lang/Short":
visitShortLiteral(((Double) value).shortValue(), false); if(value instanceof Double)
visitShortLiteral(((Double) value).shortValue(), false);
if(value instanceof Integer)
visitShortLiteral(((Integer) value).shortValue(), false);
break; break;
case "java/lang/Integer": case "java/lang/Integer":
// zweite Argument isLong // zweite Argument isLong
@ -1266,10 +1292,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitIntegerLiteral(((Integer) value).intValue(), false); visitIntegerLiteral(((Integer) value).intValue(), false);
break; break;
case "java/lang/Long": case "java/lang/Long":
visitLongLiteral(((Integer) value).longValue(), true); if(value instanceof Double)
visitLongLiteral(((Double) value).longValue(), true);
if(value instanceof Integer)
visitLongLiteral(((Integer) value).longValue(), true);
break; break;
case "java/lang/Float": case "java/lang/Float":
visitFloatLiteral(((Double) value).floatValue()); if(value instanceof Double)
visitFloatLiteral(((Double) value).floatValue());
if(value instanceof Integer)
visitFloatLiteral(((Integer) value).floatValue());
break; break;
case "java/lang/Double": case "java/lang/Double":
if(value instanceof Double) if(value instanceof Double)

View File

@ -0,0 +1,19 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class BytecodeGeneratorError extends RuntimeException {
/**
* @param message
*/
public BytecodeGeneratorError(String message) {
super(message);
}
}

View File

@ -0,0 +1,25 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class NotFoundException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @param message
*/
public NotFoundException(String message) {
super(message);
}
}

View File

@ -0,0 +1,26 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class NotInCurrentPackageException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @param message
*/
public NotInCurrentPackageException(String message) {
super(message);
}
}

View File

@ -5,7 +5,11 @@ package de.dhbwstuttgart.bytecode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
@ -13,13 +17,18 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar; import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
/** /**
@ -29,14 +38,14 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
public class TPHExtractor extends AbstractASTWalker { public class TPHExtractor extends AbstractASTWalker {
// Alle TPHs der Felder werden iKopf der Klasse definiert // Alle TPHs der Felder werden iKopf der Klasse definiert
// alle TPHs der Klasse: (TPH, is in Method?) // alle TPHs der Klasse: (TPH, is in Method?)
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>(); final HashMap<String, Boolean> allTPHS = new HashMap<>();
MethodAndTPH methodAndTph; MethodAndTPH methodAndTph;
Boolean inMethod = false; Boolean inMethod = false;
boolean inLocalOrParam = false; boolean inLocalOrParam = false;
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>(); public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>(); final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> allPairs = new ArrayList<>();
public final ArrayList<TPHConstraint> allCons = new ArrayList<>(); public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
private ResultSet resultSet; private ResultSet resultSet;
@ -58,19 +67,80 @@ public class TPHExtractor extends AbstractASTWalker {
methodAndTph.getLocalTphs().add(resolvedTPH.getName()); methodAndTph.getLocalTphs().add(resolvedTPH.getName());
} }
allTPHS.put(resolvedTPH, inMethod); allTPHS.put(resolvedTPH.getName(), inMethod);
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> { // final List<TPHConstraint> cons = new ArrayList<>();
if (ag.contains(resolvedTPH) && ag.TA1.equals(resolvedTPH) && !contains(allPairs, ag)) { // resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
// TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
// cons.add(con);
// });
//
// Map<TPHConstraint, Boolean> visitMap = new HashMap<>();
// for(TPHConstraint cc : cons) {
// visitMap.put(cc, false);
// }
//
// String left = resolvedTPH.getName();
// for (TPHConstraint cc : visitMap.keySet()) {
//
// if(visitMap.get(cc))
// continue;
//
// if (cc.getLeft().equals(left)) {
// allCons.add(cc);
// List<TPHConstraint> toVisit = getToVisitCons(cons,cc.getRight(), visitMap);
// }
// }
//resultSet.resolveType(tph).getAdditionalGenerics().forEach(ag -> {
resultSet.genIns.forEach(ag -> {
// if (ag.contains(resolvedTPH) /* && ag.TA1.equals(resolvedTPH) */ && !contains(allPairs, ag)) {
if (inMethod) if (inMethod)
methodAndTph.getPairs().add(ag); methodAndTph.getPairs().add(ag);
allPairs.add(ag); allPairs.add(ag);
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); TPHConstraint con = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
allCons.add(con); if(!containsConstraint(allCons,con))
} allCons.add(con);
// }
}); });
} else if (resultSet.resolveType(tph).resolvedType instanceof RefType) {
RefType rt = (RefType) resultSet.resolveType(tph).resolvedType;
rt.accept(this);
} }
} }
private static boolean containsConstraint(ArrayList<TPHConstraint> allCons, TPHConstraint c) {
for(TPHConstraint con:allCons) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) {
return true;
}
}
return false;
}
private List<TPHConstraint> getToVisitCons(List<TPHConstraint> cons, String right, Map<TPHConstraint, Boolean> visitMap) {
List<TPHConstraint> res = new ArrayList<>();
for(TPHConstraint cc : cons) {
if(cc.getLeft().equals(right)) {
res.add(cc);
if(visitMap.get(cc))
visitMap.replace(cc, false);
}
}
return res;
}
@Override
public void visit(GenericRefType genericRefType) {
String name = genericRefType.getParsedName();
if (inMethod) {
methodAndTph.getLocalTphs().add(name);
if (inLocalOrParam)
methodAndTph.getLocalTphs().add(name);
}
allTPHS.put(name, inMethod);
}
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) { private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
for (int i = 0; i < pairs.size(); ++i) { for (int i = 0; i < pairs.size(); ++i) {
GenericInsertPair p = pairs.get(i); GenericInsertPair p = pairs.get(i);

View File

@ -41,11 +41,11 @@ public class Signature {
private ResultSet resultSet; private ResultSet resultSet;
private ArrayList<GenericInsertPair> commonPairs; private ArrayList<GenericInsertPair> commonPairs;
private HashMap<TPHConstraint,HashSet<String>> methodConstraints; private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
private ArrayList<TypePlaceholder> tphsClass; private ArrayList<String> tphsClass;
private ArrayList<TPHConstraint> consClass; private ArrayList<TPHConstraint> consClass;
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds, public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass, ArrayList<TPHConstraint> consClass) { ArrayList<GenericInsertPair> commonPairs, ArrayList<String> tphsClass, ArrayList<TPHConstraint> consClass) {
this.classOrInterface = classOrInterface; this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.commonPairs = commonPairs; this.commonPairs = commonPairs;
@ -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++) {
@ -235,8 +235,9 @@ public class Signature {
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType; RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
if(resolved instanceof TypePlaceholder) { if(resolved instanceof TypePlaceholder) {
resType.additionalGenerics.forEach(ag ->{ //resType.getAdditionalGenerics().forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); resultSet.genIns.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
if(!contains(res,constr)) { if(!contains(res,constr)) {
res.add(constr); res.add(constr);
} }
@ -246,8 +247,9 @@ public class Signature {
WildcardType resWC = (WildcardType) resolved; WildcardType resWC = (WildcardType) resolved;
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType()); ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
if(resType2.resolvedType instanceof TypePlaceholder) { if(resType2.resolvedType instanceof TypePlaceholder) {
resType2.additionalGenerics.forEach(ag ->{ //resType2.getAdditionalGenerics().forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); resultSet.genIns.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
if(!contains(res,constr)) { if(!contains(res,constr)) {
res.add(constr); res.add(constr);
} }

View File

@ -2,14 +2,17 @@ package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList; import java.util.ArrayList;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
public class MethodAndTPH { public class MethodAndTPH {
private String name; private String name;
private final ArrayList<String> tphs = new ArrayList<>(); private final ArrayList<String> tphs = new ArrayList<>();
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>(); //private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
private final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> pairs = new ArrayList<>();
// tphs of local variables and parameters // tphs of local variables and parameters
private final ArrayList<String> localTphs = new ArrayList<>(); private final ArrayList<String> localTphs = new ArrayList<>();
@ -21,7 +24,10 @@ public class MethodAndTPH {
return tphs; return tphs;
} }
public ArrayList<GenericInsertPair> getPairs(){ // public ArrayList<GenericInsertPair> getPairs(){
// return pairs;
// }
public ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> getPairs(){
return pairs; return pairs;
} }

View File

@ -0,0 +1,255 @@
/**
*
*/
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.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
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.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
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.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
/**
* @author fayez
*
*/
public class MethodCallHelper {
private MethodCall methCall;
private SourceFile sourceFile;
private ResultSet resultSet;
private String path;
/**
* @param methCall
* @param sourceFile
* @param resultSet
* @param path TODO
*/
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, String path) {
this.methCall = methCall;
this.sourceFile = sourceFile;
this.resultSet = resultSet;
this.path = path;
}
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
}
public boolean isInCurrPkg(String className) {
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
if (className.equals(cl.getClassName().toString()))
return true;
}
return false;
}
public String getSuperClass(String className) throws NotInCurrentPackageException {
for (ClassOrInterface cl : sourceFile.getClasses()) {
if (className.equals(cl.getClassName().toString())) {
return cl.getSuperClass().getName().toString();
}
}
throw new NotInCurrentPackageException("Class " + className + " is not in the current package.");
}
public ClassOrInterface getClassFromCurrPkg(String className) throws NotInCurrentPackageException {
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
if (className.equals(cl.getClassName().toString()))
return cl;
}
throw new NotInCurrentPackageException("Class of " + className + " is not in the current package.");
}
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
String name = methCall.name;
ClassOrInterface clazz = getClassFromCurrPkg(className);
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
modifyGenAndBounds(genAndBoundsClass);
for (Method m : clazz.getMethods()) {
if (name.equals(m.getName())) {
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
modifyGenAndBounds(genAndBoundsMethod);
boolean hasGen = hasGen(m, genAndBoundsClass);
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
(HashMap<String, String>) genAndBoundsMethod, hasGen);
return nm.accept(new DescriptorToString(resultSet));
}
}
throw new NotFoundException("Method " + name + " is not found");
}
private boolean hasGen(Method m, Map<String, String> genericsAndBounds) {
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") || retType.contains("<");
Map<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
Iterator<FormalParameter> itr = m.getParameterList().iterator();
while(itr.hasNext()) {
FormalParameter fp = itr.next();
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
}
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, 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 sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.contains("TPH ")||sigOfParam.contains("<")) {
hasGenInParameterList = true;
break;
}
}
}
return m.getGenerics().iterator().hasNext() || hasGenInParameterList;
}
private Map<String, String> getGenericsAndBoundsMethod(Iterable<? extends GenericTypeVar> generics) {
Map<String, String> genAndBounds = new HashMap<>();
Iterator<? extends GenericTypeVar> itr = generics.iterator();
while (itr.hasNext()) {
GenericTypeVar gtv = itr.next();
getBoundsOfTypeVar(gtv, genAndBounds);
}
return genAndBounds;
}
private void modifyGenAndBounds(Map<String, String> genAndBoundsClass) {
List<String> visited = new ArrayList<>(genAndBoundsClass.size());
Map<String, String> toReplace = new HashMap<>();
for (String tv : genAndBoundsClass.keySet()) {
if (visited.contains(tv))
continue;
List<String> types = new LinkedList<>();
String bound = genAndBoundsClass.get(tv);
types.add(tv);
visited.add(tv);
boolean doReplace = false;
while (genAndBoundsClass.keySet().contains(bound)) {
doReplace = true;
types.add(bound);
visited.add(bound);
bound = genAndBoundsClass.get(bound);
}
if (doReplace) {
for (String tt : types) {
toReplace.put(tt, bound);
}
}
}
for (String key : toReplace.keySet()) {
genAndBoundsClass.replace(key, toReplace.get(key));
}
}
private Map<String, String> getGenericsAndBounds(GenericDeclarationList generics) {
Map<String, String> genAndBounds = new HashMap<>();
Iterator<GenericTypeVar> itr = generics.iterator();
while (itr.hasNext()) {
GenericTypeVar gtv = itr.next();
getBoundsOfTypeVar(gtv, genAndBounds);
}
return genAndBounds;
}
private void getBoundsOfTypeVar(GenericTypeVar g, Map<String, String> genAndBounds) {
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
while (bItr.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
String boundDesc = b.acceptTV(new TypeToDescriptor());
genAndBounds.put(g.getName(), boundDesc);
}
}
public String generateBCForFunN() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
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();
}
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();
}
}
}

View File

@ -23,6 +23,7 @@ public class MethodFromMethodCall {
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
} }
public ArgumentList getArgList() { public ArgumentList getArgList() {
return argList; return argList;
} }

View File

@ -19,7 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify { public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor, public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) { ArrayList<String> tphsClass) {
// 1. check if there are any simple cycles like L<R and R<L: // 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and: // a) yes => set L=R and:
// * remove both constraints // * remove both constraints
@ -38,8 +38,10 @@ public class Simplify {
ArrayList<TPHConstraint> allCons = new ArrayList<>(); ArrayList<TPHConstraint> allCons = new ArrayList<>();
for(TPHConstraint c : tphExtractor.allCons) { for(TPHConstraint c : tphExtractor.allCons) {
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel()); if(!containsConstraint(allCons,c)) {
allCons.add(nc); TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
allCons.add(nc);
}
} }
ArrayList<TPHConstraint> consToRemove = new ArrayList<>(); ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@ -382,7 +384,7 @@ public class Simplify {
if (!containTPH(methodTphs, superTphRes)) { if (!containTPH(methodTphs, superTphRes)) {
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes); HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
if (classTPHSContainsTPH(tphsClass, superTphRes)) { if (tphsClass.contains(superTphRes)/*classTPHSContainsTPH(tphsClass, superTphRes)*/) {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals); result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
} else { } else {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
@ -450,6 +452,15 @@ public class Simplify {
return result; return result;
} }
private static boolean containsConstraint(ArrayList<TPHConstraint> allCons, TPHConstraint c) {
for(TPHConstraint con:allCons) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) {
return true;
}
}
return false;
}
private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) { private static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
List<String> oldNames = replRes.values().iterator().next(); List<String> oldNames = replRes.values().iterator().next();
String newName = replRes.keySet().iterator().next(); String newName = replRes.keySet().iterator().next();
@ -463,7 +474,7 @@ public class Simplify {
} }
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor, public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) { ArrayList<String> tphsClass) {
// all constraints that will be simplified // all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons; ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> consToRemove = new ArrayList<>(); ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@ -627,7 +638,9 @@ public class Simplify {
if (isTPHInConstraint(result, sub)) if (isTPHInConstraint(result, sub))
continue; continue;
if (!classTPHSContainsTPH(tphsClass, sub)) // if (!classTPHSContainsTPH(tphsClass, sub))
// continue;
if (!tphsClass.contains(sub))
continue; continue;
if (numOfVisitedPairs >= size) if (numOfVisitedPairs >= size)
@ -656,7 +669,7 @@ public class Simplify {
// add X at the beginning of the list. // add X at the beginning of the list.
while (subAndSuper.containsValue(subTphRes)) { while (subAndSuper.containsValue(subTphRes)) {
for (String tph : subAndSuper.keySet()) { for (String tph : subAndSuper.keySet()) {
if (classTPHSContainsTPH(tphsClass, tph) && subAndSuper.get(tph).equals(subTphRes)) { if (/*classTPHSContainsTPH(tphsClass, tph)*/tphsClass.contains(tph) && subAndSuper.get(tph).equals(subTphRes)) {
subTphRes = tph; subTphRes = tph;
break; break;
} }

View File

@ -16,10 +16,10 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
*/ */
public class SimplifyResult { public class SimplifyResult {
private final ArrayList<TPHConstraint> classConstraints; private final ArrayList<TPHConstraint> classConstraints;
private final ArrayList<TypePlaceholder> tphsClass; private final ArrayList<String> tphsClass;
private final HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints; private final HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints;
public SimplifyResult(ArrayList<TPHConstraint> classConstraints, ArrayList<TypePlaceholder> tphsClass, public SimplifyResult(ArrayList<TPHConstraint> classConstraints, ArrayList<String> tphsClass,
HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints) { HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints) {
super(); super();
this.classConstraints = classConstraints; this.classConstraints = classConstraints;
@ -35,7 +35,7 @@ public class SimplifyResult {
return methodsConstraints; return methodsConstraints;
} }
public ArrayList<TypePlaceholder> getTphsClass() { public ArrayList<String> getTphsClass() {
return tphsClass; return tphsClass;
} }

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.utilities.SimplifyResult; import de.dhbwstuttgart.bytecode.utilities.SimplifyResult;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
@ -51,6 +52,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; import org.antlr.v4.parse.ANTLRParser.throwsSpec_return;
import org.apache.commons.io.output.NullOutputStream;
//import org.apache.commons.io.output.NullOutputStream; //import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler { public class JavaTXCompiler {
@ -563,8 +565,8 @@ public class JavaTXCompiler {
} }
/* UnifyResultModel End */ /* UnifyResultModel End */
else { else {
Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure)); //Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure));
//Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure)); Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure));
System.out.println("RESULT: " + result); System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString()+"\n"); logFile.write("RES: " + result.toString()+"\n");
logFile.flush(); logFile.flush();
@ -650,7 +652,7 @@ public class JavaTXCompiler {
return ret; return ret;
} }
// um pfad erweitern // um pfad erweitern
public void generateBytecode(String path) throws ClassNotFoundException, IOException { public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
for(File f : sourceFiles.keySet()) { for(File f : sourceFiles.keySet()) {
HashMap<String,byte[]> classFiles = new HashMap<>(); HashMap<String,byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);

View File

@ -23,4 +23,9 @@ public class GenericInsertPair {
if(TA2.equals(additionalTPH))return true; if(TA2.equals(additionalTPH))return true;
return false; return false;
} }
@Override
public String toString() {
return "GenIns(" + TA1.toString() + " < " + TA2.toString() + ")";
}
} }

View File

@ -21,4 +21,9 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override
public String toString() {
return "(" + left.toString() + " = " + right.toString() + ")";
}
} }

View File

@ -20,4 +20,9 @@ public class PairTPHsmallerTPH extends ResultPair{
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override
public String toString() {
return "(" + left.toString() + " < " + right.toString() + ")";
}
} }

View File

@ -8,10 +8,10 @@ import java.util.Set;
public class ResolvedType{ public class ResolvedType{
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType; public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
public final Set<GenericInsertPair> additionalGenerics; //public final Set<GenericInsertPair> additionalGenerics;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){ public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
this.resolvedType = resolvedType; this.resolvedType = resolvedType;
this.additionalGenerics = additionalGenerics; //this.additionalGenerics = additionalGenerics;
} }
} }

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.result;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
@ -15,9 +16,15 @@ import static de.dhbwstuttgart.typeinference.result.ResultPairMap.RESULT_PAIRS;
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public class ResultSet { public class ResultSet {
public final Set<ResultPair> results; public final Set<ResultPair> results;
public ResultSet(Set<ResultPair> set){ public Set<GenericInsertPair> genIns;
public ResultSet(Set<ResultPair> set){
this.results = set; this.results = set;
this.genIns = results.stream().filter(a -> a instanceof PairTPHsmallerTPH)
- .map(b -> new GenericInsertPair( (TypePlaceholder)(b.getLeft()), (TypePlaceholder)
- .collect(Collectors.toCollection(HashSet::new));
} }
public boolean contains(ResultPair toCheck) { public boolean contains(ResultPair toCheck) {
@ -284,5 +291,4 @@ class RelatedTypeWalker implements ResultSetVisitor {
@Override @Override
public void visit(GenericRefType genericRefType) { public void visit(GenericRefType genericRefType) {
} }
}

View File

@ -19,6 +19,8 @@ import java.util.function.BinaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.commons.io.output.NullOutputStream;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
@ -46,6 +48,7 @@ import de.dhbwstuttgart.typeinference.unify.model.Pair;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@ -165,7 +168,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
thNo = totalnoOfThread; thNo = totalnoOfThread;
writeLog("thNo2 " + thNo); writeLog("thNo2 " + thNo);
try { try {
this.logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo)); this.logFile = new OutputStreamWriter(new NullOutputStream());
//new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo));
logFile.write("");
} }
catch (IOException e) { catch (IOException e) {
System.err.println("log-File nicht vorhanden"); System.err.println("log-File nicht vorhanden");

View File

@ -0,0 +1,37 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class ClassGenLamTest {
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;
@Test
public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/ClassGenLam.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
compiler.generateBytecode(pathToClassFile);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("ClassGenLam");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@ -0,0 +1,8 @@
import java.lang.Integer;
public class ClassGenLam {
lam = x-> x;
// public ClassGenLam() {
// lam = x->x;
// }
}

View File

@ -1,22 +1,25 @@
import java.lang.Integer; import java.lang.Integer;
import java.lang.Long;
import java.lang.Short;
public class Faculty { public class Faculty {
public fact; public fact;
Faculty() { Faculty() {
fact = (x) -> { fact = (x) -> {
if (x == 1) { if (x == 1) {
return 1; return 1;
} }
else { else {
return x * (fact.apply(x-1)); return x * (fact.apply(x-1));
} }
}; };
} }
public getFact(x) { public getFact(x) {
return fact.apply(x); return fact.apply(x);
} }
}
// m (x) { // m (x) {
// //
//// var fact = (x) -> { //// var fact = (x) -> {

View File

@ -1,6 +1,6 @@
public class Id { public class Id {
id(CKE b){ id(b){
return b; return b;
} }
} }

View File

@ -1,6 +1,6 @@
import java.util.Vector; import java.util.Vector;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Byte; //import java.lang.Byte;
import java.lang.Boolean; import java.lang.Boolean;
public class MatrixOP extends Vector<Vector<Integer>> { public class MatrixOP extends Vector<Vector<Integer>> {
@ -18,7 +18,7 @@ public class MatrixOP extends Vector<Vector<Integer>> {
} }
} }
Fun2$$<java.util.Vector<? extends java.util.Vector<? extends java.lang.Integer>>, java.util.Vector<? extends java.util.Vector<? extends java.lang.Integer>>, MatrixOP> mul = (m1, m2) -> { public mul = (m1, m2) -> {
var ret = new MatrixOP(); var ret = new MatrixOP();
var i = 0; var i = 0;
while(i < m1.size()) { while(i < m1.size()) {

View File

@ -10,8 +10,6 @@ public class OL {
} }
public class OLMain { public class OLMain {
java.lang.Integer main(java.lang.Integer x) { java.lang.Integer main(java.lang.Integer x) {

View File

@ -1,6 +1,12 @@
public class TypedID/*<L extends K,K> */ { public class TypedID/*<L extends K,K> */ {
<K> id(K b){ lam = x-> x;
id(b){
return b; return b;
} }
m(){
return lam;
}
} }