diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java index 321be6b0..d7ffe727 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java @@ -770,6 +770,7 @@ public class BytecodeGenMethod implements StatementVisitor { // This will be used if the class is not standard class (not in API) ClassLoader cLoader2; + //ToDo methodCallType wird nicht korrekt resolved, da kein Constraint vorhanden ist String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String[] typesOfParams = getTypes(methodCall.arglist.getArguments()); try { @@ -817,9 +818,10 @@ public class BytecodeGenMethod implements StatementVisitor { //ToDo Etienne: Für Type Erasure wichtig?! } else if(!helper.isInCurrPkg(clazz)){ if(clazz.contains(CONSTANTS.$$)) { + //ToDo Methoden Deskriptor neu setzen + //ToDo Receiver neu setzen?! mDesc = helper.getDescriptorOfApplyMethod(methCallType); - helper.generateBCForFunN(mDesc); -// mDesc = helper.generateBCForFunN(methCallType,typesOfParams); + helper.generateBCForFunN(typesOfParams, methCallType); }else { try { cLoader2 = new DirectoryClassLoader(path, classLoader); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java b/src/main/java/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java index c8306f02..6d5d4896 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/signature/TypeToSignature.java @@ -99,4 +99,34 @@ public class TypeToSignature implements TypeVisitor { .filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph)) .findFirst(); } + + /** + * //ToDo beschreiben + * + * @param type + * @return + * + * @since Studienarbeit Type Erasure + * @author Etienne Zink + */ + public String visit(RefTypeOrTPHOrWildcardOrGeneric type){ + String returnString = ""; + if (type instanceof GenericRefType){ + GenericRefType genericRefType = (GenericRefType) type; + returnString += visit(genericRefType); + } else if (type instanceof RefType){ + RefType refType = (RefType) type; + returnString += visit(refType); + } else if (type instanceof TypePlaceholder){ + TypePlaceholder typePlaceholder = (TypePlaceholder) type; + returnString += visit(typePlaceholder); + } else if (type instanceof SuperWildcardType){ + SuperWildcardType superWildcardType = (SuperWildcardType) type; + returnString += visit(superWildcardType); + } else if (type instanceof ExtendsWildcardType) { + ExtendsWildcardType extendsWildcardType = (ExtendsWildcardType) type; + returnString += visit(extendsWildcardType); + } + return returnString; + } } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/ByteCodeForFunNGenerator.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/ByteCodeForFunNGenerator.java index 4fe8140b..71dfd9a2 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/ByteCodeForFunNGenerator.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/ByteCodeForFunNGenerator.java @@ -1,10 +1,12 @@ package de.dhbwstuttgart.bytecode.utilities; import de.dhbwstuttgart.bytecode.signature.Signature; +import de.dhbwstuttgart.bytecode.signature.TypeToSignature; import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.type.*; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; @@ -12,9 +14,11 @@ import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureWriter; import java.io.*; +import java.sql.Ref; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.stream.Collectors; import static org.objectweb.asm.Opcodes.*; @@ -55,36 +59,39 @@ public class ByteCodeForFunNGenerator { writeClassFile(name, classWriter.toByteArray(), path); } - public static void generateBCForFunN(ArgumentList argumentList, String methDesc, File path) { + /** + * //ToDo beschreiben + * + * @param typesOfFormalParameters + * @param returnType + * @param path + * + * @since Studienarbeit Type Erasure + * @author Etienne Zink + */ + public static void generateBCForFunN(String[] typesOfFormalParameters, String returnType, File path) { ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); - List arguments = argumentList.getArguments(); + int numberOfParameters = typesOfFormalParameters.length; + generateSuperFunNInterface(numberOfParameters, path); - /* //ToDo neu machen - int numberOfParams = arguments.size(); - //ToDo Classname anpassen - String className = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$; + String className = getBaseFunClassname(numberOfParameters); + String classSignature = String.format("L%s;L%s<", Type.getInternalName(Object.class), className); - Signature sig = new Signature(numberOfParams); - classWriter.visit(V1_8, ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, className, sig.toString(), - Type.getInternalName(Object.class), new String[]{String.format("Fun%d$$", numberOfParams)}); - writeClassFile(className, classWriter.toByteArray(), path); - */ - - SignatureWriter signatureWriter = new SignatureWriter(); - int numberOfParams = 0; - SignatureVisitor paramVisitor = signatureWriter.visitParameterType(); - - for (Expression argument:arguments) { - paramVisitor.visitTypeVariable(CONSTANTS.T + ++numberOfParams); + //ToDo testen ob der Klassenname und -signatur so passt + for (String typeOfFormalParameter: typesOfFormalParameters) { + className += String.format("%s$_$", typeOfFormalParameter); + classSignature += String.format("L%s;", typeOfFormalParameter); } + className += returnType; + className = className.replace('/', '$'); + classSignature += String.format("L%s>;", returnType); - signatureWriter.visitReturnType().visitTypeVariable(CONSTANTS.R); - Signature sig = new Signature(numberOfParams); - String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$; - classWriter.visit(V1_8, ACC_PUBLIC + ACC_INTERFACE + ACC_ABSTRACT, name, sig.toString(), Type.getInternalName(Object.class), null); - MethodVisitor mvApply = classWriter.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "apply", methDesc, signatureWriter.toString(), null); - mvApply.visitEnd(); - writeClassFile(name, classWriter.toByteArray(), path); + System.out.println("Generated className: " + className); + System.out.println("Generated signature: " + classSignature); + + classWriter.visit(V1_8, ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, className, classSignature, + Type.getInternalName(Object.class), new String[]{getBaseFunClassname(numberOfParameters)}); + writeClassFile(className, classWriter.toByteArray(), path); } /** @@ -101,7 +108,7 @@ public class ByteCodeForFunNGenerator { public static boolean generateSuperFunNInterface(int numberOfParameters, File path){ if(alreadyGeneratedFunN.contains(numberOfParameters)) return true; //ToDo Etienne: Generierung der Signaturen/Deskriptoren vielleicht auslagern? Bzw. schauen ob nicht schon vorhanden und anpassen! - String className = String.format("Fun%d$$", numberOfParameters); + String className = getBaseFunClassname(numberOfParameters); String classSignature = "<"; String methodSignature = "("; String methodDescriptor = "("; @@ -128,6 +135,18 @@ public class ByteCodeForFunNGenerator { return alreadyGeneratedFunN.contains(numberOfParameters); } + /** + * + * @param countParameters + * @return the String of the super Fun$$ type + * + * @since Studienarbeit Type Erasure + * @author Etienne Zink + */ + private static String getBaseFunClassname(int countParameters){ + return String.format("Fun%d$$", countParameters); + } + /** * Generates a {@code class-File} for the class {@code className} with the {@code bytecode}. * diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java index 6df534d2..a3728904 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/MethodCallHelper.java @@ -221,8 +221,9 @@ public class MethodCallHelper { } //ToDo Etienne: Für Type Erasure wichtig?! - public void generateBCForFunN(String methodDescriptor) { - ByteCodeForFunNGenerator.generateBCForFunN(methCall.arglist,methodDescriptor,path); + public void generateBCForFunN(String[] typesOfFormalParams, String receiverType) { + //ToDo return Descriptor auf apply Methode? + ByteCodeForFunNGenerator.generateBCForFunN(typesOfFormalParams, receiverType,path); } //ToDo Etienne: Für Type Erasure wichtig diff --git a/src/test/java/bytecode/OLFunTest.java b/src/test/java/bytecode/OLFunTest.java index c342d4a3..d76b73a6 100644 --- a/src/test/java/bytecode/OLFunTest.java +++ b/src/test/java/bytecode/OLFunTest.java @@ -64,6 +64,4 @@ public class OLFunTest { public static void cleanUp(){ TestCleanUp.cleanUpDirectory(new File(generatedByteCodeDirectory), f -> f.getName().contains(".class")); } - - public static Integer apply(Integer x) {return x;} }