[FIR] Properly track problems in contract description during effect extraction

This commit is contained in:
Dmitriy Novozhilov
2023-04-12 17:31:16 +03:00
committed by Space Team
parent 79d378f2bd
commit 5a92eb2c67
34 changed files with 563 additions and 102 deletions
@@ -0,0 +1,28 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.contracts
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.contracts.description.ConeContractDescriptionElement
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirContractElementDeclaration : FirPureAbstractElement(), FirElement {
abstract override val source: KtSourceElement?
abstract val effect: ConeContractDescriptionElement
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitContractElementDeclaration(this, data)
@Suppress("UNCHECKED_CAST")
override fun <E : FirElement, D> transform(transformer: FirTransformer<D>, data: D): E =
transformer.transformContractElementDeclaration(this, data) as E
}
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.contracts
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirPureAbstractElement
import org.jetbrains.kotlin.fir.contracts.description.ConeEffectDeclaration
import org.jetbrains.kotlin.fir.visitors.*
@@ -16,9 +15,9 @@ import org.jetbrains.kotlin.fir.visitors.*
* DO NOT MODIFY IT MANUALLY
*/
abstract class FirEffectDeclaration : FirPureAbstractElement(), FirElement {
abstract class FirEffectDeclaration : FirContractElementDeclaration() {
abstract override val source: KtSourceElement?
abstract val effect: ConeEffectDeclaration
abstract override val effect: ConeEffectDeclaration
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitEffectDeclaration(this, data)
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.fir.contracts
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -18,7 +17,7 @@ import org.jetbrains.kotlin.fir.visitors.*
abstract class FirResolvedContractDescription : FirContractDescription() {
abstract override val source: KtSourceElement?
abstract val effects: List<FirEffectDeclaration>
abstract val unresolvedEffects: List<ConeUnresolvedEffect>
abstract val unresolvedEffects: List<FirContractElementDeclaration>
override fun <R, D> accept(visitor: FirVisitor<R, D>, data: D): R = visitor.visitResolvedContractDescription(this, data)
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("DuplicatedCode")
package org.jetbrains.kotlin.fir.contracts.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeContractDescriptionElement
import org.jetbrains.kotlin.fir.contracts.impl.FirContractElementDeclarationImpl
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
@FirBuilderDsl
class FirContractElementDeclarationBuilder {
var source: KtSourceElement? = null
lateinit var effect: ConeContractDescriptionElement
fun build(): FirContractElementDeclaration {
return FirContractElementDeclarationImpl(
source,
effect,
)
}
}
@OptIn(ExperimentalContracts::class)
inline fun buildContractElementDeclaration(init: FirContractElementDeclarationBuilder.() -> Unit): FirContractElementDeclaration {
contract {
callsInPlace(init, kotlin.contracts.InvocationKind.EXACTLY_ONCE)
}
return FirContractElementDeclarationBuilder().apply(init).build()
}
@@ -10,9 +10,9 @@ package org.jetbrains.kotlin.fir.contracts.builder
import kotlin.contracts.*
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.contracts.impl.FirResolvedContractDescriptionImpl
import org.jetbrains.kotlin.fir.visitors.*
@@ -25,7 +25,7 @@ import org.jetbrains.kotlin.fir.visitors.*
class FirResolvedContractDescriptionBuilder {
var source: KtSourceElement? = null
val effects: MutableList<FirEffectDeclaration> = mutableListOf()
val unresolvedEffects: MutableList<ConeUnresolvedEffect> = mutableListOf()
val unresolvedEffects: MutableList<FirContractElementDeclaration> = mutableListOf()
fun build(): FirResolvedContractDescription {
return FirResolvedContractDescriptionImpl(
@@ -0,0 +1,29 @@
/*
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("DuplicatedCode")
package org.jetbrains.kotlin.fir.contracts.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeContractDescriptionElement
import org.jetbrains.kotlin.fir.visitors.*
/*
* This file was generated automatically
* DO NOT MODIFY IT MANUALLY
*/
internal class FirContractElementDeclarationImpl(
override val source: KtSourceElement?,
override val effect: ConeContractDescriptionElement,
) : FirContractElementDeclaration() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirContractElementDeclarationImpl {
return this
}
}
@@ -8,9 +8,9 @@
package org.jetbrains.kotlin.fir.contracts.impl
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.contracts.description.ConeUnresolvedEffect
import org.jetbrains.kotlin.fir.visitors.*
/*
@@ -21,14 +21,16 @@ import org.jetbrains.kotlin.fir.visitors.*
internal class FirResolvedContractDescriptionImpl(
override val source: KtSourceElement?,
override val effects: MutableList<FirEffectDeclaration>,
override val unresolvedEffects: MutableList<ConeUnresolvedEffect>,
override val unresolvedEffects: MutableList<FirContractElementDeclaration>,
) : FirResolvedContractDescription() {
override fun <R, D> acceptChildren(visitor: FirVisitor<R, D>, data: D) {
effects.forEach { it.accept(visitor, data) }
unresolvedEffects.forEach { it.accept(visitor, data) }
}
override fun <D> transformChildren(transformer: FirTransformer<D>, data: D): FirResolvedContractDescriptionImpl {
effects.transformInplace(transformer, data)
unresolvedEffects.transformInplace(transformer, data)
return this
}
}
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.types.FirDynamicTypeRef
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirIntersectionTypeRef
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -314,6 +315,8 @@ abstract class FirDefaultVisitor<out R, in D> : FirVisitor<R, D>() {
override fun visitImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: D): R = visitTypeRef(implicitTypeRef, data)
override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): R = visitContractElementDeclaration(effectDeclaration, data)
override fun visitLegacyRawContractDescription(legacyRawContractDescription: FirLegacyRawContractDescription, data: D): R = visitContractDescription(legacyRawContractDescription, data)
override fun visitRawContractDescription(rawContractDescription: FirRawContractDescription, data: D): R = visitContractDescription(rawContractDescription, data)
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.types.FirDynamicTypeRef
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirIntersectionTypeRef
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -314,6 +315,8 @@ abstract class FirDefaultVisitorVoid : FirVisitorVoid() {
override fun visitImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef) = visitTypeRef(implicitTypeRef)
override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration) = visitContractElementDeclaration(effectDeclaration)
override fun visitLegacyRawContractDescription(legacyRawContractDescription: FirLegacyRawContractDescription) = visitContractDescription(legacyRawContractDescription)
override fun visitRawContractDescription(rawContractDescription: FirRawContractDescription) = visitContractDescription(rawContractDescription)
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.types.FirDynamicTypeRef
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirIntersectionTypeRef
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -731,7 +732,11 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformElement(implicitTypeRef, data)
}
open fun transformEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): FirEffectDeclaration {
open fun transformContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration, data: D): FirContractElementDeclaration {
return transformElement(contractElementDeclaration, data)
}
open fun transformEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): FirContractElementDeclaration {
return transformElement(effectDeclaration, data)
}
@@ -1323,7 +1328,11 @@ abstract class FirTransformer<in D> : FirVisitor<FirElement, D>() {
return transformImplicitTypeRef(implicitTypeRef, data)
}
final override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): FirEffectDeclaration {
final override fun visitContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration, data: D): FirContractElementDeclaration {
return transformContractElementDeclaration(contractElementDeclaration, data)
}
final override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): FirContractElementDeclaration {
return transformEffectDeclaration(effectDeclaration, data)
}
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.types.FirDynamicTypeRef
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirIntersectionTypeRef
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -446,6 +447,8 @@ abstract class FirVisitor<out R, in D> {
open fun visitImplicitTypeRef(implicitTypeRef: FirImplicitTypeRef, data: D): R = visitElement(implicitTypeRef, data)
open fun visitContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration, data: D): R = visitElement(contractElementDeclaration, data)
open fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: D): R = visitElement(effectDeclaration, data)
open fun visitContractDescription(contractDescription: FirContractDescription, data: D): R = visitElement(contractDescription, data)
@@ -148,6 +148,7 @@ import org.jetbrains.kotlin.fir.types.FirDynamicTypeRef
import org.jetbrains.kotlin.fir.types.FirFunctionTypeRef
import org.jetbrains.kotlin.fir.types.FirIntersectionTypeRef
import org.jetbrains.kotlin.fir.types.FirImplicitTypeRef
import org.jetbrains.kotlin.fir.contracts.FirContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
import org.jetbrains.kotlin.fir.contracts.FirLegacyRawContractDescription
@@ -730,6 +731,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitElement(implicitTypeRef)
}
open fun visitContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration) {
visitElement(contractElementDeclaration)
}
open fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration) {
visitElement(effectDeclaration)
}
@@ -1322,6 +1327,10 @@ abstract class FirVisitorVoid : FirVisitor<Unit, Nothing?>() {
visitImplicitTypeRef(implicitTypeRef)
}
final override fun visitContractElementDeclaration(contractElementDeclaration: FirContractElementDeclaration, data: Nothing?) {
visitContractElementDeclaration(contractElementDeclaration)
}
final override fun visitEffectDeclaration(effectDeclaration: FirEffectDeclaration, data: Nothing?) {
visitEffectDeclaration(effectDeclaration)
}
@@ -6,16 +6,27 @@
package org.jetbrains.kotlin.fir.contracts
import org.jetbrains.kotlin.KtSourceElement
import org.jetbrains.kotlin.fir.contracts.builder.buildContractElementDeclaration
import org.jetbrains.kotlin.fir.contracts.builder.buildEffectDeclaration
import org.jetbrains.kotlin.fir.contracts.description.ConeContractDescriptionElement
import org.jetbrains.kotlin.fir.contracts.description.ConeEffectDeclaration
val FirContractDescription.effects: List<FirEffectDeclaration>?
get() = (this as? FirResolvedContractDescription)?.effects
fun ConeEffectDeclaration.toFirEffectDeclaration(source: KtSourceElement? = null): FirEffectDeclaration =
fun ConeEffectDeclaration.toFirElement(source: KtSourceElement? = null): FirEffectDeclaration =
buildEffectDeclaration {
if (source != null) {
this.source = source
}
effect = this@toFirEffectDeclaration
effect = this@toFirElement
}
fun ConeContractDescriptionElement.toFirElement(source: KtSourceElement? = null): FirContractElementDeclaration =
buildContractElementDeclaration {
if (source != null) {
this.source = source
}
effect = this@toFirElement
}
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.fir.contracts.description
interface ConeContractDescriptionElement {
fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R
val erroneous: Boolean
}
abstract class ConeEffectDeclaration : ConeContractDescriptionElement {
@@ -23,6 +23,9 @@ abstract class ConeContractDescriptionVisitor<out R, in D> {
open fun visitCallsEffectDeclaration(callsEffect: ConeCallsEffectDeclaration, data: D): R =
visitEffectDeclaration(callsEffect, data)
open fun visitErroneousCallsEffectDeclaration(callsEffect: ConeErroneousCallsEffectDeclaration, data: D): R =
visitCallsEffectDeclaration(callsEffect, data)
// Expressions
open fun visitBooleanExpression(booleanExpression: ConeBooleanExpression, data: D): R =
visitContractDescriptionElement(booleanExpression, data)
@@ -35,6 +38,9 @@ abstract class ConeContractDescriptionVisitor<out R, in D> {
open fun visitIsInstancePredicate(isInstancePredicate: ConeIsInstancePredicate, data: D): R =
visitBooleanExpression(isInstancePredicate, data)
open fun visitErroneousIsInstancePredicate(isInstancePredicate: ConeErroneousIsInstancePredicate, data: D): R =
visitIsInstancePredicate(isInstancePredicate, data)
open fun visitIsNullPredicate(isNullPredicate: ConeIsNullPredicate, data: D): R = visitBooleanExpression(isNullPredicate, data)
// Values
@@ -45,9 +51,19 @@ abstract class ConeContractDescriptionVisitor<out R, in D> {
open fun visitBooleanConstantDescriptor(booleanConstantDescriptor: ConeBooleanConstantReference, data: D): R =
visitConstantDescriptor(booleanConstantDescriptor, data)
open fun visitErroneousConstantReference(erroneousConstantReference: ConeErroneousConstantReference, data: D): R =
visitConstantDescriptor(erroneousConstantReference, data)
open fun visitValueParameterReference(valueParameterReference: ConeValueParameterReference, data: D): R =
visitValue(valueParameterReference, data)
open fun visitBooleanValueParameterReference(booleanValueParameterReference: ConeBooleanValueParameterReference, data: D): R =
visitValueParameterReference(booleanValueParameterReference, data)
}
open fun visitErroneousValueParameterReference(valueParameterReference: ConeErroneousValueParameterReference, data: D): R =
visitValueParameterReference(valueParameterReference, data)
// Error
open fun visitErroneousElement(element: ConeErroneousContractElement, data: D): R =
visitContractDescriptionElement(element, data)
}
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
/**
* Effect with condition attached to it.
@@ -22,6 +23,9 @@ import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
* - if [condition] is true, we *can't* reason that [effect] will be observed.
*/
class ConeConditionalEffectDeclaration(val effect: ConeEffectDeclaration, val condition: ConeBooleanExpression) : ConeEffectDeclaration() {
override val erroneous: Boolean
get() = effect.erroneous || condition.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitConditionalEffectDeclaration(this, data)
}
@@ -31,9 +35,11 @@ class ConeConditionalEffectDeclaration(val effect: ConeEffectDeclaration, val co
* Effect which specifies that subroutine returns some particular value
*/
class ConeReturnsEffectDeclaration(val value: ConeConstantReference) : ConeEffectDeclaration() {
override val erroneous: Boolean
get() = value.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitReturnsEffectDeclaration(this, data)
}
@@ -41,7 +47,24 @@ class ConeReturnsEffectDeclaration(val value: ConeConstantReference) : ConeEffec
* Effect which specifies, that during execution of subroutine, callable [valueParameterReference] will be invoked
* [kind] amount of times, and will never be invoked after subroutine call is finished.
*/
class ConeCallsEffectDeclaration(val valueParameterReference: ConeValueParameterReference, val kind: EventOccurrencesRange) : ConeEffectDeclaration() {
open class ConeCallsEffectDeclaration(
val valueParameterReference: ConeValueParameterReference,
val kind: EventOccurrencesRange
) : ConeEffectDeclaration() {
override val erroneous: Boolean
get() = valueParameterReference.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitCallsEffectDeclaration(this, data)
}
}
class ConeErroneousCallsEffectDeclaration(
valueParameterReference: ConeValueParameterReference,
val diagnostic: ConeDiagnostic
) : ConeCallsEffectDeclaration(valueParameterReference, EventOccurrencesRange.UNKNOWN) {
override val erroneous: Boolean
get() = true
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitErroneousCallsEffectDeclaration(this, data)
}
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
class ConeErroneousContractElement(
val diagnostic: ConeDiagnostic
) : ConeEffectDeclaration(), ConeBooleanExpression, ConeContractDescriptionValue {
override val erroneous: Boolean
get() = true
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R {
return contractDescriptionVisitor.visitErroneousElement(this, data)
}
}
@@ -8,12 +8,18 @@ package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.expressions.LogicOperationKind
class ConeBinaryLogicExpression(val left: ConeBooleanExpression, val right: ConeBooleanExpression, val kind: LogicOperationKind) : ConeBooleanExpression {
override val erroneous: Boolean
get() = left.erroneous || right.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R {
return contractDescriptionVisitor.visitLogicalBinaryOperationContractExpression(this, data)
}
}
class ConeLogicalNot(val arg: ConeBooleanExpression) : ConeBooleanExpression {
override val erroneous: Boolean
get() = arg.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitLogicalNot(this, data)
}
@@ -5,9 +5,13 @@
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
import org.jetbrains.kotlin.fir.types.ConeKotlinType
class ConeIsInstancePredicate(val arg: ConeValueParameterReference, val type: ConeKotlinType, val isNegated: Boolean) : ConeBooleanExpression {
open class ConeIsInstancePredicate(val arg: ConeValueParameterReference, val type: ConeKotlinType, val isNegated: Boolean) : ConeBooleanExpression {
override val erroneous: Boolean
get() = arg.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitIsInstancePredicate(this, data)
@@ -15,10 +19,26 @@ class ConeIsInstancePredicate(val arg: ConeValueParameterReference, val type: Co
ConeIsInstancePredicate(arg, type, isNegated.not())
}
class ConeErroneousIsInstancePredicate(
arg: ConeValueParameterReference,
type: ConeKotlinType,
isNegated: Boolean,
val diagnostic: ConeDiagnostic
) : ConeIsInstancePredicate(arg, type, isNegated) {
override val erroneous: Boolean
get() = true
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitErroneousIsInstancePredicate(this, data)
}
class ConeIsNullPredicate(val arg: ConeValueParameterReference, val isNegated: Boolean) : ConeBooleanExpression {
override val erroneous: Boolean
get() = arg.erroneous
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitIsNullPredicate(this, data)
fun negated(): ConeIsNullPredicate =
ConeIsNullPredicate(arg, isNegated.not())
}
}
@@ -1,10 +0,0 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.expressions.FirStatement
class ConeUnresolvedEffect(val statement: FirStatement)
@@ -5,12 +5,17 @@
package org.jetbrains.kotlin.fir.contracts.description
import org.jetbrains.kotlin.fir.diagnostics.ConeDiagnostic
interface ConeContractDescriptionValue : ConeContractDescriptionElement {
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitValue(this, data)
}
open class ConeConstantReference protected constructor(val name: String) : ConeContractDescriptionValue {
override val erroneous: Boolean
get() = false
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitConstantDescriptor(this, data)
@@ -31,6 +36,14 @@ class ConeBooleanConstantReference private constructor(name: String) : ConeConst
}
}
class ConeErroneousConstantReference(val diagnostic: ConeDiagnostic) : ConeConstantReference("ERROR") {
override val erroneous: Boolean
get() = true
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitErroneousConstantReference(this, data)
}
/*
* Index of value parameter of function
* -1 means that it is reference to extension receiver
@@ -40,6 +53,9 @@ open class ConeValueParameterReference(val parameterIndex: Int, val name: String
assert(parameterIndex >= -1)
}
override val erroneous: Boolean
get() = false
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitValueParameterReference(this, data)
}
@@ -47,4 +63,12 @@ open class ConeValueParameterReference(val parameterIndex: Int, val name: String
class ConeBooleanValueParameterReference(parameterIndex: Int, name: String) : ConeValueParameterReference(parameterIndex, name), ConeBooleanExpression {
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitBooleanValueParameterReference(this, data)
}
}
class ConeErroneousValueParameterReference(val diagnostic: ConeDiagnostic) : ConeValueParameterReference(Int.MAX_VALUE, "ERROR") {
override val erroneous: Boolean
get() = true
override fun <R, D> accept(contractDescriptionVisitor: ConeContractDescriptionVisitor<R, D>, data: D): R =
contractDescriptionVisitor.visitErroneousValueParameterReference(this, data)
}
@@ -180,7 +180,8 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
val intersectionTypeRef by element(TypeRef, typeRefWithNullability)
val implicitTypeRef by element(TypeRef, typeRef)
val effectDeclaration by element(Contracts)
val contractElementDeclaration by element(Contracts)
val effectDeclaration by element(Contracts, contractElementDeclaration)
val contractDescription by element(Contracts)
val legacyRawContractDescription by element(Contracts, contractDescription)
@@ -562,6 +562,8 @@ object ImplementationConfigurator : AbstractFirTreeImplementationConfigurator()
noImpl(argumentList)
noImpl(annotationArgumentMapping)
impl(contractElementDeclaration)
val implementationsWithoutStatusAndTypeParameters = listOf(
"FirAnonymousFunctionImpl",
"FirValueParameterImpl",
@@ -732,6 +732,10 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
+field(varianceType)
}
contractElementDeclaration.configure {
+field("effect", coneContractElementType)
}
effectDeclaration.configure {
+field("effect", coneEffectDeclarationType)
}
@@ -742,7 +746,7 @@ object NodeConfigurator : AbstractFieldConfigurator<FirTreeBuilder>(FirTreeBuild
resolvedContractDescription.configure {
+fieldList("effects", effectDeclaration)
+fieldList("unresolvedEffects", coneUnresolvedEffect)
+fieldList("unresolvedEffects", contractElementDeclaration)
}
legacyRawContractDescription.configure {
@@ -79,11 +79,11 @@ val emptyArgumentListType = type("fir.expressions", "FirEmptyArgumentList")
val firScopeProviderType = type("fir.scopes", "FirScopeProvider")
val pureAbstractElementType = generatedType("FirPureAbstractElement")
val coneContractElementType = type("fir.contracts.description", "ConeContractDescriptionElement")
val coneEffectDeclarationType = type("fir.contracts.description", "ConeEffectDeclaration")
val emptyContractDescriptionType = generatedType("contracts.impl", "FirEmptyContractDescription")
val coneDiagnosticType = generatedType("diagnostics", "ConeDiagnostic")
val coneStubDiagnosticType = generatedType("diagnostics", "ConeStubDiagnostic")
val coneUnresolvedEffect = type("fir.contracts.description", "ConeUnresolvedEffect")
val dslBuilderAnnotationType = generatedType("builder", "FirBuilderDsl")
val firImplementationDetailType = generatedType("FirImplementationDetail")