FIR IDE/LC: introduce/use delegated member scope
This commit is contained in:
committed by
Ilya Kirillov
parent
700f8ac287
commit
3f2c86afb8
+23
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.delegateFields
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import java.util.*
|
||||
@@ -54,6 +55,7 @@ internal class KtFirScopeProvider(
|
||||
|
||||
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtMemberScope>()
|
||||
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDeclaredMemberScope>()
|
||||
private val delegatedMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDelegatedMemberScope>()
|
||||
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtDeclarationScope<KtSymbolWithDeclarations>>()
|
||||
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
|
||||
|
||||
@@ -101,6 +103,27 @@ internal class KtFirScopeProvider(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtDelegatedMemberScope = withValidityAssertion {
|
||||
val declaredScope = (getDeclaredMemberScope(classSymbol) as? KtFirDeclaredMemberScope)?.firScope
|
||||
?: return delegatedMemberScopeCache.getOrPut(classSymbol) { KtFirEmptyMemberScope(classSymbol) }
|
||||
delegatedMemberScopeCache.getOrPut(classSymbol) {
|
||||
val firScope = classSymbol.withFirForScope { fir ->
|
||||
val delegateFields = fir.delegateFields
|
||||
if (delegateFields.isNotEmpty()) {
|
||||
FirDelegatedMemberScope(
|
||||
analysisSession.rootModuleSession,
|
||||
ScopeSession(),
|
||||
fir,
|
||||
declaredScope,
|
||||
delegateFields
|
||||
)
|
||||
} else null
|
||||
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
|
||||
|
||||
KtFirDelegatedMemberScope(classSymbol, firScope, token, builder)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations> = withValidityAssertion {
|
||||
fileScopeCache.getOrPut(fileSymbol) {
|
||||
check(fileSymbol is KtFirFileSymbol) { "KtFirScopeProvider can only work with KtFirFileSymbol, but ${fileSymbol::class} was provided" }
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
|
||||
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtDelegatedMemberScope
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbolOrigin
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||
|
||||
internal class KtFirDelegatedMemberScope(
|
||||
override val owner: KtSymbolWithMembers,
|
||||
override val firScope: FirContainingNamesAwareScope,
|
||||
token: ValidityToken,
|
||||
builder: KtSymbolByFirBuilder
|
||||
) : KtFirDelegatingScope<FirContainingNamesAwareScope>(builder, token),
|
||||
KtDelegatedMemberScope,
|
||||
ValidityTokenOwner {
|
||||
|
||||
override fun getCallableSymbols(nameFilter: KtScopeNameFilter): Sequence<KtCallableSymbol> {
|
||||
return super.getCallableSymbols(nameFilter).filter { it.origin == KtSymbolOrigin.DELEGATED }
|
||||
}
|
||||
}
|
||||
+5
-2
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.analysis.api.fir.scopes
|
||||
import org.jetbrains.kotlin.analysis.api.tokens.ValidityToken
|
||||
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtDeclaredMemberScope
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtDelegatedMemberScope
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtMemberScope
|
||||
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
||||
@@ -16,7 +17,9 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtConstructorSymbol
|
||||
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) : KtMemberScope, KtDeclaredMemberScope, ValidityTokenOwner {
|
||||
internal class KtFirEmptyMemberScope(
|
||||
override val owner: KtSymbolWithMembers
|
||||
) : KtMemberScope, KtDeclaredMemberScope, KtDelegatedMemberScope, ValidityTokenOwner {
|
||||
override fun getPossibleCallableNames(): Set<Name> = emptySet()
|
||||
|
||||
override fun getPossibleClassifierNames(): Set<Name> = emptySet()
|
||||
@@ -34,4 +37,4 @@ internal class KtFirEmptyMemberScope(override val owner: KtSymbolWithMembers) :
|
||||
|
||||
override val token: ValidityToken
|
||||
get() = owner.token
|
||||
}
|
||||
}
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.scopes
|
||||
|
||||
import org.jetbrains.kotlin.analysis.api.fir.FirFrontendApiTestConfiguratorService
|
||||
import org.jetbrains.kotlin.analysis.api.impl.base.test.scopes.AbstractDelegateMemberScopeTest
|
||||
|
||||
abstract class AbstractFirDelegateMemberScopeTest : AbstractDelegateMemberScopeTest(FirFrontendApiTestConfiguratorService)
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.analysis.api.fir.scopes;
|
||||
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import org.jetbrains.kotlin.test.util.KtTestUtil;
|
||||
import org.jetbrains.kotlin.test.TestMetadata;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
|
||||
@SuppressWarnings("all")
|
||||
@TestMetadata("analysis/analysis-api/testData/scopes/delegatedMemberScope")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class FirDelegateMemberScopeTestGenerated extends AbstractFirDelegateMemberScopeTest {
|
||||
@Test
|
||||
public void testAllFilesPresentInDelegatedMemberScope() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/scopes/delegatedMemberScope"), Pattern.compile("^(.+)\\.kt$"), null, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("simple.kt")
|
||||
public void testSimple() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/scopes/delegatedMemberScope/simple.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("withOverridden.kt")
|
||||
public void testWithOverridden() throws Exception {
|
||||
runTest("analysis/analysis-api/testData/scopes/delegatedMemberScope/withOverridden.kt");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user