Skip to content

Commit

Permalink
Merge pull request #242 from usethesource/fix-for-rascal-issue-1812
Browse files Browse the repository at this point in the history
added proper alias checks to the match implementations of parametrized types
jurgenvinju authored Feb 13, 2024
2 parents dada98d + ad23ea6 commit 6c9ac23
Showing 6 changed files with 25 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -428,7 +428,7 @@ public boolean match(Type matched, Map<Type, Type> bindings) throws FactTypeUseE
return false;
}

if (matched.isAbstractData() || matched.isBottom()) {
if (matched.isAbstractData() || (matched.isAliased() && matched.getAliased().isAbstractData()) || matched.isBottom()) {
return getTypeParameters().match(matched.getTypeParameters(), bindings);
}

5 changes: 2 additions & 3 deletions src/main/java/io/usethesource/vallang/type/ListType.java
Original file line number Diff line number Diff line change
@@ -286,12 +286,11 @@ protected Type glbWithList(Type type) {
}

@Override
public boolean match(Type matched, Map<Type, Type> bindings)
throws FactTypeUseException {
public boolean match(Type matched, Map<Type, Type> bindings) throws FactTypeUseException {
if (!super.match(matched, bindings)) {
return false;
}
else if (matched.isList() || matched.isBottom()) {
else if (matched.isList() || (matched.isAliased() && matched.getAliased().isList()) || matched.isBottom()) {
return getElementType().match(matched.getElementType(), bindings);
}

2 changes: 1 addition & 1 deletion src/main/java/io/usethesource/vallang/type/MapType.java
Original file line number Diff line number Diff line change
@@ -244,7 +244,7 @@ public boolean match(Type matched, Map<Type, Type> bindings)throws FactTypeUseEx
return false;
}

if (matched.isMap() || matched.isBottom()) {
if (matched.isMap() || (matched.isAliased() && matched.getAliased().isMap()) || matched.isBottom()) {
return getKeyType().match(matched.getKeyType(), bindings)
&& getValueType().match(matched.getValueType(), bindings);
}
2 changes: 1 addition & 1 deletion src/main/java/io/usethesource/vallang/type/SetType.java
Original file line number Diff line number Diff line change
@@ -289,7 +289,7 @@ public boolean match(Type matched, Map<Type, Type> bindings) throws FactTypeUseE
if (!super.match(matched, bindings)) {
return false;
}
else if (matched.isSet() || matched.isBottom()) {
else if (matched.isSet() || (matched.isAliased() && matched.getAliased().isSet()) || matched.isBottom()) {
return getElementType().match(matched.getElementType(), bindings);
}

2 changes: 1 addition & 1 deletion src/main/java/io/usethesource/vallang/type/TupleType.java
Original file line number Diff line number Diff line change
@@ -419,7 +419,7 @@ public boolean match(Type matched, Map<Type, Type> bindings)
return false;
}

if (matched.isTuple() || matched.isBottom()) {
if (matched.isTuple() || (matched.isAliased() && matched.getAliased().isTuple()) || matched.isBottom()) {
for (int i = getArity() - 1; i >= 0; i--) {
if (!getFieldType(i).match(matched.getFieldType(i), bindings)) {
return false;
23 changes: 19 additions & 4 deletions src/test/java/io/usethesource/vallang/specification/TypeTest.java
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@@ -168,21 +169,35 @@ public void testParameterizedAlias(TypeFactory ft, TypeStore ts) {
Type T = ft.parameterType("T");
// DiGraph[&T] = rel[&T from ,&T to]
@SuppressWarnings("deprecation")
Type DiGraph = ft.aliasType(ts, "DiGraph", ft.relType(T, "from", T, "to"), T);
Type relType = ft.relType(T, "from", T, "to");
Type DiGraph = ft.aliasType(ts, "DiGraph", relType, T);
Type IntInstance = ft.relType(ft.integerType(), ft.integerType());
Type ValueInstance = ft.relType(ft.valueType(), ft.valueType());

// after instantiation rel[int,int] is a sub-type of rel[&T, &T]
// after instantiation rel[int,int] is a sub-type of rel[&T, &T], and vice versa, and also reflectively
assertTrue(IntInstance.isSubtypeOf(DiGraph));

assertTrue(DiGraph.isSubtypeOf(IntInstance));
assertTrue(DiGraph.isSubtypeOf(DiGraph));

// vice versa: the aliased type can be matched using the alias type
Map<Type, Type> bindings = new HashMap<>();
assertTrue(DiGraph.match(IntInstance, bindings));
assertTrue(bindings.get(T) == ft.integerType());

// and the alias type can be matched by the aliased type (not we reuse the bindings from the previous assert)
Type instanceDiGraph = DiGraph.instantiate(bindings);
bindings = new HashMap<>(); // reset the bindings
assertTrue(relType.match(instanceDiGraph, bindings));
assertTrue(bindings.get(T) == ft.integerType());

// before instantiation, the parameterized type rel[&T, &T]
// could be instantiated later by rel[int, int]
assertTrue(DiGraph.isSubtypeOf(IntInstance));

// the generic graph is also always a sub-type of the most general instantiation
assertTrue(DiGraph.isSubtypeOf(ValueInstance));

Map<Type, Type> bindings = new HashMap<>();
bindings = new HashMap<>();
DiGraph.match(IntInstance, bindings);
assertTrue(bindings.get(T) == ft.integerType());

0 comments on commit 6c9ac23

Please sign in to comment.