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:
committed by
Space Team
parent
33dcbaac16
commit
cc1b608661
@@ -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
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -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(
|
||||
|
||||
+2
-4
@@ -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
|
||||
}
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user