fc identifier from string to type

This commit is contained in:
Florian Steurer 2015-11-15 18:08:46 +01:00
parent 480c7dca61
commit ae37dd6255
6 changed files with 171 additions and 43 deletions

View File

@ -48,5 +48,5 @@ public interface IFiniteClosure {
public Set<Type> grArg(PlaceholderType type);
public Set<Type> smArg(PlaceholderType type);
public Type getType(String typeName);
public Type getType(Type type);
}

View File

@ -322,7 +322,7 @@ public class RuleSet implements IRuleSet{
if(lhsType.getName().equals(rhsType.getName()))
return Optional.empty();
Type lhsFromFc = finiteClosure.getType(lhsType.getName());
Type lhsFromFc = finiteClosure.getType(lhsType);
if(lhsFromFc == null)
return Optional.empty();
@ -364,9 +364,9 @@ public class RuleSet implements IRuleSet{
Type lhsFromFc;
if(lhsType instanceof SimpleType)
lhsFromFc = finiteClosure.getType(lhsType.getName());
lhsFromFc = finiteClosure.getType(lhsType);
else
lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType().getName()));
lhsFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) lhsType).getExtendedType()));
if(lhsFromFc == null)
return Optional.empty();
@ -392,8 +392,51 @@ public class RuleSet implements IRuleSet{
@Override
public Optional<MPair> adaptSup(MPair pair) {
// TODO Auto-generated method stub
return null;
if(pair.getPairOp() != PairOperator.SMALLERDOTWC)
return Optional.empty();
Type lhsType = pair.getLhsType();
if(!(lhsType instanceof SimpleType) && !(lhsType instanceof SuperType))
return Optional.empty();
Type rhsType = pair.getRhsType();
if(!(rhsType instanceof SuperType))
return Optional.empty();
if(lhsType.getTypeParams().size() == 0 || rhsType.getTypeParams().size() == 0)
return Optional.empty();
Type lhsFromFc;
Type newRhs;
if(lhsType instanceof SimpleType) {
lhsFromFc = finiteClosure.getType(lhsType);
newRhs = new ExtendsType(lhsType);
}
else {
lhsFromFc = new ExtendsType(finiteClosure.getType(((SuperType) lhsType).getSuperedType()));
newRhs = new ExtendsType(((SuperType) lhsType).getSuperedType());
}
if(lhsFromFc == null)
return Optional.empty();
Set<Type> grArg = finiteClosure.grArg(lhsFromFc);
Optional<Type> opt = grArg.stream().filter(x -> x.getName().equals(rhsType.getName())).findAny();
if(!opt.isPresent())
return Optional.empty();
Type newLhs = opt.get();
TypeParams lhsTypeParams = lhsType.getTypeParams();
TypeParams lhsFromFcTypeParams = lhsFromFc.getTypeParams();
Unifier unif = new Unifier(lhsFromFcTypeParams.get(0), lhsTypeParams.get(0));
for(int i = 1; i < lhsTypeParams.size(); i++)
unif.andThen(new Unifier(lhsFromFcTypeParams.get(i), lhsTypeParams.get(i)));
return Optional.of(new MPair(newLhs.apply(unif), newRhs, PairOperator.SMALLERDOTWC));
}
/**
@ -405,11 +448,11 @@ public class RuleSet implements IRuleSet{
private int[] pi(Type C, Type D) {
Type cFromFc = null;
if(C instanceof SimpleType)
cFromFc = finiteClosure.getType(C.getName());
cFromFc = finiteClosure.getType(C);
else if(C instanceof ExtendsType)
cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType().getName()));
cFromFc = new ExtendsType(finiteClosure.getType(((ExtendsType) C).getExtendedType()));
else if(C instanceof SuperType)
cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType().getName()));
cFromFc = new SuperType(finiteClosure.getType(((SuperType) C).getSuperedType()));
if(cFromFc == null)
return new int[0];

View File

@ -9,11 +9,12 @@ import de.dhbwstuttgart.typinference.unify.model.MPair.PairOperator;
public class FiniteClosure implements IFiniteClosure {
private HashMap<String, Node<Type>> inheritanceGraph;
private HashMap<Type, Node<Type>> inheritanceGraph;
private HashMap<String, HashSet<Node<Type>>> strInheritanceGraph;
public FiniteClosure(Set<MPair> pairs) {
inheritanceGraph = new HashMap<String, Node<Type>>();
inheritanceGraph = new HashMap<Type, Node<Type>>();
// Build the transitive closure of the inheritance tree
for(MPair pair : pairs) {
@ -21,13 +22,13 @@ public class FiniteClosure implements IFiniteClosure {
continue;
// Add nodes if not already in the graph
if(!inheritanceGraph.containsKey(pair.getLhsType().getName()))
inheritanceGraph.put(pair.getLhsType().getName(), new Node<Type>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType().getName()))
inheritanceGraph.put(pair.getRhsType().getName(), new Node<Type>(pair.getRhsType()));
if(!inheritanceGraph.containsKey(pair.getLhsType()))
inheritanceGraph.put(pair.getLhsType(), new Node<Type>(pair.getLhsType()));
if(!inheritanceGraph.containsKey(pair.getRhsType()))
inheritanceGraph.put(pair.getRhsType(), new Node<Type>(pair.getRhsType()));
Node<Type> childNode = inheritanceGraph.get(pair.getLhsType().getName());
Node<Type> parentNode = inheritanceGraph.get(pair.getRhsType().getName());
Node<Type> childNode = inheritanceGraph.get(pair.getLhsType());
Node<Type> parentNode = inheritanceGraph.get(pair.getRhsType());
// Add edge
parentNode.AddDescendant(childNode);
@ -36,6 +37,16 @@ public class FiniteClosure implements IFiniteClosure {
parentNode.getPredecessors().stream().forEach(x -> x.AddDescendant(childNode));
childNode.getDescendants().stream().forEach(x -> x.AddPredecessor(parentNode));
}
// Build the alternative representation with strings as keys
strInheritanceGraph = new HashMap<>();
for(Type key : inheritanceGraph.keySet()) {
if(!strInheritanceGraph.containsKey(key.getName()))
strInheritanceGraph.put(key.getName(), new HashSet<>());
strInheritanceGraph.get(key.getName()).add(inheritanceGraph.get(key));
}
}
/**
@ -44,21 +55,15 @@ public class FiniteClosure implements IFiniteClosure {
*/
@Override
public Set<Type> smaller(Type type) {
if(!inheritanceGraph.containsKey(type.getName()))
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
Set<Type> result = inheritanceGraph.get(type.getName()).getContentOfDescendants();
Set<Type> result = inheritanceGraph.get(type).getContentOfDescendants();
result.add(type);
return result;
}
@Override
public Type getType(String typeName) {
if(!inheritanceGraph.containsKey(typeName))
return null;
return inheritanceGraph.get(typeName).getContent();
}
/**
* Returns all types of the finite closure that are supertypes of the argument.
@ -66,10 +71,10 @@ public class FiniteClosure implements IFiniteClosure {
*/
@Override
public Set<Type> greater(Type type) {
if(!inheritanceGraph.containsKey(type.getName()))
if(!inheritanceGraph.containsKey(type))
return new HashSet<>();
Set<Type> result = inheritanceGraph.get(type.getName()).getContentOfPredecessors();
Set<Type> result = inheritanceGraph.get(type).getContentOfPredecessors();
result.add(type);
return result;
}
@ -82,12 +87,12 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(SimpleType type) {
if(!inheritanceGraph.containsKey(type.getName()))
if(!inheritanceGraph.containsKey(type))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getName()).getContent();
Type t = inheritanceGraph.get(type).getContent();
result.add(t);
smaller(type).forEach(x -> result.add(new SuperType(x)));
@ -98,12 +103,12 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(ExtendsType type) {
if(!inheritanceGraph.containsKey(type.getExtendedType().getName()))
if(!inheritanceGraph.containsKey(type.getExtendedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent();
Type t = inheritanceGraph.get(type.getExtendedType()).getContent();
greater(t).forEach(x -> result.add(new ExtendsType(x)));
@ -112,12 +117,12 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> grArg(SuperType type) {
if(!inheritanceGraph.containsKey(type.getSuperedType().getName()))
if(!inheritanceGraph.containsKey(type.getSuperedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent();
Type t = inheritanceGraph.get(type.getSuperedType()).getContent();
smaller(t).forEach(x -> result.add(new SuperType(x)));
@ -136,12 +141,12 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> smArg(SimpleType type) {
if(!inheritanceGraph.containsKey(type.getName()))
if(!inheritanceGraph.containsKey(type))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getName()).getContent();
Type t = inheritanceGraph.get(type).getContent();
result.add(t);
smaller(type).forEach(x -> result.add(new ExtendsType(x)));
@ -150,12 +155,12 @@ public class FiniteClosure implements IFiniteClosure {
}
public Set<Type> smArg(ExtendsType type) {
if(!inheritanceGraph.containsKey(type.getExtendedType().getName()))
if(!inheritanceGraph.containsKey(type.getExtendedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getExtendedType().getName()).getContent();
Type t = inheritanceGraph.get(type.getExtendedType()).getContent();
result.add(t);
smaller(t).forEach(x -> {
@ -169,12 +174,12 @@ public class FiniteClosure implements IFiniteClosure {
@Override
public Set<Type> smArg(SuperType type) {
if(!inheritanceGraph.containsKey(type.getSuperedType().getName()))
if(!inheritanceGraph.containsKey(type.getSuperedType()))
return new HashSet<Type>();
Set<Type> result = new HashSet<Type>();
Type t = inheritanceGraph.get(type.getSuperedType().getName()).getContent();
Type t = inheritanceGraph.get(type.getSuperedType()).getContent();
result.add(t);
greater(t).forEach(x -> {
@ -189,4 +194,20 @@ public class FiniteClosure implements IFiniteClosure {
public Set<Type> smArg(PlaceholderType type) {
return new HashSet<>();
}
@Override
public Type getType(Type type) {
if(!strInheritanceGraph.containsKey(type.getName()))
return null;
HashSet<Node<Type>> candidates = strInheritanceGraph.get(type.getName());
for(Node<Type> node : candidates) {
Type candidate = node.getContent();
if(candidate.getTypeParams().arePlaceholders())
return candidate;
}
return null;
}
}

View File

@ -10,7 +10,7 @@ public final class SuperType extends Type {
private Type superedType;
public SuperType(Type superedType) {
super("? extends " + superedType.getName(), superedType.getTypeParams());
super("? super " + superedType.getName(), superedType.getTypeParams());
this.superedType = superedType;
}

View File

@ -7,11 +7,18 @@ import de.dhbwstuttgart.typeinference.unifynew.Unifier;
public final class TypeParams implements Iterable<Type>{
private final Type[] typeParams;
public TypeParams(Type... types) {
typeParams = types;
}
public boolean arePlaceholders() {
for(Type t : typeParams)
if(!(t instanceof PlaceholderType))
return false;
return true;
}
@Override
public String toString() {
String res = "";

View File

@ -396,7 +396,7 @@ public class RuleSetTest {
* Positive Tests
*/
MPair erase1 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT);
MPair erase2 = new MPair(tf.getSimpleType("HashSet", "W"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT);
MPair erase2 = new MPair(tf.getSimpleType("HashSet", "T"), tf.getSimpleType("Collection"), PairOperator.SMALLERDOT);
MPair erase3 = new MPair(tf.getSimpleType("List", "T"), tf.getSimpleType("List", "T"), PairOperator.SMALLERDOT);
Assert.assertTrue(rules.erase1(erase1));
@ -568,9 +568,12 @@ public class RuleSetTest {
SimpleType t1 = tf.getSimpleType("Type1", "T", "U");
SimpleType t2 = tf.getSimpleType("Type2", "T");
SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer"));
SimpleType t32 = tf.getSimpleType("Type3", "T", "U");
SimpleType t4 = tf.getSimpleType("Object");
fcb.add(t1, t2);
fcb.add(t2, t3);
fcb.add(t32, t4);
IRuleSet rules = new RuleSet(fcb.getFiniteClosure());
@ -621,6 +624,60 @@ public class RuleSetTest {
@Test
public void testAdaptSup() {
TypeFactory tf = new TypeFactory();
FiniteClosureBuilder fcb = new FiniteClosureBuilder();
SimpleType t1 = tf.getSimpleType("Type1", "T", "U");
SimpleType t2 = tf.getSimpleType("Type2", "T");
SimpleType t3 = tf.getSimpleType("Type3", tf.getPlaceholderType("T"), tf.getSimpleType("Integer"));
fcb.add(t1, t2);
fcb.add(t2, t3);
IRuleSet rules = new RuleSet(fcb.getFiniteClosure());
/*
* Positive Tests
*/
SimpleType c1 = tf.getSimpleType("Type1", "String", "Double");
SimpleType c2 = tf.getSimpleType("Type2", "Object");
SimpleType c3 = tf.getSimpleType("Type3", "Object", "Number");
SuperType supc1 = new SuperType(c1);
SuperType supc2 = new SuperType(c2);
SuperType supc3 = new SuperType(c3);
MPair pair1 = new MPair(c2, supc1, PairOperator.SMALLERDOTWC);
MPair pair2 = new MPair(c3, supc2, PairOperator.SMALLERDOTWC);
MPair pair3 = new MPair(c3, supc1, PairOperator.SMALLERDOTWC);
MPair pair4 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC);
MPair pair5 = new MPair(supc3, supc2, PairOperator.SMALLERDOTWC);
MPair pair6 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC);
MPair pair7 = new MPair(supc1, supc1, PairOperator.SMALLERDOTWC);
System.out.println("------ AdaptSup ------");
System.out.println(rules.adaptSup(pair1));
System.out.println(rules.adaptSup(pair2));
System.out.println(rules.adaptSup(pair3));
System.out.println(rules.adaptSup(pair4));
System.out.println(rules.adaptSup(pair5));
System.out.println(rules.adaptSup(pair6));
System.out.println(rules.adaptSup(pair7));
/*
* Negative Tests
*/
MPair noAdapt1 = new MPair(supc2, supc1, PairOperator.SMALLERDOTWC);
MPair noAdapt2 = new MPair(supc1, c2, PairOperator.SMALLERDOTWC);
MPair noAdapt3 = new MPair(tf.getExtendsType(c1), supc2, PairOperator.SMALLERDOTWC);
MPair noAdapt4 = new MPair(supc3, supc1, PairOperator.SMALLERDOTWC);
MPair noAdapt5 = new MPair(c1, supc2, PairOperator.SMALLERDOT);
Assert.assertFalse(rules.adaptExt(noAdapt1).isPresent());
Assert.assertFalse(rules.adaptExt(noAdapt2).isPresent());
Assert.assertFalse(rules.adaptExt(noAdapt3).isPresent());
Assert.assertFalse(rules.adaptExt(noAdapt4).isPresent());
Assert.assertFalse(rules.adaptExt(noAdapt5).isPresent());
}
}