Compose: adapt new API for intercepting candidates in call resolvers

Most part is made by @lelandrichardson
This commit is contained in:
Mikhail Zarechenskiy
2020-05-22 13:08:19 +03:00
parent 500acf412f
commit 4dbd4a56d5
6 changed files with 229 additions and 59 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.extensions.internal
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.extensions.ProjectExtensionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
@@ -18,7 +19,9 @@ import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
@OptIn(InternalNonStableExtensionPoints::class)
class CandidateInterceptor(project: Project) {
@@ -28,7 +31,7 @@ class CandidateInterceptor(project: Project) {
candidates: Collection<NewResolutionOldInference.MyCandidate>,
context: BasicCallResolutionContext,
candidateResolver: CandidateResolver,
callResolver: CallResolver?,
callResolver: CallResolver,
name: Name,
kind: NewResolutionOldInference.ResolutionKind,
tracing: TracingStrategy
@@ -36,34 +39,58 @@ class CandidateInterceptor(project: Project) {
extension.interceptCandidates(it, context, candidateResolver, callResolver, name, kind, tracing)
}
fun interceptResolvedCandidates(
callResolutionResult: CallResolutionResult,
context: BasicCallResolutionContext,
callResolver: KotlinCallResolver,
name: Name,
kind: NewResolutionOldInference.ResolutionKind,
tracing: TracingStrategy
): CallResolutionResult {
var resolutionResult = callResolutionResult
for (extension in extensions) {
resolutionResult = extension.interceptCandidates(
resolutionResult, context, callResolver, name, kind, tracing
)
}
return resolutionResult
}
fun interceptCandidates(
fun interceptFunctionCandidates(
candidates: Collection<FunctionDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: CallResolver?,
callResolver: CallResolver,
name: Name,
location: LookupLocation
): Collection<FunctionDescriptor> = extensions.fold(candidates) { it, extension ->
extension.interceptCandidates(it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location)
extension.interceptFunctionCandidates(it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location)
}
fun interceptFunctionCandidates(
candidates: Collection<FunctionDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: PSICallResolver,
name: Name,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<FunctionDescriptor> = extensions.fold(candidates) { it, extension ->
extension.interceptFunctionCandidates(
it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location, dispatchReceiver, extensionReceiver
)
}
fun interceptVariableCandidates(
candidates: Collection<VariableDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: CallResolver,
name: Name,
location: LookupLocation
): Collection<VariableDescriptor> = extensions.fold(candidates) { it, extension ->
extension.interceptVariableCandidates(it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location)
}
fun interceptVariableCandidates(
candidates: Collection<VariableDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: PSICallResolver,
name: Name,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<VariableDescriptor> = extensions.fold(candidates) { it, extension ->
extension.interceptVariableCandidates(it, scopeTower, resolutionContext, resolutionScope, callResolver, name, location, dispatchReceiver, extensionReceiver)
}
companion object : ProjectExtensionDescriptor<CallResolutionInterceptorExtension>(
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.extensions.internal
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
@@ -13,13 +14,13 @@ import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtLambdaExpression
import org.jetbrains.kotlin.resolve.calls.CallResolver
import org.jetbrains.kotlin.resolve.calls.CandidateResolver
import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver
import org.jetbrains.kotlin.resolve.calls.context.BasicCallResolutionContext
import org.jetbrains.kotlin.resolve.calls.model.CallResolutionResult
import org.jetbrains.kotlin.resolve.calls.tasks.TracingStrategy
import org.jetbrains.kotlin.resolve.calls.tower.ImplicitScopeTower
import org.jetbrains.kotlin.resolve.calls.tower.NewResolutionOldInference
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
import org.jetbrains.kotlin.resolve.scopes.ResolutionScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext
@@ -51,26 +52,68 @@ interface TypeResolutionInterceptorExtension {
@InternalNonStableExtensionPoints
interface CallResolutionInterceptorExtension {
@JvmDefault
fun interceptCandidates(
candidates: Collection<NewResolutionOldInference.MyCandidate>,
context: BasicCallResolutionContext,
candidateResolver: CandidateResolver,
callResolver: CallResolver?,
callResolver: CallResolver,
name: Name,
kind: NewResolutionOldInference.ResolutionKind,
tracing: TracingStrategy
): Collection<NewResolutionOldInference.MyCandidate> = candidates
@JvmDefault
fun interceptCandidates(
callResolutionResult: CallResolutionResult,
context: BasicCallResolutionContext,
callResolver: KotlinCallResolver,
fun interceptFunctionCandidates(
candidates: Collection<FunctionDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: CallResolver,
name: Name,
kind: NewResolutionOldInference.ResolutionKind,
tracing: TracingStrategy
): CallResolutionResult = callResolutionResult
location: LookupLocation
): Collection<FunctionDescriptor> = candidates
@JvmDefault
fun interceptFunctionCandidates(
candidates: Collection<FunctionDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: PSICallResolver,
name: Name,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<FunctionDescriptor> = candidates
@JvmDefault
fun interceptVariableCandidates(
candidates: Collection<VariableDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: CallResolver,
name: Name,
location: LookupLocation
): Collection<VariableDescriptor> = candidates
@JvmDefault
fun interceptVariableCandidates(
candidates: Collection<VariableDescriptor>,
scopeTower: ImplicitScopeTower,
resolutionContext: BasicCallResolutionContext,
resolutionScope: ResolutionScope,
callResolver: PSICallResolver,
name: Name,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<VariableDescriptor> = candidates
@Suppress("DeprecatedCallableAddReplaceWith")
@Deprecated("Please use dedicated interceptVariableCandidates and interceptFunctionCandidates instead")
@JvmDefault
fun interceptCandidates(
candidates: Collection<FunctionDescriptor>,
scopeTower: ImplicitScopeTower,
@@ -80,4 +123,4 @@ interface CallResolutionInterceptorExtension {
name: Name,
location: LookupLocation
): Collection<FunctionDescriptor> = candidates
}
}
@@ -379,13 +379,27 @@ class NewResolutionOldInference(
override val isNewInferenceEnabled: Boolean
get() = resolutionContext.languageVersionSettings.supportsFeature(LanguageFeature.NewInference)
override fun interceptCandidates(
override fun interceptFunctionCandidates(
resolutionScope: ResolutionScope,
name: Name,
initialResults: Collection<FunctionDescriptor>,
location: LookupLocation
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<FunctionDescriptor> {
return candidateInterceptor.interceptCandidates(initialResults, this, resolutionContext, resolutionScope, callResolver, name, location)
return candidateInterceptor.interceptFunctionCandidates(initialResults, this, resolutionContext, resolutionScope, callResolver, name, location)
}
override fun interceptVariableCandidates(
resolutionScope: ResolutionScope,
name: Name,
initialResults: Collection<VariableDescriptor>,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<VariableDescriptor> {
return candidateInterceptor.interceptVariableCandidates(initialResults, this, resolutionContext, resolutionScope, callResolver, name, location)
}
}
@@ -110,10 +110,6 @@ class PSICallResolver(
return OverloadResolutionResultsImpl.nameNotFound()
}
result = candidateInterceptor.interceptResolvedCandidates(
result, context, kotlinCallResolver, name, resolutionKind, tracingStrategy
)
val overloadResolutionResults = convertToOverloadResolutionResults<D>(context, result, tracingStrategy)
return overloadResolutionResults.also {
clearCacheForApproximationResults()
@@ -407,13 +403,46 @@ class PSICallResolver(
}
}
override fun interceptCandidates(
override fun interceptFunctionCandidates(
resolutionScope: ResolutionScope,
name: Name,
initialResults: Collection<FunctionDescriptor>,
location: LookupLocation
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<FunctionDescriptor> {
return candidateInterceptor.interceptCandidates(initialResults, this, context, resolutionScope, null, name, location)
return candidateInterceptor.interceptFunctionCandidates(
initialResults,
this,
context,
resolutionScope,
this@PSICallResolver,
name,
location,
dispatchReceiver,
extensionReceiver
)
}
override fun interceptVariableCandidates(
resolutionScope: ResolutionScope,
name: Name,
initialResults: Collection<VariableDescriptor>,
location: LookupLocation,
dispatchReceiver: ReceiverValueWithSmartCastInfo?,
extensionReceiver: ReceiverValueWithSmartCastInfo?
): Collection<VariableDescriptor> {
return candidateInterceptor.interceptVariableCandidates(
initialResults,
this,
context,
resolutionScope,
this@PSICallResolver,
name,
location,
dispatchReceiver,
extensionReceiver
)
}
}