FIR: make inference context mandatory in withNullability() etc.
This commit is contained in:
committed by
TeamCityServer
parent
bb37728e4f
commit
7ee6597873
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
|
|||||||
import org.jetbrains.kotlin.fir.expressions.classId
|
import org.jetbrains.kotlin.fir.expressions.classId
|
||||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
@@ -222,6 +223,9 @@ class Fir2IrTypeConverter(
|
|||||||
private fun approximateType(type: ConeKotlinType): ConeKotlinType {
|
private fun approximateType(type: ConeKotlinType): ConeKotlinType {
|
||||||
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
|
if (type is ConeClassLikeType && type.typeArguments.isEmpty()) return type
|
||||||
val substitutor = object : AbstractConeSubstitutor() {
|
val substitutor = object : AbstractConeSubstitutor() {
|
||||||
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = session.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
return if (type is ConeIntersectionType) {
|
return if (type is ConeIntersectionType) {
|
||||||
type.alternativeType?.let { substituteOrSelf(it) }
|
type.alternativeType?.let { substituteOrSelf(it) }
|
||||||
|
|||||||
+3
@@ -665,6 +665,9 @@ class CallAndReferenceGenerator(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val starProjectionApproximator = object : AbstractConeSubstitutor() {
|
private val starProjectionApproximator = object : AbstractConeSubstitutor() {
|
||||||
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = session.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
|
if (type !is ConeClassLikeType || type.typeArguments.none { it == ConeStarProjection }) return null
|
||||||
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
|
val fir = type.lookupTag.toSymbol(session)?.fir as? FirTypeParameterRefsOwner ?: return null
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.fir.references.impl.FirReferencePlaceholderForResolv
|
|||||||
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
|
import org.jetbrains.kotlin.fir.resolve.bindSymbolToLookupTag
|
||||||
import org.jetbrains.kotlin.fir.resolve.defaultType
|
import org.jetbrains.kotlin.fir.resolve.defaultType
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeUnresolvedReferenceError
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols
|
import org.jetbrains.kotlin.fir.resolve.providers.getClassDeclaredPropertySymbols
|
||||||
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
import org.jetbrains.kotlin.fir.resolve.symbolProvider
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -274,7 +275,7 @@ private fun computeRawProjection(
|
|||||||
session: FirSession,
|
session: FirSession,
|
||||||
parameter: FirTypeParameter,
|
parameter: FirTypeParameter,
|
||||||
attr: TypeComponentPosition,
|
attr: TypeComponentPosition,
|
||||||
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound()
|
erasedUpperBound: ConeKotlinType = parameter.getErasedUpperBound(session)
|
||||||
) = when (attr) {
|
) = when (attr) {
|
||||||
// Raw(List<T>) => (List<Any?>..List<*>)
|
// Raw(List<T>) => (List<Any?>..List<*>)
|
||||||
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
|
// Raw(Enum<T>) => (Enum<Enum<*>>..Enum<out Enum<*>>)
|
||||||
@@ -306,6 +307,7 @@ private fun computeRawProjection(
|
|||||||
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
|
// ErasedUpperBound(T : A) = A // UpperBound(T) is a type A without arguments
|
||||||
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
|
// ErasedUpperBound(T : F) = UpperBound(F) // UB(T) is another type parameter F
|
||||||
private fun FirTypeParameter.getErasedUpperBound(
|
private fun FirTypeParameter.getErasedUpperBound(
|
||||||
|
session: FirSession,
|
||||||
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
|
// Calculation of `potentiallyRecursiveTypeParameter.upperBounds` may recursively depend on `this.getErasedUpperBound`
|
||||||
// E.g. `class A<T extends A, F extends A>`
|
// E.g. `class A<T extends A, F extends A>`
|
||||||
// To prevent recursive calls return defaultValue() instead
|
// To prevent recursive calls return defaultValue() instead
|
||||||
@@ -318,10 +320,11 @@ private fun FirTypeParameter.getErasedUpperBound(
|
|||||||
|
|
||||||
val firstUpperBound = this.bounds.first().coneType
|
val firstUpperBound = this.bounds.first().coneType
|
||||||
|
|
||||||
return getErasedVersionOfFirstUpperBound(firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
|
return getErasedVersionOfFirstUpperBound(session, firstUpperBound, mutableSetOf(this, potentiallyRecursiveTypeParameter), defaultValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getErasedVersionOfFirstUpperBound(
|
private fun getErasedVersionOfFirstUpperBound(
|
||||||
|
session: FirSession,
|
||||||
firstUpperBound: ConeKotlinType,
|
firstUpperBound: ConeKotlinType,
|
||||||
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
|
alreadyVisitedParameters: MutableSet<FirTypeParameter?>,
|
||||||
defaultValue: () -> ConeKotlinType
|
defaultValue: () -> ConeKotlinType
|
||||||
@@ -332,18 +335,18 @@ private fun getErasedVersionOfFirstUpperBound(
|
|||||||
|
|
||||||
is ConeFlexibleType -> {
|
is ConeFlexibleType -> {
|
||||||
val lowerBound =
|
val lowerBound =
|
||||||
getErasedVersionOfFirstUpperBound(firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
|
getErasedVersionOfFirstUpperBound(session, firstUpperBound.lowerBound, alreadyVisitedParameters, defaultValue)
|
||||||
.lowerBoundIfFlexible()
|
.lowerBoundIfFlexible()
|
||||||
if (firstUpperBound.upperBound is ConeTypeParameterType) {
|
if (firstUpperBound.upperBound is ConeTypeParameterType) {
|
||||||
// Avoid exponential complexity
|
// Avoid exponential complexity
|
||||||
ConeFlexibleType(
|
ConeFlexibleType(
|
||||||
lowerBound,
|
lowerBound,
|
||||||
lowerBound.withNullability(ConeNullability.NULLABLE)
|
lowerBound.withNullability(ConeNullability.NULLABLE, session.inferenceComponents.ctx)
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
ConeFlexibleType(
|
ConeFlexibleType(
|
||||||
lowerBound,
|
lowerBound,
|
||||||
getErasedVersionOfFirstUpperBound(firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
|
getErasedVersionOfFirstUpperBound(session, firstUpperBound.upperBound, alreadyVisitedParameters, defaultValue)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -352,7 +355,7 @@ private fun getErasedVersionOfFirstUpperBound(
|
|||||||
|
|
||||||
if (alreadyVisitedParameters.add(current)) {
|
if (alreadyVisitedParameters.add(current)) {
|
||||||
val nextUpperBound = current.bounds.first().coneType
|
val nextUpperBound = current.bounds.first().coneType
|
||||||
getErasedVersionOfFirstUpperBound(nextUpperBound, alreadyVisitedParameters, defaultValue)
|
getErasedVersionOfFirstUpperBound(session, nextUpperBound, alreadyVisitedParameters, defaultValue)
|
||||||
} else {
|
} else {
|
||||||
defaultValue()
|
defaultValue()
|
||||||
}
|
}
|
||||||
@@ -433,7 +436,7 @@ private fun FirRegularClass.createRawArguments(
|
|||||||
defaultArgs: List<ConeStarProjection>,
|
defaultArgs: List<ConeStarProjection>,
|
||||||
position: TypeComponentPosition
|
position: TypeComponentPosition
|
||||||
): List<ConeTypeProjection> = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter ->
|
): List<ConeTypeProjection> = typeParameters.filterIsInstance<FirTypeParameter>().map { typeParameter ->
|
||||||
val erasedUpperBound = typeParameter.getErasedUpperBound {
|
val erasedUpperBound = typeParameter.getErasedUpperBound(session) {
|
||||||
defaultType().withArguments(defaultArgs.toTypedArray())
|
defaultType().withArguments(defaultArgs.toTypedArray())
|
||||||
}
|
}
|
||||||
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
computeRawProjection(session, typeParameter, position, erasedUpperBound)
|
||||||
|
|||||||
@@ -299,7 +299,9 @@ fun FirCheckedSafeCallSubject.propagateTypeFromOriginalReceiver(nullableReceiver
|
|||||||
|
|
||||||
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
val expandedReceiverType = if (receiverType is ConeClassLikeType) receiverType.fullyExpandedType(session) else receiverType
|
||||||
|
|
||||||
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull())
|
val resolvedTypeRef = typeRef.resolvedTypeFromPrototype(
|
||||||
|
expandedReceiverType.makeConeTypeDefinitelyNotNullOrNotNull(session.inferenceComponents.ctx)
|
||||||
|
)
|
||||||
replaceTypeRef(resolvedTypeRef)
|
replaceTypeRef(resolvedTypeRef)
|
||||||
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
session.lookupTracker?.recordTypeResolveAsLookup(resolvedTypeRef, source, null)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.resolve
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
import org.jetbrains.kotlin.fir.declarations.FirTypeAlias
|
||||||
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
import org.jetbrains.kotlin.fir.declarations.expandedConeType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirTypeAliasSymbol
|
||||||
import org.jetbrains.kotlin.fir.typeContext
|
import org.jetbrains.kotlin.fir.typeContext
|
||||||
@@ -62,7 +63,7 @@ fun ConeClassLikeType.directExpansionType(
|
|||||||
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(useSiteSession, this) ?: return null
|
val resultType = expandedConeType(typeAlias)?.applyNullabilityFrom(useSiteSession, this) ?: return null
|
||||||
|
|
||||||
if (resultType.typeArguments.isEmpty()) return resultType
|
if (resultType.typeArguments.isEmpty()) return resultType
|
||||||
return mapTypeAliasArguments(typeAlias, this, resultType) as? ConeClassLikeType
|
return mapTypeAliasArguments(typeAlias, this, resultType, useSiteSession) as? ConeClassLikeType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeClassLikeType.applyNullabilityFrom(
|
private fun ConeClassLikeType.applyNullabilityFrom(
|
||||||
@@ -77,6 +78,7 @@ private fun mapTypeAliasArguments(
|
|||||||
typeAlias: FirTypeAlias,
|
typeAlias: FirTypeAlias,
|
||||||
abbreviatedType: ConeClassLikeType,
|
abbreviatedType: ConeClassLikeType,
|
||||||
resultingType: ConeClassLikeType,
|
resultingType: ConeClassLikeType,
|
||||||
|
useSiteSession: FirSession,
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
if (typeAlias.typeParameters.isNotEmpty() && abbreviatedType.typeArguments.isEmpty()) {
|
if (typeAlias.typeParameters.isNotEmpty() && abbreviatedType.typeArguments.isEmpty()) {
|
||||||
return resultingType.lookupTag.constructClassType(emptyArray(), resultingType.isNullable)
|
return resultingType.lookupTag.constructClassType(emptyArray(), resultingType.isNullable)
|
||||||
@@ -84,6 +86,9 @@ private fun mapTypeAliasArguments(
|
|||||||
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
val typeAliasMap = typeAlias.typeParameters.map { it.symbol }.zip(abbreviatedType.typeArguments).toMap()
|
||||||
|
|
||||||
val substitutor = object : AbstractConeSubstitutor() {
|
val substitutor = object : AbstractConeSubstitutor() {
|
||||||
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = useSiteSession.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-6
@@ -16,6 +16,8 @@ import org.jetbrains.kotlin.types.model.TypeSubstitutorMarker
|
|||||||
import org.jetbrains.kotlin.types.model.typeConstructor
|
import org.jetbrains.kotlin.types.model.typeConstructor
|
||||||
|
|
||||||
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
||||||
|
abstract val typeInferenceContext: ConeInferenceContext
|
||||||
|
|
||||||
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
private fun wrapProjection(old: ConeTypeProjection, newType: ConeKotlinType): ConeTypeProjection {
|
||||||
return when (old) {
|
return when (old) {
|
||||||
is ConeStarProjection -> old
|
is ConeStarProjection -> old
|
||||||
@@ -35,8 +37,8 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
|
|
||||||
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
|
fun ConeKotlinType?.updateNullabilityIfNeeded(originalType: ConeKotlinType): ConeKotlinType? {
|
||||||
return when {
|
return when {
|
||||||
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL)
|
originalType is ConeDefinitelyNotNullType -> this?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext)
|
||||||
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE)
|
originalType.isMarkedNullable -> this?.withNullability(ConeNullability.NULLABLE, typeInferenceContext)
|
||||||
else -> this
|
else -> this
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +46,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteOrNull(type: ConeKotlinType): ConeKotlinType? {
|
||||||
val newType = substituteType(type)
|
val newType = substituteType(type)
|
||||||
if (newType != null && type is ConeDefinitelyNotNullType) {
|
if (newType != null && type is ConeDefinitelyNotNullType) {
|
||||||
return newType.makeConeTypeDefinitelyNotNullOrNotNull()
|
return newType.makeConeTypeDefinitelyNotNullOrNotNull(typeInferenceContext)
|
||||||
}
|
}
|
||||||
return (newType ?: type.substituteRecursive())
|
return (newType ?: type.substituteRecursive())
|
||||||
}
|
}
|
||||||
@@ -82,7 +84,7 @@ abstract class AbstractConeSubstitutor : ConeSubstitutor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
private fun ConeDefinitelyNotNullType.substituteOriginal(): ConeKotlinType? {
|
||||||
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL) ?: return null
|
val substituted = substituteOrNull(original)?.withNullability(ConeNullability.NOT_NULL, typeInferenceContext) ?: return null
|
||||||
return ConeDefinitelyNotNullType.create(substituted) ?: substituted
|
return ConeDefinitelyNotNullType.create(substituted) ?: substituted
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,6 +159,9 @@ data class ConeSubstitutorByMap(
|
|||||||
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
val substitution: Map<FirTypeParameterSymbol, ConeKotlinType>,
|
||||||
val useSiteSession: FirSession
|
val useSiteSession: FirSession
|
||||||
) : AbstractConeSubstitutor() {
|
) : AbstractConeSubstitutor() {
|
||||||
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = useSiteSession.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeTypeParameterType) return null
|
if (type !is ConeTypeParameterType) return null
|
||||||
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
|
val result = substitution[type.lookupTag.symbol].updateNullabilityIfNeeded(type) ?: return null
|
||||||
@@ -171,8 +176,10 @@ data class ConeSubstitutorByMap(
|
|||||||
|
|
||||||
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
fun createTypeSubstitutorByTypeConstructor(map: Map<TypeConstructorMarker, ConeKotlinType>, context: ConeTypeContext): ConeSubstitutor {
|
||||||
if (map.isEmpty()) return ConeSubstitutor.Empty
|
if (map.isEmpty()) return ConeSubstitutor.Empty
|
||||||
return object : AbstractConeSubstitutor(),
|
return object : AbstractConeSubstitutor(), TypeSubstitutorMarker {
|
||||||
TypeSubstitutorMarker {
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = context.session.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
if (type !is ConeLookupTagBasedType && type !is ConeStubType) return null
|
||||||
val new = map[type.typeConstructor(context)] ?: return null
|
val new = map[type.typeConstructor(context)] ?: return null
|
||||||
|
|||||||
@@ -228,12 +228,12 @@ interface ConeInferenceContext : TypeSystemInferenceExtensionContext, ConeTypeCo
|
|||||||
|
|
||||||
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
override fun KotlinTypeMarker.makeDefinitelyNotNullOrNotNull(): KotlinTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return makeConeTypeDefinitelyNotNullOrNotNull()
|
return makeConeTypeDefinitelyNotNullOrNotNull(this@ConeInferenceContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker {
|
override fun SimpleTypeMarker.makeSimpleTypeDefinitelyNotNullOrNotNull(): SimpleTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return makeConeTypeDefinitelyNotNullOrNotNull() as SimpleTypeMarker
|
return makeConeTypeDefinitelyNotNullOrNotNull(this@ConeInferenceContext) as SimpleTypeMarker
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createCapturedType(
|
override fun createCapturedType(
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirVarargArgumentsExpression
|
|||||||
import org.jetbrains.kotlin.fir.expressions.arguments
|
import org.jetbrains.kotlin.fir.expressions.arguments
|
||||||
import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache
|
import org.jetbrains.kotlin.fir.resolve.correspondingSupertypesCache
|
||||||
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.ConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
import org.jetbrains.kotlin.fir.resolve.substitution.substitutorByMap
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
@@ -128,7 +129,7 @@ interface ConeTypeContext : TypeSystemContext, TypeSystemOptimizationContext, Ty
|
|||||||
|
|
||||||
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
|
override fun SimpleTypeMarker.withNullability(nullable: Boolean): SimpleTypeMarker {
|
||||||
require(this is ConeKotlinType)
|
require(this is ConeKotlinType)
|
||||||
return withNullability(ConeNullability.create(nullable), this as? ConeInferenceContext)
|
return withNullability(ConeNullability.create(nullable), session.inferenceComponents.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
|
override fun SimpleTypeMarker.typeConstructor(): TypeConstructorMarker {
|
||||||
|
|||||||
@@ -56,11 +56,11 @@ fun ConeDefinitelyNotNullType.Companion.create(original: ConeKotlinType): ConeDe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(): ConeKotlinType {
|
fun ConeKotlinType.makeConeTypeDefinitelyNotNullOrNotNull(typeContext: ConeInferenceContext): ConeKotlinType {
|
||||||
if (this is ConeIntersectionType) {
|
if (this is ConeIntersectionType) {
|
||||||
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull() })
|
return ConeIntersectionType(intersectedTypes.map { it.makeConeTypeDefinitelyNotNullOrNotNull(typeContext) })
|
||||||
}
|
}
|
||||||
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL)
|
return ConeDefinitelyNotNullType.create(this) ?: this.withNullability(ConeNullability.NOT_NULL, typeContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>): T {
|
fun <T : ConeKotlinType> T.withArguments(arguments: Array<out ConeTypeProjection>): T {
|
||||||
@@ -95,7 +95,7 @@ fun <T : ConeKotlinType> T.withAttributes(attributes: ConeAttributes): T {
|
|||||||
|
|
||||||
fun <T : ConeKotlinType> T.withNullability(
|
fun <T : ConeKotlinType> T.withNullability(
|
||||||
nullability: ConeNullability,
|
nullability: ConeNullability,
|
||||||
typeContext: ConeInferenceContext? = null,
|
typeContext: ConeInferenceContext,
|
||||||
attributes: ConeAttributes = this.attributes,
|
attributes: ConeAttributes = this.attributes,
|
||||||
): T {
|
): T {
|
||||||
if (this.nullability == nullability && this.attributes == attributes) {
|
if (this.nullability == nullability && this.attributes == attributes) {
|
||||||
@@ -123,7 +123,7 @@ fun <T : ConeKotlinType> T.withNullability(
|
|||||||
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes)
|
is ConeCapturedType -> ConeCapturedType(captureStatus, lowerType, nullability, constructor, attributes)
|
||||||
is ConeIntersectionType -> when (nullability) {
|
is ConeIntersectionType -> when (nullability) {
|
||||||
ConeNullability.NULLABLE -> this.mapTypes {
|
ConeNullability.NULLABLE -> this.mapTypes {
|
||||||
it.withNullability(nullability)
|
it.withNullability(nullability, typeContext)
|
||||||
}
|
}
|
||||||
ConeNullability.UNKNOWN -> this // TODO: is that correct?
|
ConeNullability.UNKNOWN -> this // TODO: is that correct?
|
||||||
ConeNullability.NOT_NULL -> this
|
ConeNullability.NOT_NULL -> this
|
||||||
@@ -140,7 +140,7 @@ fun <T : ConeKotlinType> T.withNullability(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun coneFlexibleOrSimpleType(
|
fun coneFlexibleOrSimpleType(
|
||||||
typeContext: ConeInferenceContext?,
|
typeContext: ConeInferenceContext,
|
||||||
lowerBound: ConeKotlinType,
|
lowerBound: ConeKotlinType,
|
||||||
upperBound: ConeKotlinType,
|
upperBound: ConeKotlinType,
|
||||||
): ConeKotlinType {
|
): ConeKotlinType {
|
||||||
@@ -151,15 +151,8 @@ fun coneFlexibleOrSimpleType(
|
|||||||
return coneFlexibleOrSimpleType(typeContext, lowerBound, upperBound.upperBound)
|
return coneFlexibleOrSimpleType(typeContext, lowerBound, upperBound.upperBound)
|
||||||
}
|
}
|
||||||
return when {
|
return when {
|
||||||
typeContext != null && AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, lowerBound, upperBound) -> {
|
AbstractStrictEqualityTypeChecker.strictEqualTypes(typeContext, lowerBound, upperBound) -> lowerBound
|
||||||
lowerBound
|
else -> ConeFlexibleType(lowerBound, upperBound)
|
||||||
}
|
|
||||||
typeContext == null && lowerBound == upperBound -> {
|
|
||||||
lowerBound
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
ConeFlexibleType(lowerBound, upperBound)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.FirSession
|
|||||||
import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper
|
import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.isPrimitiveType
|
import org.jetbrains.kotlin.fir.isPrimitiveType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.inference.inferenceComponents
|
||||||
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
import org.jetbrains.kotlin.fir.resolve.substitution.AbstractConeSubstitutor
|
||||||
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol
|
||||||
@@ -76,8 +77,13 @@ internal fun KtNamedClassOrObjectSymbol.typeForClassSymbol(psiElement: PsiElemen
|
|||||||
return types.coneType.asPsiType(session, firRef.resolveState, TypeMappingMode.DEFAULT, psiElement)
|
return types.coneType.asPsiType(session, firRef.resolveState, TypeMappingMode.DEFAULT, psiElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
private class AnonymousTypesSubstitutor(private val session: FirSession, private val state: FirModuleResolveState) :
|
private class AnonymousTypesSubstitutor(
|
||||||
AbstractConeSubstitutor() {
|
private val session: FirSession,
|
||||||
|
private val state: FirModuleResolveState
|
||||||
|
) : AbstractConeSubstitutor() {
|
||||||
|
override val typeInferenceContext: ConeInferenceContext
|
||||||
|
get() = session.inferenceComponents.ctx
|
||||||
|
|
||||||
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
override fun substituteType(type: ConeKotlinType): ConeKotlinType? {
|
||||||
|
|
||||||
if (type !is ConeClassLikeType) return null
|
if (type !is ConeClassLikeType) return null
|
||||||
|
|||||||
Reference in New Issue
Block a user