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

View File

@ -6,7 +6,7 @@ package de.dhbwstuttgart.intermediate.types;
* @since Studienarbeit Type Erasure * @since Studienarbeit Type Erasure
* @author etiennezink * @author etiennezink
*/ */
public class IntermediateWildcard extends IntermediateType{ public final class IntermediateWildcard extends IntermediateType{
/** /**
* Caches the hashCode after first computation. * 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()); }
}