From f453343f1c33a51750a753155dbaa0cd6aa25309 Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Tue, 6 Mar 2018 19:14:27 +0100 Subject: [PATCH] =?UTF-8?q?Bytecode=20f=C3=BCr=20arithmetische=20Operatore?= =?UTF-8?q?n=20mit=20Parametern=20unterschiedlicher=20Typen.=20Testf=C3=A4?= =?UTF-8?q?lle=20bereinigt=20und=20aufger=C3=A4umt.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bytecode/BytecodeGenMethod.java | 465 +++++++++--------- src/de/dhbwstuttgart/core/JavaTXCompiler.java | 27 +- test/bytecode/ATest.java | 8 - test/bytecode/AssignToLitTest.java | 7 - test/bytecode/DuMethodTest.java | 7 - test/bytecode/ForTest.java | 11 - test/bytecode/Generics2Test.java | 7 - test/bytecode/GenericsTest.java | 7 - test/bytecode/ImportTest.java | 7 - test/bytecode/InterfaceTest.java | 7 - test/bytecode/JavaTXCompilerTest.java | 90 ---- test/bytecode/LamAssignTest.java | 7 - test/bytecode/MethodsTest.java | 7 - test/bytecode/Op.jav | 46 -- test/bytecode/OpTest.java | 156 +++++- test/bytecode/OverlaodGenTest.java | 7 - test/bytecode/TestIfTest.java | 7 - test/bytecode/{ => javFiles}/AssignToLit.jav | 0 test/bytecode/{ => javFiles}/DuMethod.jav | 0 test/bytecode/{ => javFiles}/EmptyMethod.jav | 0 test/bytecode/{ => javFiles}/Example.jav | 0 test/bytecode/{ => javFiles}/Exceptions.jav | 0 test/bytecode/{ => javFiles}/Faculty.jav | 0 test/bytecode/{ => javFiles}/Faculty2.jav | 0 test/bytecode/{ => javFiles}/For.jav | 0 test/bytecode/{ => javFiles}/Gen.jav | 0 test/bytecode/{ => javFiles}/Generics.jav | 0 test/bytecode/{ => javFiles}/Generics2.jav | 0 test/bytecode/{ => javFiles}/IfTest.jav | 0 test/bytecode/{ => javFiles}/Import.jav | 0 test/bytecode/{ => javFiles}/Interface1.jav | 0 test/bytecode/{ => javFiles}/LamAssign.jav | 0 test/bytecode/{ => javFiles}/LamRunnable.jav | 0 test/bytecode/{ => javFiles}/Lambda.jav | 0 test/bytecode/{ => javFiles}/Lambda2.jav | 0 test/bytecode/{ => javFiles}/Lambda3.jav | 0 test/bytecode/{ => javFiles}/Methods.jav | 0 test/bytecode/javFiles/Op.jav | 88 ++++ test/bytecode/{ => javFiles}/OverlaodGen.jav | 0 .../bytecode/{ => javFiles}/RecursiveMeth.jav | 0 test/bytecode/{ => javFiles}/ReturnMethod.jav | 0 test/bytecode/{ => javFiles}/VoidMeth.jav | 0 42 files changed, 505 insertions(+), 456 deletions(-) delete mode 100644 test/bytecode/ATest.java delete mode 100644 test/bytecode/AssignToLitTest.java delete mode 100644 test/bytecode/DuMethodTest.java delete mode 100644 test/bytecode/ForTest.java delete mode 100644 test/bytecode/Generics2Test.java delete mode 100644 test/bytecode/GenericsTest.java delete mode 100644 test/bytecode/ImportTest.java delete mode 100644 test/bytecode/InterfaceTest.java delete mode 100644 test/bytecode/JavaTXCompilerTest.java delete mode 100644 test/bytecode/LamAssignTest.java delete mode 100644 test/bytecode/MethodsTest.java delete mode 100644 test/bytecode/Op.jav delete mode 100644 test/bytecode/OverlaodGenTest.java delete mode 100644 test/bytecode/TestIfTest.java rename test/bytecode/{ => javFiles}/AssignToLit.jav (100%) rename test/bytecode/{ => javFiles}/DuMethod.jav (100%) rename test/bytecode/{ => javFiles}/EmptyMethod.jav (100%) rename test/bytecode/{ => javFiles}/Example.jav (100%) rename test/bytecode/{ => javFiles}/Exceptions.jav (100%) rename test/bytecode/{ => javFiles}/Faculty.jav (100%) rename test/bytecode/{ => javFiles}/Faculty2.jav (100%) rename test/bytecode/{ => javFiles}/For.jav (100%) rename test/bytecode/{ => javFiles}/Gen.jav (100%) rename test/bytecode/{ => javFiles}/Generics.jav (100%) rename test/bytecode/{ => javFiles}/Generics2.jav (100%) rename test/bytecode/{ => javFiles}/IfTest.jav (100%) rename test/bytecode/{ => javFiles}/Import.jav (100%) rename test/bytecode/{ => javFiles}/Interface1.jav (100%) rename test/bytecode/{ => javFiles}/LamAssign.jav (100%) rename test/bytecode/{ => javFiles}/LamRunnable.jav (100%) rename test/bytecode/{ => javFiles}/Lambda.jav (100%) rename test/bytecode/{ => javFiles}/Lambda2.jav (100%) rename test/bytecode/{ => javFiles}/Lambda3.jav (100%) rename test/bytecode/{ => javFiles}/Methods.jav (100%) create mode 100644 test/bytecode/javFiles/Op.jav rename test/bytecode/{ => javFiles}/OverlaodGen.jav (100%) rename test/bytecode/{ => javFiles}/RecursiveMeth.jav (100%) rename test/bytecode/{ => javFiles}/ReturnMethod.jav (100%) rename test/bytecode/{ => javFiles}/VoidMeth.jav (100%) diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 49a6750e..5c9df9e1 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -38,34 +38,34 @@ import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.typeinference.result.ResultSet; -public class BytecodeGenMethod implements StatementVisitor{ - +public class BytecodeGenMethod implements StatementVisitor { + private Method m; private MethodVisitor mv; - private HashMap paramsAndLocals = new HashMap<>(); + private HashMap paramsAndLocals = new HashMap<>(); private String className; private int lamCounter = -1; private ClassWriter cw; private ResultSet resultSet; private boolean isInterface; HashMap genericsAndBoundsMethod; - private HashMap genericsAndBounds; + private HashMap genericsAndBounds; private boolean isBinaryExp = false; - - //for tests ** + + // for tests ** private String fieldName; private String fieldDesc; private Expression rightSideTemp; private boolean isRightSideALambda = false; private KindOfLambda kindOfLambda; private HashMap classFiles; - + private ArrayList varsFunInterface = new ArrayList<>();; - - public BytecodeGenMethod(String className,ResultSet resultSet, Method m, MethodVisitor mv, - HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, - HashMap genericsAndBounds, boolean isInterface, HashMap classFiles) { - + + public BytecodeGenMethod(String className, ResultSet resultSet, Method m, MethodVisitor mv, + HashMap paramsAndLocals, ClassWriter cw, HashMap genericsAndBoundsMethod, + HashMap genericsAndBounds, boolean isInterface, HashMap classFiles) { + this.className = className; this.resultSet = resultSet; this.m = m; @@ -76,15 +76,15 @@ public class BytecodeGenMethod implements StatementVisitor{ this.genericsAndBounds = genericsAndBounds; this.isInterface = isInterface; this.classFiles = classFiles; - - if(!isInterface) + + if (!isInterface) this.m.block.accept(this); - + } - - public BytecodeGenMethod(LambdaExpression lambdaExpression,ResultSet resultSet ,MethodVisitor mv, - int indexOfFirstParamLam, boolean isInterface, HashMap classFiles) { - + + public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv, + int indexOfFirstParamLam, boolean isInterface, HashMap classFiles) { + this.resultSet = resultSet; this.mv = mv; this.isInterface = isInterface; @@ -92,46 +92,46 @@ public class BytecodeGenMethod implements StatementVisitor{ Iterator itr = lambdaExpression.params.iterator(); int i = indexOfFirstParamLam; - while(itr.hasNext()) { + while (itr.hasNext()) { FormalParameter fp = itr.next(); this.paramsAndLocals.put(fp.getName(), i); i++; } lambdaExpression.methodBody.accept(this); } - + private String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) { return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor()); } - - + @Override public void visit(Block block) { - for(Statement stmt : block.getStatements()) { + for (Statement stmt : block.getStatements()) { stmt.accept(this); } } - + @Override public void visit(SuperCall superCall) { superCall.receiver.accept(this); superCall.arglist.accept(this); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), - superCall.name, "()V",isInterface); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), superCall.name, "()V", + isInterface); } - + // ?? @Override 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. - + mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); - - if(isBinaryExp) { + + if (isBinaryExp) { getVlaueIns(getResolvedType(localVar.getType())); } } + // ?? @Override public void visit(LocalVarDecl localVarDecl) { @@ -141,72 +141,97 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(Assign assign) { // if the right side is a lambda => the left side must be a functional interface - if(assign.rightSide instanceof LambdaExpression) { + if (assign.rightSide instanceof LambdaExpression) { isRightSideALambda = true; - }else { + } else { isRightSideALambda = false; } - - if(assign.rightSide instanceof BinaryExpr) + + if (assign.rightSide instanceof BinaryExpr) isBinaryExp = true; - - if(assign.lefSide instanceof AssignToField) { + + if (assign.lefSide instanceof AssignToField) { // load_0, ldc or .. then putfield this.rightSideTemp = assign.rightSide; - }else { + } else { assign.rightSide.accept(this); } - if(isBinaryExp) { + if (isBinaryExp) { getValueOfIns(getResolvedType(assign.lefSide.getType())); isBinaryExp = false; } assign.lefSide.accept(this); } - /* - * Die folgeneden Fälle müssen noch betrachtet werden: - * - Long OPARATION Integer usw. - * */ + + /* + * Die folgeneden Fälle müssen noch betrachtet werden: - Long OPARATION Integer + * usw. + */ @Override public void visit(BinaryExpr binary) { String typeOfBinary = getResolvedType(binary.getType()); - if(typeOfBinary.equals(Type.getInternalName(String.class))) { + if (typeOfBinary.equals(Type.getInternalName(String.class))) { mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class)); mv.visitInsn(Opcodes.DUP); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), - "", "()V", false); + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(StringBuilder.class), "", "()V", + false); } binary.lexpr.accept(this); + if(!getResolvedType(binary.lexpr.getType()).equals(typeOfBinary)) + doCast(getResolvedType(binary.lexpr.getType()), typeOfBinary); binary.rexpr.accept(this); switch (binary.operation.toString()) { case "ADD": doVisitAddOpInsn(typeOfBinary); break; - + case "SUB": doVisitSubOpInsn(typeOfBinary); break; - + case "MUL": doVisitMulOpInsn(typeOfBinary); break; - + case "DIV": doVisitDivOpInsn(typeOfBinary); break; - + case "MOD": doVisitModOpInsn(typeOfBinary); break; - + case "LESSTHAN": doVisitLessOpInsn(typeOfBinary); break; - + default: break; } - + } + + private void doCast(String typeOfExp, String typeOfBinary) { + switch (typeOfBinary) { + case "java/lang/Long": + mv.visitInsn(Opcodes.I2L); + break; + + case "java/lang/Double": + if(typeOfExp.equals(Type.getInternalName(Long.class))) { + mv.visitInsn(Opcodes.L2D); + } else if(typeOfExp.equals(Type.getInternalName(Float.class))) { + mv.visitInsn(Opcodes.F2D); + } else { + mv.visitInsn(Opcodes.I2D); + } + break; + + default: + break; + } + } + // TODO private void doVisitLessOpInsn(String typeOfBinary) { switch (typeOfBinary) { @@ -298,7 +323,7 @@ public class BytecodeGenMethod implements StatementVisitor{ mv.visitInsn(Opcodes.ISUB); break; } - + } private void doVisitAddOpInsn(String typeOfBinary) { @@ -329,147 +354,148 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(LambdaExpression lambdaExpression) { this.lamCounter++; - + Lambda lam = new Lambda(lambdaExpression); String lamDesc = lam.accept(new DescriptorToString(resultSet)); - //Call site, which, when invoked, returns an instance of the functional interface to which - //the lambda is being converted + // Call site, which, when invoked, returns an instance of the functional + // interface to which + // the lambda is being converted MethodType mt = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, - MethodType.class, MethodType.class, MethodHandle.class, MethodType.class); - + MethodType.class, MethodType.class, MethodHandle.class, MethodType.class); - Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", - "metafactory", mt.toMethodDescriptorString(), false); + Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", + mt.toMethodDescriptorString(), false); String methodName = "lambda$new$" + this.lamCounter; - - // Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die Typlöschung) - + + // Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die + // Typlöschung) + String typeErasure = "("; Iterator itr = lambdaExpression.params.iterator(); - while(itr.hasNext()) { + while (itr.hasNext()) { itr.next(); - typeErasure += "L"+Type.getInternalName(Object.class) + ";"; + typeErasure += "L" + Type.getInternalName(Object.class) + ";"; } - - typeErasure += ")L"+Type.getInternalName(Object.class) + ";"; + + typeErasure += ")L" + Type.getInternalName(Object.class) + ";"; // Type erasure Type arg1 = Type.getMethodType(typeErasure); -// Type arg1 = Type.getMethodType(lamDesc); + // Type arg1 = Type.getMethodType(lamDesc); // real Type Type arg3 = Type.getMethodType(lamDesc); - - int staticOrSpecial=0; - int staticOrInstance=0; + + int staticOrSpecial = 0; + int staticOrInstance = 0; int indexOfFirstParamLam = 0; this.kindOfLambda = new KindOfLambda(lambdaExpression); - if(kindOfLambda.isInstanceCapturingLambda()) { + if (kindOfLambda.isInstanceCapturingLambda()) { mv.visitVarInsn(Opcodes.ALOAD, 0); staticOrSpecial = Opcodes.H_INVOKESPECIAL; indexOfFirstParamLam = 1; - }else { + } else { staticOrSpecial = Opcodes.H_INVOKESTATIC; staticOrInstance = Opcodes.ACC_STATIC; } - + // first check if capturing lambda then invokestatic or invokespecial - Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, - arg3.toString(),false); + Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, arg3.toString(), false); // Descriptor of functional interface methode SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); // Desc: (this/nothing)TargetType String fiMethodDesc = samMethod.accept(new DescriptorToString(resultSet)); - mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2,arg3); - - MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE+ staticOrInstance + Opcodes.ACC_SYNTHETIC, + mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3); + + MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC, methodName, arg3.toString(), null, null); - new BytecodeGenMethod(lambdaExpression,this.resultSet,mvLambdaBody,indexOfFirstParamLam,isInterface, + new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, classFiles); - + mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitEnd(); cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup", Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL); - -// generateBCForFunN(lambdaExpression,typeErasure); + + // generateBCForFunN(lambdaExpression,typeErasure); } private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) { - ClassWriter classWriter =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); - + ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); + SignatureWriter methSig = new SignatureWriter(); - + int numberOfParams = 0; SignatureVisitor paramVisitor = methSig.visitParameterType(); Iterator itr = lambdaExpression.params.iterator(); - while(itr.hasNext()) { + while (itr.hasNext()) { numberOfParams++; // getBounds - paramVisitor.visitTypeVariable("T"+numberOfParams); + paramVisitor.visitTypeVariable("T" + numberOfParams); itr.next(); } methSig.visitReturnType().visitTypeVariable("R"); // ")"+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(), Type.getInternalName(Object.class), null); - MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_ABSTRACT, "apply", - methDesc, methSig.toString(), null); + Signature sig = new Signature(lambdaExpression, numberOfParams); + String name = "Fun" + numberOfParams; + classWriter.visit(Opcodes.V1_8, 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); + writeClassFile(classWriter.toByteArray(), name); } - + public void writeClassFile(byte[] bytecode, String name) { FileOutputStream output; try { - System.out.println("generating "+name+ ".class file..."); - output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" +name+".class")); + System.out.println("generating " + name + ".class file..."); + output = new FileOutputStream( + new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/examples/" + name + ".class")); output.write(bytecode); output.close(); - System.out.println(name+".class file generated"); + System.out.println(name + ".class file generated"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } - -} + + } @Override public void visit(CastExpr castExpr) { // TODO Auto-generated method stub - + } @Override public void visit(EmptyStmt emptyStmt) { // TODO Auto-generated method stub - + } @Override public void visit(FieldVar fieldVar) { - + fieldName = fieldVar.fieldVarName; - fieldDesc = "L"+getResolvedType(fieldVar.getType())+";"; - + fieldDesc = "L" + getResolvedType(fieldVar.getType()) + ";"; + fieldVar.receiver.accept(this); // test (if) - if(!fieldVar.receiver.getClass().equals(StaticClassName.class)) { - mv.visitFieldInsn(Opcodes.GETFIELD,getResolvedType(fieldVar.receiver.getType()), - fieldName ,fieldDesc); + if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) { + mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc); } - -// mv.visitFieldInsn(Opcodes.GETSTATIC, fieldVar.receiver.getType().toString().replace(".", "/"), -// fieldVar.fieldVarName, fieldVar.getType().toString()); + + // mv.visitFieldInsn(Opcodes.GETSTATIC, + // fieldVar.receiver.getType().toString().replace(".", "/"), + // fieldVar.fieldVarName, fieldVar.getType().toString()); } @Override public void visit(ForStmt forStmt) { // TODO Auto-generated method stub - + } @Override @@ -480,52 +506,52 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(InstanceOf instanceOf) { // TODO Auto-generated method stub - + } @Override public void visit(MethodCall methodCall) { methodCall.receiver.accept(this); methodCall.arglist.accept(this); - + MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), - genericsAndBoundsMethod,genericsAndBounds); + genericsAndBoundsMethod, genericsAndBounds); String mDesc = method.accept(new DescriptorToString(resultSet)); - - // is methodCall.receiver functional Interface)? - if(varsFunInterface.contains(methodCall.receiver.getType())) { - mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc, false); - }else { - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), - methodCall.name, mDesc, isInterface); + + // is methodCall.receiver functional Interface)? + if (varsFunInterface.contains(methodCall.receiver.getType())) { + mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, getResolvedType(methodCall.receiver.getType()), methodCall.name, + mDesc, false); + } else { + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, getResolvedType(methodCall.receiver.getType()), methodCall.name, + mDesc, isInterface); } // test -// if(!methodCall.getType().toString().equals("V")) { -// mv.visitInsn(Opcodes.POP); -// } + // if(!methodCall.getType().toString().equals("V")) { + // mv.visitInsn(Opcodes.POP); + // } } @Override public void visit(NewClass methodCall) { - + mv.visitTypeInsn(Opcodes.NEW, methodCall.name.replace(".", "/")); mv.visitInsn(Opcodes.DUP); // creates Descriptor methodCall.arglist.accept(this); String d = "("; - for(Expression e : methodCall.arglist.getArguments()) { - d = d + "L"+getResolvedType(e.getType()) + ";"; + for (Expression e : methodCall.arglist.getArguments()) { + d = d + "L" + getResolvedType(e.getType()) + ";"; } d += ")V"; - + mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "", d, isInterface); } @Override public void visit(NewArray newArray) { // TODO Auto-generated method stub - + } @Override @@ -551,10 +577,10 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(StaticClassName staticClassName) { -// mv.visitMethodInsn(Opcodes.INVOKESTATIC, staticClassName.getType().toString().replace(".", "/"), -// staticClassName.toString(), staticClassName.getType().toString(), false); - mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), - fieldName, fieldDesc); + // mv.visitMethodInsn(Opcodes.INVOKESTATIC, + // staticClassName.getType().toString().replace(".", "/"), + // staticClassName.toString(), staticClassName.getType().toString(), false); + mv.visitFieldInsn(Opcodes.GETSTATIC, getResolvedType(staticClassName.getType()), fieldName, fieldDesc); } @Override @@ -576,51 +602,44 @@ public class BytecodeGenMethod implements StatementVisitor{ @Override public void visit(DoStmt whileStmt) { // TODO Auto-generated method stub - + } @Override public void visit(Literal literal) { Object value = literal.value; - String typeOfLiteral = resultSet.resolveType( - literal.getType()).resolvedType.acceptTV(new TypeToDescriptor()); - + String typeOfLiteral = resultSet.resolveType(literal.getType()).resolvedType.acceptTV(new TypeToDescriptor()); + doAssign(typeOfLiteral, value); - + } - + private void getVlaueIns(String type) { switch (type) { case "java/lang/String": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), - "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append", + "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); + break; case "java/lang/Boolean": break; case "java/lang/Byte": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", - "()B", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); break; case "java/lang/Short": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", - "()S", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); break; case "java/lang/Integer": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", - "()I", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); break; case "java/lang/Long": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", - "()J", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); break; case "java/lang/Float": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", - "()F", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); break; case "java/lang/Double": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", - "()D", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); break; case "java/lang/Character": break; @@ -638,24 +657,24 @@ public class BytecodeGenMethod implements StatementVisitor{ visitBooleanLiteral((Boolean) value); break; case "java/lang/Byte": - visitByteLiteral(((Double) value).byteValue(),false); - if(!this.isBinaryExp) + visitByteLiteral(((Double) value).byteValue(), false); + if (!this.isBinaryExp) getValueOfIns(type); break; case "java/lang/Short": - visitShortLiteral(((Double) value).shortValue(),false); - if(!this.isBinaryExp) + visitShortLiteral(((Double) value).shortValue(), false); + if (!this.isBinaryExp) getValueOfIns(type); break; case "java/lang/Integer": - //zweite Argument isLong + // zweite Argument isLong visitIntegerLiteral(((Double) value).intValue(), false); - if(!this.isBinaryExp) + if (!this.isBinaryExp) getValueOfIns(type); break; case "java/lang/Long": visitLongLiteral(((Double) value).longValue(), true); - if(!this.isBinaryExp) + if (!this.isBinaryExp) getValueOfIns(type); break; case "java/lang/Float": @@ -671,44 +690,37 @@ public class BytecodeGenMethod implements StatementVisitor{ break; } } - + private void getValueOfIns(String type) { switch (type) { case "java/lang/String": - mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", - "()Ljava/lang/String;", false); + mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", + false); break; case "java/lang/Boolean": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", - "(Z)Ljava/lang/Boolean;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); break; case "java/lang/Byte": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", - "(B)Ljava/lang/Byte;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); break; case "java/lang/Short": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", - "(S)Ljava/lang/Short;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); break; case "java/lang/Integer": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", - "(I)Ljava/lang/Integer;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); break; case "java/lang/Long": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", - "(J)Ljava/lang/Long;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); break; case "java/lang/Float": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", - "(F)Ljava/lang/Float;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); break; case "java/lang/Double": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", - "(D)Ljava/lang/Double;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); break; case "java/lang/Character": - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", - "(C)Ljava/lang/Character;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", + false); break; default: break; @@ -717,112 +729,111 @@ public class BytecodeGenMethod implements StatementVisitor{ private void visitCharLiteral(Character value) { mv.visitIntInsn(Opcodes.BIPUSH, (int) value); - if(!this.isBinaryExp) + if (!this.isBinaryExp) getValueOfIns(Type.getInternalName(Character.class)); } private void visitDoubleLiteral(Double value) { - if(value == 0) { + if (value == 0) { mv.visitInsn(Opcodes.DCONST_0); - }else if(value == 1) { + } else if (value == 1) { mv.visitInsn(Opcodes.DCONST_1); - }else { + } else { mv.visitLdcInsn(value); } - if(!this.isBinaryExp) + if (!this.isBinaryExp) getValueOfIns(Type.getInternalName(Double.class)); } private void visitFloatLiteral(Float value) { - if(value.intValue()>-1 && value.intValue() < 3) { - //Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw - mv.visitInsn(value.intValue()+11); - }else { + if (value.intValue() > -1 && value.intValue() < 3) { + // Opcodes.FCONST_0 = 11, Opcodes.FCONST_1 = 12, usw + mv.visitInsn(value.intValue() + 11); + } else { mv.visitLdcInsn(value); } - if(!this.isBinaryExp) + if (!this.isBinaryExp) getValueOfIns(Type.getInternalName(Float.class)); } private void visitLongLiteral(Long value, boolean isLong) { - if(value=-Math.pow(2, 15))&&value<-128) { - visitShortLiteral(value.shortValue(),isLong); - }else { + if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) { + visitShortLiteral(value.shortValue(), isLong); + } else { mv.visitLdcInsn(value); } } - private void visitShortLiteral(Short value,boolean isLong) { - if(value< 128 || (value>-129 && value<-1)) { + private void visitShortLiteral(Short value, boolean isLong) { + if (value < 128 || (value > -129 && value < -1)) { visitByteLiteral(value.byteValue(), isLong); - }else if(value=-Math.pow(2, 15))&&value<-128) { + } else if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) { mv.visitIntInsn(Opcodes.SIPUSH, value); } } private void visitByteLiteral(Byte value, boolean isLong) { - - if(!isLong && value<6 && value>-1) { - //Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw - mv.visitInsn(value+3); - }else if(isLong && value>-1 && value<2){ - //Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10 - mv.visitInsn(value+9); - }else { + + if (!isLong && value < 6 && value > -1) { + // Opcodes.ICONST_0 = 3, Opcodes.ICONST_1 = 4, usw + mv.visitInsn(value + 3); + } else if (isLong && value > -1 && value < 2) { + // Opcodes.LCONST_0 = 9, Opcodes.LCONST_1 = 10 + mv.visitInsn(value + 9); + } else { mv.visitIntInsn(Opcodes.BIPUSH, value); } - + } private void visitIntegerLiteral(Integer value, boolean isLong) { - - if(value=-Math.pow(2, 15))&&value<-128) { - visitShortLiteral(value.shortValue(),isLong); - }else { + + if (value < Math.pow(2, 15) || (value >= -Math.pow(2, 15)) && value < -128) { + visitShortLiteral(value.shortValue(), isLong); + } else { mv.visitLdcInsn(value); } } private void visitBooleanLiteral(Boolean b) { - if(b) { + if (b) { mv.visitInsn(Opcodes.ICONST_1); - }else { + } else { mv.visitInsn(Opcodes.ICONST_0); } // muss noch getestet werden. - mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", - "(Z)Ljava/lang/Boolean;", false); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); } @Override public void visit(ArgumentList argumentList) { - for(Expression al : argumentList.getArguments()) { + for (Expression al : argumentList.getArguments()) { al.accept(this); } } @Override public void visit(AssignToField assignLeftSide) { -// temporäre Lösung für testen, bis ich weiss wie man funktionale -// interfaces erkennt - if(isRightSideALambda) + // temporäre Lösung für testen, bis ich weiss wie man funktionale + // interfaces erkennt + if (isRightSideALambda) varsFunInterface.add(assignLeftSide.field.getType()); - // Loads the an object reference from the local variable - // array slot onto the top of the operand stack. + // Loads the an object reference from the local variable + // array slot onto the top of the operand stack. assignLeftSide.field.receiver.accept(this); this.rightSideTemp.accept(this); - mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), + mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType())); } @Override public void visit(AssignToLocal assignLeftSide) { - if(isRightSideALambda) + if (isRightSideALambda) varsFunInterface.add(assignLeftSide.localVar.getType()); - paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size()+1); + paramsAndLocals.put(assignLeftSide.localVar.name, paramsAndLocals.size() + 1); mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.size()); // Debug::: - + } } diff --git a/src/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/de/dhbwstuttgart/core/JavaTXCompiler.java index 8d381e37..3873b1b5 100644 --- a/src/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -1,6 +1,7 @@ package de.dhbwstuttgart.core; +import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.scope.GenericsRegistry; @@ -23,6 +24,8 @@ import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; import java.io.IOException; import java.util.*; import java.util.stream.Collectors; @@ -103,7 +106,7 @@ public class JavaTXCompiler { System.out.println(xConsSet); Set> result = unify.unify(xConsSet, finiteClosure); System.out.println("RESULT: " + result.size()); - //results.addAll(result); + results.addAll(result); } return results.stream().map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList()); @@ -129,5 +132,27 @@ public class JavaTXCompiler { SourceFile ret = generator.convert(tree, environment.packageCrawler); return ret; } + + public void generateBytecode() throws ClassNotFoundException, IOException { + for(File f : sourceFiles.keySet()) { + HashMap classFiles = new HashMap<>(); + SourceFile sf = sourceFiles.get(f); + List typeinferenceResult = this.typeInference(); + BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0)); + bytecodeGen.visit(sf); + this.writeClassFile(bytecodeGen.getClassFiles()); + } + } + private void writeClassFile(HashMap classFiles) throws IOException { + FileOutputStream output; + for(String name : classFiles.keySet()) { + byte[] bytecode = classFiles.get(name); + System.out.println("generating "+name+ ".class file ..."); + output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); + output.write(bytecode); + output.close(); + System.out.println(name+".class file generated"); + } + } } \ No newline at end of file diff --git a/test/bytecode/ATest.java b/test/bytecode/ATest.java deleted file mode 100644 index 14dbacbf..00000000 --- a/test/bytecode/ATest.java +++ /dev/null @@ -1,8 +0,0 @@ -package bytecode; - -public class ATest extends JavaTXCompilerTest { - public ATest() { - fileName = "Example"; - } - -} diff --git a/test/bytecode/AssignToLitTest.java b/test/bytecode/AssignToLitTest.java deleted file mode 100644 index dc5d397b..00000000 --- a/test/bytecode/AssignToLitTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class AssignToLitTest extends JavaTXCompilerTest { - public AssignToLitTest() { - this.fileName = "AssignToLit"; - } -} diff --git a/test/bytecode/DuMethodTest.java b/test/bytecode/DuMethodTest.java deleted file mode 100644 index a4c8a226..00000000 --- a/test/bytecode/DuMethodTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class DuMethodTest extends JavaTXCompilerTest{ - public DuMethodTest() { - this.fileName = "DuMethod"; - } -} diff --git a/test/bytecode/ForTest.java b/test/bytecode/ForTest.java deleted file mode 100644 index c95138d3..00000000 --- a/test/bytecode/ForTest.java +++ /dev/null @@ -1,11 +0,0 @@ -package bytecode; - -import org.objectweb.asm.Opcodes; - -public class ForTest extends JavaTXCompilerTest { - - public ForTest() { - this.fileName = "For"; - } - -} diff --git a/test/bytecode/Generics2Test.java b/test/bytecode/Generics2Test.java deleted file mode 100644 index 26e52665..00000000 --- a/test/bytecode/Generics2Test.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class Generics2Test extends JavaTXCompilerTest{ - public Generics2Test() { - this.fileName = "Generics2"; - } -} diff --git a/test/bytecode/GenericsTest.java b/test/bytecode/GenericsTest.java deleted file mode 100644 index cca16129..00000000 --- a/test/bytecode/GenericsTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class GenericsTest extends JavaTXCompilerTest { - public GenericsTest() { - this.fileName = "Generics"; - } -} diff --git a/test/bytecode/ImportTest.java b/test/bytecode/ImportTest.java deleted file mode 100644 index b7244e15..00000000 --- a/test/bytecode/ImportTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class ImportTest extends JavaTXCompilerTest{ - public ImportTest() { - this.fileName = "Import"; - } -} diff --git a/test/bytecode/InterfaceTest.java b/test/bytecode/InterfaceTest.java deleted file mode 100644 index ed378127..00000000 --- a/test/bytecode/InterfaceTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class InterfaceTest extends JavaTXCompilerTest{ - public InterfaceTest() { - this.fileName = "Interface1"; - } -} diff --git a/test/bytecode/JavaTXCompilerTest.java b/test/bytecode/JavaTXCompilerTest.java deleted file mode 100644 index 623fc96e..00000000 --- a/test/bytecode/JavaTXCompilerTest.java +++ /dev/null @@ -1,90 +0,0 @@ -package bytecode; - -import de.dhbwstuttgart.bytecode.BytecodeGen; -import de.dhbwstuttgart.core.JavaTXCompiler; -import de.dhbwstuttgart.syntaxtree.SourceFile; -import de.dhbwstuttgart.typeinference.result.ResultPair; -import de.dhbwstuttgart.typeinference.result.ResultSet; -import org.junit.Test; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; - -import static org.junit.Assert.*; - -public class JavaTXCompilerTest { - - private static final String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; - private static final List filesToTest = new ArrayList<>(); - - protected String fileName = ""; - - @Test - public void test() throws IOException, java.lang.ClassNotFoundException { - System.out.println(rootDirectory); - filesToTest.add(new File(rootDirectory+fileName+".jav")); - System.out.println(rootDirectory+fileName+".jav"); - JavaTXCompiler compiler = new JavaTXCompiler(filesToTest); - for(File f : filesToTest){ - String content = readFile(f.getPath(), StandardCharsets.UTF_8); - List typeinferenceResult = compiler.typeInference(); - HashMap bytecode = this.getBytecode(compiler.sourceFiles.get(f), typeinferenceResult.get(0)); - -// for(ResultPair ep : typeinferenceResult.get(0).results) { -// System.out.println(ep.getLeft() + " ->" + ep.getRight()); -// } - - String name; - int pos = f.getName().lastIndexOf("."); - if(pos != -1) { - name = f.getName().substring(0, pos); - } - this.writeClassFile(bytecode); - } - - } - - - public HashMap getBytecode(SourceFile sf, ResultSet resultSet) { - HashMap classFiles = new HashMap<>(); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles,resultSet); - bytecodeGen.visit(sf); - return bytecodeGen.getClassFiles(); - } - - public void writeClassFile(HashMap classFiles) { - FileOutputStream output; - for(String name : classFiles.keySet()) { - byte[] bytecode = classFiles.get(name); - try { - System.out.println("generating "+name+ ".class file ..."); - output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); - output.write(bytecode); - output.close(); - System.out.println(name+".class file generated"); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - } - - static String readFile(String path, Charset encoding) - throws IOException - { - byte[] encoded = Files.readAllBytes(Paths.get(path)); - return new String(encoded, encoding); - } - -} \ No newline at end of file diff --git a/test/bytecode/LamAssignTest.java b/test/bytecode/LamAssignTest.java deleted file mode 100644 index 3442c1d1..00000000 --- a/test/bytecode/LamAssignTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class LamAssignTest extends JavaTXCompilerTest{ - public LamAssignTest() { - this.fileName = "LamAssign"; - } -} diff --git a/test/bytecode/MethodsTest.java b/test/bytecode/MethodsTest.java deleted file mode 100644 index 11195b71..00000000 --- a/test/bytecode/MethodsTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class MethodsTest extends JavaTXCompilerTest { - public MethodsTest() { - this.fileName = "Methods"; - } -} diff --git a/test/bytecode/Op.jav b/test/bytecode/Op.jav deleted file mode 100644 index 3a8d157a..00000000 --- a/test/bytecode/Op.jav +++ /dev/null @@ -1,46 +0,0 @@ -import java.lang.Integer; -import java.lang.String; -import java.lang.Long; -import java.lang.Float; -import java.lang.Double; -import java.lang.Boolean; - -class Op { - addInt(Integer a, Integer b) { - Integer c = a+b; - return c; - } - addString(String a, String b) { - String c = a+b; - return c; - } - addLong(Long a, Long b) { - Long c = a+b; - return c; - } - addFloat(Float a, Float b) { - Float c = a+b; - return c; - } - addDouble(Double a, Double b) { - Double c = a+b; - return c; - } - - subInt(Integer a, Integer b) { - Integer c = a-b; - return c; - } - subLong(Long a, Long b) { - Long c = a-b; - return c; - } - subFloat(Float a, Float b) { - Float c = a-b; - return c; - } - subDouble(Double a, Double b) { - Double c = a-b; - return c; - } -} \ No newline at end of file diff --git a/test/bytecode/OpTest.java b/test/bytecode/OpTest.java index cd8fee06..ebdd6a1b 100644 --- a/test/bytecode/OpTest.java +++ b/test/bytecode/OpTest.java @@ -1,7 +1,157 @@ package bytecode; -public class OpTest extends JavaTXCompilerTest { - public OpTest() { - this.fileName = "Op"; +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; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.objectweb.asm.Opcodes; + +import de.dhbwstuttgart.core.JavaTXCompiler; + +public class OpTest { + 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/Op.jav"; + fileToTest = new File(path); + compiler = new JavaTXCompiler(fileToTest); + compiler.generateBytecode(); + pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; + loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); + classToTest = loader.loadClass("Op"); + instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); } + + @Test + public void testClassname() { + assertEquals("Op", classToTest.getName()); + } + + @Test + public void testClassModifiers() { + assertEquals(Opcodes.ACC_PUBLIC, classToTest.getModifiers()); + } + + @Test + public void testNumberOfMethods() { + int numOfMeth = classToTest.getDeclaredMethods().length; + assertEquals(5, numOfMeth); + } + + @Test + public void testAddString() throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, InstantiationException { + Method addString = classToTest.getDeclaredMethod("addString", String.class,String.class); + String result = (String) addString.invoke(instanceOfClass, "Byte","Code"); + assertEquals("ByteCode", result); + } + + @Test + public void testAddInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, InstantiationException { + Method addInt = classToTest.getDeclaredMethod("addInt", Integer.class,Integer.class); + Integer result = (Integer) addInt.invoke(instanceOfClass, 7,3); + assertEquals(10, result); + } + + @Test + public void testAddLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, InstantiationException { + Method addLong = classToTest.getDeclaredMethod("addLong", Long.class,Long.class); + Long result = (Long) addLong.invoke(instanceOfClass, 7L,3L); + assertEquals(10L, result); + } + + @Test + public void testAddFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, InstantiationException { + Method addFloat = classToTest.getDeclaredMethod("addFloat", Float.class,Float.class); + Float result = (Float) addFloat.invoke(instanceOfClass, 7f,3f); + assertEquals(10f, result); + } + + @Test + public void testAddDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, + IllegalArgumentException, InvocationTargetException, InstantiationException { + Method addDouble = classToTest.getDeclaredMethod("addDouble", Double.class,Double.class); + Double result = (Double) addDouble.invoke(instanceOfClass, 7.0,3.0); + assertEquals(10.0, result); + } + +// @Test +// public void testAddIntLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Integer.class,Long.class); +// Long result = (Long) add.invoke(instanceOfClass, 7,3L); +// assertEquals(10L, result); +// } + +// @Test +// public void testAddDLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Double.class,Long.class); +// Double result = (Double) add.invoke(instanceOfClass, 7d,3L); +// assertEquals(10d, result); +// } +// +// @Test +// public void testAddIntShort() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Integer.class,Short.class); +// Integer result = (Integer) add.invoke(instanceOfClass, 7,3); +// assertEquals(10, result); +// } +// +// @Test +// public void testAddIntByte() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Integer.class,Byte.class); +// Integer result = (Integer) add.invoke(instanceOfClass, 7,3); +// assertEquals(10, result); +// } +// +// @Test +// public void testAddDFloat() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Float.class,Double.class); +// Double result = (Double) add.invoke(instanceOfClass, 7f,3d); +// assertEquals(10d, result); +// } +// +// @Test +// public void testAddIntD() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Integer.class,Double.class); +// Double result = (Double) add.invoke(instanceOfClass, 7,3d); +// assertEquals(10d, result); +// } +// +// @Test +// public void testAddShortD() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Short.class,Double.class); +// Double result = (Double) add.invoke(instanceOfClass, 7,3d); +// assertEquals(10d, result); +// } +// +// @Test +// public void testAddByteD() throws NoSuchMethodException, SecurityException, IllegalAccessException, +// IllegalArgumentException, InvocationTargetException, InstantiationException { +// Method add = classToTest.getDeclaredMethod("add", Byte.class,Double.class); +// Double result = (Double) add.invoke(instanceOfClass, 7,3d); +// assertEquals(10d, result); +// } } diff --git a/test/bytecode/OverlaodGenTest.java b/test/bytecode/OverlaodGenTest.java deleted file mode 100644 index 72bde4f9..00000000 --- a/test/bytecode/OverlaodGenTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class OverlaodGenTest extends JavaTXCompilerTest { - public OverlaodGenTest() { - this.fileName = "OverlaodGen"; - } -} diff --git a/test/bytecode/TestIfTest.java b/test/bytecode/TestIfTest.java deleted file mode 100644 index 804a0616..00000000 --- a/test/bytecode/TestIfTest.java +++ /dev/null @@ -1,7 +0,0 @@ -package bytecode; - -public class TestIfTest extends JavaTXCompilerTest{ - public TestIfTest() { - this.fileName = "IfTest"; - } -} diff --git a/test/bytecode/AssignToLit.jav b/test/bytecode/javFiles/AssignToLit.jav similarity index 100% rename from test/bytecode/AssignToLit.jav rename to test/bytecode/javFiles/AssignToLit.jav diff --git a/test/bytecode/DuMethod.jav b/test/bytecode/javFiles/DuMethod.jav similarity index 100% rename from test/bytecode/DuMethod.jav rename to test/bytecode/javFiles/DuMethod.jav diff --git a/test/bytecode/EmptyMethod.jav b/test/bytecode/javFiles/EmptyMethod.jav similarity index 100% rename from test/bytecode/EmptyMethod.jav rename to test/bytecode/javFiles/EmptyMethod.jav diff --git a/test/bytecode/Example.jav b/test/bytecode/javFiles/Example.jav similarity index 100% rename from test/bytecode/Example.jav rename to test/bytecode/javFiles/Example.jav diff --git a/test/bytecode/Exceptions.jav b/test/bytecode/javFiles/Exceptions.jav similarity index 100% rename from test/bytecode/Exceptions.jav rename to test/bytecode/javFiles/Exceptions.jav diff --git a/test/bytecode/Faculty.jav b/test/bytecode/javFiles/Faculty.jav similarity index 100% rename from test/bytecode/Faculty.jav rename to test/bytecode/javFiles/Faculty.jav diff --git a/test/bytecode/Faculty2.jav b/test/bytecode/javFiles/Faculty2.jav similarity index 100% rename from test/bytecode/Faculty2.jav rename to test/bytecode/javFiles/Faculty2.jav diff --git a/test/bytecode/For.jav b/test/bytecode/javFiles/For.jav similarity index 100% rename from test/bytecode/For.jav rename to test/bytecode/javFiles/For.jav diff --git a/test/bytecode/Gen.jav b/test/bytecode/javFiles/Gen.jav similarity index 100% rename from test/bytecode/Gen.jav rename to test/bytecode/javFiles/Gen.jav diff --git a/test/bytecode/Generics.jav b/test/bytecode/javFiles/Generics.jav similarity index 100% rename from test/bytecode/Generics.jav rename to test/bytecode/javFiles/Generics.jav diff --git a/test/bytecode/Generics2.jav b/test/bytecode/javFiles/Generics2.jav similarity index 100% rename from test/bytecode/Generics2.jav rename to test/bytecode/javFiles/Generics2.jav diff --git a/test/bytecode/IfTest.jav b/test/bytecode/javFiles/IfTest.jav similarity index 100% rename from test/bytecode/IfTest.jav rename to test/bytecode/javFiles/IfTest.jav diff --git a/test/bytecode/Import.jav b/test/bytecode/javFiles/Import.jav similarity index 100% rename from test/bytecode/Import.jav rename to test/bytecode/javFiles/Import.jav diff --git a/test/bytecode/Interface1.jav b/test/bytecode/javFiles/Interface1.jav similarity index 100% rename from test/bytecode/Interface1.jav rename to test/bytecode/javFiles/Interface1.jav diff --git a/test/bytecode/LamAssign.jav b/test/bytecode/javFiles/LamAssign.jav similarity index 100% rename from test/bytecode/LamAssign.jav rename to test/bytecode/javFiles/LamAssign.jav diff --git a/test/bytecode/LamRunnable.jav b/test/bytecode/javFiles/LamRunnable.jav similarity index 100% rename from test/bytecode/LamRunnable.jav rename to test/bytecode/javFiles/LamRunnable.jav diff --git a/test/bytecode/Lambda.jav b/test/bytecode/javFiles/Lambda.jav similarity index 100% rename from test/bytecode/Lambda.jav rename to test/bytecode/javFiles/Lambda.jav diff --git a/test/bytecode/Lambda2.jav b/test/bytecode/javFiles/Lambda2.jav similarity index 100% rename from test/bytecode/Lambda2.jav rename to test/bytecode/javFiles/Lambda2.jav diff --git a/test/bytecode/Lambda3.jav b/test/bytecode/javFiles/Lambda3.jav similarity index 100% rename from test/bytecode/Lambda3.jav rename to test/bytecode/javFiles/Lambda3.jav diff --git a/test/bytecode/Methods.jav b/test/bytecode/javFiles/Methods.jav similarity index 100% rename from test/bytecode/Methods.jav rename to test/bytecode/javFiles/Methods.jav diff --git a/test/bytecode/javFiles/Op.jav b/test/bytecode/javFiles/Op.jav new file mode 100644 index 00000000..f36b790d --- /dev/null +++ b/test/bytecode/javFiles/Op.jav @@ -0,0 +1,88 @@ +import java.lang.Integer; +import java.lang.String; +import java.lang.Long; +import java.lang.Float; +import java.lang.Double; +import java.lang.Boolean; +import java.lang.Short; +import java.lang.Byte; + +public class Op { + addInt(Integer a, Integer b) { + Integer c = a+b; + return c; + } + addString(String a, String b) { + String c = a+b; + return c; + } + addLong(Long a, Long b) { + Long c = a+b; + return c; + } + addFloat(Float a, Float b) { + Float c = a+b; + return c; + } + addDouble(Double a, Double b) { + Double c = a+b; + return c; + } + +// subInt(Integer a, Integer b) { +// Integer c = a-b; +// return c; +// } +// subLong(Long a, Long b) { +// Long c = a-b; +// return c; +// } +// subFloat(Float a, Float b) { +// Float c = a-b; +// return c; +// } +// subDouble(Double a, Double b) { +// Double c = a-b; +// return c; +// } + +// Long add(Integer a, Long b) { +// Long c = a+b; +// return c; +// } + +// add(Double a, Long b) { +// Double c = a+b; +// return c; +// } +// +// add(Integer a, Short b) { +// Integer c = a+b; +// return c; +// } +// +// add(Integer a, Byte b) { +// Integer c = a+b; +// return c; +// } +// +// add(Float a, Double b) { +// Double c = a+b; +// return c; +//} +// +// add(Integer a, Double b) { +// Double c = a+b; +// return c; +// } +// +// add(Short a, Double b) { +// Double c = a+b; +// return c; +// } +// +// add(Byte a, Double b) { +// Double c = a+b; +// return c; +// } +} \ No newline at end of file diff --git a/test/bytecode/OverlaodGen.jav b/test/bytecode/javFiles/OverlaodGen.jav similarity index 100% rename from test/bytecode/OverlaodGen.jav rename to test/bytecode/javFiles/OverlaodGen.jav diff --git a/test/bytecode/RecursiveMeth.jav b/test/bytecode/javFiles/RecursiveMeth.jav similarity index 100% rename from test/bytecode/RecursiveMeth.jav rename to test/bytecode/javFiles/RecursiveMeth.jav diff --git a/test/bytecode/ReturnMethod.jav b/test/bytecode/javFiles/ReturnMethod.jav similarity index 100% rename from test/bytecode/ReturnMethod.jav rename to test/bytecode/javFiles/ReturnMethod.jav diff --git a/test/bytecode/VoidMeth.jav b/test/bytecode/javFiles/VoidMeth.jav similarity index 100% rename from test/bytecode/VoidMeth.jav rename to test/bytecode/javFiles/VoidMeth.jav