Utilities for collecting all supertypes (with proper substitution)
This commit is contained in:
@@ -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 }",
|
||||
|
||||
Reference in New Issue
Block a user