
org.jetbrains.kotlin.resolve.calls.model.ResolutionAtoms.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.calls.model
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.components.CallableReferenceCandidate
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper
import org.jetbrains.kotlin.resolve.calls.components.extractInputOutputTypesFromCallableReferenceExpectedType
import org.jetbrains.kotlin.resolve.calls.inference.components.FreshVariableNewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.components.NewTypeSubstitutor
import org.jetbrains.kotlin.resolve.calls.inference.model.ConstraintStorage
import org.jetbrains.kotlin.resolve.calls.inference.model.NewConstraintError
import org.jetbrains.kotlin.resolve.calls.inference.model.TypeVariableForLambdaReturnType
import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.UnwrappedType
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.typeUtil.unCapture
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
/**
* Call, Callable reference, lambda & function expression, collection literal.
* In future we should add literals here, because they have similar lifecycle.
*
* Expression with type is also primitive. This is done for simplification. todo
*/
interface ResolutionAtom
sealed class ResolvedAtom {
abstract val atom: ResolutionAtom? // CallResolutionResult has no ResolutionAtom
var analyzed: Boolean = false
private set
lateinit var subResolvedAtoms: List
private set
protected open fun setAnalyzedResults(subResolvedAtoms: List) {
assert(!analyzed) {
"Already analyzed: $this"
}
analyzed = true
this.subResolvedAtoms = subResolvedAtoms
}
// For AllCandidates mode to avoid analyzing postponed arguments
fun setEmptyAnalyzedResults() {
setAnalyzedResults(emptyList())
}
}
abstract class ResolvedCallAtom : ResolvedAtom() {
abstract override val atom: KotlinCall
abstract val candidateDescriptor: CallableDescriptor
abstract val explicitReceiverKind: ExplicitReceiverKind
abstract val dispatchReceiverArgument: SimpleKotlinCallArgument?
abstract val extensionReceiverArgument: SimpleKotlinCallArgument?
abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
abstract val argumentMappingByOriginal: Map
abstract val substitutor: FreshVariableNewTypeSubstitutor
abstract val argumentsWithConversion: Map
}
class SamConversionDescription(
val convertedTypeByOriginParameter: UnwrappedType,
val convertedTypeByCandidateParameter: UnwrappedType // expected type for corresponding argument
)
class ResolvedExpressionAtom(override val atom: ExpressionKotlinCallArgument) : ResolvedAtom() {
init {
setAnalyzedResults(listOf())
}
}
interface PostponedResolvedAtomMarker {
val inputTypes: Collection
val outputType: KotlinTypeMarker?
val analyzed: Boolean
}
sealed class PostponedResolvedAtom : ResolvedAtom(), PostponedResolvedAtomMarker {
abstract override val inputTypes: Collection
abstract override val outputType: UnwrappedType?
}
class LambdaWithTypeVariableAsExpectedTypeAtom(
override val atom: LambdaKotlinCallArgument,
val expectedType: UnwrappedType
) : PostponedResolvedAtom() {
override val inputTypes: Collection get() = listOf(expectedType)
override val outputType: UnwrappedType? get() = null
fun setAnalyzed(resolvedLambdaAtom: ResolvedLambdaAtom) {
setAnalyzedResults(listOf(resolvedLambdaAtom))
}
}
class ResolvedLambdaAtom(
override val atom: LambdaKotlinCallArgument,
val isSuspend: Boolean,
val receiver: UnwrappedType?,
val parameters: List,
val returnType: UnwrappedType,
val typeVariableForLambdaReturnType: TypeVariableForLambdaReturnType?,
val expectedType: UnwrappedType?
) : PostponedResolvedAtom() {
lateinit var resultArguments: List
private set
fun setAnalyzedResults(
resultArguments: List,
subResolvedAtoms: List
) {
this.resultArguments = resultArguments
setAnalyzedResults(subResolvedAtoms)
}
override val inputTypes: Collection get() = receiver?.let { parameters + it } ?: parameters
override val outputType: UnwrappedType get() = returnType
}
abstract class ResolvedCallableReferenceAtom(
override val atom: CallableReferenceKotlinCallArgument,
val expectedType: UnwrappedType?
) : PostponedResolvedAtom() {
var candidate: CallableReferenceCandidate? = null
private set
fun setAnalyzedResults(
candidate: CallableReferenceCandidate?,
subResolvedAtoms: List
) {
this.candidate = candidate
setAnalyzedResults(subResolvedAtoms)
}
}
class EagerCallableReferenceAtom(
atom: CallableReferenceKotlinCallArgument,
expectedType: UnwrappedType?
) : ResolvedCallableReferenceAtom(atom, expectedType) {
override val inputTypes: Collection get() = emptyList()
override val outputType: UnwrappedType? get() = null
fun transformToPostponed(): PostponedCallableReferenceAtom = PostponedCallableReferenceAtom(this)
}
class PostponedCallableReferenceAtom(
eagerCallableReferenceAtom: EagerCallableReferenceAtom
) : ResolvedCallableReferenceAtom(eagerCallableReferenceAtom.atom, eagerCallableReferenceAtom.expectedType) {
override val inputTypes: Collection
get() = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.inputTypes ?: listOfNotNull(expectedType)
override val outputType: UnwrappedType?
get() = extractInputOutputTypesFromCallableReferenceExpectedType(expectedType)?.outputType
}
class ResolvedCollectionLiteralAtom(
override val atom: CollectionLiteralKotlinCallArgument,
val expectedType: UnwrappedType?
) : ResolvedAtom() {
init {
setAnalyzedResults(listOf())
}
}
sealed class CallResolutionResult(
resultCallAtom: ResolvedCallAtom?,
val diagnostics: List,
val constraintSystem: ConstraintStorage
) : ResolvedAtom() {
init {
setAnalyzedResults(listOfNotNull(resultCallAtom))
}
final override fun setAnalyzedResults(subResolvedAtoms: List) {
super.setAnalyzedResults(subResolvedAtoms)
}
fun completedDiagnostic(substitutor: NewTypeSubstitutor): List {
return diagnostics.map {
if (it !is NewConstraintError) return@map it
val lowerType = it.lowerType.safeAs()?.unwrap() ?: return@map it
val newLowerType = substitutor.safeSubstitute(lowerType.unCapture())
NewConstraintError(newLowerType, it.upperType, it.position)
}
}
override val atom: ResolutionAtom? get() = null
override fun toString() = "diagnostics: (${diagnostics.joinToString()})"
}
open class SingleCallResolutionResult(
val resultCallAtom: ResolvedCallAtom,
diagnostics: List,
constraintSystem: ConstraintStorage
) : CallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class PartialCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class CompletedCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class ErrorCallResolutionResult(
resultCallAtom: ResolvedCallAtom,
diagnostics: List,
constraintSystem: ConstraintStorage
) : SingleCallResolutionResult(resultCallAtom, diagnostics, constraintSystem)
class AllCandidatesResolutionResult(
val allCandidates: Collection
) : CallResolutionResult(null, emptyList(), ConstraintStorage.Empty)
data class CandidateWithDiagnostics(val candidate: KotlinResolutionCandidate, val diagnostics: List)
fun CallResolutionResult.resultCallAtom(): ResolvedCallAtom? =
if (this is SingleCallResolutionResult) resultCallAtom else null
val ResolvedCallAtom.freshReturnType: UnwrappedType?
get() {
val returnType = candidateDescriptor.returnType ?: return null
return substitutor.safeSubstitute(returnType.unwrap())
}
class PartialCallContainer(val result: PartialCallResolutionResult?) {
companion object {
val empty = PartialCallContainer(null)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy