diff --git a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 32570541..643e98d5 100644 --- a/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -69,7 +69,7 @@ public class BytecodeGenMethod implements StatementVisitor { private SourceFile sf; private IStatement statement = null; -// private int numMethodCalls = 0; + private boolean needDUP = false; // for tests ** private String fieldName; @@ -159,7 +159,7 @@ public class BytecodeGenMethod implements StatementVisitor { // 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) { doUnboxing(getResolvedType(localVar.getType())); } @@ -195,6 +195,7 @@ public class BytecodeGenMethod implements StatementVisitor { doBoxing(binaryType); isBinaryExp = false; } + System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType())); String typeOfRightSide = getResolvedType(assign.rightSide.getType()); if(typeOfRightSide.contains("<")) { @@ -225,12 +226,18 @@ public class BytecodeGenMethod implements StatementVisitor { // this case for while loops if (statement instanceof LoopStmt) mv.visitLabel(endLabel); - + + if(binary.lexpr instanceof UnaryExpr) + needDUP = true; + binary.lexpr.accept(this); if (!lexpType.equals(rexpType) && !lexpType.equals(largerType)) doCast(lexpType, largerType); - + + if(binary.rexpr instanceof UnaryExpr) + needDUP = true; + binary.rexpr.accept(this); if (!lexpType.equals(rexpType) && !rexpType.equals(largerType)) @@ -273,10 +280,6 @@ public class BytecodeGenMethod implements StatementVisitor { } - /* - * Diese Methode wird nicht mehr gebraucht, da es jetzt nicht möglich ist, dass - * solche Fälle: Integer -> Integer (OP) Short ,... usw, nicht vorkommen! - */ private String getLargerType(String lexpType, String rexpType) { if (lexpType.equals(Type.getInternalName(String.class)) || rexpType.equals(Type.getInternalName(String.class))) { @@ -828,7 +831,6 @@ public class BytecodeGenMethod implements StatementVisitor { @Override public void visit(UnaryExpr unaryExpr) { - unaryExpr.expr.accept(this); Operation op = unaryExpr.operation; @@ -865,6 +867,10 @@ public class BytecodeGenMethod implements StatementVisitor { // das wird später gemacht, da bytecode für cast noch nicht erzeugt wird if (isIncOrDec && (unaryExpr.expr instanceof LocalVar)) { + if(needDUP) { + mv.visitInsn(Opcodes.DUP); + needDUP = false; + } LocalVar local = (LocalVar) unaryExpr.expr; mv.visitVarInsn(Opcodes.ASTORE, paramsAndLocals.get(local.name)); } @@ -913,7 +919,10 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(Return aReturn) { statement = new ReturnStmt(aReturn.retexpr); isBinaryExp = statement.isExprBinary(); - + + if(aReturn.retexpr instanceof UnaryExpr) + needDUP = true; + aReturn.retexpr.accept(this); if (isBinaryExp) { @@ -1173,7 +1182,17 @@ public class BytecodeGenMethod implements StatementVisitor { public void visit(ArgumentList argumentList) { for (Expression al : argumentList.getArguments()) { statement = new ArgumentExpr(al); + isBinaryExp = statement.isExprBinary(); + if(al instanceof UnaryExpr) + needDUP = true; al.accept(this); + //TODO: teste, ob man das für unary braucht + if (isBinaryExp) { + BinaryExpr binary = (BinaryExpr) al; + String binaryType = getResolvedType(binary.getType()); + doBoxing(binaryType); + isBinaryExp = false; + } statement = null; } } diff --git a/src/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/de/dhbwstuttgart/bytecode/signature/Signature.java index c32cbf86..ae91932a 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -20,6 +20,7 @@ import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -104,10 +105,13 @@ public class Signature { Iterator itr = method.getGenerics().iterator(); // visits all formal type parameter and visits their bounds while(itr.hasNext()) { + System.out.println("HAS GENERICS!!"); GenericTypeVar g = itr.next(); getBoundsOfTypeVar(g,genericsAndBoundsMethod); } + //TODO: paramtrisierte Typen mit Generics, Type Variablen müssen definiert werden. + // 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 if(!isConstructor) { @@ -131,7 +135,9 @@ public class Signature { if(hasTPHs(ref)) { createSignatureForParameterizedType(ref); } - + System.out.println("HAS WC = " + hasWC(ref)); + if(hasWC(ref)) + createSigForParamTypeWithWC(ref); } } } @@ -170,6 +176,10 @@ public class Signature { RefType ref = (RefType) methodParamsAndTypes.get(paramName); if(hasTPHs(ref)) createSignatureForParameterizedType(ref); + + System.out.println("HAS WC = " + hasWC(ref)); + if(hasWC(ref)) + createSigForParamTypeWithWC(ref); } for(GenericInsertPair p:methodPairs) { @@ -218,6 +228,34 @@ public class Signature { // sw.visitEnd(); } + private void createSigForParamTypeWithWC(RefType ref) { + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + if(p instanceof WildcardType) { + if(((WildcardType) p).getInnerType() instanceof GenericRefType) { + String name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType()); + if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) { + sw.visitFormalTypeParameter(name); + sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); + sw.visitClassBound().visitEnd(); + genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class)); + } + } + } + } + + } + + private boolean hasWC(RefType ref) { + for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { + System.out.println("HAS WCs: " + p.acceptTV(new TypeToString())); + System.out.println("HAS WCs: " + p.getClass()); + if(p.acceptTV(new TypeToString()).contains("WC")) + return true; + + } + return false; + } + private void createSignatureForParameterizedType(RefType ref) { ArrayList allPairs = getAllPairs(ref); allPairs.addAll(methodPairs); @@ -347,7 +385,7 @@ public class Signature { private boolean hasTPHs(RefType ref) { for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) { - System.out.println(p.acceptTV(new TypeToString())); + System.out.println("HAS TPHs: " + p.acceptTV(new TypeToString())); if(p.acceptTV(new TypeToString()).contains("WC")){ continue; } diff --git a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index 31d288f7..3bad4066 100644 --- a/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -48,7 +48,7 @@ public class TypeToSignature implements TypeVisitor { @Override public String visit(SuperWildcardType superWildcardType) { // throw new NotImplementedException(); - return "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); + return "+" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); } @Override @@ -60,7 +60,7 @@ public class TypeToSignature implements TypeVisitor { @Override public String visit(ExtendsWildcardType extendsWildcardType) { // throw new NotImplementedException(); - return "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); + return "-" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); } @Override diff --git a/test/bytecode/BinaryTest.java b/test/bytecode/BinaryTest.java index 543786ad..84f102b7 100644 --- a/test/bytecode/BinaryTest.java +++ b/test/bytecode/BinaryTest.java @@ -39,5 +39,12 @@ public class BinaryTest { Integer res = (Integer) m2.invoke(instanceOfClass, 2,3); assertEquals(6, res); } + + @Test + public void testM3() throws Exception { + Method m3 = classToTest.getDeclaredMethod("m3", Integer.class); + Integer res = (Integer) m3.invoke(instanceOfClass, 2); + assertEquals(4, res); + } } diff --git a/test/bytecode/MergeTest.java b/test/bytecode/MergeTest.java index c4da52ce..9f3943ca 100644 --- a/test/bytecode/MergeTest.java +++ b/test/bytecode/MergeTest.java @@ -1,5 +1,6 @@ package bytecode; + import static org.junit.Assert.assertEquals; import java.io.File; @@ -20,15 +21,16 @@ public class MergeTest { private static String pathToClassFile; private static Object instanceOfClass; + @Test public void generateBC() throws Exception { path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Merge.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("Merge"); +// pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/"; +// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); +// classToTest = loader.loadClass("Merge"); //instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); //Method m = classToTest.getDeclaredMethod("m"); diff --git a/test/bytecode/javFiles/BinaryInMeth.jav b/test/bytecode/javFiles/BinaryInMeth.jav index c77d7767..3b5fa77b 100644 --- a/test/bytecode/javFiles/BinaryInMeth.jav +++ b/test/bytecode/javFiles/BinaryInMeth.jav @@ -10,4 +10,8 @@ public class BinaryInMeth { m2(a,b){ return m(a+b); } + + m3(a) { + return m(++a); + } } \ No newline at end of file diff --git a/test/bytecode/javFiles/Merge.jav b/test/bytecode/javFiles/Merge.jav index 1ac08f1d..627e9f45 100644 --- a/test/bytecode/javFiles/Merge.jav +++ b/test/bytecode/javFiles/Merge.jav @@ -2,12 +2,14 @@ import java.util.List; import java.lang.Integer; import java.util.Collection; -class Merge { +class Merge { -merge(a, b) { + merge(a, b) { a.addAll(b); return a; } + + /* sort(in){ var firstHalf = in.subList(1,2);