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 902a0b47eb6..b87f81378a4 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 @@ -69,7 +69,7 @@ class KtFe10AnalysisSession( override val scopeSubstitutionImpl: KtScopeSubstitution = KtFe10ScopeSubstitution(this) override val substitutorFactoryImpl: KtSubstitutorFactory = KtFe10SubstitutorFactory(this) override val symbolProviderByJavaPsiImpl: KtSymbolProviderByJavaPsi = KtFe10SymbolProviderByJavaPsi(this) - override val resolveExtensionProviderImpl: KtSymbolFromResolveExtensionProvider = KtFe10SymbolFromResolveExtensionProvider(this) + override val resolveExtensionInfoProviderImpl: KtResolveExtensionInfoProvider = KtFe10ResolveExtensionInfoProvider(this) override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession = withValidityAssertion { diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFirSymbolFromResolveExtensionProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ResolveExtensionInfoProvider.kt similarity index 60% rename from analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFirSymbolFromResolveExtensionProvider.kt rename to analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ResolveExtensionInfoProvider.kt index 97d103f5b1d..0f000e77af9 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFirSymbolFromResolveExtensionProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ResolveExtensionInfoProvider.kt @@ -5,21 +5,28 @@ package org.jetbrains.kotlin.analysis.api.descriptors.components -import org.jetbrains.kotlin.analysis.api.components.KtSymbolFromResolveExtensionProvider +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.components.KtResolveExtensionInfoProvider import org.jetbrains.kotlin.analysis.api.descriptors.KtFe10AnalysisSession import org.jetbrains.kotlin.analysis.api.descriptors.components.base.Fe10KtAnalysisSessionComponent import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtEmptyScope import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.scopes.KtScope +import org.jetbrains.kotlin.psi.KtElement -internal class KtFe10SymbolFromResolveExtensionProvider( +// Resolve extensions are not supported on FE1.0, so return empty results. +internal class KtFe10ResolveExtensionInfoProvider( override val analysisSession: KtFe10AnalysisSession, -) : KtSymbolFromResolveExtensionProvider(), Fe10KtAnalysisSessionComponent { +) : KtResolveExtensionInfoProvider(), Fe10KtAnalysisSessionComponent { override val token: KtLifetimeToken get() = analysisSession.token override fun getResolveExtensionScopeWithTopLevelDeclarations(): KtScope { - // Not supported for FE1.0 return KtEmptyScope(token) } + + override fun isResolveExtensionFile(file: VirtualFile): Boolean = false + + override fun getResolveExtensionNavigationElements(originalPsi: KtElement): Collection = emptyList() } \ No newline at end of file diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFirSubstitutorFactory.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SubstitutorFactory.kt similarity index 100% rename from analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFirSubstitutorFactory.kt rename to analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10SubstitutorFactory.kt 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 9dcf00cb5b4..008e4f66204 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 @@ -126,7 +126,7 @@ private constructor( override val symbolProviderByJavaPsiImpl = KtFirSymbolProviderByJavaPsi(this) - override val resolveExtensionProviderImpl: KtSymbolFromResolveExtensionProvider = KtFirSymbolFromResolveExtensionProvider(this) + override val resolveExtensionInfoProviderImpl: KtResolveExtensionInfoProvider = KtFirResolveExtensionInfoProvider(this) @Suppress("AnalysisApiMissingLifetimeCheck") override fun createContextDependentCopy(originalKtFile: KtFile, elementToReanalyze: KtElement): KtAnalysisSession { diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirResolveExtensionInfoProvider.kt similarity index 68% rename from analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt rename to analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirResolveExtensionInfoProvider.kt index 30e1280b602..4473e297502 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirSymbolFromResolveExtensionProvider.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/components/KtFirResolveExtensionInfoProvider.kt @@ -5,7 +5,9 @@ package org.jetbrains.kotlin.analysis.api.fir.components -import org.jetbrains.kotlin.analysis.api.components.KtSymbolFromResolveExtensionProvider +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.components.KtResolveExtensionInfoProvider import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession import org.jetbrains.kotlin.analysis.api.impl.base.scopes.KtEmptyScope import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken @@ -15,13 +17,17 @@ import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter import org.jetbrains.kotlin.analysis.api.symbols.* import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionTool import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.LLFirResolveExtensionToolDeclarationProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.navigationTargetsProvider +import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtNamedDeclaration -internal class KtFirSymbolFromResolveExtensionProvider( +internal class KtFirResolveExtensionInfoProvider( override val analysisSession: KtFirAnalysisSession, -) : KtSymbolFromResolveExtensionProvider(), KtFirAnalysisSessionComponent { +) : KtResolveExtensionInfoProvider(), KtFirAnalysisSessionComponent { override val token: KtLifetimeToken get() = analysisSession.token @@ -30,6 +36,16 @@ internal class KtFirSymbolFromResolveExtensionProvider( if (tools.isEmpty()) return KtEmptyScope(token) return KtFirResolveExtensionScope(analysisSession, tools) } + + @OptIn(KtModuleStructureInternals::class) + override fun isResolveExtensionFile(file: VirtualFile): Boolean = + file.navigationTargetsProvider != null + + @OptIn(KtModuleStructureInternals::class) + override fun getResolveExtensionNavigationElements(originalPsi: KtElement): Collection { + val targetsProvider = originalPsi.containingFile?.virtualFile?.navigationTargetsProvider ?: return emptyList() + return with(targetsProvider) { analysisSession.getNavigationTargets(originalPsi) } + } } private class KtFirResolveExtensionScope( @@ -43,7 +59,7 @@ private class KtFirResolveExtensionScope( override val token: KtLifetimeToken get() = analysisSession.token override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { - gelTopLevelDeclarations(nameFilter) { it.getTopLevelCallables() } + getTopLevelDeclarations(nameFilter) { it.getTopLevelCallables() } } override fun getCallableSymbols(names: Collection): Sequence = withValidityAssertion { @@ -53,7 +69,7 @@ private class KtFirResolveExtensionScope( } override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { - gelTopLevelDeclarations(nameFilter) { it.getTopLevelClassifiers() } + getTopLevelDeclarations(nameFilter) { it.getTopLevelClassifiers() } } override fun getClassifierSymbols(names: Collection): Sequence = withValidityAssertion { @@ -62,7 +78,7 @@ private class KtFirResolveExtensionScope( return getClassifierSymbols { it in namesSet } } - private inline fun gelTopLevelDeclarations( + private inline fun getTopLevelDeclarations( crossinline nameFilter: KtScopeNameFilter, crossinline getDeclarationsByProvider: (LLFirResolveExtensionToolDeclarationProvider) -> Sequence, ): Sequence = sequence { @@ -83,10 +99,14 @@ private class KtFirResolveExtensionScope( override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence = withValidityAssertion { sequence { + // Only emit package symbols for top-level packages (subpackages of root). This matches the behavior + // of the root-level KtFirPackageScope. + val seenTopLevelPackages = mutableSetOf() for (tool in tools) { - for (packageName in tool.packageFilter.getAllPackages()) { - if (!nameFilter(packageName.shortName())) continue - analysisSession.firSymbolBuilder.createPackageSymbol(packageName) + for (packageName in tool.packageFilter.getAllSubPackages(FqName.ROOT)) { + if (seenTopLevelPackages.add(packageName) && nameFilter(packageName)) { + yield(analysisSession.firSymbolBuilder.createPackageSymbol(FqName.ROOT.child(packageName))) + } } } } diff --git a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/KtFirReference.kt b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/KtFirReference.kt index 18e2d520f3e..872cb05cc8b 100644 --- a/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/KtFirReference.kt +++ b/analysis/analysis-api-fir/src/org/jetbrains/kotlin/analysis/api/fir/references/KtFirReference.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin -import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.psiTargetsProvider +import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.extensions.navigationTargetsProvider import org.jetbrains.kotlin.analysis.project.structure.KtModuleStructureInternals import org.jetbrains.kotlin.psi.KtFile @@ -21,7 +21,6 @@ interface KtFirReference : KtReference, KtSymbolBasedReference { fun getResolvedToPsi(analysisSession: KtAnalysisSession, referenceTargetSymbols: Collection): Collection = with(analysisSession) { referenceTargetSymbols.flatMap { symbol -> - symbol.getPsiForGeneratedExtensionSymbol()?.let { return@flatMap it } when (symbol) { is KtFirSymbol<*> -> getPsiDeclarations(symbol) else -> listOfNotNull(symbol.psi) @@ -29,19 +28,6 @@ interface KtFirReference : KtReference, KtSymbolBasedReference { } } - context(KtAnalysisSession) - @OptIn(KtModuleStructureInternals::class) - private fun KtSymbol.getPsiForGeneratedExtensionSymbol(): Collection? { - // TODO symbols generated by KtResolveExtension should probably have their own KtSymbolOrigin, now it's KtSymbolOrigin.SOURCE - if (origin != KtSymbolOrigin.SOURCE) return null - val psi = psi ?: return null - val ktFile = psi.containingFile as? KtFile ?: return null - val psiTargetsProvider = ktFile.virtualFile?.psiTargetsProvider ?: return null - return with(psiTargetsProvider) { - getReferenceTargetsForSymbol(this@getPsiForGeneratedExtensionSymbol) - } - } - fun getResolvedToPsi(analysisSession: KtAnalysisSession): Collection = with(analysisSession) { getResolvedToPsi(analysisSession, resolveToSymbols()) diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeDependentAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeDependentAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java new file mode 100644 index 00000000000..f4ef4df7242 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeDependentAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java @@ -0,0 +1,60 @@ +/* + * 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.resolveExtensionInfoProvider; + +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.resolveExtensionInfoProvider.AbstractResolveExtensionInfoProviderTest; +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/resolveExtensionInfoProvider/extensionScopeWithPsi") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeDependentAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated extends AbstractResolveExtensionInfoProviderTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Dependent, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInExtensionScopeWithPsi() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("multipleExtensions.kt") + public void testMultipleExtensions() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt"); + } + + @Test + @TestMetadata("singleModule.kt") + public void testSingleModule() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.kt"); + } +} diff --git a/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java new file mode 100644 index 00000000000..7c551ccfe11 --- /dev/null +++ b/analysis/analysis-api-fir/tests-gen/org/jetbrains/kotlin/analysis/api/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirIdeNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java @@ -0,0 +1,60 @@ +/* + * 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.resolveExtensionInfoProvider; + +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.resolveExtensionInfoProvider.AbstractResolveExtensionInfoProviderTest; +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/resolveExtensionInfoProvider/extensionScopeWithPsi") +@TestDataPath("$PROJECT_ROOT") +public class FirIdeNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated extends AbstractResolveExtensionInfoProviderTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Normal, + AnalysisApiMode.Ide + ) + ); + } + + @Test + public void testAllFilesPresentInExtensionScopeWithPsi() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("multipleExtensions.kt") + public void testMultipleExtensions() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt"); + } + + @Test + @TestMetadata("singleModule.kt") + public void testSingleModule() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.kt"); + } +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/resolveExtensionInfoProvider/AbstractResolveExtensionInfoProviderTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/resolveExtensionInfoProvider/AbstractResolveExtensionInfoProviderTest.kt new file mode 100644 index 00000000000..924fb0782e2 --- /dev/null +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/components/resolveExtensionInfoProvider/AbstractResolveExtensionInfoProviderTest.kt @@ -0,0 +1,83 @@ +/* + * 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.resolveExtensionInfoProvider + +import org.jetbrains.kotlin.analysis.api.KtAnalysisSession +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.scopeProvider.TestScopeRenderer.renderForTests +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.resolve.extensions.KtResolveExtensionTestSupport +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.resolve.extensions.getDescription +import org.jetbrains.kotlin.analysis.api.scopes.KtScope +import org.jetbrains.kotlin.analysis.api.symbols.KtDeclarationSymbol +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiBasedTest +import org.jetbrains.kotlin.analysis.test.framework.base.AbstractAnalysisApiSingleFileTest +import org.jetbrains.kotlin.analysis.test.framework.project.structure.ktModuleProvider +import org.jetbrains.kotlin.analysis.utils.printer.prettyPrint +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.builders.TestConfigurationBuilder +import org.jetbrains.kotlin.test.model.TestModule +import org.jetbrains.kotlin.test.services.TestModuleStructure +import org.jetbrains.kotlin.test.services.TestServices +import org.jetbrains.kotlin.test.services.assertions + +abstract class AbstractResolveExtensionInfoProviderTest : AbstractAnalysisApiBasedTest() { + override fun configureTest(builder: TestConfigurationBuilder) { + super.configureTest(builder) + KtResolveExtensionTestSupport.configure(builder) + } + + private fun List.findMainModule(): TestModule = + singleOrNull() + ?: find { it.name == "main" } + ?: error("There should either be a single module, or a module named 'main'.") + + private fun List.findMainKt(): KtFile = + singleOrNull() + ?: find { it.name == "main.kt" } + ?: error("There should either be a single Kotlin file in the main module, or a file named 'main.kt'.") + + override fun doTestByModuleStructure(moduleStructure: TestModuleStructure, testServices: TestServices) { + val mainModule = moduleStructure.modules.findMainModule() + val ktFiles = testServices.ktModuleProvider.getModuleFiles(mainModule).filterIsInstance() + val mainKt = ktFiles.findMainKt() + + analyseForTest(mainKt) { + val resolveExtensionScope = getResolveExtensionScopeWithTopLevelDeclarations() + + val actual = resolveExtensionScope.renderSymbolsWithExtendedPsiInfo(pretty = false) + val actualPretty = resolveExtensionScope.renderSymbolsWithExtendedPsiInfo(pretty = true) + + testServices.assertions.assertEqualsToTestDataFileSibling(actual) + testServices.assertions.assertEqualsToTestDataFileSibling(actualPretty, extension = ".pretty.txt") + } + } + + context(KtAnalysisSession) + private fun KtScope.renderSymbolsWithExtendedPsiInfo(pretty: Boolean) = prettyPrint { + renderForTests(this@renderSymbolsWithExtendedPsiInfo, pretty) { symbol -> + (symbol as? KtDeclarationSymbol)?.getPsiDeclarationInfo() + } + } + + context(KtAnalysisSession) + private fun KtDeclarationSymbol.getPsiDeclarationInfo(): String = prettyPrint { + val ktElement = psi as? KtElement + val containingVirtualFile = ktElement?.containingFile?.virtualFile + appendLine("PSI: ${ktElement?.getDescription()} [from ${containingVirtualFile?.name}]") + if (ktElement == null || containingVirtualFile == null) { + return@prettyPrint + } + + withIndent { + val isResolveExtensionFile = containingVirtualFile.isResolveExtensionFile + appendLine("From resolve extension: $isResolveExtensionFile") + + val navTargets = ktElement.getResolveExtensionNavigationElements() + appendLine("Resolve extension navigation targets: ${navTargets.size}") + withIndent { navTargets.forEach { appendLine(it.toString()) } } + } + }.trimEnd() +} diff --git a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/resolve/extensions/KtResolveExtensionForTest.kt b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/resolve/extensions/KtResolveExtensionForTest.kt index 3e8e6a6eb4a..d3e71b8170c 100644 --- a/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/resolve/extensions/KtResolveExtensionForTest.kt +++ b/analysis/analysis-api-impl-base/tests/org/jetbrains/kotlin/analysis/api/impl/base/test/cases/resolve/extensions/KtResolveExtensionForTest.kt @@ -12,13 +12,15 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analysis.api.KtAnalysisSession import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile +import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionNavigationTargetsProvider import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider -import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionReferencePsiTargetsProvider -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol import org.jetbrains.kotlin.analysis.project.structure.KtModule import org.jetbrains.kotlin.analysis.test.framework.services.environmentManager import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.test.services.TestServices class KtResolveExtensionProviderForTest( @@ -56,7 +58,7 @@ class KtResolveExtensionFileForTests( topLevelClassifiersNames: Set, topLevelCallableNames: Set, private val fileText: String, - private val psiTargetProvider: KtResolveExtensionReferencePsiTargetsProvider? = null + private val navigationTargetsProvider: KtResolveExtensionNavigationTargetsProvider? = null ) : KtResolveExtensionFile() { private val topLevelClassifiersNames: Set = topLevelClassifiersNames.mapTo(mutableSetOf()) { Name.identifier(it) } @@ -68,12 +70,27 @@ class KtResolveExtensionFileForTests( override fun buildFileText(): String = fileText - private object EmptyReferencePsiTargetsProvider : KtResolveExtensionReferencePsiTargetsProvider() { - override fun KtAnalysisSession.getReferenceTargetsForSymbol(symbol: KtSymbol): Collection = - emptyList() + private object ResolveExtensionNavigationTargetProviderForTest : KtResolveExtensionNavigationTargetsProvider() { + override fun KtAnalysisSession.getNavigationTargets(element: KtElement): Collection = + listOf(KtResolveExtensionNavigationTargetPsiElementForTest(element)) } - override fun createPsiTargetsProvider(): KtResolveExtensionReferencePsiTargetsProvider = - psiTargetProvider ?: EmptyReferencePsiTargetsProvider + override fun createNavigationTargetsProvider(): KtResolveExtensionNavigationTargetsProvider = + navigationTargetsProvider ?: ResolveExtensionNavigationTargetProviderForTest +} + +fun KtElement.getDescription(): String = buildString { + val declaration = when (this@getDescription) { + is KtDeclaration -> this@getDescription + else -> { + append("${this@getDescription.javaClass.simpleName} in ") + getStrictParentOfType() ?: containingKtFile + } + } + append("${declaration.javaClass.simpleName} ${declaration.name}") +} + +class KtResolveExtensionNavigationTargetPsiElementForTest(val originalElement: KtElement) : PsiElement by originalElement { + override fun toString() = "[Resolve extension navigation target for test for ${originalElement.getDescription()}]" } diff --git a/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirStandaloneNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirStandaloneNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java new file mode 100644 index 00000000000..394ca4186d9 --- /dev/null +++ b/analysis/analysis-api-standalone/tests-gen/org/jetbrains/kotlin/analysis/api/standalone/fir/test/cases/generated/cases/components/resolveExtensionInfoProvider/FirStandaloneNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated.java @@ -0,0 +1,60 @@ +/* + * 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.resolveExtensionInfoProvider; + +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.resolveExtensionInfoProvider.AbstractResolveExtensionInfoProviderTest; +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/resolveExtensionInfoProvider/extensionScopeWithPsi") +@TestDataPath("$PROJECT_ROOT") +public class FirStandaloneNormalAnalysisSourceModuleResolveExtensionInfoProviderTestGenerated extends AbstractResolveExtensionInfoProviderTest { + @NotNull + @Override + public AnalysisApiTestConfigurator getConfigurator() { + return AnalysisApiFirStandaloneModeTestConfiguratorFactory.INSTANCE.createConfigurator( + new AnalysisApiTestConfiguratorFactoryData( + FrontendKind.Fir, + TestModuleKind.Source, + AnalysisSessionMode.Normal, + AnalysisApiMode.Standalone + ) + ); + } + + @Test + public void testAllFilesPresentInExtensionScopeWithPsi() throws Exception { + KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @Test + @TestMetadata("multipleExtensions.kt") + public void testMultipleExtensions() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt"); + } + + @Test + @TestMetadata("singleModule.kt") + public void testSingleModule() throws Exception { + runTest("analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.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 9054d3fc28e..1d32c54e847 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 @@ -64,7 +64,7 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke KtSignatureSubstitutorMixIn, KtScopeSubstitutionMixIn, KtSymbolProviderByJavaPsiMixIn, - KtSymbolFromResolveExtensionProviderMixIn { + KtResolveExtensionInfoProviderMixIn { public abstract val useSiteModule: KtModule @@ -162,8 +162,8 @@ public abstract class KtAnalysisSession(final override val token: KtLifetimeToke internal val scopeSubstitution: KtScopeSubstitution get() = scopeSubstitutionImpl protected abstract val scopeSubstitutionImpl: KtScopeSubstitution - internal val resolveExtensionProvider: KtSymbolFromResolveExtensionProvider get() = resolveExtensionProviderImpl - protected abstract val resolveExtensionProviderImpl: KtSymbolFromResolveExtensionProvider + internal val resolveExtensionInfoProvider: KtResolveExtensionInfoProvider get() = resolveExtensionInfoProviderImpl + protected abstract val resolveExtensionInfoProviderImpl: KtResolveExtensionInfoProvider @KtAnalysisApiInternals public val substitutorFactory: KtSubstitutorFactory get() = substitutorFactoryImpl diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtResolveExtensionInfoProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtResolveExtensionInfoProvider.kt new file mode 100644 index 00000000000..00e8af5215f --- /dev/null +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtResolveExtensionInfoProvider.kt @@ -0,0 +1,68 @@ +/* + * 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.components + +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion +import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension +import org.jetbrains.kotlin.analysis.api.scopes.KtScope +import org.jetbrains.kotlin.psi.KtElement + +public abstract class KtResolveExtensionInfoProvider : KtAnalysisSessionComponent() { + public abstract fun getResolveExtensionScopeWithTopLevelDeclarations(): KtScope + public abstract fun isResolveExtensionFile(file: VirtualFile): Boolean + public abstract fun getResolveExtensionNavigationElements(originalPsi: KtElement): Collection +} + +public interface KtResolveExtensionInfoProviderMixIn : KtAnalysisSessionMixIn { + /** + * Returns [KtScope] which contains all top-level callable declarations which are generated by [KtResolveExtension] + * + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider + */ + public fun getResolveExtensionScopeWithTopLevelDeclarations(): KtScope = withValidityAssertion { + analysisSession.resolveExtensionInfoProvider.getResolveExtensionScopeWithTopLevelDeclarations() + } + + /** + * Returns whether this [VirtualFile] was provided by a [KtResolveExtension]. + * + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider + */ + public val VirtualFile.isResolveExtensionFile: Boolean + get() = withValidityAssertion { + analysisSession.resolveExtensionInfoProvider.isResolveExtensionFile(this) + } + + /** + * Returns whether this [KtElement] was provided by a [KtResolveExtension]. + * + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider + */ + public val KtElement.isFromResolveExtension: Boolean + get() = withValidityAssertion { + containingKtFile.virtualFile?.isResolveExtensionFile ?: false + } + + /** + * Returns the [PsiElement]s which should be used as a navigation target in place of this [KtElement] + * provided by a [KtResolveExtension]. + * + * These [PsiElement]s will typically be the source item(s) that caused the given [KtElement] to be generated + * by the [KtResolveExtension]. For example, for a [KtElement] generated by a resource compiler, this will + * typically be a list of the [PsiElement]s of the resource items in the corresponding resource file. + * + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension + * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider + */ + public fun KtElement.getResolveExtensionNavigationElements(): Collection = withValidityAssertion { + analysisSession.resolveExtensionInfoProvider.getResolveExtensionNavigationElements(this) + } +} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolFromResolveExtensionProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolFromResolveExtensionProvider.kt deleted file mode 100644 index e18fe2fecb5..00000000000 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/components/KtSymbolFromResolveExtensionProvider.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.components - -import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion -import org.jetbrains.kotlin.analysis.api.scopes.KtScope - -public abstract class KtSymbolFromResolveExtensionProvider : KtAnalysisSessionComponent() { - public abstract fun getResolveExtensionScopeWithTopLevelDeclarations(): KtScope -} - -public interface KtSymbolFromResolveExtensionProviderMixIn : KtAnalysisSessionMixIn { - /** - * Returns [KtScope] which contains all top-level callable declarations which are generated by [org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension] - * - * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension - * @see org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider - */ - public fun getResolveExtensionScopeWithTopLevelDeclarations(): KtScope = withValidityAssertion { - analysisSession.resolveExtensionProvider.getResolveExtensionScopeWithTopLevelDeclarations() - } -} diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionFile.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionFile.kt index 6767ecac398..a2bc23cddce 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionFile.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionFile.kt @@ -77,10 +77,10 @@ public abstract class KtResolveExtensionFile { public abstract fun buildFileText(): String /** - * Creates a [KtResolveExtensionReferencePsiTargetsProvider] for this [KtResolveExtensionFile]. + * Creates a [KtResolveExtensionNavigationTargetsProvider] for this [KtResolveExtensionFile]. * - * @see KtResolveExtensionReferencePsiTargetsProvider + * @see KtResolveExtensionNavigationTargetsProvider * @see KtResolveExtensionFile */ - public abstract fun createPsiTargetsProvider(): KtResolveExtensionReferencePsiTargetsProvider + public abstract fun createNavigationTargetsProvider(): KtResolveExtensionNavigationTargetsProvider } \ No newline at end of file diff --git a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionReferencePsiTargetsProvider.kt b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionNavigationTargetsProvider.kt similarity index 64% rename from analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionReferencePsiTargetsProvider.kt rename to analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionNavigationTargetsProvider.kt index ed765b9e5d0..4e2b8565e50 100644 --- a/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionReferencePsiTargetsProvider.kt +++ b/analysis/analysis-api/src/org/jetbrains/kotlin/analysis/api/resolve/extensions/KtResolveExtensionNavigationTargetsProvider.kt @@ -7,16 +7,16 @@ package org.jetbrains.kotlin.analysis.api.resolve.extensions import com.intellij.psi.PsiElement import org.jetbrains.kotlin.analysis.api.KtAnalysisSession -import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol +import org.jetbrains.kotlin.psi.KtElement -public abstract class KtResolveExtensionReferencePsiTargetsProvider { +public abstract class KtResolveExtensionNavigationTargetsProvider { /** - * Provides a [PsiElement] where `reference.resolveTo` will lead for a [symbol] + * Provides a [PsiElement] which will be opened on a navigation request for [element]. * * Usually returns a single result. Might return an empty collection if there is no navigation target. * Also, might multiple targets in a case of ambiguity or multiple targets for a [symbol] * - * Returned [PsiElement] will be used as a navigation target for a reference inside the IDE. + * Returned [PsiElement] will be used as a navigation target inside the IDE. */ - public abstract fun KtAnalysisSession.getReferenceTargetsForSymbol(symbol: KtSymbol): Collection + public abstract fun KtAnalysisSession.getNavigationTargets(element: KtElement): Collection } \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt new file mode 100644 index 00000000000..91cb62f727d --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.kt @@ -0,0 +1,38 @@ +// MODULE: rex1 +// WITH_RESOLVE_EXTENSION +// RESOLVE_EXTENSION_PACKAGE: rex1 + +// FILE: rex1.kt +// RESOLVE_EXTENSION_FILE +package rex1 + +// RESOLVE_EXTENSION_CLASSIFIER: RexClass1 +interface RexClass1 + +// RESOLVE_EXTENSION_CALLABLE: rexCallable1 +fun rexCallable1(): Any = TODO() + +// MODULE: rex2 +// WITH_RESOLVE_EXTENSION +// RESOLVE_EXTENSION_PACKAGE: rex2 + +// FILE: rex2.kt +// RESOLVE_EXTENSION_FILE +package rex2 + +// RESOLVE_EXTENSION_CLASSIFIER: RexClass2 +interface RexClass2 + +// RESOLVE_EXTENSION_CALLABLE: rexCallable2 +fun rexCallable2(): Any = TODO() + +// MODULE: main(rex1, rex2) +// FILE: main.kt +package main + +import rex1.* +import rex2.* + +object MainObject : RexClass1, RexClass2 { + fun foo(): List = listOf(rexCallable1(), rexCallable2()) +} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.pretty.txt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.pretty.txt new file mode 100644 index 00000000000..de43fbf9495 --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.pretty.txt @@ -0,0 +1,26 @@ +packages: 2 + rex1 + rex2 +classifiers: 2 + interface RexClass1 + PSI: KtClass RexClass1 [from rex1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass RexClass1] + interface RexClass2 + PSI: KtClass RexClass2 [from rex2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass RexClass2] +callables: 2 + fun rexCallable1(): kotlin.Any + PSI: KtNamedFunction rexCallable1 [from rex1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction rexCallable1] + fun rexCallable2(): kotlin.Any + PSI: KtNamedFunction rexCallable2 [from rex2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction rexCallable2] +constructors: 0 diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.txt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.txt new file mode 100644 index 00000000000..c7d94b92ffe --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/multipleExtensions.txt @@ -0,0 +1,126 @@ +packages: 2 + KtPackageSymbol: + fqName: rex1 + origin: SOURCE + KtPackageSymbol: + fqName: rex2 + origin: SOURCE +classifiers: 2 + KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: rex1/RexClass1 + classKind: INTERFACE + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: ABSTRACT + name: RexClass1 + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtClass RexClass1 [from rex1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass RexClass1] + KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: rex2/RexClass2 + classKind: INTERFACE + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: ABSTRACT + name: RexClass2 + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtClass RexClass2 [from rex2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass RexClass2] +callables: 2 + KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: rex1/rexCallable1 + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: rexCallable1 + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + PSI: KtNamedFunction rexCallable1 [from rex1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction rexCallable1] + KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: rex2/rexCallable2 + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: rexCallable2 + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + PSI: KtNamedFunction rexCallable2 [from rex2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction rexCallable2] +constructors: 0 diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.kt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.kt new file mode 100644 index 00000000000..dd22f60ca23 --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.kt @@ -0,0 +1,44 @@ +// WITH_RESOLVE_EXTENSION +// RESOLVE_EXTENSION_PACKAGE: generated + +// FILE: extension1.kt +// RESOLVE_EXTENSION_FILE +package generated + +// RESOLVE_EXTENSION_CLASSIFIER: GenClass1 +class GenClass1 { + fun genMemberFun1(foo: Any): String = TODO() + fun GenClass2.genMemberExtension1(): Unit = TODO() + + val genMemberVal1: String = "foo" + + var genMemberVar1: String = "bar" + private set +} + +// RESOLVE_EXTENSION_CALLABLE: genTopLevelFun1 +fun genTopLevelFun1(foo: GenClass2): String = TODO() + +// RESOLVE_EXTENSION_CALLABLE: genTopLevelExtension1 +fun String.genTopLevelExtension1(): Int = TODO() + +// RESOLVE_EXTENSION_CALLABLE: genTopLevelVal1 +val genTopLevelVal1: String = "baz" + +// RESOLVE_EXTENSION_CALLABLE: genTopLevelVar1 +var genTopLevelVar1: String = "quux" + internal set + +// RESOLVE_EXTENSION_CALLABLE: genExtensionVal1 +val GenClass2.genExtensionVal1: Int + get() = TODO + +// FILE: extension2.kt +// RESOLVE_EXTENSION_FILE +package generated + +// RESOLVE_EXTENSION_CLASSIFIER: GenClass2 +open class GenClass2 + +// FILE: main.kt +fun main() {} \ No newline at end of file diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.pretty.txt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.pretty.txt new file mode 100644 index 00000000000..bcc8e953637 --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.pretty.txt @@ -0,0 +1,41 @@ +packages: 1 + generated +classifiers: 2 + class GenClass1 + PSI: KtClass GenClass1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass GenClass1] + class GenClass2 + PSI: KtClass GenClass2 [from extension2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass GenClass2] +callables: 5 + fun genTopLevelFun1(foo: generated.GenClass2): kotlin.String + PSI: KtNamedFunction genTopLevelFun1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction genTopLevelFun1] + fun kotlin.String.genTopLevelExtension1(): kotlin.Int + PSI: KtNamedFunction genTopLevelExtension1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction genTopLevelExtension1] + val genTopLevelVal1: kotlin.String + PSI: KtProperty genTopLevelVal1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genTopLevelVal1] + var genTopLevelVar1: kotlin.String + PSI: KtProperty genTopLevelVar1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genTopLevelVar1] + val generated.GenClass2.genExtensionVal1: kotlin.Int + get() + PSI: KtProperty genExtensionVal1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genExtensionVal1] +constructors: 0 diff --git a/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.txt b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.txt new file mode 100644 index 00000000000..9e67c8a54f2 --- /dev/null +++ b/analysis/analysis-api/testData/components/resolveExtensionInfoProvider/extensionScopeWithPsi/singleModule.txt @@ -0,0 +1,430 @@ +packages: 1 + KtPackageSymbol: + fqName: generated + origin: SOURCE +classifiers: 2 + KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: generated/GenClass1 + classKind: CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: FINAL + name: GenClass1 + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtClass GenClass1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass GenClass1] + KtNamedClassOrObjectSymbol: + annotationsList: [] + classIdIfNonLocal: generated/GenClass2 + classKind: CLASS + companionObject: null + contextReceivers: [] + isData: false + isExternal: false + isFun: false + isInline: false + isInner: false + modality: OPEN + name: GenClass2 + origin: SOURCE + superTypes: [ + KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Any + ] + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtClass GenClass2 [from extension2.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtClass GenClass2] +callables: 5 + KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: generated/genTopLevelFun1 + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: false + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: genTopLevelFun1 + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [ + KtValueParameterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + generatedPrimaryConstructorProperty: null + hasDefaultValue: false + isCrossinline: false + isExtension: false + isImplicitLambdaParameter: false + isNoinline: false + isVararg: false + name: foo + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: generated/GenClass2 + symbolKind: LOCAL + typeParameters: [] + ] + visibility: Public + PSI: KtNamedFunction genTopLevelFun1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction genTopLevelFun1] + KtFunctionSymbol: + annotationsList: [] + callableIdIfNonLocal: generated/genTopLevelExtension1 + contextReceivers: [] + contractEffects: [] + hasStableParameterNames: true + isBuiltinFunctionInvoke: false + isExtension: true + isExternal: false + isInfix: false + isInline: false + isOperator: false + isOverride: false + isStatic: false + isSuspend: false + modality: FINAL + name: genTopLevelExtension1 + origin: SOURCE + receiverParameter: KtReceiverParameterSymbol: + annotationsList: [] + origin: SOURCE + owningCallableSymbol: KtFunctionSymbol(generated/genTopLevelExtension1) + type: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Int + symbolKind: TOP_LEVEL + typeParameters: [] + valueParameters: [] + visibility: Public + PSI: KtNamedFunction genTopLevelExtension1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtNamedFunction genTopLevelExtension1] + KtKotlinPropertySymbol: + annotationsList: [] + backingFieldSymbol: KtBackingFieldSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + isExtension: false + name: field + origin: PROPERTY_BACKING_FIELD + owningProperty: KtKotlinPropertySymbol(generated/genTopLevelVal1) + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: LOCAL + typeParameters: [] + callableIdIfNonLocal: generated/genTopLevelVal1 + contextReceivers: [] + getter: KtPropertyGetterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasBody: false + hasStableParameterNames: true + isDefault: true + isExtension: false + isInline: false + isOverride: false + modality: FINAL + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: ACCESSOR + typeParameters: [] + valueParameters: [] + visibility: Public + hasBackingField: true + hasGetter: true + hasSetter: false + initializer: KtConstantInitializerValue("baz") + isConst: false + isDelegatedProperty: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: genTopLevelVal1 + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + setter: null + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtProperty genTopLevelVal1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genTopLevelVal1] + KtKotlinPropertySymbol: + annotationsList: [] + backingFieldSymbol: KtBackingFieldSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + isExtension: false + name: field + origin: PROPERTY_BACKING_FIELD + owningProperty: KtKotlinPropertySymbol(generated/genTopLevelVar1) + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: LOCAL + typeParameters: [] + callableIdIfNonLocal: generated/genTopLevelVar1 + contextReceivers: [] + getter: KtPropertyGetterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasBody: false + hasStableParameterNames: true + isDefault: true + isExtension: false + isInline: false + isOverride: false + modality: FINAL + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: ACCESSOR + typeParameters: [] + valueParameters: [] + visibility: Public + hasBackingField: true + hasGetter: true + hasSetter: true + initializer: KtConstantInitializerValue("quux") + isConst: false + isDelegatedProperty: false + isExtension: false + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: false + modality: FINAL + name: genTopLevelVar1 + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + setter: KtPropertySetterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasBody: false + hasStableParameterNames: true + isDefault: true + isExtension: false + isInline: false + isOverride: false + modality: FINAL + origin: SOURCE + parameter: KtValueParameterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + generatedPrimaryConstructorProperty: null + hasDefaultValue: false + isCrossinline: false + isExtension: false + isImplicitLambdaParameter: false + isNoinline: false + isVararg: false + name: value + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: LOCAL + typeParameters: [] + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Unit + symbolKind: ACCESSOR + typeParameters: [] + valueParameters: [ + KtValueParameterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + generatedPrimaryConstructorProperty: null + hasDefaultValue: false + isCrossinline: false + isExtension: false + isImplicitLambdaParameter: false + isNoinline: false + isVararg: false + name: value + origin: SOURCE + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/String + symbolKind: LOCAL + typeParameters: [] + ] + visibility: Internal + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtProperty genTopLevelVar1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genTopLevelVar1] + KtKotlinPropertySymbol: + annotationsList: [] + backingFieldSymbol: KtBackingFieldSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + isExtension: false + name: field + origin: PROPERTY_BACKING_FIELD + owningProperty: KtKotlinPropertySymbol(generated/genExtensionVal1) + receiverParameter: null + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Int + symbolKind: LOCAL + typeParameters: [] + callableIdIfNonLocal: generated/genExtensionVal1 + contextReceivers: [] + getter: KtPropertyGetterSymbol: + annotationsList: [] + callableIdIfNonLocal: null + contextReceivers: [] + hasBody: true + hasStableParameterNames: true + isDefault: false + isExtension: false + isInline: false + isOverride: false + modality: FINAL + origin: SOURCE + receiverParameter: KtReceiverParameterSymbol: + annotationsList: [] + origin: SOURCE + owningCallableSymbol: KtKotlinPropertySymbol(generated/genExtensionVal1) + type: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: generated/GenClass2 + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Int + symbolKind: ACCESSOR + typeParameters: [] + valueParameters: [] + visibility: Public + hasBackingField: false + hasGetter: true + hasSetter: false + initializer: null + isConst: false + isDelegatedProperty: false + isExtension: true + isFromPrimaryConstructor: false + isLateInit: false + isOverride: false + isStatic: false + isVal: true + modality: FINAL + name: genExtensionVal1 + origin: SOURCE + receiverParameter: KtReceiverParameterSymbol: + annotationsList: [] + origin: SOURCE + owningCallableSymbol: KtKotlinPropertySymbol(generated/genExtensionVal1) + type: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: generated/GenClass2 + returnType: KtUsualClassType: + annotationsList: [] + ownTypeArguments: [] + type: kotlin/Int + setter: null + symbolKind: TOP_LEVEL + typeParameters: [] + visibility: Public + PSI: KtProperty genExtensionVal1 [from extension1.kt] + From resolve extension: true + Resolve extension navigation targets: 1 + [Resolve extension navigation target for test for KtProperty genExtensionVal1] +constructors: 0 diff --git a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt index 23aa10a3b93..667bd9057e4 100644 --- a/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt +++ b/analysis/low-level-api-fir/src/org/jetbrains/kotlin/analysis/low/level/api/fir/resolve/extensions/LLFirResolveExtensionTool.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlin.analysis.api.KtAnalysisAllowanceManager import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtension import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionFile import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionProvider -import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionReferencePsiTargetsProvider +import org.jetbrains.kotlin.analysis.api.resolve.extensions.KtResolveExtensionNavigationTargetsProvider import org.jetbrains.kotlin.analysis.providers.impl.declarationProviders.FileBasedKotlinDeclarationProvider import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.LLFirSession import org.jetbrains.kotlin.analysis.project.structure.KtModule @@ -271,9 +271,12 @@ class LLFirResolveExtensionToolDeclarationProvider internal constructor( markGenerated = true, eventSystemEnabled = true // so every generated KtFile backed by some VirtualFile ) - val text = file.buildFileText() - val psiTargetsProvider = file.createPsiTargetsProvider() - val ktFile = createKtFile(factory, file.getFileName(), text, psiTargetsProvider) + val ktFile = createKtFile( + factory, + file.getFileName(), + file.buildFileText(), + file.createNavigationTargetsProvider(), + ) FileBasedKotlinDeclarationProvider(ktFile) } } @@ -284,12 +287,12 @@ class LLFirResolveExtensionToolDeclarationProvider internal constructor( factory: KtPsiFactory, fileName: String, fileText: String, - psiTargetsProvider: KtResolveExtensionReferencePsiTargetsProvider + navigationTargetsProvider: KtResolveExtensionNavigationTargetsProvider ): KtFile { val ktFile = factory.createFile(fileName, fileText) val virtualFile = ktFile.virtualFile virtualFile.analysisExtensionFileContextModule = ktModule - virtualFile.psiTargetsProvider = psiTargetsProvider + virtualFile.navigationTargetsProvider = navigationTargetsProvider return ktFile } @@ -362,7 +365,8 @@ private fun KtResolveExtensionFile.mayHaveTopLevelCallable(name: Name): Boolean } @KtModuleStructureInternals -public var VirtualFile.psiTargetsProvider: KtResolveExtensionReferencePsiTargetsProvider? by UserDataProperty(Key.create("KT_RESOLVE_EXTENSION_PSI_TARGETS_PROVIDER")) +public var VirtualFile.navigationTargetsProvider: KtResolveExtensionNavigationTargetsProvider? + by UserDataProperty(Key.create("KT_RESOLVE_EXTENSION_NAVIGATION_TARGETS_PROVIDER")) private inline fun forbidAnalysis(action: () -> R): R { return KtAnalysisAllowanceManager.forbidAnalysisInside(KtResolveExtensionProvider::class.java.simpleName, action) 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 2df8673993e..c6130b585ae 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 @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.multipl import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.psiTypeProvider.AbstractAnalysisApiExpressionPsiTypeProviderTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.psiTypeProvider.AbstractAnalysisApiPsiTypeProviderTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.referenceResolveProvider.AbstractIsImplicitCompanionReferenceTest +import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.resolveExtensionInfoProvider.AbstractResolveExtensionInfoProviderTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.scopeProvider.* import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.signatureSubstitution.AbstractAnalysisApiSignatureContractsTest import org.jetbrains.kotlin.analysis.api.impl.base.test.cases.components.signatureSubstitution.AbstractAnalysisApiSignatureSubstitutionTest @@ -299,6 +300,12 @@ private fun AnalysisApiTestGroup.generateAnalysisApiComponentsTests() { } } + component("resolveExtensionInfoProvider", filter = frontendIs(FrontendKind.Fir)) { + test(AbstractResolveExtensionInfoProviderTest::class) { + model("extensionScopeWithPsi") + } + } + component("smartCastProvider") { test(AbstractHLSmartCastInfoTest::class) { model("smartCastInfo")