[FIR] Add contract description blocks support to RawFirBuilder
This commit is contained in:
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.builder.buildRawContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.*
|
import org.jetbrains.kotlin.fir.declarations.builder.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
import org.jetbrains.kotlin.fir.declarations.impl.FirDeclarationStatusImpl
|
||||||
@@ -225,7 +226,11 @@ class RawFirBuilder(
|
|||||||
null to null
|
null to null
|
||||||
hasBlockBody() -> if (!stubMode) {
|
hasBlockBody() -> if (!stubMode) {
|
||||||
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
||||||
block.extractContractDescriptionIfPossible()
|
if (hasContractEffectList()) {
|
||||||
|
block to null
|
||||||
|
} else {
|
||||||
|
block.extractContractDescriptionIfPossible()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
FirSingleExpressionBlock(buildExpressionStub { source = this@buildFirBody.toFirSourceElement() }.toReturn()) to null
|
FirSingleExpressionBlock(buildExpressionStub { source = this@buildFirBody.toFirSourceElement() }.toReturn()) to null
|
||||||
}
|
}
|
||||||
@@ -331,8 +336,10 @@ class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
symbol = FirPropertyAccessorSymbol()
|
symbol = FirPropertyAccessorSymbol()
|
||||||
val (body, contractDescription) = this@toFirPropertyAccessor.buildFirBody()
|
val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription()
|
||||||
this.body = body
|
val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody()
|
||||||
|
this.body = bodyWithContractDescription.first
|
||||||
|
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
||||||
contractDescription?.let {
|
contractDescription?.let {
|
||||||
this.contractDescription = it
|
this.contractDescription = it
|
||||||
}
|
}
|
||||||
@@ -954,8 +961,10 @@ class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
withCapturedTypeParameters {
|
withCapturedTypeParameters {
|
||||||
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
|
if (this is FirSimpleFunctionBuilder) addCapturedTypeParameters(this.typeParameters)
|
||||||
val (body, contractDescription) = function.buildFirBody()
|
val outerContractDescription = function.obtainContractDescription()
|
||||||
this.body = body
|
val bodyWithContractDescription = function.buildFirBody()
|
||||||
|
this.body = bodyWithContractDescription.first
|
||||||
|
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
||||||
contractDescription?.let {
|
contractDescription?.let {
|
||||||
// TODO: add error reporting for contracts on lambdas
|
// TODO: add error reporting for contracts on lambdas
|
||||||
if (this is FirSimpleFunctionBuilder) {
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
@@ -969,6 +978,21 @@ class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun KtDeclarationWithBody.obtainContractDescription(): FirContractDescription? {
|
||||||
|
return when(val description = contractDescription) {
|
||||||
|
null -> null
|
||||||
|
else -> buildRawContractDescription {
|
||||||
|
source = description.toFirSourceElement()
|
||||||
|
description.extractRawEffects(rawEffects)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun KtContractEffectList.extractRawEffects(destination: MutableList<FirExpression>) {
|
||||||
|
getExpressions()
|
||||||
|
.mapTo(destination) { it.accept(this@Visitor, Unit) as FirExpression }
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitLambdaExpression(expression: KtLambdaExpression, data: Unit): FirElement {
|
override fun visitLambdaExpression(expression: KtLambdaExpression, data: Unit): FirElement {
|
||||||
val literal = expression.functionLiteral
|
val literal = expression.functionLiteral
|
||||||
val literalSource = literal.toFirSourceElement()
|
val literalSource = literal.toFirSourceElement()
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ public interface KtDeclarationWithBody extends KtDeclaration {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
default boolean hasContractEffectList() {
|
||||||
|
return getContractDescription() != null;
|
||||||
|
}
|
||||||
|
|
||||||
boolean hasBlockBody();
|
boolean hasBlockBody();
|
||||||
|
|
||||||
boolean hasBody();
|
boolean hasBody();
|
||||||
|
|||||||
Reference in New Issue
Block a user