Allow skipping extensions resolution for implicit receivers

This commit is contained in:
Ilya Muradyan
2020-06-04 13:43:31 +03:00
committed by Ilya Chernikov
parent e93bcc55ae
commit 017f640f26
7 changed files with 77 additions and 17 deletions
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.resolve.calls.model.KotlinCallDiagnostic
import org.jetbrains.kotlin.resolve.calls.tower.ResolutionCandidateApplicability.*
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeApproximator
@@ -44,6 +45,11 @@ interface ImplicitScopeTower {
val typeApproximator: TypeApproximator
val implicitsResolutionFilter: ImplicitsExtensionsResolutionFilter
fun allScopesWithImplicitsResolutionInfo(): Sequence<ScopeWithImplicitsExtensionsResolutionInfo> =
implicitsResolutionFilter.getScopesWithInfo(lexicalScope.parentsWithSelf)
fun interceptFunctionCandidates(
resolutionScope: ResolutionScope,
name: Name,
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2020 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.resolve.calls.tower
import org.jetbrains.kotlin.container.DefaultImplementation
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
@DefaultImplementation(ImplicitsExtensionsResolutionFilter.Default::class)
interface ImplicitsExtensionsResolutionFilter {
fun getScopesWithInfo(
scopes: Sequence<HierarchicalScope>
): Sequence<ScopeWithImplicitsExtensionsResolutionInfo>
object Default : ImplicitsExtensionsResolutionFilter {
override fun getScopesWithInfo(
scopes: Sequence<HierarchicalScope>
): Sequence<ScopeWithImplicitsExtensionsResolutionInfo> = scopes.map { scope ->
ScopeWithImplicitsExtensionsResolutionInfo(scope, true)
}
}
}
class ScopeWithImplicitsExtensionsResolutionInfo(
val scope: HierarchicalScope,
val resolveExtensionsForImplicitReceiver: Boolean,
)
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.progress.ProgressIndicatorAndCompilationCanceledStatus
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.resolve.descriptorUtil.HIDES_MEMBERS_NAME_LIST
import org.jetbrains.kotlin.resolve.scopes.HierarchicalScope
import org.jetbrains.kotlin.resolve.scopes.ImportingScope
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
@@ -185,7 +186,7 @@ class TowerResolver {
TowerData.TowerLevel(localLevel).process()?.let { return it }
}
for (scope in implicitScopeTower.lexicalScope.parentsWithSelf) {
fun processScope(scope: HierarchicalScope, resolveExtensionsForImplicitReceiver: Boolean): Collection<C>? {
if (scope is LexicalScope) {
// statics
if (!scope.kind.withLocalDescriptors) {
@@ -194,12 +195,23 @@ class TowerResolver {
}
implicitScopeTower.getImplicitReceiver(scope)
?.let(this::processImplicitReceiver)
?.let { processImplicitReceiver(it, resolveExtensionsForImplicitReceiver) }
?.let { return it }
} else {
TowerData.TowerLevel(ImportingScopeBasedTowerLevel(implicitScopeTower, scope as ImportingScope))
.process(scope.mayFitForName(name))?.let { return it }
}
return null
}
if (implicitScopeTower.implicitsResolutionFilter === ImplicitsExtensionsResolutionFilter.Default) {
for (scope in implicitScopeTower.lexicalScope.parentsWithSelf) {
processScope(scope, true)?.let { return it }
}
} else {
for (scopeInfo in implicitScopeTower.allScopesWithImplicitsResolutionInfo()) {
processScope(scopeInfo.scope, scopeInfo.resolveExtensionsForImplicitReceiver)?.let { return it }
}
}
recordLookups()
@@ -207,7 +219,7 @@ class TowerResolver {
return resultCollector.getFinalCandidates()
}
private fun processImplicitReceiver(implicitReceiver: ReceiverValueWithSmartCastInfo): Collection<C>? {
private fun processImplicitReceiver(implicitReceiver: ReceiverValueWithSmartCastInfo, resolveExtensions: Boolean): Collection<C>? {
if (isNameForHidesMember) {
// hides members extensions
TowerData.BothTowerLevelAndImplicitReceiver(hidesMembersLevel, implicitReceiver).process()?.let { return it }
@@ -220,17 +232,19 @@ class TowerResolver {
// synthetic properties
TowerData.BothTowerLevelAndImplicitReceiver(syntheticLevel, implicitReceiver).process()?.let { return it }
// invokeExtension on local variable
TowerData.OnlyImplicitReceiver(implicitReceiver).process()?.let { return it }
if (resolveExtensions) {
// invokeExtension on local variable
TowerData.OnlyImplicitReceiver(implicitReceiver).process()?.let { return it }
// local extensions for implicit receiver
for (localLevel in localLevels) {
TowerData.BothTowerLevelAndImplicitReceiver(localLevel, implicitReceiver).process()?.let { return it }
}
// local extensions for implicit receiver
for (localLevel in localLevels) {
TowerData.BothTowerLevelAndImplicitReceiver(localLevel, implicitReceiver).process()?.let { return it }
}
// extension for implicit receiver
for (nonLocalLevel in nonLocalLevels) {
TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it }
// extension for implicit receiver
for (nonLocalLevel in nonLocalLevels) {
TowerData.BothTowerLevelAndImplicitReceiver(nonLocalLevel, implicitReceiver).process()?.let { return it }
}
}
return null