[NI] Support EffectSystem
- During final phase of resolution (i.e. converting NI-results to OI-results), make call into EffectSystem to record all necessary effects-related information. - To be able to enhance resulting dataFlowInfo for call at that stage, introduce internal method 'updateResultingDataFlowInfo' in NewResolvedCallImpl.
This commit is contained in:
+16
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.contracts.EffectSystem
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
@@ -68,7 +69,8 @@ class KotlinToResolvedCallTransformer(
|
||||
private val deprecationResolver: DeprecationResolver,
|
||||
private val expressionTypingServices: ExpressionTypingServices,
|
||||
private val doubleColonExpressionResolver: DoubleColonExpressionResolver,
|
||||
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter
|
||||
private val additionalDiagnosticReporter: AdditionalDiagnosticReporter,
|
||||
private val effectSystem: EffectSystem
|
||||
) {
|
||||
|
||||
companion object {
|
||||
@@ -387,6 +389,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>(): ResolvedCall<D>
|
||||
protected var argumentToParameterMap: Map<ValueArgument, ArgumentMatchImpl>? = null
|
||||
protected var _valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>? = null
|
||||
|
||||
private var nonTrivialUpdatedResultInfo: DataFlowInfo? = null
|
||||
|
||||
override fun getCall(): Call = kotlinCall.psiKotlinCall.psiCall
|
||||
|
||||
override fun getValueArguments(): Map<ValueParameterDescriptor, ResolvedValueArgument> {
|
||||
@@ -423,7 +427,8 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>(): ResolvedCall<D>
|
||||
}
|
||||
|
||||
override fun getDataFlowInfoForArguments() = object : DataFlowInfoForArguments {
|
||||
override fun getResultInfo() = kotlinCall.psiKotlinCall.resultDataFlowInfo
|
||||
override fun getResultInfo(): DataFlowInfo = nonTrivialUpdatedResultInfo ?: kotlinCall.psiKotlinCall.resultDataFlowInfo
|
||||
|
||||
override fun getInfo(valueArgument: ValueArgument): DataFlowInfo {
|
||||
val externalPsiCallArgument = kotlinCall.externalArgument?.psiCallArgument
|
||||
if (externalPsiCallArgument?.valueArgument == valueArgument) {
|
||||
@@ -433,6 +438,15 @@ sealed class NewAbstractResolvedCall<D : CallableDescriptor>(): ResolvedCall<D>
|
||||
}
|
||||
}
|
||||
|
||||
// Currently, updated only with info from effect system
|
||||
internal fun updateResultingDataFlowInfo(dataFlowInfo: DataFlowInfo) {
|
||||
if (dataFlowInfo == DataFlowInfo.EMPTY) return
|
||||
assert(nonTrivialUpdatedResultInfo == null) {
|
||||
"Attempt to rewrite resulting dataFlowInfo enhancement for call: $kotlinCall"
|
||||
}
|
||||
nonTrivialUpdatedResultInfo = dataFlowInfo.and(kotlinCall.psiKotlinCall.resultDataFlowInfo)
|
||||
}
|
||||
|
||||
private fun argumentToParameterMap(
|
||||
resultingDescriptor: CallableDescriptor,
|
||||
valueArguments: Map<ValueParameterDescriptor, ResolvedValueArgument>
|
||||
|
||||
@@ -18,20 +18,15 @@ package org.jetbrains.kotlin.resolve.calls.tower
|
||||
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
||||
import org.jetbrains.kotlin.contracts.EffectSystem
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.referenceExpression
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.ModifierCheckerCore
|
||||
import org.jetbrains.kotlin.resolve.TemporaryBindingTrace
|
||||
import org.jetbrains.kotlin.resolve.TypeResolver
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.ArgumentTypeResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.KotlinCallResolver
|
||||
import org.jetbrains.kotlin.resolve.calls.callResolverUtil.isBinaryRemOperator
|
||||
@@ -73,7 +68,8 @@ class PSICallResolver(
|
||||
private val kotlinToResolvedCallTransformer: KotlinToResolvedCallTransformer,
|
||||
private val kotlinCallResolver: KotlinCallResolver,
|
||||
private val typeApproximator: TypeApproximator,
|
||||
private val argumentTypeResolver: ArgumentTypeResolver
|
||||
private val argumentTypeResolver: ArgumentTypeResolver,
|
||||
private val effectSystem: EffectSystem
|
||||
) {
|
||||
private val GIVEN_CANDIDATES_NAME = Name.special("<given candidates>")
|
||||
|
||||
@@ -221,9 +217,30 @@ class PSICallResolver(
|
||||
else {
|
||||
kotlinToResolvedCallTransformer.transformAndReport<D>(result, context)
|
||||
}
|
||||
|
||||
// NB. Be careful with moving this invocation, as effect system expects resolution results to be written in trace
|
||||
// (see EffectSystem for details)
|
||||
resolvedCall.recordEffects(trace)
|
||||
|
||||
return SingleOverloadResolutionResult(resolvedCall)
|
||||
}
|
||||
|
||||
private fun ResolvedCall<*>.recordEffects(trace: BindingTrace) {
|
||||
val moduleDescriptor = DescriptorUtils.getContainingModule(this.resultingDescriptor?.containingDeclaration ?: return)
|
||||
recordLambdasInvocations(trace, moduleDescriptor)
|
||||
recordResultInfo(trace, moduleDescriptor)
|
||||
}
|
||||
|
||||
private fun ResolvedCall<*>.recordResultInfo(trace: BindingTrace, moduleDescriptor: ModuleDescriptor) {
|
||||
if (this !is NewResolvedCallImpl) return
|
||||
val resultDFIfromES = effectSystem.getDataFlowInfoForFinishedCall(this, trace, moduleDescriptor)
|
||||
this.updateResultingDataFlowInfo(resultDFIfromES)
|
||||
}
|
||||
|
||||
private fun ResolvedCall<*>.recordLambdasInvocations(trace: BindingTrace, moduleDescriptor: ModuleDescriptor) {
|
||||
effectSystem.recordDefiniteInvocations(this, trace, moduleDescriptor)
|
||||
}
|
||||
|
||||
private fun CallResolutionResult.isEmpty(): Boolean =
|
||||
diagnostics.firstIsInstanceOrNull<NoneCandidatesCallDiagnostic>() != null
|
||||
|
||||
|
||||
Reference in New Issue
Block a user