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 expectedTypeRef: FirTypeRef,
val mayBeCoercionToUnitApplied: Boolean = false, val mayBeCoercionToUnitApplied: Boolean = false,
val expectedTypeMismatchIsReportedInChecker: 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() { ) : ResolutionMode() {
override fun toString(): String { 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. * 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) { fun ResolutionMode.expectedType(components: BodyResolveComponents): FirTypeRef? = when (this) {
is ResolutionMode.WithExpectedType -> expectedTypeRef is ResolutionMode.WithExpectedType -> expectedTypeRef.takeIf { !this.fromCast }
is ResolutionMode.ContextIndependent, is ResolutionMode.ContextIndependent,
is ResolutionMode.AssignmentLValue, is ResolutionMode.AssignmentLValue,
is ResolutionMode.ReceiverResolution -> components.noExpectedType is ResolutionMode.ReceiverResolution -> components.noExpectedType
is ResolutionMode.WithExpectedTypeFromCast -> expectedTypeRef.takeIf { allowFromCast }
is ResolutionMode.WithSuggestedType -> suggestedTypeRef
else -> null else -> null
} }
@@ -76,8 +76,8 @@ class FirCallCompleter(
data.expectedType(components, allowFromCast = true), data.expectedType(components, allowFromCast = true),
(data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true, (data as? ResolutionMode.WithExpectedType)?.mayBeCoercionToUnitApplied == true,
(data as? ResolutionMode.WithExpectedType)?.expectedTypeMismatchIsReportedInChecker == true, (data as? ResolutionMode.WithExpectedType)?.expectedTypeMismatchIsReportedInChecker == true,
isFromCast = data is ResolutionMode.WithExpectedTypeFromCast, isFromCast = (data as? ResolutionMode.WithExpectedType)?.fromCast == true,
shouldEnforceExpectedType = data !is ResolutionMode.WithSuggestedType, shouldEnforceExpectedType = (data as? ResolutionMode.WithExpectedType)?.shouldBeStrictlyEnforced == true,
) )
private fun <T> completeCall( private fun <T> completeCall(
@@ -728,11 +728,9 @@ open class FirDeclarationsResolveTransformer(transformer: FirAbstractBodyResolve
} }
is ResolutionMode.WithExpectedType -> is ResolutionMode.WithExpectedType ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data) transformAnonymousFunctionWithExpectedType(anonymousFunction, data.expectedTypeRef, data)
is ResolutionMode.WithSuggestedType ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, data.suggestedTypeRef, data)
is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution -> is ResolutionMode.ContextIndependent, is ResolutionMode.AssignmentLValue, is ResolutionMode.ReceiverResolution ->
transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data) transformAnonymousFunctionWithExpectedType(anonymousFunction, buildImplicitTypeRef(), data)
is ResolutionMode.WithStatus, is ResolutionMode.WithExpectedTypeFromCast -> is ResolutionMode.WithStatus ->
throw AssertionError("Should not be here in WithStatus/WithExpectedTypeFromCast mode") 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) { val initializerData = if (backingField.returnTypeRef is FirResolvedTypeRef) {
withExpectedType(backingField.returnTypeRef) withExpectedType(backingField.returnTypeRef)
} else if (propertyType != null) { } else if (propertyType != null) {
ResolutionMode.WithSuggestedType(propertyType) ResolutionMode.WithExpectedType(propertyType, shouldBeStrictlyEnforced = false)
} else { } else {
ResolutionMode.ContextDependent ResolutionMode.ContextDependent
} }
@@ -800,7 +800,7 @@ open class FirExpressionsResolveTransformer(transformer: FirAbstractBodyResolveT
} }
if (expectedType != null) { if (expectedType != null) {
val newMode = ResolutionMode.WithExpectedTypeFromCast(conversionTypeRef.withReplacedConeType(expectedType)) val newMode = ResolutionMode.WithExpectedType(conversionTypeRef.withReplacedConeType(expectedType), fromCast = true)
return transformOtherChildren(transformer, newMode) return transformOtherChildren(transformer, newMode)
} }
} }