Utilities for collecting all supertypes (with proper substitution)

This commit is contained in:
Andrey Breslav
2011-04-21 15:02:11 +04:00
parent 391f8e99c6
commit aedabc48e9
3 changed files with 57 additions and 2 deletions
@@ -93,13 +93,13 @@ public class JetTypeChecker {
Map<TypeConstructor, Set<JetType>> commonSupertypes = computeCommonRawSupertypes(typeSet);
while (commonSupertypes.size() > 1) {
HashSet<JetType> merge = new HashSet<JetType>();
Set<JetType> merge = new HashSet<JetType>();
for (Set<JetType> supertypes : commonSupertypes.values()) {
merge.addAll(supertypes);
}
commonSupertypes = computeCommonRawSupertypes(merge);
}
assert !commonSupertypes.isEmpty() : commonSupertypes;
assert !commonSupertypes.isEmpty() : types;
Map.Entry<TypeConstructor, Set<JetType>> entry = commonSupertypes.entrySet().iterator().next();
JetType result = computeSupertypeProjections(entry.getKey(), entry.getValue());
@@ -413,4 +413,5 @@ public class JetTypeChecker {
}
return true;
}
}
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.types;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.resolve.JetScope;
@@ -187,4 +189,35 @@ public class TypeUtils {
public static TypeProjection makeStarProjection(@NotNull TypeParameterDescriptor parameterDescriptor) {
return new TypeProjection(Variance.OUT_VARIANCE, parameterDescriptor.getBoundsAsType());
}
private static void collectImmediateSupertypes(@NotNull JetType type, @NotNull Collection<JetType> result) {
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
for (JetType supertype : type.getConstructor().getSupertypes()) {
result.add(substitutor.substitute(supertype, Variance.INVARIANT));
}
}
@NotNull
public static List<JetType> getImmediateSupertypes(@NotNull JetType type) {
List<JetType> result = Lists.newArrayList();
collectImmediateSupertypes(type, result);
return result;
}
private static void collectAllSupertypes(@NotNull JetType type, @NotNull Set<JetType> result) {
List<JetType> immediateSupertypes = getImmediateSupertypes(type);
result.addAll(immediateSupertypes);
for (JetType supertype : immediateSupertypes) {
collectAllSupertypes(supertype, result);
}
}
@NotNull
public static Set<JetType> getAllSupertypes(@NotNull JetType type) {
Set<JetType> result = Sets.newLinkedHashSet();
collectAllSupertypes(type, result);
return result;
}
}
@@ -1,5 +1,6 @@
package org.jetbrains.jet.types;
import com.google.common.collect.Sets;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.project.Project;
@@ -419,6 +420,24 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
assertType("new WithPredicate()?p", "WithPredicate?");
}
public void testSupertypes() throws Exception {
assertSupertypes("DDerived1_T<Int>", "Derived_T<Int>", "Base_T<Int>", "Any");
assertSupertypes("DDerived2_T<Int>", "Derived_T<Int>", "Base_T<Int>", "Any");
assertSupertypes("Derived1_inT<Int>", "Derived_T<Int>", "Base_T<Int>", "Any", "Base_inT<Int>");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void assertSupertypes(String typeStr, String... supertypeStrs) {
Set<JetType> allSupertypes = TypeUtils.getAllSupertypes(makeType(classDefinitions.BASIC_SCOPE, typeStr));
Set<JetType> expected = Sets.newHashSet();
for (String supertypeStr : supertypeStrs) {
JetType supertype = makeType(classDefinitions.BASIC_SCOPE, supertypeStr);
expected.add(supertype);
}
assertEquals(expected, allSupertypes);
}
private void assertSubtype(String type1, String type2) {
assertSubtypingRelation(type1, type2, true);
}
@@ -509,8 +528,10 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
"open class Derived_T<T> : Base_T<T>",
"open class DDerived_T<T> : Derived_T<T>",
"open class DDerived1_T<T> : Derived_T<T>",
"open class DDerived2_T<T> : Derived_T<T>, Base_T<T>",
"open class Base_inT<in T>",
"open class Derived_inT<in T> : Base_inT<T>",
"open class Derived1_inT<in T> : Base_inT<T>, Derived_T<T>",
"open class Base_outT<out T>",
"open class Derived_outT<out T> : Base_outT<T>",
"class Properties { val p : Int }",