org.jetbrains.kotlin.resolve.DelegateInferenceSession.kt Maven / Gradle / Ivy
/*
* Copyright 2000-2018 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
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.resolve.calls.components.*
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.inference.BuilderInferenceSession
import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemBuilder
import org.jetbrains.kotlin.resolve.calls.inference.NewConstraintSystem
import org.jetbrains.kotlin.resolve.calls.inference.components.ConstraintSystemCompletionMode
import org.jetbrains.kotlin.resolve.calls.inference.components.KotlinConstraintSystemCompleter
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.inference.model.DelegatedPropertyConstraintPositionImpl
import org.jetbrains.kotlin.resolve.calls.model.*
import org.jetbrains.kotlin.resolve.calls.tower.StubTypesBasedInferenceSession
import org.jetbrains.kotlin.resolve.calls.tower.PSICallResolver
import org.jetbrains.kotlin.resolve.calls.tower.PSIPartialCallInfo
import org.jetbrains.kotlin.types.error.ErrorUtils
import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.util.OperatorNameConventions
class DelegateInferenceSession(
val variableDescriptor: VariableDescriptorWithAccessors,
val expectedType: UnwrappedType?,
psiCallResolver: PSICallResolver,
postponedArgumentsAnalyzer: PostponedArgumentsAnalyzer,
kotlinConstraintSystemCompleter: KotlinConstraintSystemCompleter,
callComponents: KotlinCallComponents,
builtIns: KotlinBuiltIns,
override val parentSession: InferenceSession?
) : StubTypesBasedInferenceSession(
psiCallResolver, postponedArgumentsAnalyzer, kotlinConstraintSystemCompleter, callComponents, builtIns
) {
init {
if (parentSession is StubTypesBasedInferenceSession<*>) {
parentSession.addNestedInferenceSession(this)
}
}
fun getNestedBuilderInferenceSessions(): List {
val builderInferenceSessions = nestedInferenceSessions.filterIsInstance()
val delegatedPropertyInferenceSessions = nestedInferenceSessions.filterIsInstance()
return builderInferenceSessions + delegatedPropertyInferenceSessions.map { it.getNestedBuilderInferenceSessions() }.flatten()
}
override fun prepareForCompletion(commonSystem: NewConstraintSystem, resolvedCallsInfo: List) {
val csBuilder = commonSystem.getBuilder()
for (callInfo in resolvedCallsInfo) {
val resultAtom = callInfo.callResolutionResult.resultCallAtom
when (resultAtom.candidateDescriptor.name) {
OperatorNameConventions.GET_VALUE -> resultAtom.addConstraintsForGetValueMethod(csBuilder)
OperatorNameConventions.SET_VALUE -> resultAtom.addConstraintsForSetValueMethod(csBuilder)
}
}
}
private fun ResolvedCallAtom.addConstraintForThis(descriptor: CallableDescriptor, commonSystem: ConstraintSystemBuilder) {
val typeOfThis = variableDescriptor.extensionReceiverParameter?.type
?: variableDescriptor.dispatchReceiverParameter?.type
?: builtIns.nullableNothingType
val valueParameterForThis = descriptor.valueParameters.getOrNull(0) ?: return
val substitutedType = freshVariablesSubstitutor.safeSubstitute(valueParameterForThis.type.unwrap())
commonSystem.addSubtypeConstraint(typeOfThis.unwrap(), substitutedType, DelegatedPropertyConstraintPositionImpl(atom))
}
private fun ResolvedCallAtom.addConstraintsForGetValueMethod(commonSystem: ConstraintSystemBuilder) {
if (expectedType != null) {
val unsubstitutedReturnType = candidateDescriptor.returnType?.unwrap() ?: return
val substitutedReturnType = freshVariablesSubstitutor.safeSubstitute(unsubstitutedReturnType)
commonSystem.addSubtypeConstraint(substitutedReturnType, expectedType, DelegatedPropertyConstraintPositionImpl(atom))
}
addConstraintForThis(candidateDescriptor, commonSystem)
}
private fun ResolvedCallAtom.addConstraintsForSetValueMethod(commonSystem: ConstraintSystemBuilder) {
if (expectedType != null) {
val unsubstitutedParameterType = candidateDescriptor.valueParameters.getOrNull(2)?.type?.unwrap() ?: return
val substitutedParameterType = freshVariablesSubstitutor.safeSubstitute(unsubstitutedParameterType)
commonSystem.addSubtypeConstraint(expectedType, substitutedParameterType, DelegatedPropertyConstraintPositionImpl(atom))
}
addConstraintForThis(candidateDescriptor, commonSystem)
}
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map = emptyMap()
override fun initializeLambda(lambda: ResolvedLambdaAtom) {}
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom) = true
}
class InferenceSessionForExistingCandidates(
private val resolveReceiverIndependently: Boolean,
override val parentSession: InferenceSession?
) : InferenceSession {
override fun shouldRunCompletion(candidate: ResolutionCandidate): Boolean {
return !ErrorUtils.isError(candidate.resolvedCall.candidateDescriptor)
}
override fun addPartialCallInfo(callInfo: PartialCallInfo) {}
override fun addCompletedCallInfo(callInfo: CompletedCallInfo) {}
override fun addErrorCallInfo(callInfo: ErrorCallInfo) {}
override fun currentConstraintSystem(): ConstraintStorage = ConstraintStorage.Empty
override fun inferPostponedVariables(
lambda: ResolvedLambdaAtom,
constraintSystemBuilder: ConstraintSystemBuilder,
completionMode: ConstraintSystemCompletionMode,
diagnosticsHolder: KotlinDiagnosticsHolder
): Map = emptyMap()
override fun writeOnlyStubs(callInfo: SingleCallResolutionResult): Boolean = false
override fun callCompleted(resolvedAtom: ResolvedAtom): Boolean = false
override fun shouldCompleteResolvedSubAtomsOf(resolvedCallAtom: ResolvedCallAtom): Boolean {
return !ErrorUtils.isError(resolvedCallAtom.candidateDescriptor)
}
override fun computeCompletionMode(
candidate: ResolutionCandidate
): ConstraintSystemCompletionMode? = null
override fun resolveReceiverIndependently(): Boolean = resolveReceiverIndependently
override fun initializeLambda(lambda: ResolvedLambdaAtom) {}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy