[AA] Add KtResolveExtensionInfoProvider to AA.
This provider is responsible for answering queries related to resolve extensions. At the moment, this includes retrieving a KtScope with all REx top-level declarations (moved from KtSymbolFromResolveExtensionProvider), and retrieving information necessary to supply a GeneratedSourcesFilter for REx generated code. Future REx-related functions can be added to this interface. ^KT-59329
This commit is contained in:
committed by
Ilya Kirillov
parent
fa0209a322
commit
9f85739599
+1
-1
@@ -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 {
|
||||
|
||||
+29
-9
@@ -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<PsiElement> {
|
||||
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<KtCallableSymbol> = withValidityAssertion {
|
||||
gelTopLevelDeclarations(nameFilter) { it.getTopLevelCallables() }
|
||||
getTopLevelDeclarations(nameFilter) { it.getTopLevelCallables() }
|
||||
}
|
||||
|
||||
override fun getCallableSymbols(names: Collection<Name>): Sequence<KtCallableSymbol> = withValidityAssertion {
|
||||
@@ -53,7 +69,7 @@ private class KtFirResolveExtensionScope(
|
||||
}
|
||||
|
||||
override fun getClassifierSymbols(nameFilter: KtScopeNameFilter): Sequence<KtClassifierSymbol> = withValidityAssertion {
|
||||
gelTopLevelDeclarations(nameFilter) { it.getTopLevelClassifiers() }
|
||||
getTopLevelDeclarations(nameFilter) { it.getTopLevelClassifiers() }
|
||||
}
|
||||
|
||||
override fun getClassifierSymbols(names: Collection<Name>): Sequence<KtClassifierSymbol> = withValidityAssertion {
|
||||
@@ -62,7 +78,7 @@ private class KtFirResolveExtensionScope(
|
||||
return getClassifierSymbols { it in namesSet }
|
||||
}
|
||||
|
||||
private inline fun <D : KtNamedDeclaration, reified S : KtDeclaration> gelTopLevelDeclarations(
|
||||
private inline fun <D : KtNamedDeclaration, reified S : KtDeclaration> getTopLevelDeclarations(
|
||||
crossinline nameFilter: KtScopeNameFilter,
|
||||
crossinline getDeclarationsByProvider: (LLFirResolveExtensionToolDeclarationProvider) -> Sequence<D>,
|
||||
): Sequence<S> = sequence {
|
||||
@@ -83,10 +99,14 @@ private class KtFirResolveExtensionScope(
|
||||
|
||||
override fun getPackageSymbols(nameFilter: KtScopeNameFilter): Sequence<KtPackageSymbol> = 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<Name>()
|
||||
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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+1
-15
@@ -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<KtSymbol>): Collection<PsiElement> =
|
||||
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<PsiElement>? {
|
||||
// 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<PsiElement> =
|
||||
with(analysisSession) {
|
||||
getResolvedToPsi(analysisSession, resolveToSymbols())
|
||||
|
||||
+60
@@ -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");
|
||||
}
|
||||
}
|
||||
+60
@@ -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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user