FIR IDE/LC: introduce/use delegated member scope
This commit is contained in:
committed by
Ilya Kirillov
parent
700f8ac287
commit
3f2c86afb8
+13
@@ -66,11 +66,24 @@ internal class KtFe10ScopeProvider(override val analysisSession: KtFe10AnalysisS
|
|||||||
override val owner get() = classSymbol
|
override val owner get() = classSymbol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: need to return declared members only
|
||||||
return object : KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisSession), KtDeclaredMemberScope {
|
return object : KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisSession), KtDeclaredMemberScope {
|
||||||
override val owner get() = classSymbol
|
override val owner get() = classSymbol
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtDelegatedMemberScope = withValidityAssertion {
|
||||||
|
val descriptor = getDescriptor<ClassDescriptor>(classSymbol)
|
||||||
|
?: return object : KtFe10EmptyScope(token), KtDelegatedMemberScope {
|
||||||
|
override val owner get() = classSymbol
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: need to return delegated members only
|
||||||
|
return object : KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisSession), KtDelegatedMemberScope {
|
||||||
|
override val owner get() = classSymbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope = withValidityAssertion {
|
override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope = withValidityAssertion {
|
||||||
val descriptor = getDescriptor<ClassDescriptor>(symbol) ?: return KtFe10EmptyScope(token)
|
val descriptor = getDescriptor<ClassDescriptor>(symbol) ?: return KtFe10EmptyScope(token)
|
||||||
return KtFe10ScopeMember(descriptor.staticScope, analysisSession)
|
return KtFe10ScopeMember(descriptor.staticScope, analysisSession)
|
||||||
|
|||||||
+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.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.analysis.api.types.KtType
|
import org.jetbrains.kotlin.analysis.api.types.KtType
|
||||||
import org.jetbrains.kotlin.analysis.api.withValidityAssertion
|
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.KtElement
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@@ -54,6 +55,7 @@ internal class KtFirScopeProvider(
|
|||||||
|
|
||||||
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtMemberScope>()
|
private val memberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtMemberScope>()
|
||||||
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDeclaredMemberScope>()
|
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDeclaredMemberScope>()
|
||||||
|
private val delegatedMemberScopeCache = IdentityHashMap<KtSymbolWithMembers, KtDelegatedMemberScope>()
|
||||||
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtDeclarationScope<KtSymbolWithDeclarations>>()
|
private val fileScopeCache = IdentityHashMap<KtFileSymbol, KtDeclarationScope<KtSymbolWithDeclarations>>()
|
||||||
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
|
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 {
|
override fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations> = withValidityAssertion {
|
||||||
fileScopeCache.getOrPut(fileSymbol) {
|
fileScopeCache.getOrPut(fileSymbol) {
|
||||||
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" }
|
||||||
|
|||||||
+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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -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.tokens.ValidityToken
|
||||||
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
|
import org.jetbrains.kotlin.analysis.api.ValidityTokenOwner
|
||||||
import org.jetbrains.kotlin.analysis.api.scopes.KtDeclaredMemberScope
|
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.KtMemberScope
|
||||||
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
|
import org.jetbrains.kotlin.analysis.api.scopes.KtScopeNameFilter
|
||||||
import org.jetbrains.kotlin.analysis.api.symbols.KtCallableSymbol
|
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.analysis.api.symbols.markers.KtSymbolWithMembers
|
||||||
import org.jetbrains.kotlin.name.Name
|
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 getPossibleCallableNames(): Set<Name> = emptySet()
|
||||||
|
|
||||||
override fun getPossibleClassifierNames(): Set<Name> = emptySet()
|
override fun getPossibleClassifierNames(): Set<Name> = emptySet()
|
||||||
|
|||||||
+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");
|
||||||
|
}
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* 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.impl.base.test.scopes
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.barebone.test.FrontendApiTestConfiguratorService
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.SymbolByFqName
|
||||||
|
import org.jetbrains.kotlin.analysis.api.impl.base.test.symbols.AbstractSymbolByFqNameTest
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
|
||||||
|
abstract class AbstractDelegateMemberScopeTest(
|
||||||
|
configurator: FrontendApiTestConfiguratorService
|
||||||
|
) : AbstractSymbolByFqNameTest(configurator) {
|
||||||
|
|
||||||
|
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): List<KtSymbol> {
|
||||||
|
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
||||||
|
val symbols = with(symbolData) { toSymbols() }
|
||||||
|
val classSymbol = symbols.singleOrNull() as? KtClassOrObjectSymbol
|
||||||
|
?: error("Should be a single class symbol, but $symbols found")
|
||||||
|
return classSymbol.getDelegatedMemberScope().getCallableSymbols().toList()
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
-1
@@ -14,7 +14,10 @@ import org.jetbrains.kotlin.analysis.api.symbols.KtSymbol
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.services.TestServices
|
import org.jetbrains.kotlin.test.services.TestServices
|
||||||
|
|
||||||
abstract class AbstractMemberScopeByFqNameTest(configurator: FrontendApiTestConfiguratorService) : AbstractSymbolByFqNameTest(configurator) {
|
abstract class AbstractMemberScopeByFqNameTest(
|
||||||
|
configurator: FrontendApiTestConfiguratorService
|
||||||
|
) : AbstractSymbolByFqNameTest(configurator) {
|
||||||
|
|
||||||
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): List<KtSymbol> {
|
override fun KtAnalysisSession.collectSymbols(ktFile: KtFile, testServices: TestServices): List<KtSymbol> {
|
||||||
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
val symbolData = SymbolByFqName.getSymbolDataFromFile(testDataPath)
|
||||||
val symbols = with(symbolData) { toSymbols() }
|
val symbols = with(symbolData) { toSymbols() }
|
||||||
|
|||||||
+10
-1
@@ -19,11 +19,17 @@ import org.jetbrains.kotlin.psi.KtFile
|
|||||||
|
|
||||||
public abstract class KtScopeProvider : KtAnalysisSessionComponent() {
|
public abstract class KtScopeProvider : KtAnalysisSessionComponent() {
|
||||||
public abstract fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope
|
public abstract fun getMemberScope(classSymbol: KtSymbolWithMembers): KtMemberScope
|
||||||
public abstract fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope
|
|
||||||
|
|
||||||
public abstract fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope
|
public abstract fun getDeclaredMemberScope(classSymbol: KtSymbolWithMembers): KtDeclaredMemberScope
|
||||||
|
|
||||||
|
public abstract fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtDelegatedMemberScope
|
||||||
|
|
||||||
|
public abstract fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope
|
||||||
|
|
||||||
public abstract fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations>
|
public abstract fun getFileScope(fileSymbol: KtFileSymbol): KtDeclarationScope<KtSymbolWithDeclarations>
|
||||||
|
|
||||||
public abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope
|
public abstract fun getPackageScope(packageSymbol: KtPackageSymbol): KtPackageScope
|
||||||
|
|
||||||
public abstract fun getCompositeScope(subScopes: List<KtScope>): KtCompositeScope
|
public abstract fun getCompositeScope(subScopes: List<KtScope>): KtCompositeScope
|
||||||
|
|
||||||
public abstract fun getTypeScope(type: KtType): KtScope?
|
public abstract fun getTypeScope(type: KtType): KtScope?
|
||||||
@@ -41,6 +47,9 @@ public interface KtScopeProviderMixIn : KtAnalysisSessionMixIn {
|
|||||||
public fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope =
|
public fun KtSymbolWithMembers.getDeclaredMemberScope(): KtDeclaredMemberScope =
|
||||||
analysisSession.scopeProvider.getDeclaredMemberScope(this)
|
analysisSession.scopeProvider.getDeclaredMemberScope(this)
|
||||||
|
|
||||||
|
public fun KtSymbolWithMembers.getDelegatedMemberScope(): KtDelegatedMemberScope =
|
||||||
|
analysisSession.scopeProvider.getDelegatedMemberScope(this)
|
||||||
|
|
||||||
public fun KtSymbolWithMembers.getStaticMemberScope(): KtScope =
|
public fun KtSymbolWithMembers.getStaticMemberScope(): KtScope =
|
||||||
analysisSession.scopeProvider.getStaticMemberScope(this)
|
analysisSession.scopeProvider.getStaticMemberScope(this)
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,10 @@ public interface KtDeclaredMemberScope : KtDeclarationScope<KtSymbolWithMembers>
|
|||||||
override val owner: KtSymbolWithMembers
|
override val owner: KtSymbolWithMembers
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface KtDelegatedMemberScope : KtDeclarationScope<KtSymbolWithMembers> {
|
||||||
|
override val owner: KtSymbolWithMembers
|
||||||
|
}
|
||||||
|
|
||||||
public interface KtDeclarationScope<out T : KtSymbolWithDeclarations> : KtScope {
|
public interface KtDeclarationScope<out T : KtSymbolWithDeclarations> : KtScope {
|
||||||
public val owner: T
|
public val owner: T
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
// DO_NOT_CHECK_SYMBOL_RESTORE
|
||||||
|
|
||||||
|
interface I {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class A(
|
||||||
|
private val p: I
|
||||||
|
) : I by p
|
||||||
|
|
||||||
|
// class: A
|
||||||
|
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
KtFunctionSymbol:
|
||||||
|
annotatedType: [] kotlin/Unit
|
||||||
|
annotationClassIds: []
|
||||||
|
annotations: []
|
||||||
|
callableIdIfNonLocal: /I.foo
|
||||||
|
dispatchType: A
|
||||||
|
hasStableParameterNames: true
|
||||||
|
isExtension: false
|
||||||
|
isExternal: false
|
||||||
|
isInfix: false
|
||||||
|
isInline: false
|
||||||
|
isOperator: false
|
||||||
|
isOverride: false
|
||||||
|
isStatic: false
|
||||||
|
isSuspend: false
|
||||||
|
modality: OPEN
|
||||||
|
name: foo
|
||||||
|
origin: DELEGATED
|
||||||
|
receiverType: null
|
||||||
|
symbolKind: CLASS_MEMBER
|
||||||
|
typeParameters: []
|
||||||
|
valueParameters: []
|
||||||
|
visibility: Public
|
||||||
|
deprecationStatus: null
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// DO_NOT_CHECK_SYMBOL_RESTORE
|
||||||
|
|
||||||
|
interface I1 {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
class I1Impl: I1 {
|
||||||
|
override fun foo() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface I2 {
|
||||||
|
fun bar()
|
||||||
|
fun baz()
|
||||||
|
}
|
||||||
|
|
||||||
|
class I2Impl: I2 {
|
||||||
|
override fun bar() {}
|
||||||
|
override fun baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A : I1 by I1Impl()
|
||||||
|
|
||||||
|
class B : I2 by I2Impl(), A() {
|
||||||
|
override fun baz() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// class: B
|
||||||
+24
@@ -0,0 +1,24 @@
|
|||||||
|
KtFunctionSymbol:
|
||||||
|
annotatedType: [] kotlin/Unit
|
||||||
|
annotationClassIds: []
|
||||||
|
annotations: []
|
||||||
|
callableIdIfNonLocal: /I2.bar
|
||||||
|
dispatchType: B
|
||||||
|
hasStableParameterNames: true
|
||||||
|
isExtension: false
|
||||||
|
isExternal: false
|
||||||
|
isInfix: false
|
||||||
|
isInline: false
|
||||||
|
isOperator: false
|
||||||
|
isOverride: false
|
||||||
|
isStatic: false
|
||||||
|
isSuspend: false
|
||||||
|
modality: OPEN
|
||||||
|
name: bar
|
||||||
|
origin: DELEGATED
|
||||||
|
receiverType: null
|
||||||
|
symbolKind: CLASS_MEMBER
|
||||||
|
typeParameters: []
|
||||||
|
valueParameters: []
|
||||||
|
visibility: Public
|
||||||
|
deprecationStatus: null
|
||||||
+2
-5
@@ -204,11 +204,8 @@ internal class FirLightClassForSymbol(
|
|||||||
}
|
}
|
||||||
|
|
||||||
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
// NB: delegated members are not available at _declared_ member scope.
|
classOrObjectSymbol.getDelegatedMemberScope().getCallableSymbols().forEach { functionSymbol ->
|
||||||
// Thus, use member scope to get "all" callable members, including members from (interface) supertypes,
|
if (functionSymbol is KtFunctionSymbol) {
|
||||||
// and accept fake overrides with delegated origin to create delegate methods.
|
|
||||||
classOrObjectSymbol.getMemberScope().getCallableSymbols().forEach { functionSymbol ->
|
|
||||||
if (functionSymbol is KtFunctionSymbol && functionSymbol.origin == KtSymbolOrigin.DELEGATED) {
|
|
||||||
createDelegateMethod(functionSymbol)
|
createDelegateMethod(functionSymbol)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-5
@@ -9,10 +9,9 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.FirSessionComponent
|
import org.jetbrains.kotlin.fir.FirSessionComponent
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirField
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
import org.jetbrains.kotlin.fir.declarations.FirRegularClass
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.delegateFields
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
import org.jetbrains.kotlin.fir.declarations.utils.isExpect
|
||||||
import org.jetbrains.kotlin.fir.declarations.utils.isSynthetic
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.*
|
import org.jetbrains.kotlin.fir.resolve.*
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
@@ -40,17 +39,15 @@ class FirKotlinScopeProvider(
|
|||||||
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
|
return scopeSession.getOrBuild(klass.symbol, USE_SITE) {
|
||||||
val declaredScope = useSiteSession.declaredMemberScope(klass)
|
val declaredScope = useSiteSession.declaredMemberScope(klass)
|
||||||
|
|
||||||
val delegateFields = klass.declarations.filterIsInstance<FirField>().filter { it.isSynthetic }
|
|
||||||
|
|
||||||
val decoratedDeclaredMemberScope =
|
val decoratedDeclaredMemberScope =
|
||||||
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession).let {
|
declaredMemberScopeDecorator(klass, declaredScope, useSiteSession, scopeSession).let {
|
||||||
|
val delegateFields = klass.delegateFields
|
||||||
if (delegateFields.isEmpty())
|
if (delegateFields.isEmpty())
|
||||||
it
|
it
|
||||||
else
|
else
|
||||||
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
|
FirDelegatedMemberScope(useSiteSession, scopeSession, klass, it, delegateFields)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
val scopes = lookupSuperTypes(
|
val scopes = lookupSuperTypes(
|
||||||
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
|
klass, lookupInterfaces = true, deep = false, useSiteSession = useSiteSession, substituteTypes = true
|
||||||
).mapNotNull { useSiteSuperType ->
|
).mapNotNull { useSiteSuperType ->
|
||||||
|
|||||||
+3
@@ -34,6 +34,9 @@ val FirClass.superConeTypes: List<ConeClassLikeType> get() = superTypeRefs.mapNo
|
|||||||
val FirClass.anonymousInitializers: List<FirAnonymousInitializer>
|
val FirClass.anonymousInitializers: List<FirAnonymousInitializer>
|
||||||
get() = declarations.filterIsInstance<FirAnonymousInitializer>()
|
get() = declarations.filterIsInstance<FirAnonymousInitializer>()
|
||||||
|
|
||||||
|
val FirClass.delegateFields: List<FirField>
|
||||||
|
get() = declarations.filterIsInstance<FirField>().filter { it.isSynthetic }
|
||||||
|
|
||||||
val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol?
|
val FirQualifiedAccess.referredPropertySymbol: FirPropertySymbol?
|
||||||
get() {
|
get() {
|
||||||
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
val reference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||||
|
|||||||
+8
-3
@@ -15,6 +15,9 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.diagnostic.compiler.based
|
|||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractFileStructureTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.file.structure.AbstractFileStructureTest
|
||||||
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractInnerDeclarationsResolvePhaseTest
|
import org.jetbrains.kotlin.analysis.low.level.api.fir.resolve.AbstractInnerDeclarationsResolvePhaseTest
|
||||||
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
import org.jetbrains.kotlin.generators.util.TestGeneratorUtil
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.test.components.*
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByFqNameTest
|
||||||
|
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByReferenceTest
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirExpectedExpressionTypeTest
|
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirExpectedExpressionTypeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirHLExpressionTypeTest
|
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirHLExpressionTypeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirOverriddenDeclarationProviderTest
|
import org.jetbrains.kotlin.analysis.api.fir.components.AbstractFirOverriddenDeclarationProviderTest
|
||||||
@@ -24,9 +27,7 @@ import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirMemberScopeByFqNa
|
|||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByFqNameTest
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByFqNameTest
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByPsiTest
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByPsiTest
|
||||||
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByReferenceTest
|
import org.jetbrains.kotlin.analysis.api.fir.symbols.AbstractFirSymbolByReferenceTest
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.components.*
|
import org.jetbrains.kotlin.analysis.api.fir.scopes.AbstractFirDelegateMemberScopeTest
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByFqNameTest
|
|
||||||
import org.jetbrains.kotlin.analysis.api.descriptors.test.symbols.AbstractKtFe10SymbolByReferenceTest
|
|
||||||
import org.jetbrains.kotlin.spec.utils.GeneralConfiguration
|
import org.jetbrains.kotlin.spec.utils.GeneralConfiguration
|
||||||
import org.jetbrains.kotlin.spec.utils.tasks.detectDirsWithTestsMapFileOnly
|
import org.jetbrains.kotlin.spec.utils.tasks.detectDirsWithTestsMapFileOnly
|
||||||
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
import org.jetbrains.kotlin.generators.generateTestGroupSuiteWithJUnit5
|
||||||
@@ -52,6 +53,10 @@ fun main(args: Array<String>) {
|
|||||||
model("scopes/fileScopeTest", extension = "kt")
|
model("scopes/fileScopeTest", extension = "kt")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testClass<AbstractFirDelegateMemberScopeTest> {
|
||||||
|
model("scopes/delegatedMemberScope")
|
||||||
|
}
|
||||||
|
|
||||||
testClass<AbstractFirSymbolByPsiTest> {
|
testClass<AbstractFirSymbolByPsiTest> {
|
||||||
model("symbols/symbolByPsi")
|
model("symbols/symbolByPsi")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user