Änderung: Spezialisierte FunN beinhaltet TPH im Namen und dieser wird FunN als Generic hinzugefügt.

This commit is contained in:
Etienne Zink 2022-03-29 15:00:52 +02:00
parent fcedec60e7
commit 4ed30f11f7
5 changed files with 47 additions and 23 deletions

View File

@ -6,9 +6,15 @@ import de.dhbwstuttgart.syntaxtree.type.*;
public class TypeToDescriptor implements TypeVisitor<String>{
private final boolean specializedFunN;
public TypeToDescriptor(){ this(false); }
public TypeToDescriptor(boolean specializedFunN) { this.specializedFunN = specializedFunN; }
@Override
public String visit(RefType refType) {
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && refType.getParaList().size() > 0) {
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && specializedFunN) {
FunNUtilities funNUtilities = FunNGenerator.getInstance();
return funNUtilities.getSpecializedDescriptor(funNUtilities.getArguments(refType.getParaList()), funNUtilities.getReturnType(refType.getParaList()));
}

View File

@ -16,10 +16,16 @@ import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.objectweb.asm.Opcodes.*;
//ToDo Kommentieren
/**
* //ToDo beschreiben
*
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public class FunNGenerator implements FunNUtilities{
private static FunNGenerator funNGenerator = new FunNGenerator();
@ -37,8 +43,9 @@ public class FunNGenerator implements FunNUtilities{
private final RefType objectRefType = new RefType(new JavaClassName(objectSuperType), null);
private final String objectSignature = applySignature(objectRefType);
private static String applyDescriptor(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToDescriptor()); }
private static String applySignature(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToSignature()); }
private static String applyDescriptor(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToDescriptor(true)); }
private static String applySignature(RefTypeOrTPHOrWildcardOrGeneric a) { return a.acceptTV(new TypeToSignature(true)); }
private static String applyNameDescriptor(RefTypeOrTPHOrWildcardOrGeneric a){ return a instanceof TypePlaceholder ? applySignature(a)+";" : String.format("L%s;", applyDescriptor(a)); }
@Override
public byte[] generateSuperBytecode(int numberArguments) {
@ -71,17 +78,24 @@ public class FunNGenerator implements FunNUtilities{
@Override
public byte[] generateSpecializedBytecode(List<RefTypeOrTPHOrWildcardOrGeneric> argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) {
StringBuilder funNClassSignature = new StringBuilder(objectSignature + applySignature(new RefType(new JavaClassName(getSuperClassName(argumentTypes.size())), null)));
List<RefTypeOrTPHOrWildcardOrGeneric> parameters = Stream
.concat(argumentTypes.stream(), Stream.of(returnType))
.collect(Collectors.toList());
RefType superFunN = new RefType(new JavaClassName(getSuperClassName(argumentTypes.size())), parameters , null);
StringBuilder funNClassSignature = new StringBuilder(objectSignature + (superFunN.acceptTV(new TypeToSignature())));
boolean containsGeneric = false;
String genericSignature = "<";
for (int currentTypArgumentIndex = 0; currentTypArgumentIndex < argumentTypes.size(); currentTypArgumentIndex++) {
RefTypeOrTPHOrWildcardOrGeneric typArgument = argumentTypes.get(currentTypArgumentIndex);
if (typArgument == null) continue;
if (typArgument instanceof GenericRefType){
GenericRefType generic = (GenericRefType) typArgument;
genericSignature += String.format("%s:%s", generic.getParsedName(), applyDescriptor(generic));
containsGeneric = true;
} else if(typArgument instanceof TypePlaceholder){
TypePlaceholder placeholder = (TypePlaceholder) typArgument;
genericSignature += String.format("%s:%s", applySignature(placeholder).substring(1), objectSignature);
containsGeneric = true;
}
}
genericSignature += ">";
@ -100,11 +114,9 @@ public class FunNGenerator implements FunNUtilities{
argumentTypes.size(),
argumentTypes
.stream()
.map(r -> r instanceof TypePlaceholder ? objectRefType : r)
.map(FunNGenerator::applyDescriptor)
.map(d -> String.format("L%s;", d))
.map(FunNGenerator::applyNameDescriptor)
.collect(Collectors.joining()),
applyDescriptor(returnType))
applyNameDescriptor(returnType))
.replace('/', '$')
.replace(";", "$_$");
}

View File

@ -19,19 +19,26 @@ import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
public class TypeToSignature implements TypeVisitor<String> {
private List<GenericsGeneratorResult> constraints;
public TypeToSignature() {
this.constraints = new ArrayList<>();
}
private final boolean specializedFunN;
public TypeToSignature() { this(new ArrayList<>(), false); }
public TypeToSignature(boolean specializedFunN) { this(new ArrayList<>(), specializedFunN); }
public TypeToSignature(List<GenericsGeneratorResult> constraints) {
this(constraints, false);
}
public TypeToSignature(List<GenericsGeneratorResult> constraints, boolean specializedFunN){
this.constraints = constraints;
this.specializedFunN = specializedFunN;
}
@Override
public String visit(RefType refType) {
if(refType.getName().toString().equals("void"))
return "V";
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && refType.getParaList().size() > 0){
if (refType.getName().toString().matches("Fun\\d+\\$\\$") && specializedFunN){
FunNUtilities funNUtilities = FunNGenerator.getInstance();
return funNUtilities.getSpecializedSignature(funNUtilities.getArguments(refType.getParaList()), funNUtilities.getReturnType(refType.getParaList()));
}

View File

@ -38,19 +38,19 @@ public class OLFunTest {
compiler.generateBytecode(generatedByteCodeDirectory);
loader = new URLClassLoader(new URL[] {new URL("file://"+generatedByteCodeDirectory)});
classToTest = loader.loadClass("OLFun");
classFun1IntInt = loader.loadClass("Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$");
classFun1DoubleDouble = loader.loadClass("Fun1$$Ljava$lang$Double$_$Ljava$lang$Double$_$");
classFun1StringString = loader.loadClass("Fun1$$Ljava$lang$String$_$Ljava$lang$String$_$");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
//classFun1IntInt = loader.loadClass("Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$");
//classFun1DoubleDouble = loader.loadClass("Fun1$$Ljava$lang$Double$_$Ljava$lang$Double$_$");
classFun1StringString = loader.loadClass("Fun1$$Ljava$lang$String$_$Ljava$lang$String$_$");
}
@Test
//@Test
public void mExistsWithInteger() throws Exception{
Method m = classToTest.getDeclaredMethod("m", classFun1IntInt ,Integer.class);
assertNotNull(m);
}
@Test
//@Test
public void mExistsWithDouble() throws Exception{
Method m = classToTest.getDeclaredMethod("m", classFun1DoubleDouble ,Double.class);
assertNotNull(m);
@ -62,7 +62,7 @@ public class OLFunTest {
assertNotNull(m);
}
@AfterClass
//@AfterClass
public static void cleanUp(){
TestCleanUp.cleanUpDirectory(new File(generatedByteCodeDirectory), f -> f.getName().contains(".class"));
}

View File

@ -1,6 +1,6 @@
import java.lang.String;
import java.lang.Integer;
import java.lang.Double;
//import java.lang.Integer;
//import java.lang.Double;
import java.util.Vector;
import java.lang.Boolean;
@ -10,7 +10,6 @@ import java.lang.Boolean;
public class OLFun {
//f = x -> {return x + x;};
m(f, x) {
x = f.apply(x+x);
}