From 15e4cbc10dbae4f6fd726886ce71c2d879f06f75 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Wed, 20 Sep 2023 22:34:44 +0200 Subject: [PATCH] [Analysis API] implement an API to get a substitution based on an inheritance relationship between classes ^KT-62090 fixed --- .../api/descriptors/KtFe10AnalysisSession.kt | 4 +- .../analysis/api/fir/KtFirAnalysisSession.kt | 2 + .../components/KtFirSubstitutorProvider.kt | 74 ++++++++++++ .../analysis/api/fir/utils/ktSymbolUtils.kt | 1 + ...heritanceTypeSubstitutorTestGenerated.java | 48 ++++++++ ...heritanceTypeSubstitutorTestGenerated.java | 108 ++++++++++++++++++ ...heritanceTypeSubstitutorTestGenerated.java | 48 ++++++++ ...heritanceTypeSubstitutorTestGenerated.java | 108 ++++++++++++++++++ ...actCreateInheritanceTypeSubstitutorTest.kt | 62 ++++++++++ ...heritanceTypeSubstitutorTestGenerated.java | 108 ++++++++++++++++++ .../kotlin/analysis/api/KtAnalysisSession.kt | 6 +- .../api/components/KtSubstitutorProvider.kt | 49 ++++++++ .../createInheritanceTypeSubstitutor/chain.kt | 10 ++ .../chain.result.txt | 3 + .../createInheritanceTypeSubstitutor/cycle.kt | 6 + .../cycle.result.txt | 1 + .../directComplexSubstitution.kt | 8 ++ .../directComplexSubstitution.result.txt | 3 + .../directType.kt | 8 ++ .../directType.result.txt | 3 + .../directTypeParam.kt | 6 + .../directTypeParam.result.txt | 3 + .../errorInUpperBound.kt | 6 + .../errorInUpperBound.result.txt | 3 + .../extraTypeArgument.kt | 6 + .../extraTypeArgument.result.txt | 1 + .../missingTypeArgument.kt | 7 ++ .../missingTypeArgument.result.txt | 1 + .../multipleInheritance.kt | 7 ++ .../multipleInheritance.result.txt | 3 + .../createInheritanceTypeSubstitutor/self.kt | 7 ++ .../self.result.txt | 1 + .../tests/analysis/api/analysisApi.kt | 7 ++ 33 files changed, 716 insertions(+), 2 deletions(-) create mode 100644 analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSubstitutorProvider.kt create mode 100644 analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java create mode 100644 analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java create mode 100644 analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java create mode 100644 analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java create mode 100644 analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/substitutorProvider/AbstractCreateInheritanceTypeSubstitutorTest.kt create mode 100644 analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/substitutorProvider/FirStandaloneNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java create mode 100644 analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSubstitutorProvider.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.result.txt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt create mode 100644 analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.result.txt diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt index 1af03011e4c..3b0999dd9cb 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/KtFe10AnalysisSession.kt @@ -75,8 +75,10 @@ class KtFe10AnalysisSession( override val metadataCalculatorImpl: KtMetadataCalculator get() = throw UnsupportedOperationException() - @Suppress("AnalysisApiMissingLifetimeCheck") + override val substitutorProviderImpl: KtSubstitutorProvider + get() = throw UnsupportedOperationException() + override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession = KtFe10AnalysisSession(originalKtFile.project, elementToReanalyze, token) } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt index 7fb481986af..8966f4189b7 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/KtFirAnalysisSession.kt @@ -133,6 +133,8 @@ private constructor( override val metadataCalculatorImpl: KtMetadataCalculator = KtFirMetadataCalculator(this) + override val substitutorProviderImpl: KtSubstitutorProvider = KtFirSubstitutorProvider(this) + @Suppress("AnalysisApiMissingLifetimeCheck") override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession { check(mode == AnalysisSessionMode.REGULAR) { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSubstitutorProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSubstitutorProvider.kt new file mode 100644 index 00000000000..8d6705ce653 --- /dev/null +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSubstitutorProvider.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2010-2020 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.components.KtSubstitutorProvider +import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession +import org.jetbrains.kotlin.analysis.api.fir.utils.firSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor +import org.jetbrains.kotlin.fir.resolve.substitution.chain +import org.jetbrains.kotlin.fir.scopes.substitutorForSuperType +import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol +import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol +import org.jetbrains.kotlin.fir.types.ConeClassLikeType +import org.jetbrains.kotlin.fir.types.toRegularClassSymbol + +internal class KtFirSubstitutorProvider( + override val analysisSession: KtFirAnalysisSession, +) : KtSubstitutorProvider(), KtFirAnalysisSessionComponent { + override fun createSubstitutor( + subClass: KtClassOrObjectSymbol, + superClass: KtClassOrObjectSymbol, + ): KtSubstitutor? { + if (subClass == superClass) return KtSubstitutor.Empty(token) + + val baseFirSymbol = subClass.firSymbol + val superFirSymbol = superClass.firSymbol + val inheritancePath = collectInheritancePath(baseFirSymbol, superFirSymbol) ?: return null + val substitutors = inheritancePath.map { (type, symbol) -> + type.substitutorForSuperType(rootModuleSession, symbol) + } + return when (substitutors.size) { + 0 -> KtSubstitutor.Empty(token) + else -> { + val chained = substitutors.reduce { left, right -> left.chain(right) } + firSymbolBuilder.typeBuilder.buildSubstitutor(chained) + } + } + } + + + private fun collectInheritancePath( + baseSymbol: FirClassSymbol<*>, + superSymbol: FirClassSymbol<*>, + ): List>? { + val stack = mutableListOf>() + var result: List>? = null + + fun dfs(symbol: FirClassSymbol<*>) { + for (superType in symbol.resolvedSuperTypes) { + if (result != null) { + return + } + if (superType !is ConeClassLikeType) continue + val superClassSymbol = superType.toRegularClassSymbol(rootModuleSession) ?: continue + stack += superType to superClassSymbol + if (superClassSymbol == superSymbol) { + result = stack.toList() + check(stack.removeLast().second == superClassSymbol) + break + } + dfs(superClassSymbol) + check(stack.removeLast().second == superClassSymbol) + } + } + + dfs(baseSymbol) + return result?.reversed() + } + +} \ No newline at end of file diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/ktSymbolUtils.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/ktSymbolUtils.kt index a6075069a7c..0236ebc17c6 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/ktSymbolUtils.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/utils/ktSymbolUtils.kt @@ -34,6 +34,7 @@ internal val KtConstructorSymbol.firSymbol: FirConstructorSymbol get() = (this a internal val KtPropertyAccessorSymbol.firSymbol: FirPropertyAccessorSymbol get() = (this as KtFirSymbol<*>).firSymbol as FirPropertyAccessorSymbol internal val KtClassInitializerSymbol.firSymbol: FirAnonymousInitializerSymbol get() = (this as KtFirSymbol<*>).firSymbol as FirAnonymousInitializerSymbol internal val KtClassLikeSymbol.firSymbol: FirClassLikeSymbol<*> get() = (this as KtFirSymbol<*>).firSymbol as FirClassLikeSymbol<*> +internal val KtClassOrObjectSymbol.firSymbol: FirClassSymbol<*> get() = (this as KtFirSymbol<*>).firSymbol as FirClassSymbol<*> fun FirBasedSymbol<*>.getContainingKtModule(firResolveSession: LLFirResolveSession): KtModule { diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java new file mode 100644 index 00000000000..8c0578f4689 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2023 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.test.cases.generated.cases.components.substitutorProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest; +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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeDependentAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated extends AbstractCreateInheritanceTypeSubstitutorTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.ScriptSource, + AnalysisSessionMode.Dependent, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInCreateInheritanceTypeSubstitutor() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor"), Pattern.compile("^(.+)\\.kts$"), null, true); + } +} diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java new file mode 100644 index 00000000000..4d09e04d93d --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeDependentAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010-2023 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.test.cases.generated.cases.components.substitutorProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest; +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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeDependentAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated extends AbstractCreateInheritanceTypeSubstitutorTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Dependent, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInCreateInheritanceTypeSubstitutor() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("chain.kt") + public void testChain() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt"); + } + + @Test + @TestMetadata("cycle.kt") + public void testCycle() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt"); + } + + @Test + @TestMetadata("directComplexSubstitution.kt") + public void testDirectComplexSubstitution() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt"); + } + + @Test + @TestMetadata("directType.kt") + public void testDirectType() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt"); + } + + @Test + @TestMetadata("directTypeParam.kt") + public void testDirectTypeParam() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt"); + } + + @Test + @TestMetadata("errorInUpperBound.kt") + public void testErrorInUpperBound() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt"); + } + + @Test + @TestMetadata("extraTypeArgument.kt") + public void testExtraTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt"); + } + + @Test + @TestMetadata("missingTypeArgument.kt") + public void testMissingTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt"); + } + + @Test + @TestMetadata("multipleInheritance.kt") + public void testMultipleInheritance() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt"); + } + + @Test + @TestMetadata("self.kt") + public void testSelf() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt"); + } +} diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java new file mode 100644 index 00000000000..69b69228038 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2023 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.test.cases.generated.cases.components.substitutorProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest; +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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeNormalAnalysisScriptSourceModuleCreateInheritanceTypeSubstitutorTestGenerated extends AbstractCreateInheritanceTypeSubstitutorTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.ScriptSource, + AnalysisSessionMode.Normal, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInCreateInheritanceTypeSubstitutor() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor"), Pattern.compile("^(.+)\\.kts$"), null, true); + } +} diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java new file mode 100644 index 00000000000..671231e81ab --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/substitutorProvider/FirIdeNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010-2023 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.test.cases.generated.cases.components.substitutorProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.fir.test.configurators.AnalysisApiFirTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest; +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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated extends AbstractCreateInheritanceTypeSubstitutorTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Normal, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInCreateInheritanceTypeSubstitutor() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("chain.kt") + public void testChain() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt"); + } + + @Test + @TestMetadata("cycle.kt") + public void testCycle() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt"); + } + + @Test + @TestMetadata("directComplexSubstitution.kt") + public void testDirectComplexSubstitution() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt"); + } + + @Test + @TestMetadata("directType.kt") + public void testDirectType() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt"); + } + + @Test + @TestMetadata("directTypeParam.kt") + public void testDirectTypeParam() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt"); + } + + @Test + @TestMetadata("errorInUpperBound.kt") + public void testErrorInUpperBound() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt"); + } + + @Test + @TestMetadata("extraTypeArgument.kt") + public void testExtraTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt"); + } + + @Test + @TestMetadata("missingTypeArgument.kt") + public void testMissingTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt"); + } + + @Test + @TestMetadata("multipleInheritance.kt") + public void testMultipleInheritance() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt"); + } + + @Test + @TestMetadata("self.kt") + public void testSelf() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt"); + } +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/substitutorProvider/AbstractCreateInheritanceTypeSubstitutorTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/substitutorProvider/AbstractCreateInheritanceTypeSubstitutorTest.kt new file mode 100644 index 00000000000..0b41ef22de2 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/substitutorProvider/AbstractCreateInheritanceTypeSubstitutorTest.kt @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2023 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.impl.base.test.cases.components.substitutorProvider + +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.stringRepresentation +import org.jetbrains.kotlin.analysis.api.renderer.types.impl.KtTypeRendererForSource +import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol +import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest +import org.jetbrains.kotlin.analysis.test.framework.services.expressionMarkerProvider +import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint +import org.jetbrains.kotlin.psi.KtClassOrObject +import org.jetbrains.kotlin.test.services.TestModuleStructure +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.assertions +import org.jetbrains.kotlin.types.Variance +import kotlin.collections.single + +abstract class AbstractCreateInheritanceTypeSubstitutorTest : AbstractAnalysisApiBasedTest() { + override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) { + val baseClass = testServices.expressionMarkerProvider + .getElementsOfTypeAtCarets(moduleStructure, testServices, "base") + .single().first + val superClass = testServices.expressionMarkerProvider + .getElementsOfTypeAtCarets(moduleStructure, testServices, "super") + .single().first + + val substitutorRendered = analyseForTest(baseClass) { + val superClassSymbol = superClass.getClassOrObjectSymbol()!! + val substitutor = createInheritanceTypeSubstitutor(baseClass.getClassOrObjectSymbol()!!, superClassSymbol) + prettyPrint { + appendLine("Substitutor: ${stringRepresentation(substitutor)}") + if (substitutor != null) { + val functions = superClassSymbol.getDeclaredMemberScope().getAllSymbols() + .filterIsInstance() + .toList() + if (functions.isNotEmpty()) { + appendLine("Substituted callables:") + withIndent { + for (function in functions) { + val signature = function.substitute(substitutor) + append(signature.callableIdIfNonLocal!!.callableName.asString()) + printCollection(signature.valueParameters, prefix = "(", postfix = ")") { + append(it.returnType.render(typeRenderer, position = Variance.IN_VARIANCE)) + } + append(": ${signature.returnType.render(typeRenderer, position = Variance.OUT_VARIANCE)}") + } + } + } + } + } + } + testServices.assertions.assertEqualsToTestDataFileSibling(substitutorRendered, extension = ".result.txt") + } + + companion object { + private val typeRenderer = KtTypeRendererForSource.WITH_SHORT_NAMES + } +} \ No newline at end of file diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/substitutorProvider/FirStandaloneNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/substitutorProvider/FirStandaloneNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java new file mode 100644 index 00000000000..9e091d26ac6 --- /dev/null +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/substitutorProvider/FirStandaloneNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated.java @@ -0,0 +1,108 @@ +/* + * Copyright 2010-2023 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.standalone.fir.test.cases.generated.cases.components.substitutorProvider; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.util.KtTestUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.kotlin.analysis.api.standalone.fir.test.AnalysisApiFirStandaloneModeTestConfiguratorFactory; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfiguratorFactoryData; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiTestConfigurator; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.TestModuleKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.FrontendKind; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisSessionMode; +import org.jetbrains.kotlin.analysis.test.framework.test.configurators.AnalysisApiMode; +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest; +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 org.jetbrains.kotlin.generators.tests.analysis.api.GenerateAnalysisApiTestsKt}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor") +@TestDataPath("$PROJECT_ROOT") +public class FirStandaloneNormalAnalysisSourceModuleCreateInheritanceTypeSubstitutorTestGenerated extends AbstractCreateInheritanceTypeSubstitutorTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirStandaloneModeTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Normal, + AnalysisApiMode.Standalone + ) + ); + } + + @Test + public void testAllFilesPresentInCreateInheritanceTypeSubstitutor() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("chain.kt") + public void testChain() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt"); + } + + @Test + @TestMetadata("cycle.kt") + public void testCycle() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt"); + } + + @Test + @TestMetadata("directComplexSubstitution.kt") + public void testDirectComplexSubstitution() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt"); + } + + @Test + @TestMetadata("directType.kt") + public void testDirectType() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt"); + } + + @Test + @TestMetadata("directTypeParam.kt") + public void testDirectTypeParam() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt"); + } + + @Test + @TestMetadata("errorInUpperBound.kt") + public void testErrorInUpperBound() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt"); + } + + @Test + @TestMetadata("extraTypeArgument.kt") + public void testExtraTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt"); + } + + @Test + @TestMetadata("missingTypeArgument.kt") + public void testMissingTypeArgument() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt"); + } + + @Test + @TestMetadata("multipleInheritance.kt") + public void testMultipleInheritance() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt"); + } + + @Test + @TestMetadata("self.kt") + public void testSelf() throws Exception { + runTest("analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt"); + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt index f50d801ab07..b4a0be5dbce 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/KtAnalysisSession.kt @@ -68,7 +68,8 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke KtSymbolProviderByJavaPsiMixIn, KtResolveExtensionInfoProviderMixIn, KtCompilerFacilityMixIn, - KtMetadataCalculatorMixIn { + KtMetadataCalculatorMixIn, + KtSubstitutorProviderMixIn { public abstract val useSiteModule: KtModule @@ -194,6 +195,9 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke internal val typesCreator: KtTypeCreator get() = typesCreatorImpl protected abstract val typesCreatorImpl: KtTypeCreator + + internal val substitutorProvider: KtSubstitutorProvider get() = substitutorProviderImpl + protected abstract val substitutorProviderImpl: KtSubstitutorProvider } public fun KtAnalysisSession.getModule(element: PsiElement): KtModule { diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSubstitutorProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSubstitutorProvider.kt new file mode 100644 index 00000000000..e29e700cdae --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSubstitutorProvider.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2023 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.components + +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol +import org.jetbrains.kotlin.analysis.api.types.KtSubstitutor + +public abstract class KtSubstitutorProvider : KtAnalysisSessionComponent() { + public abstract fun createSubstitutor( + subClass: KtClassOrObjectSymbol, + superClass: KtClassOrObjectSymbol, + ): KtSubstitutor? +} + +public interface KtSubstitutorProviderMixIn : KtAnalysisSessionMixIn { + /** + * Creates a [KtSubstitutor] based on the inheritance relationship between [subClass] and [superClass]. + * + * The semantic of resulted [KtSubstitutor] is the substitutor that should be applied to a member of [superClass], + * so it can be called on an instance of [subClass]. + * + * Basically, it's a composition of inheritance-based substitutions for all the inheritance chain. + * + * On the following code: + * ``` + * class A : B + * class B : C + * class C + * ``` + * + * * `createInheritanceTypeSubstitutor(A, B)` returns `KtSubstitutor {T -> String}` + * * `createInheritanceTypeSubstitutor(B, C)` returns `KtSubstitutor {X -> T, Y -> Int}` + * * `createInheritanceTypeSubstitutor(A, C)` returns `KtSubstitutor {X -> T, Y -> Int} andThen KtSubstitutor {T -> String}` + * + * @param subClass the subClass or object symbol. + * @param superClass the super class symbol. + * @return [KtSubstitutor] if [subClass] inherits [superClass] and there are no error types in the inheritance path. Returns `null` otherwise. + */ + public fun createInheritanceTypeSubstitutor( + subClass: KtClassOrObjectSymbol, + superClass: KtClassOrObjectSymbol, + ): KtSubstitutor? = withValidityAssertion { + analysisSession.substitutorProvider.createSubstitutor(subClass, superClass) + } +} diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt new file mode 100644 index 00000000000..589ae5ff009 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.kt @@ -0,0 +1,10 @@ +// WITH_STDLIB + +class AA : BB + +class BB : CC> + +class CC { + fun foo(): kotlin.Triple +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.result.txt new file mode 100644 index 00000000000..118593139b6 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/chain.result.txt @@ -0,0 +1,3 @@ +Substitutor: }> then +Substituted callables: + foo(): Triple> \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt new file mode 100644 index 00000000000..85614733bde --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.kt @@ -0,0 +1,6 @@ +class AA : BB + +class BB : CC> + +class CCC : AA + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.result.txt new file mode 100644 index 00000000000..f7a92a1ee74 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/cycle.result.txt @@ -0,0 +1 @@ +Substitutor: null diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt new file mode 100644 index 00000000000..ad447fd93db --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.kt @@ -0,0 +1,8 @@ +// WITH_STDLIB + +class AA : BB, Map, S> + +class BB { + fun foo(): kotlin.Triple +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.result.txt new file mode 100644 index 00000000000..1c52cc47e1c --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directComplexSubstitution.result.txt @@ -0,0 +1,3 @@ +Substitutor: , R = kotlin/collections/Map, T = S}> +Substituted callables: + foo(): Triple, Map, S> \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt new file mode 100644 index 00000000000..62f2307be40 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.kt @@ -0,0 +1,8 @@ +// WITH_STDLIB + +class AA : BB + +class BB { + fun foo(): List +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.result.txt new file mode 100644 index 00000000000..e5b51410fa6 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directType.result.txt @@ -0,0 +1,3 @@ +Substitutor: +Substituted callables: + foo(): List \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt new file mode 100644 index 00000000000..8cf762103e5 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.kt @@ -0,0 +1,6 @@ +class AA : BB + +class BB { + fun foo(): S +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.result.txt new file mode 100644 index 00000000000..e2e6b6a0fef --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/directTypeParam.result.txt @@ -0,0 +1,3 @@ +Substitutor: +Substituted callables: + foo(): T \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt new file mode 100644 index 00000000000..449b8a8aced --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.kt @@ -0,0 +1,6 @@ +class AA : BB + +class BB { + fun foo(): S +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.result.txt new file mode 100644 index 00000000000..50f2aeb6d9f --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/errorInUpperBound.result.txt @@ -0,0 +1,3 @@ +Substitutor: +Substituted callables: + foo(): Int \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt new file mode 100644 index 00000000000..aed4ff03ee7 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.kt @@ -0,0 +1,6 @@ +class AA : BB + +class BB { + fun foo(): S +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.result.txt new file mode 100644 index 00000000000..f7a92a1ee74 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/extraTypeArgument.result.txt @@ -0,0 +1 @@ +Substitutor: null diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt new file mode 100644 index 00000000000..66aa59faa8b --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.kt @@ -0,0 +1,7 @@ +// WITH_STDLIB +class AA : BB + +class BB { + fun foo(): Triple +} + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.result.txt new file mode 100644 index 00000000000..f7a92a1ee74 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/missingTypeArgument.result.txt @@ -0,0 +1 @@ +Substitutor: null diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt new file mode 100644 index 00000000000..ec6f28d81bc --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.kt @@ -0,0 +1,7 @@ +class AA : BB, BB + +class BB { + fun foo(): Triple +} + + diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.result.txt new file mode 100644 index 00000000000..a0204cf464d --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/multipleInheritance.result.txt @@ -0,0 +1,3 @@ +Substitutor: +Substituted callables: + foo(): Triple \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt new file mode 100644 index 00000000000..e09d01adaac --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.kt @@ -0,0 +1,7 @@ +// WITH_STDLIB + +class AAA : BB + +class BB : CC> { + fun foo(): Triple +} diff --git a/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.result.txt b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.result.txt new file mode 100644 index 00000000000..9c30c8a2973 --- /dev/null +++ b/analysis/analysis-api/testData/components/substitutorProvider/createInheritanceTypeSubstitutor/self.result.txt @@ -0,0 +1 @@ +Substitutor: diff --git a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt index 092f3ead22c..f21875115e7 100644 --- a/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt +++ b/generators/analysis-api-generator/tests/org/jetbrains/kotlin/generators/tests/analysis/api/analysisApi.kt @@ -36,6 +36,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.signatu import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.signatureSubstitution.AbstractAnalysisApiSymbolAsSignatureTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.signatureSubstitution.AbstractAnalysisApiSymbolSubstitutionTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.smartCastProvider.AbstractHLSmartCastInfoTest +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substitutorProvider.AbstractCreateInheritanceTypeSubstitutorTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.substututorFactory.AbstractSubstitutorBuilderTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.symbolDeclarationOverridesProvider.AbstractIsSubclassOfTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.symbolDeclarationOverridesProvider.AbstractOverriddenDeclarationProviderTest @@ -438,6 +439,12 @@ private fun AnalysisApiTestGroup.generateAnalysisApiComponentsTests() { } } + component("substitutorProvider", filter = frontendIs(FrontendKind.Fir)) { + test(AbstractCreateInheritanceTypeSubstitutorTest::class) { + model(it, "createInheritanceTypeSubstitutor") + } + } + component("referenceResolveProvider") { test(AbstractIsImplicitCompanionReferenceTest::class) {