diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt index cc5e3f2b680..7d7dd2376cd 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirTypeProvider.kt @@ -20,12 +20,24 @@ import org.jetbrains.kotlin.analysis.api.withValidityAssertion import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LowLevelFirApiFacadeForResolveOnAir.getTowerContextProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.api.getOrBuildFir import org.jetbrains.kotlin.analysis.low.level.api.fir.api.throwUnexpectedFirElementError +import org.jetbrains.kotlin.fir.FirRenderer import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker import org.jetbrains.kotlin.fir.analysis.checkers.ConeTypeCompatibilityChecker.isCompatible +import org.jetbrains.kotlin.fir.analysis.checkers.fullyExpandedClass +import org.jetbrains.kotlin.fir.analysis.checkers.typeParameterSymbols import org.jetbrains.kotlin.fir.declarations.FirResolvePhase +import org.jetbrains.kotlin.fir.declarations.utils.superConeTypes import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall import org.jetbrains.kotlin.fir.expressions.FirGetClassCall +import org.jetbrains.kotlin.fir.render +import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents +import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap +import org.jetbrains.kotlin.fir.resolve.toSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousObjectSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirTypeParameterSymbol import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.ConeClassLikeTypeImpl @@ -34,6 +46,8 @@ import org.jetbrains.kotlin.name.StandardClassIds import org.jetbrains.kotlin.psi.KtDoubleColonExpression import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtTypeReference +import org.jetbrains.kotlin.types.TypeApproximatorConfiguration +import org.jetbrains.kotlin.types.model.CaptureStatus internal class KtFirTypeProvider( override val analysisSession: KtFirAnalysisSession, @@ -110,5 +124,68 @@ internal class KtFirTypeProvider( return analysisSession.firResolveState.getTowerContextProvider() .getClosestAvailableParentContext(position)?.implicitReceiverStack?.map { it.type.asKtType() } ?: emptyList() } + + override fun getDirectSuperTypes(type: KtType, shouldApproximate: Boolean): List { + require(type is KtFirType) + return type.coneType.getDirectSuperTypes(shouldApproximate).mapTo(mutableListOf()) { it.asKtType() } + } + + private fun ConeKotlinType.getDirectSuperTypes(shouldApproximate: Boolean): Sequence { + return when (this) { + // We also need to collect those on `upperBound` due to nullability. + is ConeFlexibleType -> lowerBound.getDirectSuperTypes(shouldApproximate) + upperBound.getDirectSuperTypes(shouldApproximate) + is ConeDefinitelyNotNullType -> original.getDirectSuperTypes(shouldApproximate).map { ConeDefinitelyNotNullType(it) } + is ConeIntersectionType -> intersectedTypes.asSequence().flatMap { it.getDirectSuperTypes(shouldApproximate) } + is ConeClassErrorType -> emptySequence() + is ConeLookupTagBasedType -> getSubstitutedSuperTypes(shouldApproximate) + else -> emptySequence() + }.distinct() + } + + private fun ConeLookupTagBasedType.getSubstitutedSuperTypes(shouldApproximate: Boolean): Sequence { + val session = analysisSession.firResolveState.rootModuleSession + val symbol = lookupTag.toSymbol(session) + val superTypes = when (symbol) { + is FirAnonymousObjectSymbol -> symbol.superConeTypes + is FirRegularClassSymbol -> symbol.superConeTypes + is FirTypeAliasSymbol -> symbol.fullyExpandedClass(session)?.superConeTypes ?: return emptySequence() + is FirTypeParameterSymbol -> symbol.resolvedBounds.map { it.type } + else -> return emptySequence() + } + + val typeParameterSymbols = symbol.typeParameterSymbols ?: return superTypes.asSequence() + val argumentTypes = (session.typeContext.captureArguments(this, CaptureStatus.FROM_EXPRESSION)?.toList() + ?: this.typeArguments.mapNotNull { it.type }) + + require(typeParameterSymbols.size == argumentTypes.size) { + "'${symbol.fir.render(FirRenderer.RenderMode.NoBodies)}' expects '${typeParameterSymbols.size}' type arguments " + + "but type '${this.render()}' has ${argumentTypes.size} type arguments." + } + + val substitutor = substitutorByMap(typeParameterSymbols.zip(argumentTypes).toMap(), session) + return superTypes.asSequence().map { + val type = substitutor.substituteOrSelf(it) + if (shouldApproximate) { + session.inferenceComponents.approximator.approximateToSuperType( + type, + TypeApproximatorConfiguration.FinalApproximationAfterResolutionAndInference + ) ?: type + } else { + type + }.withNullability(nullability, session.typeContext) + } + } + + override fun getAllSuperTypes(type: KtType, shouldApproximate: Boolean): List { + require(type is KtFirType) + val queue = type.coneType.getDirectSuperTypes(shouldApproximate).toCollection(ArrayDeque()) + return buildSet { + while (queue.isNotEmpty()) { + val current = queue.removeFirst() + if (!add(current)) continue + queue.addAll(current.getDirectSuperTypes(shouldApproximate)) + } + }.map { it.asKtType() } + } } diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractGetSuperTypesTest.kt b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractGetSuperTypesTest.kt new file mode 100644 index 00000000000..f48bffd1225 --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/AbstractGetSuperTypesTest.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.components + +import org.jetbrains.kotlin.analysis.api.analyse +import org.jetbrains.kotlin.analysis.api.fir.executeOnPooledThreadInReadAction +import org.jetbrains.kotlin.analysis.api.fir.test.framework.AbstractHLApiSingleFileTest +import org.jetbrains.kotlin.analysis.api.types.KtType +import org.jetbrains.kotlin.analysis.low.level.api.fir.test.base.expressionMarkerProvider +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.assertions + +abstract class AbstractGetSuperTypesTest : AbstractHLApiSingleFileTest() { + override fun doTestByFileStructure(ktFile: KtFile, module: TestModule, testServices: TestServices) { + val expression = testServices.expressionMarkerProvider.getSelectedElement(ktFile) + + val actual = executeOnPooledThreadInReadAction { + analyse(expression) { + val expectedType = expression.getExpectedType() ?: error("expect to get type of expression '${expression.text}'") + val directSuperTypes = expectedType.getDirectSuperTypes() + val approximatedDirectSuperTypes = expectedType.getDirectSuperTypes(shouldApproximate = true) + val allSuperTypes = expectedType.getAllSuperTypes() + val approximatedAllSuperTypes = expectedType.getAllSuperTypes(shouldApproximate = true) + + buildString { + fun List.print(name: String) { + appendLine(name) + for (type in this) { + appendLine(type.render()) + } + appendLine() + } + directSuperTypes.print("[direct super types]") + approximatedDirectSuperTypes.print("[approximated direct super types]") + allSuperTypes.print("[all super types]") + approximatedAllSuperTypes.print("[approximated all super types]") + } + } + } + testServices.assertions.assertEqualsToFile(testDataFileSibling(".txt"), actual) + } +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/GetSuperTypesTestGenerated.java b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/GetSuperTypesTestGenerated.java new file mode 100644 index 00000000000..b730437af70 --- /dev/null +++ b/analysis/analysis-api-fir/tests/org/jetbrains/kotlin/analysis/api/fir/components/GetSuperTypesTestGenerated.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.analysis.api.fir.components; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/getSuperTypes") +@TestDataPath("$PROJECT_ROOT") +public class GetSuperTypesTestGenerated extends AbstractGetSuperTypesTest { + @Test + public void testAllFilesPresentInGetSuperTypes() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/getSuperTypes"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("anonymousObject.kt") + public void testAnonymousObject() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.kt"); + } + + @Test + @TestMetadata("any.kt") + public void testAny() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/any.kt"); + } + + @Test + @TestMetadata("contravariant.kt") + public void testContravariant() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/contravariant.kt"); + } + + @Test + @TestMetadata("covariant.kt") + public void testCovariant() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/covariant.kt"); + } + + @Test + @TestMetadata("errorType.kt") + public void testErrorType() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/errorType.kt"); + } + + @Test + @TestMetadata("flexibleType.kt") + public void testFlexibleType() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/flexibleType.kt"); + } + + @Test + @TestMetadata("int.kt") + public void testInt() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/int.kt"); + } + + @Test + @TestMetadata("invariant.kt") + public void testInvariant() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/invariant.kt"); + } + + @Test + @TestMetadata("recursiveTypeParameter.kt") + public void testRecursiveTypeParameter() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.kt"); + } + + @Test + @TestMetadata("regularClass.kt") + public void testRegularClass() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/regularClass.kt"); + } + + @Test + @TestMetadata("regularClassWithBounds.kt") + public void testRegularClassWithBounds() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.kt"); + } + + @Test + @TestMetadata("star.kt") + public void testStar() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/star.kt"); + } + + @Test + @TestMetadata("string.kt") + public void testString() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/string.kt"); + } + + @Test + @TestMetadata("typeParameter.kt") + public void testTypeParameter() throws Exception { + runTest("analysis/analysis-api/testData/components/getSuperTypes/typeParameter.kt"); + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt index eec8c61a8b2..963754c10b0 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtTypeProvider.kt @@ -32,6 +32,11 @@ public abstract class KtTypeProvider : KtAnalysisSessionComponent() { public abstract fun haveCommonSubtype(a: KtType, b: KtType): Boolean public abstract fun getImplicitReceiverTypesAtPosition(position: KtElement): List + + public abstract fun getDirectSuperTypes(type: KtType, shouldApproximate: Boolean): List + + public abstract fun getAllSuperTypes(type: KtType, shouldApproximate: Boolean): List + } public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { @@ -91,6 +96,28 @@ public interface KtTypeProviderMixIn : KtAnalysisSessionMixIn { */ public fun getImplicitReceiverTypesAtPosition(position: KtElement): List = analysisSession.typeProvider.getImplicitReceiverTypesAtPosition(position) + + /** + * Gets the direct super types of the given type. For example, given `MutableList`, this returns `List` and + * `MutableCollection`. + * + * Note that for flexible types, both direct super types of the upper and lower bounds are returned. If that's not desirable, please + * first call [KtFlexibleType.upperBound] or [KtFlexibleType.lowerBound] and then call this method. + * + * @param shouldApproximate whether to approximate non-denotable types. For example, super type of `List` is + * `Collection`. With approximation set to true, `Collection` is returned instead. + */ + public fun KtType.getDirectSuperTypes(shouldApproximate: Boolean = false): List = + analysisSession.typeProvider.getDirectSuperTypes(this, shouldApproximate) + + /** + * Gets all the super types of the given type. The returned result is ordered by a BFS traversal of the class hierarchy, without any + * duplicates. + * + * @param shouldApproximate see [getDirectSuperTypes] + */ + public fun KtType.getAllSuperTypes(shouldApproximate: Boolean = false): List = + analysisSession.typeProvider.getAllSuperTypes(this, shouldApproximate) } @Suppress("PropertyName") diff --git a/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.kt b/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.kt new file mode 100644 index 00000000000..52b691d2060 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.kt @@ -0,0 +1,4 @@ +interface A +interface B +val o = object: A, B {} +val o2 = o \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.txt b/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.txt new file mode 100644 index 00000000000..cb0228a16ce --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/anonymousObject.txt @@ -0,0 +1,17 @@ +[direct super types] +A +B + +[approximated direct super types] +A +B + +[all super types] +A +B +kotlin.Any + +[approximated all super types] +A +B +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/any.kt b/analysis/analysis-api/testData/components/getSuperTypes/any.kt new file mode 100644 index 00000000000..8555bd2959f --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/any.kt @@ -0,0 +1 @@ +val a = Any() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/any.txt b/analysis/analysis-api/testData/components/getSuperTypes/any.txt new file mode 100644 index 00000000000..32a44b90d27 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/any.txt @@ -0,0 +1,7 @@ +[direct super types] + +[approximated direct super types] + +[all super types] + +[approximated all super types] diff --git a/analysis/analysis-api/testData/components/getSuperTypes/contravariant.kt b/analysis/analysis-api/testData/components/getSuperTypes/contravariant.kt new file mode 100644 index 00000000000..74286d62fcb --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/contravariant.kt @@ -0,0 +1,3 @@ +val s = get() + +fun get() : MutableList \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/contravariant.txt b/analysis/analysis-api/testData/components/getSuperTypes/contravariant.txt new file mode 100644 index 00000000000..03d38bb288a --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/contravariant.txt @@ -0,0 +1,23 @@ +[direct super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> + +[approximated direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection + +[all super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> +kotlin.collections.Collection> +kotlin.collections.MutableIterable> +kotlin.collections.Iterable> +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/covariant.kt b/analysis/analysis-api/testData/components/getSuperTypes/covariant.kt new file mode 100644 index 00000000000..09b4a6c5c75 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/covariant.kt @@ -0,0 +1,3 @@ +val s = get() + +fun get() : MutableList \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/covariant.txt b/analysis/analysis-api/testData/components/getSuperTypes/covariant.txt new file mode 100644 index 00000000000..43ae2145549 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/covariant.txt @@ -0,0 +1,23 @@ +[direct super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> + +[approximated direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection + +[all super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> +kotlin.collections.Collection> +kotlin.collections.MutableIterable> +kotlin.collections.Iterable> +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/errorType.kt b/analysis/analysis-api/testData/components/getSuperTypes/errorType.kt new file mode 100644 index 00000000000..2ee8ae0d1df --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/errorType.kt @@ -0,0 +1,2 @@ +val i: UnresolvedType? = null +val j = i \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/errorType.txt b/analysis/analysis-api/testData/components/getSuperTypes/errorType.txt new file mode 100644 index 00000000000..32a44b90d27 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/errorType.txt @@ -0,0 +1,7 @@ +[direct super types] + +[approximated direct super types] + +[all super types] + +[approximated all super types] diff --git a/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.kt b/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.kt new file mode 100644 index 00000000000..2d10c701b10 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.kt @@ -0,0 +1,12 @@ +// FILE: Java.java +import java.util.List + +class Java { + public static List getNames() { + throw Exception() + } +} + +// FILE: test.kt + +val i = Java.getNames() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.txt b/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.txt new file mode 100644 index 00000000000..2f9651da9da --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/flexibleType.txt @@ -0,0 +1,32 @@ +[direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection? + +[approximated direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection? + +[all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection? +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable? +kotlin.collections.Iterable +kotlin.Any? +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection? +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable? +kotlin.collections.Iterable +kotlin.Any? +kotlin.Any + diff --git a/analysis/analysis-api/testData/components/getSuperTypes/int.kt b/analysis/analysis-api/testData/components/getSuperTypes/int.kt new file mode 100644 index 00000000000..02175a0bd12 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/int.kt @@ -0,0 +1 @@ +val i = 1 \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/int.txt b/analysis/analysis-api/testData/components/getSuperTypes/int.txt new file mode 100644 index 00000000000..693fa648fd1 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/int.txt @@ -0,0 +1,21 @@ +[direct super types] +kotlin.Number +kotlin.Comparable +java.io.Serializable + +[approximated direct super types] +kotlin.Number +kotlin.Comparable +java.io.Serializable + +[all super types] +kotlin.Number +kotlin.Comparable +java.io.Serializable +kotlin.Any + +[approximated all super types] +kotlin.Number +kotlin.Comparable +java.io.Serializable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/invariant.kt b/analysis/analysis-api/testData/components/getSuperTypes/invariant.kt new file mode 100644 index 00000000000..63fdea49425 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/invariant.kt @@ -0,0 +1,3 @@ +val s = get() + +fun get() : MutableList \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/invariant.txt b/analysis/analysis-api/testData/components/getSuperTypes/invariant.txt new file mode 100644 index 00000000000..0b0e6e31a46 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/invariant.txt @@ -0,0 +1,23 @@ +[direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection + +[approximated direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection + +[all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.kt b/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.kt new file mode 100644 index 00000000000..ff6cb850d71 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.kt @@ -0,0 +1,3 @@ +class Foo>(t: T) { + val t2 = t +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.txt b/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.txt new file mode 100644 index 00000000000..d4ac9d936c2 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/recursiveTypeParameter.txt @@ -0,0 +1,13 @@ +[direct super types] +Foo + +[approximated direct super types] +Foo + +[all super types] +Foo +kotlin.Any + +[approximated all super types] +Foo +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/regularClass.kt b/analysis/analysis-api/testData/components/getSuperTypes/regularClass.kt new file mode 100644 index 00000000000..f549026e24f --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/regularClass.kt @@ -0,0 +1,3 @@ +class A + +val a = A() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/regularClass.txt b/analysis/analysis-api/testData/components/getSuperTypes/regularClass.txt new file mode 100644 index 00000000000..f2758a3057c --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/regularClass.txt @@ -0,0 +1,11 @@ +[direct super types] +kotlin.Any + +[approximated direct super types] +kotlin.Any + +[all super types] +kotlin.Any + +[approximated all super types] +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.kt b/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.kt new file mode 100644 index 00000000000..b2a8ba816b4 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.kt @@ -0,0 +1,5 @@ +interface I +open class A +class B: A(), I + +val b = B() \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.txt b/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.txt new file mode 100644 index 00000000000..8e5be2eff27 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/regularClassWithBounds.txt @@ -0,0 +1,17 @@ +[direct super types] +A +I + +[approximated direct super types] +A +I + +[all super types] +A +I +kotlin.Any + +[approximated all super types] +A +I +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/star.kt b/analysis/analysis-api/testData/components/getSuperTypes/star.kt new file mode 100644 index 00000000000..13011789076 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/star.kt @@ -0,0 +1,3 @@ +val s = get() + +fun get() : MutableList<*> \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/star.txt b/analysis/analysis-api/testData/components/getSuperTypes/star.txt new file mode 100644 index 00000000000..2f68e17165a --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/star.txt @@ -0,0 +1,23 @@ +[direct super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> + +[approximated direct super types] +kotlin.collections.List +kotlin.collections.MutableCollection + +[all super types] +kotlin.collections.List> +kotlin.collections.MutableCollection> +kotlin.collections.Collection> +kotlin.collections.MutableIterable> +kotlin.collections.Iterable> +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.MutableCollection +kotlin.collections.Collection +kotlin.collections.MutableIterable +kotlin.collections.Iterable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/string.kt b/analysis/analysis-api/testData/components/getSuperTypes/string.kt new file mode 100644 index 00000000000..45def69c4d7 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/string.kt @@ -0,0 +1 @@ +val s = "" \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/string.txt b/analysis/analysis-api/testData/components/getSuperTypes/string.txt new file mode 100644 index 00000000000..7413407ab90 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/string.txt @@ -0,0 +1,21 @@ +[direct super types] +kotlin.Comparable +kotlin.CharSequence +java.io.Serializable + +[approximated direct super types] +kotlin.Comparable +kotlin.CharSequence +java.io.Serializable + +[all super types] +kotlin.Comparable +kotlin.CharSequence +java.io.Serializable +kotlin.Any + +[approximated all super types] +kotlin.Comparable +kotlin.CharSequence +java.io.Serializable +kotlin.Any diff --git a/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.kt b/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.kt new file mode 100644 index 00000000000..75de952ff63 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.kt @@ -0,0 +1,3 @@ +class Foo>(t: T) { + val t2 = t +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.txt b/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.txt new file mode 100644 index 00000000000..ec30d43bf00 --- /dev/null +++ b/analysis/analysis-api/testData/components/getSuperTypes/typeParameter.txt @@ -0,0 +1,17 @@ +[direct super types] +kotlin.collections.List + +[approximated direct super types] +kotlin.collections.List + +[all super types] +kotlin.collections.List +kotlin.collections.Collection +kotlin.collections.Iterable +kotlin.Any + +[approximated all super types] +kotlin.collections.List +kotlin.collections.Collection +kotlin.collections.Iterable +kotlin.Any diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt index ce326fbf93f..0cf9dd8f9b1 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/types/TypeUtils.kt @@ -392,7 +392,7 @@ fun ConeTypeContext.captureFromArgumentsInternal(type: ConeKotlinType, status: C } } -private fun ConeTypeContext.captureArguments(type: ConeKotlinType, status: CaptureStatus): Array? { +fun ConeTypeContext.captureArguments(type: ConeKotlinType, status: CaptureStatus): Array? { val argumentsCount = type.typeArguments.size if (argumentsCount == 0) return null diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateTests.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateTests.kt index d5e7789a8f0..06b7d3f6a05 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateTests.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/GenerateTests.kt @@ -88,6 +88,10 @@ fun main(args: Array) { testClass { model("components/hasCommonSubtype") } + + testClass { + model("components/getSuperTypes") + } } testGroup("analysis/low-level-api-fir/tests", "compiler/fir/raw-fir/psi2fir/testData") {