forked from JavaTX/JavaCompilerCore
Added Method to ByteCodeForFunNGenerator which generates the basic interface FunN$$.
This commit is contained in:
parent
2ba966a4e7
commit
c613ed7e12
@ -204,6 +204,7 @@ public class Signature {
|
|||||||
if (r instanceof GenericRefType) {
|
if (r instanceof GenericRefType) {
|
||||||
sv.visitTypeVariable(sig2);
|
sv.visitTypeVariable(sig2);
|
||||||
} else if (!(r instanceof TypePlaceholder)) {
|
} else if (!(r instanceof TypePlaceholder)) {
|
||||||
|
//ToDo Etienne: Wichtig für Type Erasure?!
|
||||||
if (sig2.contains(SPECIAL_CHAR_FOR_FUN)) {
|
if (sig2.contains(SPECIAL_CHAR_FOR_FUN)) {
|
||||||
sv.visitInterface().visitClassType(sig2.substring(1));
|
sv.visitInterface().visitClassType(sig2.substring(1));
|
||||||
} else {
|
} else {
|
||||||
@ -268,6 +269,7 @@ public class Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void checkInnerSignatureOfWildCard(SignatureVisitor sv, String sigInner, int length, char superOrExtendsChar) {
|
private void checkInnerSignatureOfWildCard(SignatureVisitor sv, String sigInner, int length, char superOrExtendsChar) {
|
||||||
|
//ToDo Etienne: Wichtig für Type Erasure?!
|
||||||
if (sigInner.contains(SPECIAL_CHAR_FOR_FUN)) {
|
if (sigInner.contains(SPECIAL_CHAR_FOR_FUN)) {
|
||||||
sv.visitTypeArgument(superOrExtendsChar).visitInterface().visitClassType(sigInner.substring(1, length));
|
sv.visitTypeArgument(superOrExtendsChar).visitInterface().visitClassType(sigInner.substring(1, length));
|
||||||
} else {
|
} else {
|
||||||
|
@ -12,21 +12,19 @@ import org.objectweb.asm.Type;
|
|||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.FileNotFoundException;
|
import java.util.HashSet;
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
//ToDo Etienne: Anpassung für TypeErasure
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
//static Attribut (HashSet<int>) welches Anzahl Attribute hält -> Wenn Anzahl Attribute vorhanden, dann existiert Interface bereits
|
|
||||||
//schneller als bytecode auf Vorhandensein zu prüfen?!
|
|
||||||
//Wenn FunN$$ nicht vorhanden, dann erstellen
|
|
||||||
//Name ändern nach Konvention (FunN$$$_$...$_$)
|
|
||||||
//Muss FunN$$$_$...$_$ nun Interface sein oder?
|
|
||||||
//Frage: Worin wird Implementierung "gespeichert"?! --> Was/Wo ist der Bytecode hierfür?
|
|
||||||
public class ByteCodeForFunNGenerator {
|
public class ByteCodeForFunNGenerator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HashSet which contains the parameter number for which already a FunN$$ interface was generated.
|
||||||
|
*/
|
||||||
|
private static HashSet<Integer> alreadyGeneratedFunN = new HashSet<>();
|
||||||
|
|
||||||
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, File path) {
|
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, File path) {
|
||||||
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
|
|
||||||
@ -45,9 +43,9 @@ public class ByteCodeForFunNGenerator {
|
|||||||
// ")"+lam.getReturn.getBounds
|
// ")"+lam.getReturn.getBounds
|
||||||
Signature sig = new Signature(numberOfParams);
|
Signature sig = new Signature(numberOfParams);
|
||||||
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
classWriter.visit(V1_8, ACC_PUBLIC + ACC_INTERFACE + ACC_ABSTRACT, name, sig.toString(),
|
||||||
Type.getInternalName(Object.class), null);
|
Type.getInternalName(Object.class), null);
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
MethodVisitor mvApply = classWriter.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "apply", methDesc,
|
||||||
methSig.toString(), null);
|
methSig.toString(), null);
|
||||||
mvApply.visitEnd();
|
mvApply.visitEnd();
|
||||||
writeClassFile(classWriter.toByteArray(), name, path);
|
writeClassFile(classWriter.toByteArray(), name, path);
|
||||||
@ -72,15 +70,61 @@ public class ByteCodeForFunNGenerator {
|
|||||||
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
||||||
// ")"+lam.getReturn.getBounds
|
// ")"+lam.getReturn.getBounds
|
||||||
Signature sig = new Signature(numberOfParams);
|
Signature sig = new Signature(numberOfParams);
|
||||||
|
//ToDo Name anpassen und Signatur?
|
||||||
|
//ToDo super anpassen
|
||||||
|
//ToDo extends FunN$$ einfügen und Parameter dazu
|
||||||
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
||||||
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
|
classWriter.visit(V1_8, ACC_PUBLIC + ACC_INTERFACE + ACC_ABSTRACT, name, sig.toString(),
|
||||||
Type.getInternalName(Object.class), null);
|
Type.getInternalName(Object.class), null);
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
|
MethodVisitor mvApply = classWriter.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "apply", methDesc,
|
||||||
methSig.toString(), null);
|
methSig.toString(), null);
|
||||||
mvApply.visitEnd();
|
mvApply.visitEnd();
|
||||||
writeClassFile(classWriter.toByteArray(), name, path);
|
writeClassFile(classWriter.toByteArray(), name, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function which generates a {@code .class-File} for the super interface
|
||||||
|
* Fun<{@code numberOfParameters}>$$ if it doesn't exist already.
|
||||||
|
* @param numberOfParameters
|
||||||
|
* @return {@code true}, iff the {@code .class-File} exists after this method invocation
|
||||||
|
* based on {@link #alreadyGeneratedFunN alreadyGeneratedFunN}.
|
||||||
|
* @since Studienarbeit Type Erase
|
||||||
|
* @author Etienne Zink
|
||||||
|
*/
|
||||||
|
public static boolean generateSuperFunNInterface(int numberOfParameters, File path){
|
||||||
|
if(alreadyGeneratedFunN.contains(numberOfParameters)) return true;
|
||||||
|
|
||||||
|
String funNName = String.format("Fun%d$$", numberOfParameters);
|
||||||
|
String classSignature = "<";
|
||||||
|
String methodSignature = "(";
|
||||||
|
String methodDescriptor = "(";
|
||||||
|
for (int parameter = 1; parameter <= numberOfParameters; parameter++) {
|
||||||
|
classSignature += String.format("T%d:Ljava/lang/Object;", parameter);
|
||||||
|
methodSignature += String.format("TT%d;", parameter);
|
||||||
|
methodDescriptor += "Ljava/lang/Object;";
|
||||||
|
}
|
||||||
|
classSignature += "R:Ljava/lang/Object;>Ljava/lang/Object;";
|
||||||
|
methodSignature += ")TR;";
|
||||||
|
methodDescriptor += ")Ljava/lang/Object;";
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, funNName, classSignature, "java/lang/Object", null);
|
||||||
|
|
||||||
|
MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, "apply", methodDescriptor, methodSignature, null);
|
||||||
|
methodVisitor.visitEnd();
|
||||||
|
classWriter.visitEnd();
|
||||||
|
|
||||||
|
byte[] bytecode = classWriter.toByteArray();
|
||||||
|
try (BufferedOutputStream writer = new BufferedOutputStream(new FileOutputStream(new File(path, funNName + ".class")))) {
|
||||||
|
writer.write(bytecode);
|
||||||
|
writer.flush();
|
||||||
|
alreadyGeneratedFunN.add(numberOfParameters);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return alreadyGeneratedFunN.contains(numberOfParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void writeClassFile(byte[] bytecode, String name, File path) {
|
public static void writeClassFile(byte[] bytecode, String name, File path) {
|
||||||
FileOutputStream output;
|
FileOutputStream output;
|
||||||
|
Loading…
Reference in New Issue
Block a user