diff --git a/src/de/dhbwstuttgart/bytecode/ArgumentVisitor.java b/src/de/dhbwstuttgart/bytecode/ArgumentVisitor.java new file mode 100644 index 00000000..be0e1bc7 --- /dev/null +++ b/src/de/dhbwstuttgart/bytecode/ArgumentVisitor.java @@ -0,0 +1,255 @@ +package de.dhbwstuttgart.bytecode; + +import java.util.List; + +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; +import de.dhbwstuttgart.syntaxtree.statement.Assign; +import de.dhbwstuttgart.syntaxtree.statement.AssignToField; +import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.CastExpr; +import de.dhbwstuttgart.syntaxtree.statement.DoStmt; +import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt; +import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver; +import de.dhbwstuttgart.syntaxtree.statement.FieldVar; +import de.dhbwstuttgart.syntaxtree.statement.ForStmt; +import de.dhbwstuttgart.syntaxtree.statement.IfStmt; +import de.dhbwstuttgart.syntaxtree.statement.InstanceOf; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.statement.Literal; +import de.dhbwstuttgart.syntaxtree.statement.LocalVar; +import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; +import de.dhbwstuttgart.syntaxtree.statement.MethodCall; +import de.dhbwstuttgart.syntaxtree.statement.NewArray; +import de.dhbwstuttgart.syntaxtree.statement.NewClass; +import de.dhbwstuttgart.syntaxtree.statement.Return; +import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid; +import de.dhbwstuttgart.syntaxtree.statement.StaticClassName; +import de.dhbwstuttgart.syntaxtree.statement.Super; +import de.dhbwstuttgart.syntaxtree.statement.SuperCall; +import de.dhbwstuttgart.syntaxtree.statement.This; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.WhileStmt; + +public class ArgumentVisitor implements StatementVisitor { + private List argListMethCall; + private BytecodeGenMethod bytecodeGenMethod; + + public ArgumentVisitor(List argListMethCall, BytecodeGenMethod bytecodeGenMethod) { + this.argListMethCall = argListMethCall; + this.bytecodeGenMethod = bytecodeGenMethod; + } + + @Override + public void visit(ArgumentList argumentList) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(LambdaExpression lambdaExpression) { + lambdaExpression.accept(bytecodeGenMethod); + // Zieltype des Lambas ist Funktionale Interface + // kann nie primitiv sein => un-/boxing wird hier nicht gebraucht + argListMethCall.remove(0); + } + + @Override + public void visit(Assign assign) { + assign.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(assign.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(BinaryExpr binary) { + binary.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(Block block) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(CastExpr castExpr) { + castExpr.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(castExpr.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(EmptyStmt emptyStmt) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(FieldVar fieldVar) { + fieldVar.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(fieldVar.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(ForStmt forStmt) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(IfStmt ifStmt) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(InstanceOf instanceOf) { + instanceOf.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(instanceOf.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(LocalVar localVar) { + localVar.accept(bytecodeGenMethod); + if(!bytecodeGenMethod.isBinaryExp) { + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(localVar.getType())); + } + argListMethCall.remove(0); + } + + @Override + public void visit(LocalVarDecl localVarDecl) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(MethodCall methodCall) { + methodCall.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(NewClass methodCall) { + methodCall.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(NewArray newArray) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(Return aReturn) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(ReturnVoid aReturn) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(StaticClassName staticClassName) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(Super aSuper) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(This aThis) { + aThis.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(aThis.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(WhileStmt whileStmt) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(DoStmt whileStmt) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(AssignToField assignLeftSide) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(AssignToLocal assignLeftSide) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(SuperCall superCall) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(ExpressionReceiver expressionReceiver) { + // TODO Auto-generated method stub + + } + + @Override + public void visit(UnaryExpr unaryExpr) { + unaryExpr.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(unaryExpr.getType())); + argListMethCall.remove(0); + } + + @Override + public void visit(Literal literal) { + literal.accept(bytecodeGenMethod); + + if(argListMethCall.get(0)) + bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(literal.getType())); + argListMethCall.remove(0); + } + +} diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java index a3103657..5dac990c 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -16,6 +16,7 @@ import org.objectweb.asm.Type; 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.bytecode.signature.TypeToString; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.utilities.NormalConstructor; @@ -44,7 +45,7 @@ public class BytecodeGen implements ASTVisitor { private boolean isInterface; private List listOfResultSets; private ResultSet resultSet; - + private SourceFile sf; private String path; private int indexOfFirstParam = 0; @@ -67,9 +68,10 @@ public class BytecodeGen implements ASTVisitor { ArrayList methodNameAndParamsT = new ArrayList<>(); - public BytecodeGen(HashMap classFiles, List listOfResultSets, String path) { + public BytecodeGen(HashMap classFiles, List listOfResultSets,SourceFile sf ,String path) { this.classFiles = classFiles; this.listOfResultSets = listOfResultSets; + this.sf = sf; this.path = path; } @@ -77,7 +79,7 @@ public class BytecodeGen implements ASTVisitor { public void visit(SourceFile sourceFile) { for(ClassOrInterface cl : sourceFile.getClasses()) { System.out.println("in Class: " + cl.getClassName().toString()); - BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets,path); + BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path); cl.accept(classGen); classGen.writeClass(cl.getClassName().toString()); } @@ -129,7 +131,8 @@ public class BytecodeGen implements ASTVisitor { * Signature looks like: * Superclass */ - if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty()) { + if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() || + classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")) { Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs); sig = signature.toString(); System.out.println("Signature: => " + sig); @@ -178,15 +181,17 @@ public class BytecodeGen implements ASTVisitor { boolean hasGen = false; for(String paramName : methodParamsAndTypes.keySet()) { - String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor()); - if(genericsAndBounds.containsKey(typeOfParam)) { + String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); + if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.substring(0, 4).equals("TPH ") + || typeOfParam.contains("<")) { hasGen = true; break; } } String sig = null; if(hasGen) { - Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes); + ArrayList pairs = simplifyPairs(field.name,tphExtractor.allPairs); + Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,pairs); sig = signature.toString(); } NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen); @@ -194,7 +199,7 @@ public class BytecodeGen implements ASTVisitor { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "", desc, sig, null); mv.visitCode(); BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw, - genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, path); + genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path); if(!field.getParameterList().iterator().hasNext()) { mv.visitInsn(Opcodes.RETURN); } @@ -228,13 +233,15 @@ public class BytecodeGen implements ASTVisitor { System.out.println(acc); /*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/ - boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH "); + boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ") || + resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<"); /*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()); - if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")) { + String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); + if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")||sigOfParam.contains("<")) { hasGenInParameterList = true; break; } @@ -248,11 +255,9 @@ public class BytecodeGen implements ASTVisitor { /* method.getGenerics: <....> RT method(..) * */ boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList; - /* if method has generics or return type is TPH, create signature */ // zwite operand muss weggelassen werden - if(hasGen||method.getReturnType().acceptTV(new TypeToString()).equals("TPH")) { - + if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) { ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs); System.out.println(method.name + " => Simplified Pairs: "); pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName())); @@ -268,7 +273,7 @@ public class BytecodeGen implements ASTVisitor { mv.visitCode(); BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw, - genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, path); + genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path); mv.visitMaxs(0, 0); mv.visitEnd(); @@ -318,9 +323,13 @@ public class BytecodeGen implements ASTVisitor { tphsInRel.put(tphsInRel.size(), superTph); numOfVisitedPairs++; - + boolean isCycle = false; while(subAndSuperTph.containsKey(superTph)) { superTph = subAndSuperTph.get(superTph); + if(tphsInRel.containsValue(superTph)) { + isCycle = true; + break; + } tphsInRel.put(tphsInRel.size(), superTph); numOfVisitedPairs++; } @@ -356,7 +365,8 @@ public class BytecodeGen implements ASTVisitor { // Y muss durch Object ersetzt. // Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen) - if(methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes)) { + if((methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes)) + && !subTphRes.equals(superTphRes)) { GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes); simplifiedPairs.add(sPair); } diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 6b6cab17..e17f545b 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -8,9 +8,14 @@ import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.syntaxtree.statement.*; @@ -36,9 +41,12 @@ import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall; import de.dhbwstuttgart.bytecode.utilities.SamMethod; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.StatementVisitor; +import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -55,11 +63,14 @@ public class BytecodeGenMethod implements StatementVisitor { private boolean isInterface; private HashMap genericsAndBoundsMethod; private HashMap genericsAndBounds; - private boolean isBinaryExp = false; + public boolean isBinaryExp = false; private String superClass; private String path; + private SourceFile sf; private IStatement statement = null; - + +// private int numMethodCalls = 0; + // for tests ** private String fieldName; private String fieldDesc; @@ -73,7 +84,7 @@ public class BytecodeGenMethod implements StatementVisitor { public BytecodeGenMethod(String className, String superClass,ResultSet resultSet, Method m, MethodVisitor mv, HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, - HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, String path) { + HashMap genericsAndBounds, boolean isInterface, HashMap classFiles, SourceFile sf,String path) { this.className = className; this.superClass = superClass; @@ -86,6 +97,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.genericsAndBounds = genericsAndBounds; this.isInterface = isInterface; this.classFiles = classFiles; + this.sf = sf; this.path = path; if (!isInterface) @@ -116,7 +128,7 @@ public class BytecodeGenMethod implements StatementVisitor { this.isBinaryExp =isBinary; } - private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { + public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); } @@ -124,6 +136,11 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(Block block) { for (Statement stmt : block.getStatements()) { stmt.accept(this); + if(stmt instanceof MethodCall) { + String ret = getResolvedType(((MethodCall) stmt).getType()); + if(!ret.equals("void")) + mv.visitInsn(Opcodes.POP); + } } } @@ -140,7 +157,7 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(LocalVar localVar) { // wenn String + String zuerst wird ein StringBuilder initialisiert dann // wird die lokale Var geladen. Sonst wird zuerst die lokale Var geladen. - + System.out.println(localVar.name); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); if (isBinaryExp) { @@ -196,7 +213,7 @@ public class BytecodeGenMethod implements StatementVisitor { String largerType = getLargerType(lexpType, rexpType); String typeOfBinary = getResolvedType(binary.getType()); - + if (typeOfBinary.equals(Type.getInternalName(String.class))) { mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class)); mv.visitInsn(Opcodes.DUP); @@ -564,7 +581,7 @@ public class BytecodeGenMethod implements StatementVisitor { // ")"+lam.getReturn.getBounds Signature sig = new Signature(lambdaExpression, numberOfParams); String name = "Fun" + numberOfParams + "$$"; - classWriter.visit(Opcodes.V1_8, 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); MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc, methSig.toString(), null); @@ -591,7 +608,6 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(CastExpr castExpr) { - // TODO Auto-generated method stub } @@ -603,7 +619,6 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(FieldVar fieldVar) { - fieldName = fieldVar.fieldVarName; fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";"; @@ -631,51 +646,157 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(InstanceOf instanceOf) { - // TODO Auto-generated method stub } @Override public void visit(MethodCall methodCall) { - - //ClassLoader.getSystemClassLoader().loadClass(className).getMethod(name, parameterTypes) + System.out.println("In MethodCall = " + methodCall.name); String receiverName = getResolvedType(methodCall.receiver.getType()); System.out.println("Methods of " + receiverName + " "); - ClassLoader cl = ClassLoader.getSystemClassLoader(); + ClassLoader cLoader = ClassLoader.getSystemClassLoader(); + java.lang.reflect.Method methodRefl = null; + String clazz = receiverName.replace("/", "."); try { - java.lang.reflect.Method[] methods = cl.loadClass("java.util.Vector").getMethods(); + if(receiverName.contains("<")) { + clazz = clazz.substring(0, receiverName.indexOf("<")); + } + java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); System.out.println("Methods of " + receiverName + " "); for(java.lang.reflect.Method m : methods) { - System.out.println(m.getName() + " " + m.toGenericString()+ " ==> "); + if(methodCall.name.equals(m.getName())) { + methodRefl = m; + break; + } } } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + String superClass = ""; + // TODO: Test SubMatrix.jav + 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 { + String superClazz = superClass.replace("/", "."); + 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) { + if(methodCall.name.equals(m.getName())) { + methodRefl = m; + break; + } + } + + break; + } catch (Exception e2) { + receiverName = superClass; + continue; + } + } + } + methodCall.receiver.accept(this); System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); - methodCall.receiver.accept(this); - methodCall.arglist.accept(this); - - MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), - receiverName, genericsAndBoundsMethod, genericsAndBounds); - String mDesc = method.accept(new DescriptorToString(resultSet)); + String mDesc = ""; + List argListMethCall = new LinkedList<>(); + if(methodRefl == null) { + MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), + receiverName, genericsAndBoundsMethod, genericsAndBounds); + mDesc = method.accept(new DescriptorToString(resultSet)); + methodCall.arglist.accept(this); + } else { + for(Parameter p:methodRefl.getParameters()) { + System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive()); + argListMethCall.add(p.getType().isPrimitive()); + } + mDesc = getMethodDesc(methodRefl); + for (Expression al : methodCall.arglist.getArguments()) { + statement = new ArgumentExpr(al); + ArgumentVisitor argV = new ArgumentVisitor(argListMethCall,this); + al.accept(argV); + statement = null; + } + } + System.out.println("Methodcall Desc : " + mDesc); + + +// methodCall.arglist.accept(this); + // is methodCall.receiver functional Interface)? if (varsFunInterface.contains(methodCall.receiver.getType())) { - mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name, + mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name, mDesc, true); } else { - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name, + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clazz.replace(".", "/"), methodCall.name, mDesc, isInterface); } - // test - // if(!methodCall.getType().toString().equals("V")) { - // mv.visitInsn(Opcodes.POP); - // } - if(isBinaryExp) { - doUnboxing(getResolvedType(methodCall.getType())); + + if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) { + if(methodRefl.getReturnType().equals(Object.class)) { + String checkCast = getResolvedType(methodCall.getType()); + int pos = checkCast.length(); + if(checkCast.contains("<")) + pos = checkCast.indexOf("<"); + mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos)); + } + if(isBinaryExp) + doUnboxing(getResolvedType(methodCall.getType())); } + + } + + private String getMethodDesc(java.lang.reflect.Method methodRefl) { + StringBuilder sb = new StringBuilder("("); + + for(final Class c:(methodRefl.getParameterTypes())) + sb= sb.append(getDescriptorForClass(c)); + + sb.append(')'); + sb.append(getDescriptorForClass(methodRefl.getReturnType())); + return sb.toString(); + } + + private String getDescriptorForClass(final Class c) { + if(c.isPrimitive()) + { + if(c==byte.class) + return "B"; + if(c==char.class) + return "C"; + if(c==double.class) + return "D"; + if(c==float.class) + return "F"; + if(c==int.class) + return "I"; + if(c==long.class) + return "J"; + if(c==short.class) + return "S"; + if(c==boolean.class) + return "Z"; + if(c==void.class) + return "V"; + + } + if(c.isArray()) + return c.getName().replace('.', '/'); + + return ('L'+c.getName()+';').replace('.', '/'); } @Override @@ -707,6 +828,7 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(UnaryExpr unaryExpr) { + unaryExpr.expr.accept(this); Operation op = unaryExpr.operation; @@ -854,7 +976,7 @@ public class BytecodeGenMethod implements StatementVisitor { } // Unboxing: RefType -> prim - private void doUnboxing(String type) { + public void doUnboxing(String type) { switch (type) { case "java/lang/String": mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append", @@ -1079,14 +1201,5 @@ public class BytecodeGenMethod implements StatementVisitor { mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(var)); } - - private class TPHEx extends AbstractASTWalker{ - // Liste enthält alle tph der Methode - ArrayList allTPHS = new ArrayList<>(); - @Override - public void visit(TypePlaceholder tph) { - allTPHS.add(tph); - } - } } diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index 11f3ca20..c06f7b38 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -44,10 +44,13 @@ public class Signature { createSignatureForClassOrInterface(); } - public Signature(Constructor constructor, HashMap genericsAndBounds, HashMap methodParamsAndTypes) { + public Signature(Constructor constructor, HashMap genericsAndBounds, + HashMap methodParamsAndTypes,ResultSet resultSet,ArrayList methodPairs) { this.constructor = constructor; this.genericsAndBounds = genericsAndBounds; this.methodParamsAndTypes = methodParamsAndTypes; + this.resultSet = resultSet; + this.methodPairs = methodPairs; sw = new SignatureWriter(); createSignatureForConsOrMethod(this.constructor,true); } @@ -107,40 +110,45 @@ public class Signature { // Wenn die RückgabeType eine TPH ist, wird als generic behandelt // z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object - String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); - if(ret.substring(0,4).equals("TPH ")) { - String g = ret.substring(4,ret.length())+"$"; - if(genericsAndBounds.containsKey(g)) { - genericsAndBoundsMethod.put(g, genericsAndBounds.get(g)); - }else { - sw.visitFormalTypeParameter(g); - sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); - genericsAndBoundsMethod.put(g, Type.getInternalName(Object.class)); - sw.visitClassBound().visitEnd(); + if(!isConstructor) { + String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); + if(!ret.equals("V")) { + // TODO TypeToSignature nochmal kontrollieren und schauen ob man dort wirklich + // T... braucht und L ... + if(ret.contains("$") && !ret.contains("$$")) { + if(genericsAndBounds.containsKey(ret)) { + genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1))); + }else { + sw.visitFormalTypeParameter(ret.substring(1)); + sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); + genericsAndBoundsMethod.put(ret.substring(1), Type.getInternalName(Object.class)); + sw.visitClassBound().visitEnd(); + } + } + + if(ret.contains("<")) { + RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType; + if(hasTPHs(ref)) { + createSignatureForParameterizedType(ref); + } + + } } } - if(ret.contains("<")) { - RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType; - if(hasTPHs(ref)) { - createSignatureForParameterizedType(ref); - } - - } - // Parameters for(String paramName : methodParamsAndTypes.keySet()) { RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName); String pT = t.acceptTV(new TypeToSignature()); // S.o - if(pT.substring(0,4).equals("TPH ")) { - String gP = pT.substring(4,pT.length())+"$"; - if(!genericsAndBounds.containsKey(gP) && !genericsAndBoundsMethod.containsKey(gP)) { - sw.visitFormalTypeParameter(gP); + if(t instanceof TypePlaceholder) { + String gP = t.acceptTV(new TypeToSignature()); + if(!genericsAndBounds.containsKey(gP.substring(1)) && !genericsAndBoundsMethod.containsKey(gP.substring(1))) { + sw.visitFormalTypeParameter(gP.substring(1)); String bound = Type.getInternalName(Object.class); boolean isTypeVar = false; for(GenericInsertPair pair : methodPairs) { - if(pT.substring(4).equals(pair.TA1.getName())) { + if(pT.substring(1,pT.length()-1).equals(pair.TA1.getName())) { bound = pair.TA2.getName()+"$"; isTypeVar = true; break; @@ -154,7 +162,7 @@ public class Signature { sw.visitClassBound().visitEnd(); } - genericsAndBoundsMethod.put(gP, bound); + genericsAndBoundsMethod.put(gP.substring(1), bound); } } @@ -199,7 +207,8 @@ public class Signature { // parameter type deswegen ist true doVisitParamsOrReturn(t,true); } - if(isConstructor) { + if(isConstructor || + resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).equals("V")) { sw.visitReturnType().visitBaseType('V'); }else { RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType(); @@ -338,6 +347,10 @@ public class Signature { private boolean hasTPHs(RefType ref) { for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + System.out.println(p.acceptTV(new TypeToString())); + if(p.acceptTV(new TypeToString()).contains("WC")){ + continue; + } if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder) return true; } @@ -361,24 +374,34 @@ public class Signature { } switch (type) { case "RT": - sv.visitClassType(t.acceptTV(new TypeToSignature())); + String sig = t.acceptTV(new TypeToSignature()); + sv.visitClassType(sig.substring(1, sig.length())); break; case "GRT": GenericRefType g = (GenericRefType) t; - sv.visitTypeVariable(g.acceptTV(new TypeToSignature())); + sv.visitTypeVariable(g.acceptTV(new TypeToSignature()).substring(1)); break; case "TPH": RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType; // der Fall wenn die Type eine Interface ist, muss betrachtet werden // Deswegen muss in ResutSet noch enthalten werden, ob die Type eine // Interface oder eine Klasse ist. - if(!r.acceptTV(new TypeToSignature()).substring(0, 4).equals("TPH ")) { -// sv.visitInterface().visitClassType(r.acceptTV(new TypeToSignature())); - sv.visitClassType(r.acceptTV(new TypeToSignature())); + + // das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature()) + // + String sig2 = r.acceptTV(new TypeToSignature()); + if(!(r instanceof TypePlaceholder)) { + if(sig2.contains("$$")) { + sv.visitInterface().visitClassType(sig2.substring(1, sig2.length())); + } else { + sv.visitClassType(sig2.substring(1, sig2.length())); + } + } else { System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature())); - sv.visitTypeVariable(r.acceptTV(new TypeToSignature()).substring(4)+"$"); + sv.visitTypeVariable(sig2.substring(1, sig2.length())); } + break; default: if(!isParameterType) @@ -426,7 +449,8 @@ public class Signature { } } } - sw.visitSuperclass().visitClassType(classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()));; + String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature()); + sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1)); sw.visitEnd(); } /** diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index 62227c8e..785bfabe 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -15,6 +15,8 @@ public class TypeToSignature implements TypeVisitor { @Override public String visit(RefType refType) { + if(refType.getName().toString().equals("void")) + return "V"; // return refType.toString().replace(".", "/"); String params = ""; if(refType.getParaList().size()>0){ @@ -22,34 +24,41 @@ public class TypeToSignature implements TypeVisitor { Iterator it = refType.getParaList().iterator(); while(it.hasNext()){ RefTypeOrTPHOrWildcardOrGeneric param = it.next(); - if(param instanceof TypePlaceholder) { - params += "T" + ((TypePlaceholder) param).getName() + "$"; - } else { - params += "L"+param.toString().replace(".", "/"); - } - - if(it.hasNext())params += ";"; +// if(param instanceof TypePlaceholder) { +// params += "T" + ((TypePlaceholder) param).getName() + "$"; +// } else if(param instanceof ExtendsWildcardType) { +// params += "+" + ((ExtendsWildcardType) param).getInnerType().acceptTV(new TypeToSignature()); +// } else if(param instanceof SuperWildcardType) { +// params += "-" + ((SuperWildcardType) param).getInnerType().acceptTV(new TypeToSignature()); +// } else { +// params += "L"+param.toString().replace(".", "/"); +// } + params += param.acceptTV(new TypeToSignature()); +// if(it.hasNext())params += ";"; } - params += ";>"; + params += ">"; } // String t = refType.getName().toString().replace(".", "/"); // return t.equals("Fun1")?t+"$$"+params+";":t+params+";"; - return refType.getName().toString().replace(".", "/") + params+";"; + return "L"+refType.getName().toString().replace(".", "/") + params+";"; } @Override public String visit(SuperWildcardType superWildcardType) { - throw new NotImplementedException(); +// throw new NotImplementedException(); + return "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); } @Override public String visit(TypePlaceholder typePlaceholder) { - return typePlaceholder.toString().replace(".", "/"); +// return typePlaceholder.toString().replace(".", "/"); + return "T" + typePlaceholder.getName() + "$"; } @Override public String visit(ExtendsWildcardType extendsWildcardType) { - throw new NotImplementedException(); +// throw new NotImplementedException(); + return "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); } @Override diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToString.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToString.java index 94314afe..a0e280c2 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToString.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToString.java @@ -17,7 +17,7 @@ public class TypeToString implements TypeVisitor{ @Override public String visit(SuperWildcardType superWildcardType) { - throw new NotImplementedException(); + return "SWC"; } @Override @@ -27,7 +27,7 @@ public class TypeToString implements TypeVisitor{ @Override public String visit(ExtendsWildcardType extendsWildcardType) { - throw new NotImplementedException(); + return "EWC"; } @Override diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index c4db69f2..ffa8d54d 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -246,7 +246,7 @@ public class JavaTXCompiler { HashMap classFiles = new HashMap<>(); SourceFile sf = sourceFiles.get(f); List typeinferenceResult = this.typeInference(); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,path); + BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path); // BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0)); bytecodeGen.visit(sf); this.writeClassFile(bytecodeGen.getClassFiles(), path); diff --git a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java index e87f2f55..f84a4dbe 100644 --- a/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java +++ b/src/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java @@ -223,50 +223,75 @@ public class TYPEStmt implements StatementVisitor{ //Zuerst der Fall für Numerische AusdrücPairOpnumericeratorke, das sind Mul, Mod und Div immer: //see: https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.17 //Expression muss zu Numeric Convertierbar sein. also von Numeric erben - Constraint numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); - numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); - numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); - numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), longg, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); - numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), floatt, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); - numeric = new Constraint<>(); - numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); - numeric.add(new Pair(binary.getType(), doublee, PairOperator.SMALLERDOT)); - numericAdditionOrStringConcatenation.add(numeric); + Constraint numeric; + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(bytee.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), bytee, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), bytee, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(shortt.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), shortt, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), shortt, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(integer.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), integer, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), integer, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), integer, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(longg.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), longg, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), longg, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), longg, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(floatt.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), floatt, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), floatt, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), floatt, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + //PL eingefuegt 2018-07-17 + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(doublee.getName())) { + numeric = new Constraint<>(); + numeric.add(new Pair(binary.lexpr.getType(), doublee, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.rexpr.getType(), doublee, PairOperator.SMALLERDOT)); + numeric.add(new Pair(binary.getType(), doublee, PairOperator.SMALLERDOT)); + numericAdditionOrStringConcatenation.add(numeric); + } + /* PL auskommentiert Anfang 2018-07-17 /* In Java passiert bei den binären Operatoren eine sogenannte Type Promotion: https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2 Das bedeutet, dass Java die Typen je nach belieben castet, so lange sie nur von Number erben - */ + + numeric = new Constraint<>(); numeric.add(new Pair(binary.getType(), number, PairOperator.SMALLERDOT)); numericAdditionOrStringConcatenation.add(numeric); + * PL auskommentiert Ende 2018-07-17 */ + if(binary.operation.equals(BinaryExpr.Operator.ADD)) { //Dann kann der Ausdruck auch das aneinanderfügen zweier Strings sein: ("a" + "b") oder (1 + 2) - Constraint stringConcat = new Constraint<>(); - stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT)); - stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT)); - stringConcat.add(new Pair(binary.getType(), string, PairOperator.EQUALSDOT)); - numericAdditionOrStringConcatenation.add(stringConcat); + if (info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new)).contains(string.getName())) { + Constraint stringConcat = new Constraint<>(); + stringConcat.add(new Pair(binary.lexpr.getType(), string, PairOperator.EQUALSDOT)); + stringConcat.add(new Pair(binary.rexpr.getType(), string, PairOperator.EQUALSDOT)); + stringConcat.add(new Pair(binary.getType(), string, PairOperator.EQUALSDOT)); + numericAdditionOrStringConcatenation.add(stringConcat); + } } constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); }else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || diff --git a/test/bytecode/LambdaTest.java b/test/bytecode/LambdaTest.java index 72d21f54..bdcfc0da 100644 --- a/test/bytecode/LambdaTest.java +++ b/test/bytecode/LambdaTest.java @@ -1,6 +1,12 @@ package bytecode; +import static org.junit.Assert.assertEquals; + import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; import org.junit.Test; @@ -10,6 +16,10 @@ public class LambdaTest { 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 { @@ -17,6 +27,22 @@ public class LambdaTest { fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("Lambda"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + + Method m = classToTest.getDeclaredMethod("m"); + Class lambda = m.invoke(instanceOfClass).getClass(); + Method apply = lambda.getMethod("apply", Object.class); + + // Damit man auf die Methode zugreifen kann + apply.setAccessible(true); + + Integer i = 77; + // result = 77*77 = 5929 + Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i); + assertEquals(5929, result); } diff --git a/test/bytecode/MatrixTest.java b/test/bytecode/MatrixTest.java index db8dc8ab..cd0a20b7 100644 --- a/test/bytecode/MatrixTest.java +++ b/test/bytecode/MatrixTest.java @@ -3,8 +3,12 @@ package bytecode; import static org.junit.Assert.*; import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; +import java.util.Vector; import org.junit.BeforeClass; import org.junit.Test; @@ -18,23 +22,70 @@ public class MatrixTest { private static ClassLoader loader; private static Class classToTest; private static String pathToClassFile; - private static Object instanceOfClass; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { + private static Object instanceOfClass_m1; + private static Object instanceOfClass_m2; + private static Object instanceOfClass_m3; + + @Test + public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException { path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Matrix.jav"; fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; compiler.generateBytecode(pathToClassFile); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); - classToTest = loader.loadClass("Matrix"); - instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); - } + classToTest = loader.loadClass("Matrix"); + + Vector> vv = new Vector>(); + Vector v1 = new Vector (); + v1.addElement(2); + v1.addElement(2); + Vector v2 = new Vector (); + v2.addElement(3); + v2.addElement(3); + //Matrix m1 = new Matrix(); + //m1.addElement(v1); + //m1.addElement(v2); + vv.addElement(v1); + vv.addElement(v2); + instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv); - @Test - public void test() { - fail("Not yet implemented"); + Vector> vv1 = new Vector>(); + Vector v3 = new Vector (); + v3.addElement(2); + v3.addElement(2); + Vector v4 = new Vector (); + v4.addElement(3); + v4.addElement(3); + //Matrix m2 = new Matrix(); + //m2.addElement(v3); + //m2.addElement(v4); + vv1.addElement(v3); + vv1.addElement(v4); + instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1); + + + + //Matrix m3 = m1.mul(vv1); + Method mul = classToTest.getDeclaredMethod("mul", Vector.class); + Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2); + System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString()); + + Vector> res = new Vector>(); + Vector v5 = new Vector (); + v5.addElement(10); + v5.addElement(10); + Vector v6 = new Vector (); + v6.addElement(15); + v6.addElement(15); + //Matrix m2 = new Matrix(); + //m2.addElement(v3); + //m2.addElement(v4); + res.addElement(v5); + res.addElement(v6); + instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res); + assertEquals(result, instanceOfClass_m3); + } } diff --git a/test/bytecode/OLTest.java b/test/bytecode/OLTest.java index 288e580f..d6ab4dd1 100644 --- a/test/bytecode/OLTest.java +++ b/test/bytecode/OLTest.java @@ -3,6 +3,8 @@ package bytecode; import static org.junit.Assert.*; import java.io.File; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -17,8 +19,10 @@ public class OLTest { private static JavaTXCompiler compiler; private static ClassLoader loader; private static Class classToTest; + private static Class classToTest1; private static String pathToClassFile; private static Object instanceOfClass; + private static Object instanceOfClass1; @BeforeClass public static void setUpBeforeClass() throws Exception { @@ -30,10 +34,59 @@ public class OLTest { loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); classToTest = loader.loadClass("OL"); instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + classToTest1 = loader.loadClass("OLMain"); + instanceOfClass1 = classToTest1.getDeclaredConstructor().newInstance(); } + @Test - public void test() { - fail("Not yet implemented"); + public void testOLClassName() { + assertEquals("OL", classToTest.getName()); + } + + @Test + public void testmInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("m", Integer.class); + Integer result = (Integer) m.invoke(instanceOfClass, 5); + assertEquals(10, result); + } + + @Test + public void testmDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("m", Double.class); + Double result = (Double) m.invoke(instanceOfClass, 5.0); + assertEquals(10.0, result); + } + + @Test + public void testmString() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method m = classToTest.getDeclaredMethod("m", String.class); + String result = (String) m.invoke(instanceOfClass, "xxx"); + assertEquals("xxxxxx", result); + } + + @Test + public void testOLMainClassName() { + assertEquals("OLMain", classToTest1.getName()); + } + + @Test + public void testmainInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method main = classToTest1.getDeclaredMethod("main", Integer.class); + Integer result = (Integer) main.invoke(instanceOfClass1, 5); + assertEquals(10, result); + } + + @Test + public void testmainDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method main = classToTest1.getDeclaredMethod("main", Double.class); + Double result = (Double) main.invoke(instanceOfClass1, 5.0); + assertEquals(10.0, result); + } + + @Test + public void testmainString() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Method main = classToTest1.getDeclaredMethod("main", String.class); + String result = (String) main.invoke(instanceOfClass1, "xxx"); + assertEquals("xxxxxx", result); } - } diff --git a/test/bytecode/SubMatTest.java b/test/bytecode/SubMatTest.java new file mode 100644 index 00000000..8818bd40 --- /dev/null +++ b/test/bytecode/SubMatTest.java @@ -0,0 +1,27 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; + +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class SubMatTest { + private static String path; + private static File fileToTest; + private static JavaTXCompiler compiler; + private static String pathToClassFile; + + @Test + public void test() throws ClassNotFoundException, IOException { + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/SubMatrix.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + compiler.generateBytecode(pathToClassFile); + } + +} diff --git a/test/bytecode/Tph2Test.java b/test/bytecode/Tph2Test.java index de706431..f267f45a 100644 --- a/test/bytecode/Tph2Test.java +++ b/test/bytecode/Tph2Test.java @@ -3,6 +3,7 @@ package bytecode; import static org.junit.Assert.*; import java.io.File; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -34,8 +35,35 @@ public class Tph2Test { } @Test - public void test() { - fail("Not yet implemented"); + public void test1() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,2); + + assertEquals(1,result); + } + + @Test + public void test2() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, "sss",2); + + assertEquals("sss",result); + } + + @Test + public void test3() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,2); + + assertEquals(2,result); + } + + @Test + public void test4() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,"xxx"); + + assertEquals("xxx",result); } } diff --git a/test/bytecode/Tph3Test.java b/test/bytecode/Tph3Test.java new file mode 100644 index 00000000..64bfa28f --- /dev/null +++ b/test/bytecode/Tph3Test.java @@ -0,0 +1,69 @@ +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 Tph3Test { + + private static String path; + private static File fileToTest; + private static JavaTXCompiler compiler; + private static ClassLoader loader; + private static Class classToTest; + private static String pathToClassFile; + private static Object instanceOfClass; + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Tph3.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + compiler.generateBytecode(pathToClassFile); + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("Tph3"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + } + + @Test + public void test1() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,2); + + assertEquals(1,result); + } + + @Test + public void test2() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, "sss",2); + + assertEquals("sss",result); + } + + @Test + public void test3() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,2); + + assertEquals(2,result); + } + + @Test + public void test4() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,"xxx"); + + assertEquals("xxx",result); + } + +} diff --git a/test/bytecode/TphTest.java b/test/bytecode/TphTest.java index 92b786ce..3f0a7bb3 100644 --- a/test/bytecode/TphTest.java +++ b/test/bytecode/TphTest.java @@ -3,6 +3,7 @@ package bytecode; import static org.junit.Assert.*; import java.io.File; +import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; @@ -12,6 +13,7 @@ import org.junit.Test; import de.dhbwstuttgart.core.JavaTXCompiler; public class TphTest { + private static String path; private static File fileToTest; private static JavaTXCompiler compiler; @@ -33,8 +35,35 @@ public class TphTest { } @Test - public void test() { - fail("Not yet implemented"); + public void test1() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1,2); + + assertEquals(2,result); + } + + @Test + public void test2() throws Exception { + Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); + Object result = m.invoke(instanceOfClass, 1, "sss"); + + assertEquals("sss",result); + } + + @Test + public void test3() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class); + Object result = m.invoke(instanceOfClass, 2); + + assertEquals(2,result); + } + + @Test + public void test4() throws Exception { + Method m = classToTest.getDeclaredMethod("m2", Object.class); + Object result = m.invoke(instanceOfClass,"xxx"); + + assertEquals("xxx",result); } } diff --git a/test/bytecode/applyLambdaTest.java b/test/bytecode/applyLambdaTest.java new file mode 100644 index 00000000..b73cf507 --- /dev/null +++ b/test/bytecode/applyLambdaTest.java @@ -0,0 +1,39 @@ +package bytecode; + +import static org.junit.Assert.assertEquals; + +import java.io.File; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; + +import org.junit.Test; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class applyLambdaTest { + 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")+"/test/bytecode/javFiles/applyLambda.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/"); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("applyLambda"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); + + Method m = classToTest.getDeclaredMethod("m"); + Object result = m.invoke(instanceOfClass); + + assertEquals(result.getClass(), loader.loadClass("Apply")); + } +} diff --git a/test/bytecode/javFiles/Lambda.jav b/test/bytecode/javFiles/Lambda.jav index bc2b8d60..d7809e7e 100644 --- a/test/bytecode/javFiles/Lambda.jav +++ b/test/bytecode/javFiles/Lambda.jav @@ -1,16 +1,11 @@ -import java.util.Vector; -class Apply { } +import java.lang.Integer; public class Lambda { m () { - var lam1 = (x) -> { - return x; + var lam1 = (Integer x) -> { + return x * x; }; - - return lam1.apply(new Apply()); - //return lam1; -// return new Vector(); + return lam1; } } - diff --git a/test/bytecode/javFiles/Matrix.jav b/test/bytecode/javFiles/Matrix.jav index eff095c7..2ba7f307 100644 --- a/test/bytecode/javFiles/Matrix.jav +++ b/test/bytecode/javFiles/Matrix.jav @@ -1,26 +1,42 @@ import java.util.Vector; import java.lang.Integer; +//import java.lang.Byte; import java.lang.Boolean; public class Matrix extends Vector> { - mul(m) { + + Matrix () { + } + + Matrix(vv) { + Integer i; + i = 0; + while(i < vv.size()) { +// Boolean a = this.add(vv.elementAt(i)); + this.add(vv.elementAt(i)); + i=i+1; + } + } + + mul(m) { var ret = new Matrix(); var i = 0; while(i < size()) { var v1 = this.elementAt(i); -// var v2 = new Vector(); -// var j = 0; -// while(j < v1.size()) { -// var erg = 0; - // var k = 0; - // while(k < v1.size()) { -// erg = erg + v1.elementAt(k) - // * m.elementAt(k).elementAt(j); - // k++; } - // v2.addElement(new Integer(erg)); -// j++; } -// ret.addElement(v2); -// i++; + var v2 = new Vector(); + var j = 0; + while(j < v1.size()) { + var erg = 0; + var k = 0; + while(k < v1.size()) { + erg = erg + v1.elementAt(k) + * m.elementAt(k).elementAt(j); + k++; } +// v2.addElement(new Integer(erg)); + v2.addElement(erg); + j++; } + ret.addElement(v2); + i++; } return ret; } diff --git a/test/bytecode/javFiles/OL.jav b/test/bytecode/javFiles/OL.jav index fd2c30a4..263cf1ec 100644 --- a/test/bytecode/javFiles/OL.jav +++ b/test/bytecode/javFiles/OL.jav @@ -1,10 +1,11 @@ +import java.lang.String; import java.lang.Integer; import java.lang.Double; -class OL { +public class OL { - m(java.lang.Double x) { return x + x; } + m(x) { return x + x; } //m(x) { return x || x; } @@ -12,7 +13,7 @@ class OL { } -class Main { +public class OLMain { main(x) { var ol; diff --git a/test/bytecode/javFiles/SubMatrix.jav b/test/bytecode/javFiles/SubMatrix.jav new file mode 100644 index 00000000..f761321c --- /dev/null +++ b/test/bytecode/javFiles/SubMatrix.jav @@ -0,0 +1,13 @@ +import java.util.Vector; +import java.lang.Integer; + +public class Matrix2 extends Vector { + +} + +public class SubMatrix extends Matrix2 { + m(){ + Vector v = new Vector(); + v.add(1); + } +} \ No newline at end of file diff --git a/test/bytecode/javFiles/Tph.jav b/test/bytecode/javFiles/Tph.jav index 3f9d0aab..8dbb1507 100644 --- a/test/bytecode/javFiles/Tph.jav +++ b/test/bytecode/javFiles/Tph.jav @@ -2,7 +2,7 @@ public class Tph { m(a,b){ var c = m2(b); - return a; + return c; } m2(b){ diff --git a/test/bytecode/javFiles/Tph3.jav b/test/bytecode/javFiles/Tph3.jav new file mode 100644 index 00000000..42d5d687 --- /dev/null +++ b/test/bytecode/javFiles/Tph3.jav @@ -0,0 +1,10 @@ +public class Tph3 { + m(a,b){ + var c = m2(a,b); + return c; + } + + m2(a,b){ + return m(a,b); + } +} diff --git a/test/bytecode/javFiles/Tph4.jav b/test/bytecode/javFiles/Tph4.jav new file mode 100644 index 00000000..1eb529de --- /dev/null +++ b/test/bytecode/javFiles/Tph4.jav @@ -0,0 +1,12 @@ +public class Tph4{ + m(a,b){ + var c = m2(b); + var d = m2(c); + return a; + } + + m2(b){ + return b + } + +} \ No newline at end of file diff --git a/test/bytecode/javFiles/applyLambda.jav b/test/bytecode/javFiles/applyLambda.jav new file mode 100644 index 00000000..331bfbfe --- /dev/null +++ b/test/bytecode/javFiles/applyLambda.jav @@ -0,0 +1,16 @@ +import java.util.Vector; +class Apply { } + +public class applyLambda { + + m () { + var lam1 = (x) -> { + return x; + }; + + return lam1.apply(new Apply()); + //return lam1; + //return new Vector(); + } +} +