[Analysis API] Allow handling scopes from KtScopeContext separately
^KT-55527
This commit is contained in:
committed by
teamcity
parent
d89d774411
commit
4b7164a557
+43
-24
@@ -6,9 +6,7 @@
|
||||
package org.jetbrains.kotlin.analysis.api.fir.components
|
||||
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtImplicitReceiver
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtScopeContext
|
||||
import org.jetbrains.kotlin.analysis.api.components.KtScopeProvider
|
||||
import org.jetbrains.kotlin.analysis.api.components.*
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtFirAnalysisSession
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.fir.scopes.*
|
||||
@@ -28,6 +26,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtPackageSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.unexpectedElementError
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.getElementTextInContext
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
@@ -142,7 +141,7 @@ internal class KtFirScopeProvider(
|
||||
}
|
||||
|
||||
override fun getFileScope(fileSymbol: KtFileSymbol): KtScope {
|
||||
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
|
||||
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
|
||||
return KtFirFileScope(fileSymbol, builder)
|
||||
}
|
||||
|
||||
@@ -178,31 +177,29 @@ internal class KtFirScopeProvider(
|
||||
val towerDataContext =
|
||||
analysisSession.firResolveSession.getTowerContextProvider(originalFile).getClosestAvailableParentContext(positionInFakeFile)
|
||||
?: error("Cannot find enclosing declaration for ${positionInFakeFile.getElementTextInContext()}")
|
||||
val towerDataElementsIndexed = towerDataContext.towerDataElements.asReversed().withIndex()
|
||||
|
||||
val implicitReceivers = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.implicitReceiver }.distinct()
|
||||
val implicitKtReceivers = implicitReceivers.map { receiver ->
|
||||
KtImplicitReceiver(
|
||||
token,
|
||||
builder.typeBuilder.buildKtType(receiver.type),
|
||||
builder.buildSymbol(receiver.boundSymbol.fir),
|
||||
)
|
||||
val implicitReceivers = towerDataElementsIndexed.flatMap { (index, towerDataElement) ->
|
||||
val receivers = listOfNotNull(towerDataElement.implicitReceiver) + towerDataElement.contextReceiverGroup.orEmpty()
|
||||
|
||||
receivers.map { receiver ->
|
||||
KtImplicitReceiver(
|
||||
token,
|
||||
builder.typeBuilder.buildKtType(receiver.type),
|
||||
builder.buildSymbol(receiver.boundSymbol.fir),
|
||||
index
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val implicitReceiverScopes = implicitReceivers.mapNotNull { it.implicitScope }
|
||||
val nonLocalScopes = towerDataContext.nonLocalTowerDataElements.mapNotNull { it.scope }.distinct()
|
||||
val firLocalScopes = towerDataContext.localScopes
|
||||
|
||||
val allKtScopes = buildList<KtScope> {
|
||||
implicitReceiverScopes.mapTo(this, ::convertToKtScope)
|
||||
nonLocalScopes.mapTo(this, ::convertToKtScope)
|
||||
firLocalScopes.mapTo(this, ::convertToKtScope)
|
||||
val firScopes = towerDataElementsIndexed.flatMap { (index, towerDataElement) ->
|
||||
towerDataElement.getAvailableScopes().map { IndexedValue(index, it) }
|
||||
}
|
||||
val scopes = firScopes.map { (index, firScope) ->
|
||||
KtScopeWithKind(convertToKtScope(firScope), getScopeKind(firScope, index), token)
|
||||
}
|
||||
|
||||
return KtScopeContext(
|
||||
getCompositeScope(allKtScopes.asReversed()),
|
||||
implicitKtReceivers.asReversed(),
|
||||
token
|
||||
)
|
||||
return KtScopeContext(scopes, implicitReceivers, token)
|
||||
}
|
||||
|
||||
private fun convertToKtScope(firScope: FirScope): KtScope {
|
||||
@@ -215,6 +212,28 @@ internal class KtFirScopeProvider(
|
||||
}
|
||||
}
|
||||
|
||||
private fun getScopeKind(firScope: FirScope, indexInTower: Int): KtScopeKind = when (firScope) {
|
||||
is FirNameAwareOnlyCallablesScope -> getScopeKind(firScope.delegate, indexInTower)
|
||||
is FirNameAwareOnlyClassifiersScope -> getScopeKind(firScope.delegate, indexInTower)
|
||||
|
||||
is FirLocalScope -> KtScopeKind.LocalScope(indexInTower)
|
||||
is FirTypeScope -> KtScopeKind.SimpleTypeScope(indexInTower)
|
||||
is FirTypeParameterScope -> KtScopeKind.TypeParameterScope(indexInTower)
|
||||
is FirPackageMemberScope -> KtScopeKind.PackageMemberScope(indexInTower)
|
||||
|
||||
is FirNestedClassifierScope -> KtScopeKind.StaticMemberScope(indexInTower)
|
||||
is FirNestedClassifierScopeWithSubstitution -> KtScopeKind.StaticMemberScope(indexInTower)
|
||||
is FirLazyNestedClassifierScope -> KtScopeKind.StaticMemberScope(indexInTower)
|
||||
is FirStaticScope -> KtScopeKind.StaticMemberScope(indexInTower)
|
||||
|
||||
is FirExplicitSimpleImportingScope -> KtScopeKind.ExplicitSimpleImportingScope(indexInTower)
|
||||
is FirExplicitStarImportingScope -> KtScopeKind.ExplicitStarImportingScope(indexInTower)
|
||||
is FirDefaultSimpleImportingScope -> KtScopeKind.DefaultSimpleImportingScope(indexInTower)
|
||||
is FirDefaultStarImportingScope -> KtScopeKind.DefaultStarImportingScope(indexInTower)
|
||||
|
||||
else -> unexpectedElementError("scope", firScope)
|
||||
}
|
||||
|
||||
private fun createPackageScope(fqName: FqName): KtFirPackageScope {
|
||||
return KtFirPackageScope(
|
||||
fqName,
|
||||
|
||||
+2
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.*
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithKind
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.sessions.llFirSession
|
||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.util.originalDeclaration
|
||||
import org.jetbrains.kotlin.analysis.project.structure.KtModule
|
||||
import org.jetbrains.kotlin.analysis.utils.errors.buildErrorWithAttachment
|
||||
import org.jetbrains.kotlin.analysis.utils.printer.parentOfType
|
||||
@@ -113,5 +114,5 @@ internal class KtFirSymbolContainingDeclarationProvider(
|
||||
when (val container = this.parentOfType<KtDeclaration>()) {
|
||||
is KtDestructuringDeclaration -> container.parentOfType()
|
||||
else -> container
|
||||
}
|
||||
}?.let { it.originalDeclaration ?: it }
|
||||
}
|
||||
|
||||
+1
-1
@@ -50,7 +50,7 @@ internal object KDocReferenceResolver {
|
||||
|
||||
context(KtAnalysisSession)
|
||||
private fun MutableCollection<KtSymbol>.collectSymbolsFromPositionScopes(owner: KtDeclaration, fqName: FqName) {
|
||||
val initialScope = owner.containingKtFile.getScopeContextForPosition(owner).scopes
|
||||
val initialScope = owner.containingKtFile.getScopeContextForPosition(owner).getCompositeScope()
|
||||
|
||||
val scope = fqName.pathSegments()
|
||||
.dropLast(1)
|
||||
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.scopes;
|
||||
|
||||
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.scopes.AbstractScopeContextForPositionTest;
|
||||
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/scopeProvider/scopeContextForPosition")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirIdeDependentAnalysisSourceModuleScopeContextForPositionTestGenerated extends AbstractScopeContextForPositionTest {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnalysisApiTestConfigurator getConfigurator() {
|
||||
return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator(
|
||||
new AnalysisApiTestConfiguratorFactoryData(
|
||||
FrontendKind.Fir,
|
||||
TestModuleKind.Source,
|
||||
AnalysisSessionMode.Dependent,
|
||||
AnalysisApiMode.Ide
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInScopeContextForPosition() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("contextReceiver.kt")
|
||||
public void testContextReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/contextReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("enumEntry.kt")
|
||||
public void testEnumEntry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/enumEntry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorType.kt")
|
||||
public void testErrorType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/errorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localTypeScope.kt")
|
||||
public void testLocalTypeScope() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/localTypeScope.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleScopeContextForPosition.kt")
|
||||
public void testSimpleScopeContextForPosition() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/simpleScopeContextForPosition.kt");
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.scopes;
|
||||
|
||||
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.scopes.AbstractScopeContextForPositionTest;
|
||||
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/scopeProvider/scopeContextForPosition")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirIdeNormalAnalysisSourceModuleScopeContextForPositionTestGenerated extends AbstractScopeContextForPositionTest {
|
||||
@NotNull
|
||||
@Override
|
||||
public AnalysisApiTestConfigurator getConfigurator() {
|
||||
return AnalysisApiFirTestConfiguratorFactory.INSTANCE.createConfigurator(
|
||||
new AnalysisApiTestConfiguratorFactoryData(
|
||||
FrontendKind.Fir,
|
||||
TestModuleKind.Source,
|
||||
AnalysisSessionMode.Normal,
|
||||
AnalysisApiMode.Ide
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAllFilesPresentInScopeContextForPosition() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("contextReceiver.kt")
|
||||
public void testContextReceiver() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/contextReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("enumEntry.kt")
|
||||
public void testEnumEntry() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/enumEntry.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("errorType.kt")
|
||||
public void testErrorType() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/errorType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("localTypeScope.kt")
|
||||
public void testLocalTypeScope() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/localTypeScope.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simpleScopeContextForPosition.kt")
|
||||
public void testSimpleScopeContextForPosition() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/components/scopeProvider/scopeContextForPosition/simpleScopeContextForPosition.kt");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user