Hinzufügen von FunN zur Generierung von echten Funktionstypen.

FunN ist Subtyp von IntermediateRefType.
Hinzufügen erster FunNTests.
This commit is contained in:
Etienne Zink 2022-03-20 22:25:55 +01:00
parent 0d84e8361f
commit ac1e0340c3
4 changed files with 120 additions and 16 deletions

View File

@ -0,0 +1,69 @@
package de.dhbwstuttgart.intermediate.generation;
import de.dhbwstuttgart.intermediate.types.IntermediateRefType;
import de.dhbwstuttgart.intermediate.types.IntermediateType;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* Class which represents a function type.
* Offers different methods to generate or interact with this real function type.
*
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public final class FunN extends IntermediateRefType {
/**
* Caches the bytecode after first computation.
*/
private byte[] bytecode;
/**
* Caches the superBytecode after first computation.
*/
private byte[] superBytecode;
public FunN(List<IntermediateType> typArguments, IntermediateType returnType) {
super(new JavaClassName(
String.format("Fun%d$$%s%s",
typArguments.size(),
typArguments
.stream()
.map(IntermediateType::getSignature)
.collect(Collectors.joining()),
returnType.getSignature())
.replace('/', '$')
.replace(";", "$_$")),
Stream.concat(typArguments.stream(), Stream.of(returnType)).collect(Collectors.toList()));
}
/**
* @return the bytecode for the super FunN type
*/
public byte[] getSuperBytecode(){
byte[] superBytecode = this.superBytecode;
if (superBytecode == null){
//ToDo
this.superBytecode = superBytecode;
}
return superBytecode;
}
/**
* Generates the bytecode for this FunN type.
* Make sure to generate the bytecode for the super FunN as well.
* @return the bytecode for this explicit FunN type
*/
public byte[] getBytecode(){
byte[] bytecode = this.bytecode;
if (bytecode == null){
//ToDo
this.bytecode = bytecode;
}
return bytecode;
}
}

View File

@ -11,9 +11,9 @@ import java.util.List;
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public final class IntermediateRefType extends IntermediateInnerType{
public class IntermediateRefType extends IntermediateInnerType{
private final List<IntermediateType> typParameters;
private final List<IntermediateType> typArguments;
private final JavaClassName className;
/**
@ -35,9 +35,9 @@ public final class IntermediateRefType extends IntermediateInnerType{
this(className, new ArrayList<>());
}
public IntermediateRefType(JavaClassName className, List<IntermediateType> typParameters){
public IntermediateRefType(JavaClassName className, List<IntermediateType> typArguments){
this.className = className;
this.typParameters = Collections.unmodifiableList(typParameters);
this.typArguments = Collections.unmodifiableList(typArguments);
}
@Override
@ -47,8 +47,8 @@ public final class IntermediateRefType extends IntermediateInnerType{
IntermediateRefType intermediateRefType = (IntermediateRefType) o;
if(!getFullyQualifiedName().equals(intermediateRefType.getFullyQualifiedName())) return false;
for(int index = 0; index < typParameters.size(); index++){
if(!typParameters.get(index).equals(intermediateRefType.typParameters.get(index))) return false;
for(int index = 0; index < typArguments.size(); index++){
if(!typArguments.get(index).equals(intermediateRefType.typArguments.get(index))) return false;
}
return true;
}
@ -59,8 +59,8 @@ public final class IntermediateRefType extends IntermediateInnerType{
int hashCode = this.hashCode;
if (hashCode == 0){
hashCode += getFullyQualifiedName().hashCode();
for (IntermediateType typeParameter:typParameters) {
hashCode = prime * hashCode + typeParameter.hashCode();
for (IntermediateType typeArgument: typArguments) {
hashCode = prime * hashCode + typeArgument.hashCode();
}
this.hashCode = hashCode;
}
@ -75,10 +75,10 @@ public final class IntermediateRefType extends IntermediateInnerType{
if (className.getClassName().equals("void")) signature = "V";
else {
signature += String.format("L%s", getFullyQualifiedName());
if (typParameters.size() != 0){
if (typArguments.size() != 0){
signature += "<";
for (IntermediateType typParameter:typParameters) {
signature += typParameter.getSignature();
for (IntermediateType typArgument: typArguments) {
signature += typArgument.getSignature();
}
signature += ">";
}
@ -98,17 +98,17 @@ public final class IntermediateRefType extends IntermediateInnerType{
return descriptor;
}
public boolean isParametrized() { return typParameters.size() > 0; }
public boolean isParametrized() { return typArguments.size() > 0; }
public int getTypParameterSize(){ return typParameters.size(); }
public int getTypParameterSize(){ return typArguments.size(); }
/**
* @param index
* @return the typ parameter at {@code index} or {@code null}, iff {@code |typ parameters| < index}
*/
public IntermediateType getTypParameter(int index) {
if(typParameters.size() < index) return null;
return typParameters.get(index);
if(typArguments.size() < index) return null;
return typArguments.get(index);
}
private String getFullyQualifiedName(){ return className.toString(); }

View File

@ -6,7 +6,7 @@ package de.dhbwstuttgart.intermediate.types;
* @since Studienarbeit Type Erasure
* @author etiennezink
*/
public class IntermediateWildcard extends IntermediateType{
public final class IntermediateWildcard extends IntermediateType{
/**
* Caches the hashCode after first computation.

View File

@ -0,0 +1,35 @@
package intermediate.generation;
import de.dhbwstuttgart.intermediate.generation.FunN;
import de.dhbwstuttgart.intermediate.types.IntermediateRefType;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import java.util.Arrays;
import static org.junit.Assert.assertEquals;
public class FunNTest {
private static String fun1IntIntSignature;
private static String fun1IntIntDescriptor;
private static FunN fun1IntInt;
//ToDo mehr Tests und Bytecode Tests
@BeforeClass
public static void SetUp(){
IntermediateRefType integer = new IntermediateRefType(new JavaClassName(Type.getInternalName(Integer.class)));
fun1IntIntSignature = "LFun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$<Ljava/lang/Integer;Ljava/lang/Integer;>;";
fun1IntIntDescriptor = "LFun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$;";
fun1IntInt = new FunN(Arrays.asList(integer), integer);
}
@Test
public void SignatureTest_Fun1IntegerInteger(){ assertEquals(fun1IntIntSignature, fun1IntInt.getSignature()); }
@Test
public void DescriptorTest_Fun1IntegerInteger(){ assertEquals(fun1IntIntDescriptor, fun1IntInt.getDescriptor()); }
}