forked from JavaTX/JavaCompilerCore
Implementierung von getBytecode() in FunN und Hinzufügen entsprechender Tests.
This commit is contained in:
parent
918a2cc04d
commit
6381d09174
@ -1,6 +1,7 @@
|
|||||||
package de.dhbwstuttgart.intermediate.generation;
|
package de.dhbwstuttgart.intermediate.generation;
|
||||||
|
|
||||||
import de.dhbwstuttgart.intermediate.types.IntermediateGenericType;
|
import de.dhbwstuttgart.intermediate.types.IntermediateGenericType;
|
||||||
|
import de.dhbwstuttgart.intermediate.types.IntermediateInnerType;
|
||||||
import de.dhbwstuttgart.intermediate.types.IntermediateRefType;
|
import de.dhbwstuttgart.intermediate.types.IntermediateRefType;
|
||||||
import de.dhbwstuttgart.intermediate.types.IntermediateType;
|
import de.dhbwstuttgart.intermediate.types.IntermediateType;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
@ -24,10 +25,18 @@ import static org.objectweb.asm.Opcodes.*;
|
|||||||
*/
|
*/
|
||||||
public final class FunN extends IntermediateRefType {
|
public final class FunN extends IntermediateRefType {
|
||||||
|
|
||||||
private final String superFunNName;
|
|
||||||
private final String argumentGenericBase = "T";
|
private final String argumentGenericBase = "T";
|
||||||
private final String returnGeneric = "R";
|
private final String returnGeneric = "R";
|
||||||
private final String methodName = "apply";
|
private final String methodName = "apply";
|
||||||
|
private final int bytecodeVersion = V1_8;
|
||||||
|
|
||||||
|
private final String objectSuperType = Type.getInternalName(Object.class).replace('.','/');
|
||||||
|
private final String objectSignature = new IntermediateRefType(new JavaClassName(Type.getInternalName(Object.class))).getSignature();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the super interface of this specialized function.
|
||||||
|
*/
|
||||||
|
private final IntermediateRefType superFunN;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches the superBytecode after first computation.
|
* Caches the superBytecode after first computation.
|
||||||
@ -39,9 +48,10 @@ public final class FunN extends IntermediateRefType {
|
|||||||
*/
|
*/
|
||||||
private byte[] bytecode;
|
private byte[] bytecode;
|
||||||
|
|
||||||
public FunN(IntermediateType returnType){ this(Collections.emptyList(), returnType); }
|
public FunN(IntermediateInnerType returnType){ this(Collections.emptyList(), returnType); }
|
||||||
|
|
||||||
public FunN(List<IntermediateType> typArguments, IntermediateType returnType) {
|
public FunN(List<IntermediateInnerType> typArguments, IntermediateInnerType returnType) {
|
||||||
|
//using stream-API for single line processing of relevant data in the super()-call
|
||||||
super(new JavaClassName(
|
super(new JavaClassName(
|
||||||
String.format("Fun%d$$%s%s",
|
String.format("Fun%d$$%s%s",
|
||||||
typArguments.size(),
|
typArguments.size(),
|
||||||
@ -53,7 +63,8 @@ public final class FunN extends IntermediateRefType {
|
|||||||
.replace('/', '$')
|
.replace('/', '$')
|
||||||
.replace(";", "$_$")),
|
.replace(";", "$_$")),
|
||||||
Stream.concat(typArguments.stream(), Stream.of(returnType)).collect(Collectors.toList()));
|
Stream.concat(typArguments.stream(), Stream.of(returnType)).collect(Collectors.toList()));
|
||||||
superFunNName = String.format("Fun%d$$", typArguments.size());
|
superFunN = new IntermediateRefType(new JavaClassName(String.format("Fun%d$$", typArguments.size())),
|
||||||
|
Stream.concat(typArguments.stream(), Stream.of(returnType)).collect(Collectors.toList()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,9 +73,6 @@ public final class FunN extends IntermediateRefType {
|
|||||||
public byte[] getSuperBytecode(){
|
public byte[] getSuperBytecode(){
|
||||||
byte[] superBytecode = this.superBytecode;
|
byte[] superBytecode = this.superBytecode;
|
||||||
if (superBytecode == null){
|
if (superBytecode == null){
|
||||||
String superType = Type.getInternalName(Object.class).replace('.','/');
|
|
||||||
String objectSignature = new IntermediateRefType(new JavaClassName(Type.getInternalName(Object.class))).getSignature();
|
|
||||||
|
|
||||||
String superFunNClassSignature = "<";
|
String superFunNClassSignature = "<";
|
||||||
String superFunNMethodSignature = "(";
|
String superFunNMethodSignature = "(";
|
||||||
String superFunNMethodDescriptor = "(";
|
String superFunNMethodDescriptor = "(";
|
||||||
@ -81,7 +89,7 @@ public final class FunN extends IntermediateRefType {
|
|||||||
|
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
classWriter.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, superFunNName, superFunNClassSignature, superType, null);
|
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, superFunN.getClassName(), superFunNClassSignature, objectSuperType, null);
|
||||||
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor, superFunNMethodSignature , null);
|
methodVisitor = classWriter.visitMethod(ACC_PUBLIC | ACC_ABSTRACT, methodName, superFunNMethodDescriptor, superFunNMethodSignature , null);
|
||||||
methodVisitor.visitEnd();
|
methodVisitor.visitEnd();
|
||||||
classWriter.visitEnd();
|
classWriter.visitEnd();
|
||||||
@ -99,7 +107,26 @@ public final class FunN extends IntermediateRefType {
|
|||||||
public byte[] getBytecode(){
|
public byte[] getBytecode(){
|
||||||
byte[] bytecode = this.bytecode;
|
byte[] bytecode = this.bytecode;
|
||||||
if (bytecode == null){
|
if (bytecode == null){
|
||||||
//ToDo
|
String funNClassSignature = objectSignature + superFunN.getSignature();
|
||||||
|
boolean containsGeneric = false;
|
||||||
|
|
||||||
|
String genericSignature = "<";
|
||||||
|
for (int currentTypArgumentIndex = 0; currentTypArgumentIndex < getTypArgumentSize(); currentTypArgumentIndex++) {
|
||||||
|
IntermediateType typArgument = getTypArgument(currentTypArgumentIndex);
|
||||||
|
if (typArgument == null) continue;
|
||||||
|
if (typArgument instanceof IntermediateGenericType){
|
||||||
|
IntermediateGenericType generic = (IntermediateGenericType) typArgument;
|
||||||
|
genericSignature += String.format("%s:%s", generic.getGenericName(), generic.getDescriptor());
|
||||||
|
containsGeneric = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
genericSignature += ">";
|
||||||
|
if (containsGeneric) funNClassSignature = genericSignature + funNClassSignature;
|
||||||
|
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(bytecodeVersion, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, getClassName(), funNClassSignature, objectSuperType, new String[]{superFunN.getClassName()});
|
||||||
|
classWriter.visitEnd();
|
||||||
|
bytecode = classWriter.toByteArray();
|
||||||
this.bytecode = bytecode;
|
this.bytecode = bytecode;
|
||||||
}
|
}
|
||||||
return bytecode;
|
return bytecode;
|
||||||
|
@ -26,8 +26,6 @@ public class FunNTest {
|
|||||||
|
|
||||||
private static FunN fun2IntIntString;
|
private static FunN fun2IntIntString;
|
||||||
|
|
||||||
//ToDo mehr Tests und Bytecode Tests
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void SetUp(){
|
public static void SetUp(){
|
||||||
IntermediateRefType integer = new IntermediateRefType(new JavaClassName(Type.getInternalName(Integer.class)));
|
IntermediateRefType integer = new IntermediateRefType(new JavaClassName(Type.getInternalName(Integer.class)));
|
||||||
@ -51,12 +49,21 @@ public class FunNTest {
|
|||||||
@Test
|
@Test
|
||||||
public void BytecodeTest_Super0(){ assertArrayEquals(generatedASMFun0(), fun0T.getSuperBytecode()) ;}
|
public void BytecodeTest_Super0(){ assertArrayEquals(generatedASMFun0(), fun0T.getSuperBytecode()) ;}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BytecodeTest_Fun0T(){ assertArrayEquals(generatedASMFun0T(), fun0T.getBytecode()) ;}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void BytecodeTest_Super1(){ assertArrayEquals(generatedASMFun1(), fun1IntInt.getSuperBytecode()) ;}
|
public void BytecodeTest_Super1(){ assertArrayEquals(generatedASMFun1(), fun1IntInt.getSuperBytecode()) ;}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BytecodeTest_Fun1IntInt(){ assertArrayEquals(generatedASMFun1IntInt(), fun1IntInt.getBytecode()) ;}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void BytecodeTest_Super2(){ assertArrayEquals(generatedASMFun2(), fun2IntIntString.getSuperBytecode()) ;}
|
public void BytecodeTest_Super2(){ assertArrayEquals(generatedASMFun2(), fun2IntIntString.getSuperBytecode()) ;}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void BytecodeTest_Fun2IntIntString(){ assertArrayEquals(generatedASMFun2IntIntString(), fun2IntIntString.getBytecode()) ;}
|
||||||
|
|
||||||
private byte[] generatedASMFun0() {
|
private byte[] generatedASMFun0() {
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
@ -67,6 +74,13 @@ public class FunNTest {
|
|||||||
return classWriter.toByteArray();
|
return classWriter.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] generatedASMFun0T() {
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "Fun0$$TT$_$", "<T:Ljava/lang/Object;>Ljava/lang/Object;LFun0$$<TT;>;", "java/lang/Object", new String[]{"Fun0$$"});
|
||||||
|
classWriter.visitEnd();
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] generatedASMFun1() {
|
private byte[] generatedASMFun1() {
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
@ -77,6 +91,13 @@ public class FunNTest {
|
|||||||
return classWriter.toByteArray();
|
return classWriter.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] generatedASMFun1IntInt() {
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$", "Ljava/lang/Object;LFun1$$<Ljava/lang/Integer;Ljava/lang/Integer;>;", "java/lang/Object", new String[]{"Fun1$$"});
|
||||||
|
classWriter.visitEnd();
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
private byte[] generatedASMFun2() {
|
private byte[] generatedASMFun2() {
|
||||||
ClassWriter classWriter = new ClassWriter(0);
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
MethodVisitor methodVisitor;
|
MethodVisitor methodVisitor;
|
||||||
@ -86,4 +107,11 @@ public class FunNTest {
|
|||||||
classWriter.visitEnd();
|
classWriter.visitEnd();
|
||||||
return classWriter.toByteArray();
|
return classWriter.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private byte[] generatedASMFun2IntIntString() {
|
||||||
|
ClassWriter classWriter = new ClassWriter(0);
|
||||||
|
classWriter.visit(V1_8, ACC_PUBLIC | ACC_ABSTRACT | ACC_INTERFACE, "Fun2$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$Ljava$lang$String$_$", "Ljava/lang/Object;LFun2$$<Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/String;>;", "java/lang/Object", new String[]{"Fun2$$"});
|
||||||
|
classWriter.visitEnd();
|
||||||
|
return classWriter.toByteArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user