forked from JavaTX/JavaCompilerCore
Erstellung echter Funktionstypen hinzugefügt.
Rückgabetypen dieser werden nicht korrekt aufgelöst. Dies muss geändert werden. Deskriptoren nicht angepasst. Da Basis-Interface FunN$$ mit erstellt wird, sind Tests noch korrekt.
This commit is contained in:
parent
65448c3bf3
commit
c7c50f4669
@ -770,6 +770,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// This will be used if the class is not standard class (not in API)
|
// This will be used if the class is not standard class (not in API)
|
||||||
ClassLoader cLoader2;
|
ClassLoader cLoader2;
|
||||||
|
|
||||||
|
//ToDo methodCallType wird nicht korrekt resolved, da kein Constraint vorhanden ist
|
||||||
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
|
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
|
||||||
try {
|
try {
|
||||||
@ -817,9 +818,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
//ToDo Etienne: Für Type Erasure wichtig?!
|
//ToDo Etienne: Für Type Erasure wichtig?!
|
||||||
} else if(!helper.isInCurrPkg(clazz)){
|
} else if(!helper.isInCurrPkg(clazz)){
|
||||||
if(clazz.contains(CONSTANTS.$$)) {
|
if(clazz.contains(CONSTANTS.$$)) {
|
||||||
|
//ToDo Methoden Deskriptor neu setzen
|
||||||
|
//ToDo Receiver neu setzen?!
|
||||||
mDesc = helper.getDescriptorOfApplyMethod(methCallType);
|
mDesc = helper.getDescriptorOfApplyMethod(methCallType);
|
||||||
helper.generateBCForFunN(mDesc);
|
helper.generateBCForFunN(typesOfParams, methCallType);
|
||||||
// mDesc = helper.generateBCForFunN(methCallType,typesOfParams);
|
|
||||||
}else {
|
}else {
|
||||||
try {
|
try {
|
||||||
cLoader2 = new DirectoryClassLoader(path, classLoader);
|
cLoader2 = new DirectoryClassLoader(path, classLoader);
|
||||||
|
@ -99,4 +99,34 @@ public class TypeToSignature implements TypeVisitor<String> {
|
|||||||
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
|
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
|
||||||
.findFirst();
|
.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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package de.dhbwstuttgart.bytecode.utilities;
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
|
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
|
||||||
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
import de.dhbwstuttgart.syntaxtree.FormalParameter;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
import org.objectweb.asm.ClassWriter;
|
import org.objectweb.asm.ClassWriter;
|
||||||
import org.objectweb.asm.MethodVisitor;
|
import org.objectweb.asm.MethodVisitor;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
@ -12,9 +14,11 @@ import org.objectweb.asm.signature.SignatureVisitor;
|
|||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.sql.Ref;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
@ -55,36 +59,39 @@ public class ByteCodeForFunNGenerator {
|
|||||||
writeClassFile(name, classWriter.toByteArray(), path);
|
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);
|
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
||||||
List<Expression> arguments = argumentList.getArguments();
|
int numberOfParameters = typesOfFormalParameters.length;
|
||||||
|
generateSuperFunNInterface(numberOfParameters, path);
|
||||||
|
|
||||||
/* //ToDo neu machen
|
String className = getBaseFunClassname(numberOfParameters);
|
||||||
int numberOfParams = arguments.size();
|
String classSignature = String.format("L%s;L%s<", Type.getInternalName(Object.class), className);
|
||||||
//ToDo Classname anpassen
|
|
||||||
String className = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
|
||||||
|
|
||||||
Signature sig = new Signature(numberOfParams);
|
//ToDo testen ob der Klassenname und -signatur so passt
|
||||||
classWriter.visit(V1_8, ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, className, sig.toString(),
|
for (String typeOfFormalParameter: typesOfFormalParameters) {
|
||||||
Type.getInternalName(Object.class), new String[]{String.format("Fun%d$$", numberOfParams)});
|
className += String.format("%s$_$", typeOfFormalParameter);
|
||||||
writeClassFile(className, classWriter.toByteArray(), path);
|
classSignature += String.format("L%s;", typeOfFormalParameter);
|
||||||
*/
|
|
||||||
|
|
||||||
SignatureWriter signatureWriter = new SignatureWriter();
|
|
||||||
int numberOfParams = 0;
|
|
||||||
SignatureVisitor paramVisitor = signatureWriter.visitParameterType();
|
|
||||||
|
|
||||||
for (Expression argument:arguments) {
|
|
||||||
paramVisitor.visitTypeVariable(CONSTANTS.T + ++numberOfParams);
|
|
||||||
}
|
}
|
||||||
|
className += returnType;
|
||||||
|
className = className.replace('/', '$');
|
||||||
|
classSignature += String.format("L%s>;", returnType);
|
||||||
|
|
||||||
signatureWriter.visitReturnType().visitTypeVariable(CONSTANTS.R);
|
System.out.println("Generated className: " + className);
|
||||||
Signature sig = new Signature(numberOfParams);
|
System.out.println("Generated signature: " + classSignature);
|
||||||
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
|
|
||||||
classWriter.visit(V1_8, ACC_PUBLIC + ACC_INTERFACE + ACC_ABSTRACT, name, sig.toString(), Type.getInternalName(Object.class), null);
|
classWriter.visit(V1_8, ACC_PUBLIC | ACC_INTERFACE | ACC_ABSTRACT, className, classSignature,
|
||||||
MethodVisitor mvApply = classWriter.visitMethod(ACC_PUBLIC + ACC_ABSTRACT, "apply", methDesc, signatureWriter.toString(), null);
|
Type.getInternalName(Object.class), new String[]{getBaseFunClassname(numberOfParameters)});
|
||||||
mvApply.visitEnd();
|
writeClassFile(className, classWriter.toByteArray(), path);
|
||||||
writeClassFile(name, classWriter.toByteArray(), path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -101,7 +108,7 @@ public class ByteCodeForFunNGenerator {
|
|||||||
public static boolean generateSuperFunNInterface(int numberOfParameters, File path){
|
public static boolean generateSuperFunNInterface(int numberOfParameters, File path){
|
||||||
if(alreadyGeneratedFunN.contains(numberOfParameters)) return true;
|
if(alreadyGeneratedFunN.contains(numberOfParameters)) return true;
|
||||||
//ToDo Etienne: Generierung der Signaturen/Deskriptoren vielleicht auslagern? Bzw. schauen ob nicht schon vorhanden und anpassen!
|
//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 classSignature = "<";
|
||||||
String methodSignature = "(";
|
String methodSignature = "(";
|
||||||
String methodDescriptor = "(";
|
String methodDescriptor = "(";
|
||||||
@ -128,6 +135,18 @@ public class ByteCodeForFunNGenerator {
|
|||||||
return alreadyGeneratedFunN.contains(numberOfParameters);
|
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}.
|
* Generates a {@code class-File} for the class {@code className} with the {@code bytecode}.
|
||||||
*
|
*
|
||||||
|
@ -221,8 +221,9 @@ public class MethodCallHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ToDo Etienne: Für Type Erasure wichtig?!
|
//ToDo Etienne: Für Type Erasure wichtig?!
|
||||||
public void generateBCForFunN(String methodDescriptor) {
|
public void generateBCForFunN(String[] typesOfFormalParams, String receiverType) {
|
||||||
ByteCodeForFunNGenerator.generateBCForFunN(methCall.arglist,methodDescriptor,path);
|
//ToDo return Descriptor auf apply Methode?
|
||||||
|
ByteCodeForFunNGenerator.generateBCForFunN(typesOfFormalParams, receiverType,path);
|
||||||
}
|
}
|
||||||
|
|
||||||
//ToDo Etienne: Für Type Erasure wichtig
|
//ToDo Etienne: Für Type Erasure wichtig
|
||||||
|
@ -64,6 +64,4 @@ public class OLFunTest {
|
|||||||
public static void cleanUp(){
|
public static void cleanUp(){
|
||||||
TestCleanUp.cleanUpDirectory(new File(generatedByteCodeDirectory), f -> f.getName().contains(".class"));
|
TestCleanUp.cleanUpDirectory(new File(generatedByteCodeDirectory), f -> f.getName().contains(".class"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Integer apply(Integer x) {return x;}
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user