forked from JavaTX/JavaCompilerCore
smaller and test cases
This commit is contained in:
parent
bbfd8699e8
commit
5e18496847
@ -19,10 +19,6 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
private HashMap<Type, Node<Type>> inheritanceGraph;
|
private HashMap<Type, Node<Type>> inheritanceGraph;
|
||||||
private HashMap<String, HashSet<Node<Type>>> strInheritanceGraph;
|
private HashMap<String, HashSet<Node<Type>>> strInheritanceGraph;
|
||||||
|
|
||||||
public FiniteClosure() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public FiniteClosure(Set<MPair> pairs) {
|
public FiniteClosure(Set<MPair> pairs) {
|
||||||
inheritanceGraph = new HashMap<Type, Node<Type>>();
|
inheritanceGraph = new HashMap<Type, Node<Type>>();
|
||||||
|
|
||||||
@ -76,32 +72,42 @@ public class FiniteClosure implements IFiniteClosure {
|
|||||||
// where foreach type var a in T2:
|
// where foreach type var a in T2:
|
||||||
// sigma1(T1) <=* sigma2(T2)
|
// sigma1(T1) <=* sigma2(T2)
|
||||||
//If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied)
|
//If a type of the same name is in the fc AND the type "type" is parameterized (some substitution sigma1 was applied)
|
||||||
if(strInheritanceGraph.containsKey(type.getName())) {
|
|
||||||
IUnify unify = new MartelliMontanariUnify();
|
IUnify unify = new MartelliMontanariUnify();
|
||||||
HashSet<Node<Type>> candidateNodes = strInheritanceGraph.get(type.getName());
|
HashSet<Type> candidates = new HashSet<>();
|
||||||
for(Node<Type> candidateNode : candidateNodes) {
|
if (strInheritanceGraph.containsKey(type.getName()))
|
||||||
Type theta2 = candidateNode.getContent();
|
strInheritanceGraph.get(type.getName()).forEach(x -> candidates.add(x.getContent()));
|
||||||
Optional<Unifier> sigma2 = unify.unify(theta2, type);
|
else
|
||||||
if(!sigma2.isPresent())
|
candidates.add(type);
|
||||||
continue;
|
|
||||||
Set<Type> theta1s = inheritanceGraph.containsKey(type) ? inheritanceGraph.get(type).getContentOfDescendants() : smaller(theta2);
|
for (Type theta2 : candidates) {
|
||||||
for(Type theta1 : theta1s) {
|
Optional<Unifier> sigma2 = unify.unify(theta2, type);
|
||||||
// Because only the most general type is calculated, sigma1 = sigma2
|
if (!sigma2.isPresent())
|
||||||
Type sigma1Theta1 = sigma2.get().apply(theta1);
|
continue;
|
||||||
|
Set<Type> theta1s = new HashSet<>();
|
||||||
|
if(inheritanceGraph.containsKey(type))
|
||||||
|
theta1s = inheritanceGraph.get(type).getContentOfDescendants();
|
||||||
|
else if(theta2.equals(type))
|
||||||
|
theta1s.add(type);
|
||||||
|
else
|
||||||
|
theta1s = smaller(theta2);
|
||||||
|
for (Type theta1 : theta1s) {
|
||||||
|
// Because only the most general type is calculated, sigma1 =
|
||||||
|
// sigma2
|
||||||
|
Type sigma1Theta1 = sigma2.get().apply(theta1);
|
||||||
|
|
||||||
ArrayList<Set<Type>> paramCandidates = new ArrayList<>();
|
ArrayList<Set<Type>> paramCandidates = new ArrayList<>();
|
||||||
for(Type param : sigma1Theta1.getTypeParams())
|
for (Type param : sigma1Theta1.getTypeParams())
|
||||||
paramCandidates.add(smArg(param));
|
paramCandidates.add(smArg(param));
|
||||||
|
|
||||||
Set<TypeParams> permResult = new HashSet<>();
|
Set<TypeParams> permResult = new HashSet<>();
|
||||||
permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]);
|
permuteParams(paramCandidates, 0, permResult, new Type[paramCandidates.size()]);
|
||||||
|
|
||||||
for(TypeParams newParams : permResult)
|
for (TypeParams newParams : permResult)
|
||||||
result.add(sigma1Theta1.setTypeParams(newParams));
|
result.add(sigma1Theta1.setTypeParams(newParams));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,49 +1,218 @@
|
|||||||
package unify;
|
package unify;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.MPair;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.MPair.PairOperator;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.Type;
|
import de.dhbwstuttgart.typeinference.unify.model.Type;
|
||||||
import de.dhbwstuttgart.typeinference.unifynew.TypeFactory;
|
import de.dhbwstuttgart.typeinference.unifynew.TypeFactory;
|
||||||
|
|
||||||
public class FiniteClosureTest extends FiniteClosure {
|
public class FiniteClosureTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMatch() {
|
public void testSmaller() {
|
||||||
TypeFactory tf = new TypeFactory();
|
TypeFactory tf = new TypeFactory();
|
||||||
|
|
||||||
Type a = tf.getPlaceholderType("a");
|
Type integer = tf.getSimpleType("Integer");
|
||||||
Type b = tf.getPlaceholderType("b");
|
Type number = tf.getSimpleType("Number");
|
||||||
Type c = tf.getPlaceholderType("c");
|
|
||||||
|
|
||||||
Type A = tf.getSimpleType("A");
|
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
|
||||||
Type B = tf.getSimpleType("B");
|
fcb.add(integer, number);
|
||||||
Type C1 = tf.getSimpleType("C", a, b, c);
|
fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer")));
|
||||||
Type C2 = tf.getSimpleType("C", a, A, b);
|
fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection"));
|
||||||
Type C3 = tf.getSimpleType("C", A, B, A);
|
IFiniteClosure fc = fcb.getCollectionExample();
|
||||||
Type D1 = tf.getSimpleType("D", C1, a, b, c);
|
|
||||||
Type D2 = tf.getSimpleType("D", C3, A, B, A);
|
/*
|
||||||
|
* Test Case 1:
|
||||||
|
*
|
||||||
|
* smaller(Set<Integer>) = { HashSet<Integer>, Set<Integer, TreeSet<Integer>, LinkedHashSet<Integer> }
|
||||||
|
*/
|
||||||
|
|
||||||
System.out.println(match(C2, C1));
|
Type setInt = tf.getSimpleType("Set", integer);
|
||||||
System.out.println(match(C3, C1));
|
Type hashSetInt = tf.getSimpleType("HashSet", integer);
|
||||||
System.out.println(match(D2, D1));
|
Type treeSetInt = tf.getSimpleType("TreeSet", integer);
|
||||||
Assert.assertFalse(match(C3, C2).isPresent());
|
Type linkedHashSetInt = tf.getSimpleType("LinkedHashSet", integer);
|
||||||
Assert.assertFalse(match(C1, C2).isPresent());
|
|
||||||
|
Set<Type> expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setInt, hashSetInt, linkedHashSetInt, treeSetInt,
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setInt));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 2:
|
||||||
|
*
|
||||||
|
* smaller(Set<? ext Integer>) =
|
||||||
|
* { HashSet<Integer>, Set<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||||
|
* HashSet<? ext Integer>, Set<? ext Integer>, TreeSet<? ext Integer>, LinkedHashSet<? ext Integer> }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Type extInt = tf.getExtendsType(integer);
|
||||||
|
Type hashSetExtInt = tf.getSimpleType("HashSet", extInt);
|
||||||
|
Type treeSetExtInt = tf.getSimpleType("TreeSet", extInt);
|
||||||
|
Type linkedHashSetExtInt = tf.getSimpleType("LinkedHashSet", extInt);
|
||||||
|
Type setExtInt = tf.getSimpleType("Set", extInt);
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setInt, hashSetInt, linkedHashSetInt, treeSetInt,
|
||||||
|
hashSetExtInt, treeSetExtInt, linkedHashSetExtInt, setExtInt,
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setExtInt));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 3:
|
||||||
|
*
|
||||||
|
* smaller(Set<? ext Number>) =
|
||||||
|
* { HashSet<Integer>, Set<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||||
|
* HashSet<Number>, Set<Number>, TreeSet<Number>, LinkedHashSet<Number>,
|
||||||
|
* HashSet<? ext Integer>, Set<? ext Integer>, TreeSet<? ext Integer>, LinkedHashSet<? ext Integer>
|
||||||
|
* HashSet<? ext Number, Set<? ext Number, TreeSet<? ext Number, LinkedHashSet<? ext Number> }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Type hashSetNum = tf.getSimpleType("HashSet", number);
|
||||||
|
Type treeSetNum = tf.getSimpleType("TreeSet", number);
|
||||||
|
Type linkedHashSetNum = tf.getSimpleType("LinkedHashSet", number);
|
||||||
|
Type setNum = tf.getSimpleType("Set", number);
|
||||||
|
|
||||||
|
Type extNum = tf.getExtendsType(number);
|
||||||
|
Type hashSetExtNum = tf.getSimpleType("HashSet", extNum);
|
||||||
|
Type treeSetExtNum = tf.getSimpleType("TreeSet", extNum);
|
||||||
|
Type linkedHashSetExtNum = tf.getSimpleType("LinkedHashSet", extNum);
|
||||||
|
Type setExtNum = tf.getSimpleType("Set", extNum);
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setInt, hashSetInt, linkedHashSetInt, treeSetInt,
|
||||||
|
setNum, hashSetNum, linkedHashSetNum, treeSetNum,
|
||||||
|
setExtInt, hashSetExtInt, linkedHashSetExtInt, treeSetExtInt,
|
||||||
|
setExtNum, hashSetExtNum, linkedHashSetExtNum, treeSetExtNum
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setExtNum));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 4:
|
||||||
|
* TODO ist das ergebnis korrekt oder müssen die ? ext Ts raus weil der allgemeienste Typ T ausreicht?
|
||||||
|
* smaller(Set<T>) =
|
||||||
|
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||||
|
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Type t = tf.getPlaceholderType("T");
|
||||||
|
Type setT = tf.getSimpleType("Set", t);
|
||||||
|
Type hashSetT = tf.getSimpleType("HashSet", t);
|
||||||
|
Type treeSetT = tf.getSimpleType("TreeSet", t);
|
||||||
|
Type linkedHashSetT = tf.getSimpleType("LinkedHashSet", t);
|
||||||
|
Type hashSetExtT = tf.getSimpleType("HashSet", t);
|
||||||
|
Type treeSetExtT = tf.getSimpleType("TreeSet", t);
|
||||||
|
Type linkedHashSetExtT = tf.getSimpleType("LinkedHashSet", t);
|
||||||
|
Type setExtT = tf.getSimpleType("Set", t);
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setT, hashSetT, treeSetT, linkedHashSetT,
|
||||||
|
setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setT));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 5
|
||||||
|
*
|
||||||
|
* smaller(Set<? super Integer> =
|
||||||
|
* { Set<Integer>, HashSet<Integer>, TreeSet<Integer>, LinkedHashSet<Integer>,
|
||||||
|
* Set<? super Integer>, HashSet<? super Integer>, TreeSet<? super Integer>, LinkedHashSet<? super Integer>,
|
||||||
|
* Set<? super Number>, HashSet<? super Number>, TreeSet<? super Number>, LinkedHashSet<? super Number> }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Type superNum = tf.getSuperType(number);
|
||||||
|
Type superInt = tf.getSuperType(integer);
|
||||||
|
|
||||||
|
Type setSupInt = tf.getSimpleType("Set", superInt);
|
||||||
|
Type hashSetSupInt = tf.getSimpleType("HashSet", superInt);
|
||||||
|
Type linkedHashSetSupInt = tf.getSimpleType("LinkedHashSet", superInt);
|
||||||
|
Type treeSetSupInt = tf.getSimpleType("TreeSet", superInt);
|
||||||
|
Type setSupNum = tf.getSimpleType("Set", superNum);
|
||||||
|
Type hashSetSupNum = tf.getSimpleType("HashSet", superNum);
|
||||||
|
Type linkedHashSetSupNum = tf.getSimpleType("LinkedHashSet", superNum);
|
||||||
|
Type treeSetSupNum = tf.getSimpleType("TreeSet", superNum);
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setSupInt, hashSetSupInt, linkedHashSetSupInt, treeSetSupInt,
|
||||||
|
setSupNum, hashSetSupNum, linkedHashSetSupNum, treeSetSupNum,
|
||||||
|
setInt, hashSetInt, linkedHashSetInt, treeSetInt,
|
||||||
|
setNum, hashSetNum, linkedHashSetNum, treeSetNum
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setSupInt));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 6:
|
||||||
|
*
|
||||||
|
* smaller(Set<? ext T) =
|
||||||
|
* { HashSet<T>, Set<T>, TreeSet<T>, LinkedHashSet<T>,
|
||||||
|
* HashSet<? ext T>, Set<? ext T>, TreeSet<? ext T>, LinkedHashSet<? ext T> }
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setT, hashSetT, treeSetT, linkedHashSetT,
|
||||||
|
setExtT, hashSetExtT, treeSetExtT, linkedHashSetExtT
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setExtT));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 7:
|
||||||
|
* smaller(Set<NotInFc>) =
|
||||||
|
* { HashSet<NotInFc>, Set<NotInFc>, TreeSet<NotInFc>, LinkedHashSet<NotInFc>,
|
||||||
|
* HashSet<? ext NotInFc>, Set<? ext NotInFc>, TreeSet<? ext NotInFc>, LinkedHashSet<? ext NotInFc> }
|
||||||
|
*/
|
||||||
|
|
||||||
|
Type notInFc = tf.getSimpleType("notInFC");
|
||||||
|
Type setNotInFc = tf.getSimpleType("Set", notInFc);
|
||||||
|
Type hashSetNotInFc = tf.getSimpleType("HashSet", notInFc);
|
||||||
|
Type treeSetNotInFc = tf.getSimpleType("TreeSet", notInFc);
|
||||||
|
Type linkedHashSetNotInFc = tf.getSimpleType("LinkedHashSet", notInFc);
|
||||||
|
Type hashSetExtNotInFc = tf.getSimpleType("HashSet", notInFc);
|
||||||
|
Type treeSetExtNotInFc = tf.getSimpleType("TreeSet", notInFc);
|
||||||
|
Type linkedHashSetExtNotInFc = tf.getSimpleType("LinkedHashSet", notInFc);
|
||||||
|
Type setExtNotInFc = tf.getSimpleType("Set", notInFc);
|
||||||
|
|
||||||
|
expectedResult = new HashSet<>(Arrays.stream(new Type[] {
|
||||||
|
setNotInFc, hashSetNotInFc, treeSetNotInFc, linkedHashSetNotInFc,
|
||||||
|
setExtNotInFc, hashSetExtNotInFc, treeSetExtNotInFc, linkedHashSetExtNotInFc
|
||||||
|
}).collect(Collectors.toSet()));
|
||||||
|
|
||||||
|
Assert.assertEquals(expectedResult, fc.smaller(setNotInFc));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Test Case 8:
|
||||||
|
*
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testGreater() {
|
public void testGreater() {
|
||||||
IFiniteClosure fc = new FiniteClosureBuilder().getCollectionExample();
|
|
||||||
TypeFactory tf = new TypeFactory();
|
TypeFactory tf = new TypeFactory();
|
||||||
|
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
|
||||||
|
fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number"));
|
||||||
|
fcb.add(tf.getSimpleType("MyMap", "T"), tf.getSimpleType("HashMap", tf.getSimpleType("Integer")));
|
||||||
|
fcb.add(tf.getSimpleType("HashMap", "T"), tf.getSimpleType("Collection"));
|
||||||
|
IFiniteClosure fc = fcb.getCollectionExample();
|
||||||
|
|
||||||
System.out.println("\n\n----- Greater Test -----");
|
System.out.println("\n\n----- Greater Test -----");
|
||||||
System.out.println("Greater(LinkedList<T>) = " + fc.greater(tf.getSimpleType("LinkedList", "T")));
|
System.out.println("Greater(LinkedList<T>) = " + fc.greater(tf.getSimpleType("LinkedList", "T")));
|
||||||
System.out.println("Greater(TreeSet<T>) = " + fc.greater(tf.getSimpleType("TreeSet", "T")));
|
System.out.println("Greater(TreeSet<T>) = " + fc.greater(tf.getSimpleType("TreeSet", "T")));
|
||||||
System.out.println("Greater(Collection) = " + fc.greater(tf.getSimpleType("Collection")));
|
System.out.println("Greater(Collection) = " + fc.greater(tf.getSimpleType("Collection")));
|
||||||
|
System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Integer"))));
|
||||||
|
System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSimpleType("Number"))));
|
||||||
|
System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getExtendsType(tf.getSimpleType("Integer")))));
|
||||||
|
System.out.println(fc.greater(tf.getSimpleType("Deque", tf.getSuperType(tf.getSimpleType("Integer")))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -57,20 +226,6 @@ public class FiniteClosureTest extends FiniteClosure {
|
|||||||
System.out.println("GrArg(? super List<T>) = " + fc.grArg(tf.getSuperType(tf.getSimpleType("List", "T"))));
|
System.out.println("GrArg(? super List<T>) = " + fc.grArg(tf.getSuperType(tf.getSimpleType("List", "T"))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSmaller() {
|
|
||||||
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
|
|
||||||
TypeFactory tf = new TypeFactory();
|
|
||||||
|
|
||||||
fcb.add(tf.getSimpleType("Integer"), tf.getSimpleType("Number"));
|
|
||||||
IFiniteClosure fc = fcb.getCollectionExample();
|
|
||||||
|
|
||||||
System.out.println("\n\n----- Smaller Test -----");
|
|
||||||
System.out.println("Smaller(List<? extends Number>) = " + fc.smaller(tf.getSimpleType("List", tf.getExtendsType(tf.getSimpleType("Number")))));
|
|
||||||
System.out.println("Smaller(List<T>) = " + fc.smaller(tf.getSimpleType("List", "T")));
|
|
||||||
System.out.println("Smaller(TreeSet<T>) = " + fc.smaller(tf.getSimpleType("TreeSet", "T")));
|
|
||||||
System.out.println("Smaller(Collection) = " + fc.smaller(tf.getSimpleType("Collection")));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSmArg() {
|
public void testSmArg() {
|
||||||
|
Loading…
Reference in New Issue
Block a user