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 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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -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(
|
||||||
|
|||||||
+2
-4
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user