From 71b6151d51c01d41109e13bc4861f286df25735f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Fri, 20 May 2022 16:08:26 +0200 Subject: [PATCH] KtFe10ScopeProvider: implement declared/delegated member scope --- .../components/KtFe10ScopeProvider.kt | 92 +++++++++++++++++-- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ScopeProvider.kt b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ScopeProvider.kt index 270038ecf7b..0d4ef851184 100644 --- a/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ScopeProvider.kt +++ b/analysis/analysis-api-fe10/src/org/jetbrains/kotlin/analysis/api/descriptors/components/KtFe10ScopeProvider.kt @@ -31,15 +31,19 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolWithMembers import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken import org.jetbrains.kotlin.analysis.api.types.KtType import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.packageFragments +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.incremental.components.LookupLocation +import org.jetbrains.kotlin.incremental.components.NoLookupLocation +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.resolve.scopes.ChainedMemberScope +import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter import org.jetbrains.kotlin.resolve.scopes.LexicalScope +import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.resolve.scopes.utils.getImplicitReceiversHierarchy import org.jetbrains.kotlin.util.containingNonLocalDeclaration +import org.jetbrains.kotlin.utils.Printer internal class KtFe10ScopeProvider( override val analysisSession: KtFe10AnalysisSession @@ -55,7 +59,6 @@ internal class KtFe10ScopeProvider( val descriptor = getDescriptor(classSymbol) ?: return getEmptyScope() - // TODO either this or declared scope should return a different set of members return KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisContext) } @@ -63,16 +66,89 @@ internal class KtFe10ScopeProvider( val descriptor = getDescriptor(classSymbol) ?: return getEmptyScope() - // TODO: need to return declared members only - return KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisContext) + return KtFe10ScopeMember(DeclaredMemberScope(descriptor), analysisContext) } override fun getDelegatedMemberScope(classSymbol: KtSymbolWithMembers): KtScope = withValidityAssertion { val descriptor = getDescriptor(classSymbol) ?: return getEmptyScope() - // TODO: need to return delegated members only - return KtFe10ScopeMember(descriptor.unsubstitutedMemberScope, analysisContext) + return KtFe10ScopeMember(DeclaredMemberScope(descriptor, forDelegatedMembersOnly = true), analysisContext) + } + + private class DeclaredMemberScope( + val allMemberScope: MemberScope, + val owner: ClassDescriptor, + val forDelegatedMembersOnly: Boolean + ) : MemberScope { + constructor(owner: ClassDescriptor, forDelegatedMembersOnly: Boolean = false) : + this(owner.unsubstitutedMemberScope, owner, forDelegatedMembersOnly) + + override fun getContributedVariables(name: Name, location: LookupLocation): Collection { + return allMemberScope.getContributedVariables(name, location).filter { + it.containingDeclaration == owner && it.isDelegatedIfRequired() + }.mapToDelegatedIfRequired() + } + + override fun getContributedFunctions(name: Name, location: LookupLocation): Collection { + return allMemberScope.getContributedFunctions(name, location).filter { + it.containingDeclaration == owner && it.isDelegatedIfRequired() + }.mapToDelegatedIfRequired() + } + + override fun getFunctionNames(): Set { + return allMemberScope.getFunctionNames().filterTo(mutableSetOf()) { name -> + getContributedFunctions(name, NoLookupLocation.FROM_IDE).isNotEmpty() + } + } + + override fun getVariableNames(): Set { + return allMemberScope.getVariableNames().filterTo(mutableSetOf()) { name -> + getContributedVariables(name, NoLookupLocation.FROM_IDE).isNotEmpty() + } + } + + override fun getClassifierNames(): Set? { + if (forDelegatedMembersOnly) return null + return allMemberScope.getClassifierNames()?.filterTo(mutableSetOf()) { name -> + getContributedClassifier(name, NoLookupLocation.FROM_IDE) != null + } + } + + override fun printScopeStructure(p: Printer) { + allMemberScope.printScopeStructure(p) + } + + override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? { + if (forDelegatedMembersOnly) return null + return allMemberScope.getContributedClassifier(name, location)?.takeIf { it.containingDeclaration == owner } + } + + override fun getContributedDescriptors( + kindFilter: DescriptorKindFilter, + nameFilter: (Name) -> Boolean + ): Collection { + return allMemberScope.getContributedDescriptors(kindFilter, nameFilter).filter { + it.containingDeclaration == owner && it.isDelegatedIfRequired() + }.mapToDelegatedIfRequired() + } + + private fun DeclarationDescriptor.isDelegatedIfRequired(): Boolean = + !forDelegatedMembersOnly || this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.DELEGATION + + private inline fun Collection.mapToDelegatedIfRequired(): Collection { + if (!forDelegatedMembersOnly) return this + return map { + val overridden = (it as CallableMemberDescriptor).overriddenDescriptors.firstOrNull() + overridden?.newCopyBuilder() + ?.setModality(Modality.OPEN) + ?.setKind(CallableMemberDescriptor.Kind.DELEGATION) + ?.setDispatchReceiverParameter(it.dispatchReceiverParameter) + ?.setPreserveSourceElement() + ?.build() as? D ?: it + } + } + } override fun getStaticMemberScope(symbol: KtSymbolWithMembers): KtScope = withValidityAssertion {