diff --git a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java index d1a8340c..e3c44223 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNGenerator.java @@ -12,9 +12,11 @@ import org.objectweb.asm.ClassWriter; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Type; +import javax.annotation.Nonnull; import java.io.File; import java.io.FileOutputStream; import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -77,6 +79,8 @@ public final class FunNGenerator implements FunNUtilities{ @Override public byte[] generateSpecializedBytecode(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { + Objects.requireNonNull(argumentTypes); + Objects.requireNonNull(returnType); List parameters = Stream .concat(argumentTypes.stream(), Stream.of(returnType)) .collect(Collectors.toList()); @@ -111,6 +115,8 @@ public final class FunNGenerator implements FunNUtilities{ @Override public String getSpecializedClassName(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { + Objects.requireNonNull(argumentTypes); + Objects.requireNonNull(returnType); return String.format("Fun%d$$%s%s", argumentTypes.size(), argumentTypes @@ -124,16 +130,21 @@ public final class FunNGenerator implements FunNUtilities{ @Override public String getSpecializedDescriptor(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { + Objects.requireNonNull(argumentTypes); + Objects.requireNonNull(returnType); return applyDescriptor(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null)); } @Override public String getSpecializedSignature(List argumentTypes, RefTypeOrTPHOrWildcardOrGeneric returnType) { + Objects.requireNonNull(argumentTypes); + Objects.requireNonNull(returnType); return applySignature(new RefType(new JavaClassName(getSpecializedClassName(argumentTypes, returnType)), null)); } @Override public List getArguments(List list) { + Objects.requireNonNull(list); return list .stream() .limit(Math.max(0, list.size() - 1)) @@ -142,6 +153,7 @@ public final class FunNGenerator implements FunNUtilities{ @Override public RefTypeOrTPHOrWildcardOrGeneric getReturnType(List list) { + Objects.requireNonNull(list); if(list.size() == 0) return null; return list.get(list.size() - 1); } diff --git a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java index b9921ba3..3e612506 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/funN/FunNUtilities.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.bytecode.funN; import de.dhbwstuttgart.bytecode.utilities.CONSTANTS; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import javax.annotation.Nonnull; import java.io.File; import java.io.FileOutputStream; import java.util.List; diff --git a/src/main/java/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java b/src/main/java/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java index 644dbaee..d12a1a9f 100644 --- a/src/main/java/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java +++ b/src/main/java/de/dhbwstuttgart/syntaxtree/type/GenericRefType.java @@ -4,6 +4,8 @@ import de.dhbwstuttgart.syntaxtree.ASTVisitor; import de.dhbwstuttgart.typeinference.result.ResultSetVisitor; import org.antlr.v4.runtime.Token; +import java.util.Objects; + public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric { private String name; @@ -33,12 +35,20 @@ public class GenericRefType extends RefTypeOrTPHOrWildcardOrGeneric visitor.visit(this); } + /** + * @since Studienarbeit Type Erasure + * @author etiennezink + * + * @param o + * @return + */ @Override public boolean equals(Object o) { - // TODO Auto-generated method stub - return false; - } - + if((! (o instanceof GenericRefType))) return false; + GenericRefType genericRefType = (GenericRefType) o; + return getParsedName().equals(genericRefType.getParsedName()) && + Objects.equals(getOffset(), genericRefType.getOffset()); + } @Override public String toString() diff --git a/src/test/java/bytecode/funN/FunNGeneratorTest.java b/src/test/java/bytecode/funN/FunNGeneratorTest.java new file mode 100644 index 00000000..89a2ad1c --- /dev/null +++ b/src/test/java/bytecode/funN/FunNGeneratorTest.java @@ -0,0 +1,130 @@ +package bytecode.funN; + +import de.dhbwstuttgart.bytecode.funN.FunNGenerator; +import de.dhbwstuttgart.bytecode.funN.FunNUtilities; +import de.dhbwstuttgart.parser.scope.JavaClassName; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import org.junit.BeforeClass; +import org.junit.Test; +import org.objectweb.asm.Type; + +import java.util.Arrays; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class FunNGeneratorTest { + + static FunNUtilities funNGenerator; + static RefType voidType = new RefType(new JavaClassName(Type.getInternalName(Void.class)), null); + static RefType integerType = new RefType(new JavaClassName(Type.getInternalName(Integer.class)), null); + static GenericRefType genericT = new GenericRefType("T", null); + + @BeforeClass + public static void StartUp(){ + funNGenerator = FunNGenerator.getInstance(); + } + + @Test + public void SuperClassName_0(){ + var superClassName = funNGenerator.getSuperClassName(0); + assertEquals("Fun0$$", superClassName); + } + + @Test + public void SuperClassName_1(){ + var superClassName = funNGenerator.getSuperClassName(1); + assertEquals("Fun1$$", superClassName); + } + + @Test + public void SpecializedClassName_VoidVoid(){ + var specializedClassName = funNGenerator.getSpecializedClassName(Arrays.asList(), voidType); + assertEquals("Fun0$$Ljava$lang$Void$_$", specializedClassName); + } + + @Test + public void SpecializedClassName_VoidInt(){ + var specializedClassName = funNGenerator.getSpecializedClassName(Arrays.asList(), integerType); + assertEquals("Fun0$$Ljava$lang$Integer$_$", specializedClassName); + } + + @Test + public void SpecializedClassName_IntInt(){ + var specializedClassName = funNGenerator.getSpecializedClassName(Arrays.asList(integerType), integerType); + assertEquals("Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$", specializedClassName); + } + + @Test + public void SpecializedClassName_IntT(){ + var specializedClassName = funNGenerator.getSpecializedClassName(Arrays.asList(integerType), genericT); + assertEquals("Fun1$$Ljava$lang$Integer$_$LT$_$", specializedClassName); + } + + @Test + public void SpecializedClassName_IntTPH(){ + var specializedClassName = funNGenerator.getSpecializedClassName(Arrays.asList(integerType), TypePlaceholder.fresh(null)); + assertEquals("Fun1$$Ljava$lang$Integer$_$LTPH$_$", specializedClassName); + } + + @Test + public void Signature_IntInt(){ + var classSignature = funNGenerator.getSpecializedSignature(Arrays.asList(integerType), integerType); + assertEquals("LFun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$;", classSignature); + } + + @Test + public void Signature_IntT(){ + var classSignature = funNGenerator.getSpecializedSignature(Arrays.asList(integerType), genericT); + assertEquals("LFun1$$Ljava$lang$Integer$_$LT$_$;", classSignature); + } + + @Test + public void Descriptor_IntInt(){ + var classSignature = funNGenerator.getSpecializedDescriptor(Arrays.asList(integerType), integerType); + //does not have to contain L and ; because TypeToDescriptor returns the descriptor without these characters as well + assertEquals("Fun1$$Ljava$lang$Integer$_$Ljava$lang$Integer$_$", classSignature); + } + + @Test + public void Descriptor_IntT(){ + var classSignature = funNGenerator.getSpecializedDescriptor(Arrays.asList(integerType), genericT); + //does not have to contain L and ; because TypeToDescriptor returns the descriptor without these characters as well + assertEquals("Fun1$$Ljava$lang$Integer$_$LT$_$", classSignature); + } + + @Test + public void GetArguments_Empty(){ + var arguments = funNGenerator.getArguments(Arrays.asList()); + assertTrue(arguments.isEmpty()); + } + + @Test + public void GetArguments_Int(){ + var arguments = funNGenerator.getArguments(Arrays.asList(integerType)); + assertTrue(arguments.isEmpty()); + } + + @Test + public void GetArguments_IntT(){ + var arguments = funNGenerator.getArguments(Arrays.asList(integerType, genericT)); + assertTrue(arguments.size() == 1); + assertTrue(arguments.contains(integerType)); + } + + @Test + public void GetArguments_IntTInt(){ + var arguments = funNGenerator.getArguments(Arrays.asList(integerType, genericT, integerType)); + assertTrue(arguments.size() == 2); + assertTrue(arguments.contains(integerType)); + assertTrue(arguments.contains(genericT)); + } + + //ToDo Etienne: get return Type Test + + //ToDo Etienne: Super Bytecode Test + + //ToDo Etienne: Specialized Bytecode Test +} diff --git a/src/test/resources/testBytecode/manually/OLFunTest.java b/src/test/resources/testBytecode/manually/OLFunTest.java new file mode 100644 index 00000000..8a2603a1 --- /dev/null +++ b/src/test/resources/testBytecode/manually/OLFunTest.java @@ -0,0 +1,9 @@ +public class OLFunTest{ + public static void main(String[] args){ + var olFun2 = new OLFun2(); + olFun2.m((Integer x) -> x); + olFun2.m((Integer x) -> (Double) Double.valueOf(x)); + olFun2.m((Double x) -> x); + olFun2.m((Double x) -> x.intValue()); + } +} \ No newline at end of file