397 lines
17 KiB
Java
397 lines
17 KiB
Java
package targetast;
|
|
|
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
|
import de.dhbwstuttgart.syntaxtree.Field;
|
|
import de.dhbwstuttgart.syntaxtree.Method;
|
|
import de.dhbwstuttgart.syntaxtree.type.RefType;
|
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|
import de.dhbwstuttgart.target.generate.ASTToTargetAST;
|
|
import static de.dhbwstuttgart.target.generate.ASTToTargetAST.OBJECT;
|
|
import de.dhbwstuttgart.target.generate.Bound;
|
|
import static de.dhbwstuttgart.target.generate.Bound.*;
|
|
import de.dhbwstuttgart.target.generate.BoundsList;
|
|
import de.dhbwstuttgart.target.generate.GenericsResult;
|
|
import org.junit.Ignore;
|
|
import org.junit.Test;
|
|
import static org.junit.Assert.*;
|
|
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.nio.file.Path;
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
|
|
@Ignore("TODO: Rewrite with the new algorithm")
|
|
public class TestGenerics {
|
|
private static final String rootDirectory = System.getProperty("user.dir") + "/resources/insertGenerics/javFiles/";
|
|
private static final String bytecodeDirectory = System.getProperty("user.dir") + "targetTest";
|
|
|
|
private record Result(List<GenericsResult> genericsResults, ClassOrInterface clazz) {
|
|
Method findMethod(String name) {
|
|
return clazz.getMethods().stream().filter(m -> m.getName().equals(name)).findFirst().orElse(null);
|
|
}
|
|
|
|
Field findField(String name) {
|
|
return clazz.getFieldDecl().stream().filter(field -> field.getName().equals(name)).findFirst().orElse(null);
|
|
}
|
|
}
|
|
|
|
private static void assertStrictlyEquals(BoundsList a, BoundsList b) {
|
|
assertEquals(a.base, b.base);
|
|
assertEquals(a, b);
|
|
}
|
|
|
|
private static void assertStrictlyNotEquals(BoundsList a, BoundsList b) {
|
|
assertNotEquals(a.base, b.base);
|
|
}
|
|
|
|
private static Result computeGenerics(String filename) throws IOException, ClassNotFoundException {
|
|
var file = Path.of(rootDirectory + filename).toFile();
|
|
var compiler = new JavaTXCompiler(List.of(file), List.of(file.getParentFile()), new File(bytecodeDirectory));
|
|
var inference = compiler.typeInference(file);
|
|
compiler.generateBytecode(new File(bytecodeDirectory), inference);
|
|
var sf = compiler.sourceFiles.get(file);
|
|
var clazz = sf.getClasses().get(0);
|
|
return new Result(compiler.getGeneratedGenerics().get(sf), clazz);
|
|
}
|
|
|
|
@Test
|
|
public void testAny() throws Exception {
|
|
var result = computeGenerics("TestAny.jav");
|
|
var anyMethod = result.findMethod("anyMethod");
|
|
var otherMethod = result.findMethod("otherMethod");
|
|
var a = result.findField("a");
|
|
var b = result.findField("b");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(1, generics.get(anyMethod).size());
|
|
assertEquals(2, generics.get(result.clazz).size());
|
|
|
|
var ECK1 = generics.getBounds(otherMethod.getParameterList().getParameterAt(0).getType(), result.clazz, anyMethod);
|
|
var ECK2 = generics.getBounds(otherMethod.getReturnType(), result.clazz, anyMethod);
|
|
var ECKChain = new BoundsList(onClass(OBJECT));
|
|
assertStrictlyEquals(ECK1, ECK2);
|
|
assertEquals(ECK2, generics.getBounds(b.getType(), result.clazz));
|
|
|
|
var M = generics.getBounds(a.getType(), result.clazz);
|
|
var MChain = new BoundsList(onClass("ECK"), onClass(OBJECT));
|
|
assertEquals(M, MChain);
|
|
}
|
|
|
|
@Test
|
|
public void testClassField() throws Exception {
|
|
var result = computeGenerics("TestClassField.jav");
|
|
var fReturn = result.findMethod("fReturn");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(1, generics.get(result.clazz).size());
|
|
assertEquals(0, generics.get(fReturn).size());
|
|
|
|
var N = generics.getBounds(fReturn.getReturnType(), result.clazz);
|
|
var NChain = new BoundsList(onClass(OBJECT));
|
|
assertEquals(N, NChain);
|
|
}
|
|
|
|
@Test
|
|
public void testContraVariant() throws Exception {
|
|
var result = computeGenerics("TestContraVariant.jav");
|
|
var m = result.findMethod("m");
|
|
var main = result.findMethod("main");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(0, generics.get(result.clazz).size());
|
|
assertEquals(3, generics.get(m).size());
|
|
assertEquals(3, generics.get(main).size());
|
|
|
|
{
|
|
var AJ = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
|
var AK = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
var KWU = generics.getBounds(((RefType) generics.resolve(m.getReturnType())).getParaList().get(0), result.clazz, m);
|
|
var AK2 = generics.getBounds(((RefType) generics.resolve(m.getReturnType())).getParaList().get(1), result.clazz, m);
|
|
|
|
assertStrictlyEquals(AK, AK2);
|
|
assertStrictlyNotEquals(AJ, KWU);
|
|
var NChain = new BoundsList(onMethod(OBJECT));
|
|
assertEquals(AJ, NChain);
|
|
assertEquals(AK, NChain);
|
|
assertEquals(KWU, NChain);
|
|
}
|
|
|
|
{
|
|
var O = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
|
var P = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
|
var KWQ = generics.getBounds(((RefType) generics.resolve(main.getReturnType())).getParaList().get(1), result.clazz, main);
|
|
var O2 = generics.getBounds(((RefType) generics.resolve(main.getReturnType())).getParaList().get(0), result.clazz, main);
|
|
|
|
assertStrictlyEquals(O, O2);
|
|
assertStrictlyNotEquals(P, KWQ);
|
|
var NChain = new BoundsList(onMethod(OBJECT));
|
|
assertEquals(O, NChain);
|
|
assertEquals(P, NChain);
|
|
assertEquals(KWQ, NChain);
|
|
}
|
|
}
|
|
|
|
@Test
|
|
public void testGGFinder() throws Exception {
|
|
var result = computeGenerics("TestGGFinder.jav");
|
|
var id = result.findMethod("id");
|
|
var setA = result.findMethod("setA");
|
|
var m = result.findMethod("m");
|
|
var a = result.findField("a");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(1, generics.get(result.clazz).size());
|
|
assertEquals(2, generics.get(id).size());
|
|
assertEquals(1, generics.get(setA).size());
|
|
assertEquals(2, generics.get(m).size());
|
|
|
|
var R = generics.getBounds(a.getType(), result.clazz);
|
|
var RChain = new BoundsList(onClass(OBJECT));
|
|
assertEquals(R, RChain);
|
|
|
|
var O = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
|
var AB = generics.getBounds(id.getReturnType(), result.clazz, id);
|
|
assertEquals(O, AB);
|
|
assertEquals(AB, new BoundsList(onMethod(OBJECT)));
|
|
|
|
var S = generics.getBounds(setA.getParameterList().getParameterAt(0).getType(), result.clazz, setA);
|
|
assertEquals(S, RChain);
|
|
assertEquals(generics.getBounds(setA.getReturnType(), result.clazz, setA), RChain);
|
|
|
|
var X = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
|
var Y = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
var XChain = new BoundsList(onMethod(OBJECT));
|
|
assertEquals(X, XChain);
|
|
assertEquals(Y, X);
|
|
}
|
|
|
|
@Test
|
|
public void testLocalVarLambda() throws Exception {
|
|
var result = computeGenerics("TestLocalVarLambda.jav");
|
|
// TODO Generics of lambdas
|
|
}
|
|
|
|
@Test
|
|
public void testMutualRecursion() throws Exception {
|
|
var result = computeGenerics("TestMutualRecursion.jav");
|
|
var id = result.findMethod("id");
|
|
var m = result.findMethod("m");
|
|
var main = result.findMethod("main");
|
|
var a = result.findField("a");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(1, generics.get(result.clazz).size());
|
|
assertEquals(2, generics.get(id).size());
|
|
assertEquals(2, generics.get(m).size());
|
|
assertEquals(3, generics.get(main).size());
|
|
|
|
var N = generics.getBounds(a.getType(), result.clazz);
|
|
assertEquals(N, new BoundsList(onClass(OBJECT)));
|
|
|
|
var P = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
|
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
|
assertEquals(P, O);
|
|
assertEquals(O, new BoundsList(onMethod(OBJECT)));
|
|
|
|
assertEquals(generics.resolve(m.getParameterList().getParameterAt(0).getType()), generics.resolve(m.getReturnType()));
|
|
var Y = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
|
var AA = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
assertEquals(Y, AA);
|
|
assertEquals(AA, new BoundsList(onMethod(OBJECT)));
|
|
|
|
var AI = generics.getBounds(m.getParameterList().getParameterAt(0).getType(), result.clazz, m);
|
|
var AJ = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
var AH = generics.getBounds(m.getReturnType(), result.clazz, m);
|
|
assertEquals(AI, AJ);
|
|
assertEquals(AJ, AH);
|
|
assertEquals(AH, new BoundsList(onMethod(OBJECT)));
|
|
}
|
|
|
|
@Test
|
|
public void testReturnVar() throws Exception {
|
|
var result = computeGenerics("TestReturnVar.jav");
|
|
var anyMethod = result.findMethod("anyMethod");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
assertEquals(1, generics.get(anyMethod).size());
|
|
|
|
var M = generics.getBounds(anyMethod.getReturnType(), result.clazz, anyMethod);
|
|
assertEquals(M, new BoundsList(onMethod(OBJECT)));
|
|
}
|
|
|
|
@Test
|
|
public void testSecondLineOfClassConstraints() throws Exception {
|
|
var result = computeGenerics("TestSecondLineOfClassConstraints.jav");
|
|
var a = result.findField("a");
|
|
var b = result.findField("b");
|
|
var anyMethod = result.findMethod("anyMethod");
|
|
var otherMethod = result.findMethod("otherMethod");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var M = generics.getBounds(a.getType(), result.clazz);
|
|
var DYX = generics.getBounds(b.getType(), result.clazz);
|
|
var MChain = new BoundsList(onClass("DYX"), onClass(OBJECT));
|
|
var DYXChain = new BoundsList(onClass(OBJECT));
|
|
assertEquals(M, MChain);
|
|
|
|
var Q = generics.getBounds(anyMethod.getReturnType(), result.clazz, anyMethod);
|
|
assertEquals(Q, new BoundsList(onMethod(OBJECT)));
|
|
|
|
System.out.println(otherMethod.getReturnType());
|
|
var DYX2 = generics.getBounds(otherMethod.getReturnType(), result.clazz, otherMethod);
|
|
assertEquals(DYX, DYX2);
|
|
assertEquals(DYX, generics.getBounds(otherMethod.getReturnType(), result.clazz, otherMethod));
|
|
}
|
|
|
|
@Test
|
|
public void testThreeArgs() throws Exception {
|
|
var result = computeGenerics("TestThreeArgs.jav");
|
|
}
|
|
|
|
@Test
|
|
public void testTPHsAndGenerics() throws Exception {
|
|
var result = computeGenerics("TestTPHsAndGenerics.jav");
|
|
var id2 = result.findMethod("id2");
|
|
var m = result.findMethod("m");
|
|
var m2 = result.findMethod("m2");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var U = generics.getBounds(id2.getParameterList().getParameterAt(0).getType(), result.clazz, id2);
|
|
var FPT = generics.getBounds(id2.getReturnType(), result.clazz, id2);
|
|
assertEquals(U, new BoundsList(onMethod("FPT"), onClass(OBJECT)));
|
|
assertEquals(FPT, new BoundsList(onClass(OBJECT)));
|
|
|
|
var AA = generics.getBounds(m.getReturnType(), result.clazz, m);
|
|
var AC = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
assertEquals(AA, new BoundsList(onMethod(OBJECT)));
|
|
assertEquals(AC, new BoundsList(onMethod(OBJECT)));
|
|
|
|
var AH = generics.getBounds(m2.getReturnType(), result.clazz, m2);
|
|
var AL = generics.getBounds(m2.getParameterList().getParameterAt(0).getType(), result.clazz, m2);
|
|
assertEquals(AH, new BoundsList(onMethod(OBJECT)));
|
|
assertEquals(AH, AL);
|
|
}
|
|
|
|
@Test
|
|
public void testTwoArgs() throws Exception {
|
|
var result = computeGenerics("TestTwoArgs.jav");
|
|
|
|
var a = result.findField("a");
|
|
var id = result.findMethod("id");
|
|
var setA = result.findMethod("setA");
|
|
var m = result.findMethod("m");
|
|
var main = result.findMethod("main");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var AO = generics.getBounds(a.getType(), result.clazz);
|
|
var AOBound = new BoundsList(
|
|
onClass("Y"),
|
|
onClass("AK"),
|
|
onClass("AE"),
|
|
onClass(OBJECT)
|
|
);
|
|
assertEquals(AO, AOBound);
|
|
|
|
var S = generics.getBounds(setA.getParameterList().getParameterAt(0).getType(), result.clazz, setA);
|
|
var c = new ArrayList<Bound>();
|
|
c.add(onMethod("AO"));
|
|
c.addAll(AOBound);
|
|
var SChain = new BoundsList(c);
|
|
assertEquals(S, SChain);
|
|
|
|
var Y = generics.getBounds(m.getParameterList().getParameterAt(1).getType(), result.clazz, m);
|
|
var YChain = new BoundsList(onMethod("AE"), onClass(OBJECT));
|
|
var AE = generics.getBounds(m.getReturnType(), result.clazz, m);
|
|
assertEquals(Y, YChain);
|
|
assertEquals(AE, new BoundsList(onClass(OBJECT)));
|
|
|
|
// TODO main seems to change between runs
|
|
/*var AE2 = generics.getBounds(main.getReturnType(), result.clazz, main);
|
|
var AF = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
|
var AG = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
|
assertEquals(AE, AE2));
|
|
assertEquals(AF, new BoundsList(onMethod("AK"), onMethod("AE"), onClass(OBJECT))));
|
|
assertEquals(AG, SChain));*/
|
|
}
|
|
|
|
@Test
|
|
public void testTwoArgs2() throws Exception {
|
|
var result = computeGenerics("TestTwoArgs2.jav");
|
|
// TODO Test generics
|
|
}
|
|
|
|
@Test
|
|
public void testTwoCalls() throws Exception {
|
|
var result = computeGenerics("TestTwoCalls.jav");
|
|
var id = result.findMethod("id");
|
|
var main = result.findMethod("main");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var O = generics.getBounds(id.getReturnType(), result.clazz, id);
|
|
var O2 = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
|
assertStrictlyEquals(O, O2);
|
|
assertEquals(O2, new BoundsList(onMethod(OBJECT)));
|
|
|
|
// TODO Maybe test in other ways if the parameter generics equals the return generics
|
|
var S = generics.getBounds(main.getReturnType(), result.clazz, main);
|
|
var S2 = generics.getBounds(main.getParameterList().getParameterAt(1).getType(), result.clazz, main);
|
|
var T = generics.getBounds(main.getParameterList().getParameterAt(0).getType(), result.clazz, main);
|
|
assertStrictlyEquals(S, S2);
|
|
assertEquals(S2, new BoundsList(onMethod(OBJECT)));
|
|
assertEquals(T, new BoundsList(onMethod(OBJECT)));
|
|
}
|
|
|
|
@Test
|
|
public void testVector() throws Exception {
|
|
var result = computeGenerics("TestVector.jav");
|
|
var m = result.findMethod("m");
|
|
var id = result.findMethod("id");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var par1 = generics.resolve(m.getParameterList().getParameterAt(0).getType());
|
|
var par2 = generics.resolve(m.getParameterList().getParameterAt(1).getType());
|
|
|
|
var S = generics.getBounds(((RefType) par1).getParaList().get(0), result.clazz, m);
|
|
var ACM = generics.getBounds(((RefType) par2).getParaList().get(0), result.clazz, m);
|
|
assertEquals(S, new BoundsList(onMethod("V"), onMethod(OBJECT)));
|
|
assertEquals(ACM, new BoundsList(onMethod(OBJECT)));
|
|
|
|
var Y = generics.getBounds(id.getParameterList().getParameterAt(0).getType(), result.clazz, id);
|
|
assertEquals(Y, new BoundsList(onMethod(OBJECT)));
|
|
assertEquals(Y, generics.getBounds(id.getReturnType(), result.clazz, id));
|
|
}
|
|
|
|
@Test
|
|
public void testVectorArg() throws Exception {
|
|
var result = computeGenerics("TestVectorArg.jav");
|
|
var add = result.findMethod("add");
|
|
var main = result.findMethod("main");
|
|
|
|
var generics = result.genericsResults.get(0);
|
|
var par1 = generics.resolve(add.getParameterList().getParameterAt(0).getType());
|
|
var ACK = generics.getBounds(((RefType) par1).getParaList().get(0), result.clazz, add);
|
|
var O = generics.getBounds(add.getParameterList().getParameterAt(1).getType(), result.clazz, add);
|
|
assertEquals(ACK, new BoundsList(onMethod(OBJECT)));
|
|
assertEquals(O, new BoundsList(onMethod("ACK"), onMethod(OBJECT)));
|
|
|
|
var par2 = generics.resolve(main.getParameterList().getParameterAt(0).getType());
|
|
var ACK2 = generics.getBounds(((RefType) par2).getParaList().get(0), result.clazz, add);
|
|
var V = generics.getBounds(add.getParameterList().getParameterAt(1).getType(), result.clazz, add);
|
|
assertStrictlyEquals(ACK2, ACK);
|
|
assertEquals(V, O);
|
|
}
|
|
|
|
@Test
|
|
public void testVoidMeth() throws Exception {
|
|
var result = computeGenerics("TestVoidMeth.jav");
|
|
}
|
|
|
|
@Test
|
|
public void testAssign() throws Exception {
|
|
// TODO Check generics
|
|
var result = computeGenerics("TestAssign.jav");
|
|
}
|
|
}
|