Use BodyResolveContext.with* functions in FirContractResolveTransformer

This commit is contained in:
Mikhail Glukhikh
2021-03-09 17:55:50 +03:00
parent 4d519f646e
commit a345b81f2a
3 changed files with 27 additions and 38 deletions
@@ -270,9 +270,15 @@ class BodyResolveContext(
inline fun <T> withRegularClass( inline fun <T> withRegularClass(
regularClass: FirRegularClass, regularClass: FirRegularClass,
holder: SessionHolder, holder: SessionHolder,
forContracts: Boolean = false,
crossinline f: () -> T crossinline f: () -> T
): T { ): T {
storeClassIfNotNested(regularClass) storeClassIfNotNested(regularClass)
if (forContracts) {
return withTypeParametersOf(regularClass) {
withContainer(regularClass, f)
}
}
return withTowerModeCleanup { return withTowerModeCleanup {
if (!regularClass.isInner && containerIfAny is FirRegularClass) { if (!regularClass.isInner && containerIfAny is FirRegularClass) {
towerDataMode = if (regularClass.isCompanion) { towerDataMode = if (regularClass.isCompanion) {
@@ -463,6 +469,7 @@ class BodyResolveContext(
property: FirProperty, property: FirProperty,
accessor: FirPropertyAccessor, accessor: FirPropertyAccessor,
holder: SessionHolder, holder: SessionHolder,
forContracts: Boolean = false,
crossinline f: () -> T crossinline f: () -> T
): T { ): T {
if (accessor is FirDefaultPropertyAccessor || accessor.body == null) { if (accessor is FirDefaultPropertyAccessor || accessor.body == null) {
@@ -471,7 +478,7 @@ class BodyResolveContext(
return withTowerDataCleanup { return withTowerDataCleanup {
val receiverTypeRef = property.receiverTypeRef val receiverTypeRef = property.receiverTypeRef
addLocalScope(FirLocalScope()) addLocalScope(FirLocalScope())
if (receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef && if (!forContracts && receiverTypeRef == null && property.returnTypeRef !is FirImplicitTypeRef &&
!property.isLocal && property.delegate == null !property.isLocal && property.delegate == null
) { ) {
storeBackingField(property) storeBackingField(property)
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.fir.resolve.transformers.contracts
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.contracts.description.* import org.jetbrains.kotlin.fir.contracts.description.*
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.types.ConeKotlinType import org.jetbrains.kotlin.fir.types.ConeKotlinType
@@ -141,12 +143,16 @@ class ConeEffectExtractor(
} }
} }
private fun FirContractDescriptionOwner.isAccessorOf(declaration: FirSymbolOwner<*>): Boolean {
return declaration is FirProperty && (declaration.getter == this || declaration.setter == this)
}
override fun visitThisReceiverExpression( override fun visitThisReceiverExpression(
thisReceiverExpression: FirThisReceiverExpression, thisReceiverExpression: FirThisReceiverExpression,
data: Nothing? data: Nothing?
): ConeContractDescriptionElement? { ): ConeContractDescriptionElement? {
val declaration = thisReceiverExpression.calleeReference.boundSymbol?.fir ?: return null val declaration = thisReceiverExpression.calleeReference.boundSymbol?.fir ?: return null
return if (declaration == owner) { return if (declaration == owner || owner.isAccessorOf(declaration)) {
val type = thisReceiverExpression.typeRef.coneType val type = thisReceiverExpression.typeRef.coneType
toValueParameterReference(type, -1, "this") toValueParameterReference(type, -1, "this")
} else { } else {
@@ -27,7 +27,6 @@ import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirBodyResolve
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef import org.jetbrains.kotlin.fir.types.builder.buildImplicitTypeRef
import org.jetbrains.kotlin.fir.types.coneType
import org.jetbrains.kotlin.fir.visitors.* import org.jetbrains.kotlin.fir.visitors.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -67,15 +66,8 @@ open class FirContractResolveTransformer(
return simpleFunction.compose() return simpleFunction.compose()
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return withTypeParametersOf(simpleFunction) { return context.withSimpleFunction(simpleFunction, components) {
val receiverTypeRef = simpleFunction.receiverTypeRef transformContractDescriptionOwner(simpleFunction)
if (receiverTypeRef != null) {
withLabelAndReceiverType(simpleFunction.name, simpleFunction, receiverTypeRef.coneType) {
transformContractDescriptionOwner(simpleFunction)
}
} else {
transformContractDescriptionOwner(simpleFunction)
}
} }
} }
@@ -91,13 +83,9 @@ open class FirContractResolveTransformer(
transformSimpleFunction(property.getter.delegate, data) transformSimpleFunction(property.getter.delegate, data)
return property.compose() return property.compose()
} }
withTypeParametersOf(property) { context.withProperty(property) {
withLocalScopeCleanup { property.getter?.let { transformPropertyAccessor(it, property) }
context.withContainer(property) { property.setter?.let { transformPropertyAccessor(it, property) }
property.getter?.let { transformPropertyAccessor(it, property) }
property.setter?.let { transformPropertyAccessor(it, property) }
}
}
} }
return property.compose() return property.compose()
} }
@@ -115,12 +103,7 @@ open class FirContractResolveTransformer(
if (!propertyAccessor.hasContractToResolve) { if (!propertyAccessor.hasContractToResolve) {
return propertyAccessor.compose() return propertyAccessor.compose()
} }
val receiverTypeRef = owner.receiverTypeRef return context.withPropertyAccessor(owner, propertyAccessor, components, forContracts = true) {
return if (receiverTypeRef != null) {
withLabelAndReceiverType(owner.name, propertyAccessor, receiverTypeRef.coneType) {
transformContractDescriptionOwner(propertyAccessor)
}
} else {
transformContractDescriptionOwner(propertyAccessor) transformContractDescriptionOwner(propertyAccessor)
} }
} }
@@ -141,14 +124,10 @@ open class FirContractResolveTransformer(
contractDescription: FirLegacyRawContractDescription contractDescription: FirLegacyRawContractDescription
): CompositeTransformResult<T> { ): CompositeTransformResult<T> {
val valueParameters = owner.valueParameters val valueParameters = owner.valueParameters
val contractCall = withNewLocalScope { for (valueParameter in valueParameters) {
for (valueParameter in valueParameters) { context.storeVariable(valueParameter)
context.storeVariable(valueParameter)
}
context.withContainer(owner as FirDeclaration) {
contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent)
}
} }
val contractCall = contractDescription.contractCall.transformSingle(transformer, ResolutionMode.ContextIndependent)
val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner) val resolvedId = contractCall.toResolvedCallableSymbol()?.callableId ?: return transformOwnerWithUnresolvedContract(owner)
if (resolvedId != FirContractsDslNames.CONTRACT) return transformOwnerWithUnresolvedContract(owner) if (resolvedId != FirContractsDslNames.CONTRACT) return transformOwnerWithUnresolvedContract(owner)
if (contractCall.arguments.size != 1) return transformOwnerOfErrorContract(owner) if (contractCall.arguments.size != 1) return transformOwnerOfErrorContract(owner)
@@ -233,12 +212,9 @@ open class FirContractResolveTransformer(
override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult<FirStatement> { override fun transformRegularClass(regularClass: FirRegularClass, data: ResolutionMode): CompositeTransformResult<FirStatement> {
regularClass.updatePhase() regularClass.updatePhase()
context.storeClassIfNotNested(regularClass)
regularClass.transformCompanionObject(this, data) regularClass.transformCompanionObject(this, data)
withTypeParametersOf(regularClass) { context.withRegularClass(regularClass, components, forContracts = true) {
context.withContainer(regularClass) { regularClass.transformDeclarations(this, data)
regularClass.transformDeclarations(this, data)
}
} }
return regularClass.compose() return regularClass.compose()
} }
@@ -248,7 +224,7 @@ open class FirContractResolveTransformer(
data: ResolutionMode data: ResolutionMode
): CompositeTransformResult<FirStatement> { ): CompositeTransformResult<FirStatement> {
anonymousObject.updatePhase() anonymousObject.updatePhase()
context.withContainer(anonymousObject) { context.withAnonymousObject(anonymousObject, components) {
anonymousObject.transformDeclarations(this, data) anonymousObject.transformDeclarations(this, data)
} }
return anonymousObject.compose() return anonymousObject.compose()