FIR IDE/LC: introduce/use delegated member scope

This commit is contained in:
Jinseong Jeon
2021-10-20 16:20:14 -07:00
committed by Ilya Kirillov
parent 700f8ac287
commit 3f2c86afb8
18 changed files with 271 additions and 20 deletions
@@ -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" }
@@ -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 }
}
}
@@ -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
}
}
@@ -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)
@@ -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");
}
}