[LL FIR] fix lazy resolve of accessors with implicit types

Before the change, such accessors would have implicit types event if the corresponding property had a resolved one
This commit is contained in:
Ilya Kirillov
2022-08-09 10:33:25 +02:00
parent 97853016d5
commit 28b159ef85
@@ -122,13 +122,13 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
return transformLocalVariable(property) return transformLocalVariable(property)
} }
val returnTypeRef = property.returnTypeRef val returnTypeRefBeforeResolve = property.returnTypeRef
val bodyResolveState = property.bodyResolveState val bodyResolveState = property.bodyResolveState
if (bodyResolveState == FirPropertyBodyResolveState.EVERYTHING_RESOLVED) return property if (bodyResolveState == FirPropertyBodyResolveState.EVERYTHING_RESOLVED) return property
val canHaveDeepImplicitTypeRefs = property.hasExplicitBackingField val canHaveDeepImplicitTypeRefs = property.hasExplicitBackingField
if (returnTypeRef !is FirImplicitTypeRef && implicitTypeOnly && !canHaveDeepImplicitTypeRefs) { if (returnTypeRefBeforeResolve !is FirImplicitTypeRef && implicitTypeOnly && !canHaveDeepImplicitTypeRefs) {
return property return property
} }
@@ -142,7 +142,7 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
context.withProperty(property) { context.withProperty(property) {
context.forPropertyInitializer { context.forPropertyInitializer {
if (!initializerIsAlreadyResolved) { if (!initializerIsAlreadyResolved) {
property.transformChildrenWithoutComponents(returnTypeRef) property.transformChildrenWithoutComponents(returnTypeRefBeforeResolve)
property.replaceBodyResolveState(FirPropertyBodyResolveState.INITIALIZER_RESOLVED) property.replaceBodyResolveState(FirPropertyBodyResolveState.INITIALIZER_RESOLVED)
} }
if (property.initializer != null) { if (property.initializer != null) {
@@ -165,7 +165,8 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
val hasNonDefaultAccessors = property.getter != null && property.getter !is FirDefaultPropertyAccessor || val hasNonDefaultAccessors = property.getter != null && property.getter !is FirDefaultPropertyAccessor ||
property.setter != null && property.setter !is FirDefaultPropertyAccessor property.setter != null && property.setter !is FirDefaultPropertyAccessor
val mayResolveSetter = shouldResolveEverything || !hasNonDefaultAccessors val mayResolveSetter = shouldResolveEverything || !hasNonDefaultAccessors
val propertyTypeIsKnown = property.returnTypeRef is FirResolvedTypeRef || property.returnTypeRef is FirErrorTypeRef val propertyTypeRefAfterResolve = property.returnTypeRef
val propertyTypeIsKnown = propertyTypeRefAfterResolve is FirResolvedTypeRef
val mayResolveGetter = mayResolveSetter || !propertyTypeIsKnown val mayResolveGetter = mayResolveSetter || !propertyTypeIsKnown
if (mayResolveGetter) { if (mayResolveGetter) {
property.transformAccessors(mayResolveSetter) property.transformAccessors(mayResolveSetter)
@@ -173,11 +174,11 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
if (mayResolveSetter) FirPropertyBodyResolveState.EVERYTHING_RESOLVED if (mayResolveSetter) FirPropertyBodyResolveState.EVERYTHING_RESOLVED
else FirPropertyBodyResolveState.INITIALIZER_AND_GETTER_RESOLVED else FirPropertyBodyResolveState.INITIALIZER_AND_GETTER_RESOLVED
) )
} else if (returnTypeRef is FirResolvedTypeRef) { } else {
// Even though we're not going to resolve accessors themselves (so as to avoid resolve cycle, like KT-48634), // Even though we're not going to resolve accessors themselves (so as to avoid resolve cycle, like KT-48634),
// we still need to resolve types in accessors (as per IMPLICIT_TYPES_BODY_RESOLVE contract). // we still need to resolve types in accessors (as per IMPLICIT_TYPES_BODY_RESOLVE contract).
property.getter?.transformTypeWithPropertyType(returnTypeRef) property.getter?.transformTypeWithPropertyType(propertyTypeRefAfterResolve)
property.setter?.transformTypeWithPropertyType(returnTypeRef) property.setter?.transformTypeWithPropertyType(propertyTypeRefAfterResolve)
property.setter?.transformReturnTypeRef(transformer, withExpectedType(session.builtinTypes.unitType.type)) property.setter?.transformReturnTypeRef(transformer, withExpectedType(session.builtinTypes.unitType.type))
} }
} }
@@ -413,24 +414,33 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
storeVariableReturnType(this) storeVariableReturnType(this)
enhancedTypeRef = returnTypeRef enhancedTypeRef = returnTypeRef
// We need update type of getter for case when its type was approximated // We need update type of getter for case when its type was approximated
getter?.transformTypeWithPropertyType(enhancedTypeRef) getter?.transformTypeWithPropertyType(enhancedTypeRef, forceUpdateForNonImplicitTypes = true)
} }
setter?.let { setter?.let {
if (it.valueParameters[0].returnTypeRef is FirImplicitTypeRef) { it.transformTypeWithPropertyType(enhancedTypeRef)
it.transformTypeWithPropertyType(enhancedTypeRef)
}
if (mayResolveSetter) { if (mayResolveSetter) {
transformAccessor(it, enhancedTypeRef, this) transformAccessor(it, enhancedTypeRef, this)
} }
} }
} }
private fun FirPropertyAccessor.transformTypeWithPropertyType(propertyTypeRef: FirTypeRef) { private fun FirPropertyAccessor.transformTypeWithPropertyType(
propertyTypeRef: FirTypeRef,
forceUpdateForNonImplicitTypes: Boolean = false
) {
when { when {
isGetter -> isGetter -> {
replaceReturnTypeRef(propertyTypeRef) if (returnTypeRef is FirImplicitTypeRef || forceUpdateForNonImplicitTypes) {
isSetter -> replaceReturnTypeRef(propertyTypeRef)
valueParameters[0].transformReturnTypeRef(StoreType, propertyTypeRef) }
}
isSetter -> {
val valueParameter = valueParameters.firstOrNull() ?: return
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
valueParameter.transformReturnTypeRef(StoreType, propertyTypeRef)
}
}
} }
} }
@@ -721,15 +731,6 @@ open class FirDeclarationsResolveTransformer(transformer: FirBodyResolveTransfor
} }
override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): FirStatement { override fun transformValueParameter(valueParameter: FirValueParameter, data: ResolutionMode): FirStatement {
if (valueParameter.returnTypeRef is FirImplicitTypeRef) {
valueParameter.replaceReturnTypeRef(
valueParameter.returnTypeRef.errorTypeFromPrototype(
ConeSimpleDiagnostic("No type for parameter", DiagnosticKind.ValueParameterWithNoTypeAnnotation)
)
)
return valueParameter
}
dataFlowAnalyzer.enterValueParameter(valueParameter) dataFlowAnalyzer.enterValueParameter(valueParameter)
val result = context.withValueParameter(valueParameter, session) { val result = context.withValueParameter(valueParameter, session) {
transformDeclarationContent( transformDeclarationContent(