org.jetbrains.kotlin.resolve.calls.results.FlatSignature.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-embeddable Show documentation
Show all versions of kotlin-compiler-embeddable Show documentation
the Kotlin compiler embeddable
/*
* 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.results
import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.model.*
interface SpecificityComparisonCallbacks {
fun isNonSubtypeEquallyOrMoreSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean
}
object OverloadabilitySpecificityCallbacks : SpecificityComparisonCallbacks {
override fun isNonSubtypeEquallyOrMoreSpecific(specific: KotlinTypeMarker, general: KotlinTypeMarker): Boolean =
false
}
class TypeWithConversion(val resultType: KotlinTypeMarker?, val originalTypeIfWasConverted: KotlinTypeMarker? = null)
class FlatSignature constructor(
val origin: T,
val typeParameters: Collection,
val hasExtensionReceiver: Boolean,
val contextReceiverCount: Int,
val hasVarargs: Boolean,
val numDefaults: Int,
val isExpect: Boolean,
val isSyntheticMember: Boolean,
val valueParameterTypes: List,
) {
val isGeneric = typeParameters.isNotEmpty()
constructor(
origin: T,
typeParameters: Collection,
valueParameterTypes: List,
hasExtensionReceiver: Boolean,
contextReceiverCount: Int,
hasVarargs: Boolean,
numDefaults: Int,
isExpect: Boolean,
isSyntheticMember: Boolean,
) : this(
origin, typeParameters, hasExtensionReceiver, contextReceiverCount, hasVarargs, numDefaults, isExpect,
isSyntheticMember, valueParameterTypes.map(::TypeWithConversion)
)
companion object
}
interface SimpleConstraintSystem {
fun registerTypeVariables(typeParameters: Collection): TypeSubstitutorMarker
fun addSubtypeConstraint(subType: KotlinTypeMarker, superType: KotlinTypeMarker)
fun hasContradiction(): Boolean
// todo hack for migration
val captureFromArgument get() = false
val context: TypeSystemInferenceExtensionContext
}
private fun SimpleConstraintSystem.isValueParameterTypeEquallyOrMoreSpecific(
specific: FlatSignature,
general: FlatSignature,
callbacks: SpecificityComparisonCallbacks,
specificityComparator: TypeSpecificityComparator,
typeKindSelector: (TypeWithConversion?) -> KotlinTypeMarker?
): Boolean {
val typeParameters = general.typeParameters
val typeSubstitutor = registerTypeVariables(typeParameters)
val specificContextReceiverCount = specific.contextReceiverCount
val generalContextReceiverCount = general.contextReceiverCount
var specificValueParameterTypes = specific.valueParameterTypes
var generalValueParameterTypes = general.valueParameterTypes
if (specificContextReceiverCount != generalContextReceiverCount) {
specificValueParameterTypes = specificValueParameterTypes.drop(specificContextReceiverCount)
generalValueParameterTypes = generalValueParameterTypes.drop(generalContextReceiverCount)
}
for (index in specificValueParameterTypes.indices) {
val specificType = typeKindSelector(specificValueParameterTypes[index]) ?: continue
val generalType = typeKindSelector(generalValueParameterTypes[index]) ?: continue
if (specificityComparator.isDefinitelyLessSpecific(specificType, generalType)) {
return false
}
if (typeParameters.isEmpty() || !generalType.dependsOnTypeParameters(context, typeParameters)) {
if (!AbstractTypeChecker.isSubtypeOf(context, specificType, generalType)) {
if (!callbacks.isNonSubtypeEquallyOrMoreSpecific(specificType, generalType)) {
return false
}
}
} else {
val substitutedGeneralType = typeSubstitutor.safeSubstitute(context, generalType)
/**
* Example:
* fun Array.sort(): Unit {}
* fun > Array.sort(): Unit {}
* Here, when we try solve this CS(Y is variables) then Array <: Array and this system impossible to solve,
* so we capture types from receiver and value parameters.
*/
val specificCapturedType = AbstractTypeChecker.prepareType(context, specificType)
.let { if (captureFromArgument) context.captureFromExpression(it) ?: it else it }
addSubtypeConstraint(specificCapturedType, substitutedGeneralType)
}
}
return true
}
fun SimpleConstraintSystem.isSignatureEquallyOrMoreSpecific(
specific: FlatSignature,
general: FlatSignature,
callbacks: SpecificityComparisonCallbacks,
specificityComparator: TypeSpecificityComparator,
useOriginalSamTypes: Boolean = false
): Boolean {
if (specific.hasExtensionReceiver != general.hasExtensionReceiver) return false
if (specific.contextReceiverCount > general.contextReceiverCount) return false
if (specific.valueParameterTypes.size - specific.contextReceiverCount != general.valueParameterTypes.size - general.contextReceiverCount)
return false
if (!isValueParameterTypeEquallyOrMoreSpecific(specific, general, callbacks, specificityComparator) { it?.resultType }) {
return false
}
if (useOriginalSamTypes && !isValueParameterTypeEquallyOrMoreSpecific(
specific, general, callbacks, specificityComparator
) { it?.originalTypeIfWasConverted }
) {
return false
}
return !hasContradiction()
}