diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java index 4c944b8afe6..30c82645c95 100644 --- a/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java +++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeChecker.java @@ -93,13 +93,13 @@ public class JetTypeChecker { Map> commonSupertypes = computeCommonRawSupertypes(typeSet); while (commonSupertypes.size() > 1) { - HashSet merge = new HashSet(); + Set merge = new HashSet(); for (Set supertypes : commonSupertypes.values()) { merge.addAll(supertypes); } commonSupertypes = computeCommonRawSupertypes(merge); } - assert !commonSupertypes.isEmpty() : commonSupertypes; + assert !commonSupertypes.isEmpty() : types; Map.Entry> entry = commonSupertypes.entrySet().iterator().next(); JetType result = computeSupertypeProjections(entry.getKey(), entry.getValue()); @@ -413,4 +413,5 @@ public class JetTypeChecker { } return true; } + } \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java index 963c7757422..5066648eea5 100644 --- a/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/idea/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -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 result) { + TypeSubstitutor substitutor = TypeSubstitutor.create(type); + for (JetType supertype : type.getConstructor().getSupertypes()) { + result.add(substitutor.substitute(supertype, Variance.INVARIANT)); + } + } + + @NotNull + public static List getImmediateSupertypes(@NotNull JetType type) { + List result = Lists.newArrayList(); + collectImmediateSupertypes(type, result); + return result; + } + + private static void collectAllSupertypes(@NotNull JetType type, @NotNull Set result) { + List immediateSupertypes = getImmediateSupertypes(type); + result.addAll(immediateSupertypes); + for (JetType supertype : immediateSupertypes) { + collectAllSupertypes(supertype, result); + } + } + + @NotNull + public static Set getAllSupertypes(@NotNull JetType type) { + Set result = Sets.newLinkedHashSet(); + collectAllSupertypes(type, result); + return result; + } + + } diff --git a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java index 7eb350ed4af..bffb951936a 100644 --- a/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java +++ b/idea/tests/org/jetbrains/jet/types/JetTypeCheckerTest.java @@ -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", "Derived_T", "Base_T", "Any"); + assertSupertypes("DDerived2_T", "Derived_T", "Base_T", "Any"); + assertSupertypes("Derived1_inT", "Derived_T", "Base_T", "Any", "Base_inT"); + } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + private void assertSupertypes(String typeStr, String... supertypeStrs) { + Set allSupertypes = TypeUtils.getAllSupertypes(makeType(classDefinitions.BASIC_SCOPE, typeStr)); + Set 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 : Base_T", "open class DDerived_T : Derived_T", "open class DDerived1_T : Derived_T", + "open class DDerived2_T : Derived_T, Base_T", "open class Base_inT", "open class Derived_inT : Base_inT", + "open class Derived1_inT : Base_inT, Derived_T", "open class Base_outT", "open class Derived_outT : Base_outT", "class Properties { val p : Int }",