K2: Merge all expected-type related resolution modes into single class

It looks more natural and allows to combine different properties
of these cases
This commit is contained in:
Denis.Zharkov
2022-12-01 11:31:04 +01:00
committed by Space Team
parent 33dcbaac16
commit cc1b608661
4 changed files with 21 additions and 47 deletions
@@ -33,9 +33,22 @@ sealed class ResolutionMode {
val expectedTypeRef: FirTypeRef,
val mayBeCoercionToUnitApplied: Boolean = false,
val expectedTypeMismatchIsReportedInChecker: Boolean = false,
val fromCast: Boolean = false,
// It might be ok if the types turn out to be incompatible
// Consider the following examples with properties and their backing fields:
//
// val items: List field = mutableListOf()
// val s: String field = 10 get() = ...
// In these examples we should try using the property type information while resolving the initializer,
// but it's ok if it's not applicable
val shouldBeStrictlyEnforced: Boolean = true,
) : ResolutionMode() {
override fun toString(): String {
return "WithExpectedType: ${expectedTypeRef.prettyString()}"
return "WithExpectedType: ${expectedTypeRef.prettyString()}, " +
"mayBeCoercionToUnitApplied=${mayBeCoercionToUnitApplied}, " +
"expectedTypeMismatchIsReportedInChecker=${expectedTypeMismatchIsReportedInChecker}, " +
"fromCast=${fromCast}, " +
"shouldBeStrictlyEnforced=${shouldBeStrictlyEnforced}, "
}
}
@@ -51,41 +64,6 @@ sealed class ResolutionMode {
}
}
class WithExpectedTypeFromCast(
val expectedTypeRef: FirTypeRef,
) : ResolutionMode() {
override fun toString(): String {
return "WithExpectedTypeFromCast: ${expectedTypeRef.prettyString()}"
}
}
/**
* This resolution mode is similar to
* WithExpectedType, but it's ok if the
* types turn out to be incompatible.
* Consider the following examples with
* properties and their backing fields:
*
* val items: List<T>
* field = mutableListOf()
*
* val s: String
* field = 10
* get() = ...
*
* In these examples we should try using
* the property type information while
* resolving the initializer, but it's ok
* if it's not applicable.
*/
class WithSuggestedType(
val suggestedTypeRef: FirTypeRef,
) : ResolutionMode() {
override fun toString(): String {
return "WithSuggestedType: ${suggestedTypeRef.prettyString()}"
}
}
/**
* This resolution mode is used for resolving the LHS of assignments.
*
@@ -110,13 +88,11 @@ sealed class ResolutionMode {
}
}
fun ResolutionMode.expectedType(components: BodyResolveComponents, allowFromCast: Boolean = false): FirTypeRef? = when (this) {
is ResolutionMode.WithExpectedType -> expectedTypeRef
fun ResolutionMode.expectedType(components: BodyResolveComponents): FirTypeRef? = when (this) {
is ResolutionMode.WithExpectedType -> expectedTypeRef.takeIf { !this.fromCast }
is ResolutionMode.ContextIndependent,
is ResolutionMode.AssignmentLValue,
is ResolutionMode.ReceiverResolution -> components.noExpectedType
is ResolutionMode.WithExpectedTypeFromCast -> expectedTypeRef.takeIf { allowFromCast }
is ResolutionMode.WithSuggestedType -> suggestedTypeRef
else -> null
}
@@ -76,8 +76,8 @@ class FirCallCompleter(
data.expectedType(components, allowFromCast = true),
(data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true,
(data as? ResolutionMode.WithExpectedType)?.expectedTypeMismatchIsReportedInChecker == true,
isFromCast = data is ResolutionMode.WithExpectedTypeFromCast,
shouldEnforceExpectedType = data !is ResolutionMode.WithSuggestedType,
isFromCast = (data as? ResolutionMode.WithExpectedType)?.fromCast == true,
shouldEnforceExpectedType = (data as? ResolutionMode.WithExpectedType)?.shouldBeStrictlyEnforced == true,
)
private fun <T> completeCall(
@@ -728,11 +728,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
}
is ResolutionMode.WithExpectedType ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data)
is ResolutionMode.WithSuggestedType ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.suggestedTypeRef, data)
is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data)
is ResolutionMode.WithStatus, is ResolutionMode.WithExpectedTypeFromCast ->
is ResolutionMode.WithStatus ->
throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode")
}
}
@@ -888,7 +886,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) {
withExpectedType(backingField.returnTypeRef)
} else if (propertyType != null) {
ResolutionMode.WithSuggestedType(propertyType)
ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false)
} else {
ResolutionMode.ContextDependent
}
@@ -800,7 +800,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
}
if (expectedType != null) {
val newMode = ResolutionMode.WithExpectedTypeFromCast(conversionTypeRef.withReplacedConeType(expectedType))
val newMode = ResolutionMode.WithExpectedType(conversionTypeRef.withReplacedConeType(expectedType), fromCast = true)
return transformOtherChildren(transformer, newMode)
}
}