[FIR] Implement checks for contract not allowed
^KT-55423 Fixed
This commit is contained in:
committed by
Space Team
parent
b2fbf8bed5
commit
f946ddeb40
+7
@@ -3678,6 +3678,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
|
|||||||
token,
|
token,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
add(FirErrors.CONTRACT_NOT_ALLOWED) { firDiagnostic ->
|
||||||
|
ContractNotAllowedImpl(
|
||||||
|
firDiagnostic.a,
|
||||||
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
token,
|
||||||
|
)
|
||||||
|
}
|
||||||
add(FirErrors.NO_GET_METHOD) { firDiagnostic ->
|
add(FirErrors.NO_GET_METHOD) { firDiagnostic ->
|
||||||
NoGetMethodImpl(
|
NoGetMethodImpl(
|
||||||
firDiagnostic as KtPsiDiagnostic,
|
firDiagnostic as KtPsiDiagnostic,
|
||||||
|
|||||||
+5
@@ -2567,6 +2567,11 @@ sealed class KtFirDiagnostic<PSI : PsiElement> : KtDiagnosticWithPsi<PSI> {
|
|||||||
abstract val reason: String
|
abstract val reason: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class ContractNotAllowed : KtFirDiagnostic<KtElement>() {
|
||||||
|
override val diagnosticClass get() = ContractNotAllowed::class
|
||||||
|
abstract val reason: String
|
||||||
|
}
|
||||||
|
|
||||||
abstract class NoGetMethod : KtFirDiagnostic<KtArrayAccessExpression>() {
|
abstract class NoGetMethod : KtFirDiagnostic<KtArrayAccessExpression>() {
|
||||||
override val diagnosticClass get() = NoGetMethod::class
|
override val diagnosticClass get() = NoGetMethod::class
|
||||||
}
|
}
|
||||||
|
|||||||
+6
@@ -3096,6 +3096,12 @@ internal class ErrorInContractDescriptionImpl(
|
|||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
) : KtFirDiagnostic.ErrorInContractDescription(), KtAbstractFirDiagnostic<KtElement>
|
) : KtFirDiagnostic.ErrorInContractDescription(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
|
internal class ContractNotAllowedImpl(
|
||||||
|
override val reason: String,
|
||||||
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
|
override val token: KtLifetimeToken,
|
||||||
|
) : KtFirDiagnostic.ContractNotAllowed(), KtAbstractFirDiagnostic<KtElement>
|
||||||
|
|
||||||
internal class NoGetMethodImpl(
|
internal class NoGetMethodImpl(
|
||||||
override val firDiagnostic: KtPsiDiagnostic,
|
override val firDiagnostic: KtPsiDiagnostic,
|
||||||
override val token: KtLifetimeToken,
|
override val token: KtLifetimeToken,
|
||||||
|
|||||||
+1
@@ -107,6 +107,7 @@ internal object FirLazyBodiesCalculator {
|
|||||||
|
|
||||||
constructor.apply {
|
constructor.apply {
|
||||||
replaceBody(newConstructor.body)
|
replaceBody(newConstructor.body)
|
||||||
|
replaceContractDescription(newConstructor.contractDescription)
|
||||||
replaceDelegatedConstructor(newConstructor.delegatedConstructor)
|
replaceDelegatedConstructor(newConstructor.delegatedConstructor)
|
||||||
replaceValueParameterDefaultValues(valueParameters, newConstructor.valueParameters)
|
replaceValueParameterDefaultValues(valueParameters, newConstructor.valueParameters)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ inline fun <reified T> requreIsInstance(value: Any) contract <!UNSUPPORTED_FEATU
|
|||||||
}
|
}
|
||||||
|
|
||||||
val Any?.myLength: Int?
|
val Any?.myLength: Int?
|
||||||
get() contract <!UNSUPPORTED_FEATURE!>[
|
get() contract <!CONTRACT_NOT_ALLOWED, UNSUPPORTED_FEATURE!>[
|
||||||
<!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this@length is String)<!>
|
<!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this@length is String)<!>
|
||||||
]<!> = (this as? String)?.length
|
]<!> = (this as? String)?.length
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -12,8 +12,8 @@ fun Any?.isNotNull(): Boolean {
|
|||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
val Any?.isNotNull: Boolean
|
val Any?.isNotNull: Boolean
|
||||||
get() {
|
get() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (this@isNotNull != null)
|
returns(true) implies (this@isNotNull != null)
|
||||||
}
|
}
|
||||||
return this@isNotNull != null
|
return this@isNotNull != null
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -7,13 +7,13 @@ interface A {
|
|||||||
@OptIn(ExperimentalContracts::class)
|
@OptIn(ExperimentalContracts::class)
|
||||||
var Any?.isNotNull: Boolean
|
var Any?.isNotNull: Boolean
|
||||||
get() {
|
get() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (this@isNotNull != null)
|
returns(true) implies (this@isNotNull != null)
|
||||||
}
|
}
|
||||||
return this != null
|
return this != null
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
<!WRONG_IMPLIES_CONDITION!>contract {
|
<!WRONG_IMPLIES_CONDITION!><!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns() implies (this@isNotNull != null)
|
returns() implies (this@isNotNull != null)
|
||||||
<!ERROR_IN_CONTRACT_DESCRIPTION!>require(<!SENSELESS_COMPARISON!>this != null<!>)<!>
|
<!ERROR_IN_CONTRACT_DESCRIPTION!>require(<!SENSELESS_COMPARISON!>this != null<!>)<!>
|
||||||
}<!>
|
}<!>
|
||||||
|
|||||||
+3
@@ -1272,6 +1272,9 @@ object DIAGNOSTICS_LIST : DiagnosticList("FirErrors") {
|
|||||||
val ERROR_IN_CONTRACT_DESCRIPTION by error<KtElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
val ERROR_IN_CONTRACT_DESCRIPTION by error<KtElement>(PositioningStrategy.SELECTOR_BY_QUALIFIED) {
|
||||||
parameter<String>("reason")
|
parameter<String>("reason")
|
||||||
}
|
}
|
||||||
|
val CONTRACT_NOT_ALLOWED by error<KtElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED) {
|
||||||
|
parameter<String>("reason")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val CONVENTIONS by object : DiagnosticGroup("Conventions") {
|
val CONVENTIONS by object : DiagnosticGroup("Conventions") {
|
||||||
|
|||||||
@@ -668,6 +668,7 @@ object FirErrors {
|
|||||||
|
|
||||||
// Function contracts
|
// Function contracts
|
||||||
val ERROR_IN_CONTRACT_DESCRIPTION by error1<KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
val ERROR_IN_CONTRACT_DESCRIPTION by error1<KtElement, String>(SourceElementPositioningStrategies.SELECTOR_BY_QUALIFIED)
|
||||||
|
val CONTRACT_NOT_ALLOWED by error1<KtElement, String>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
|
||||||
|
|
||||||
// Conventions
|
// Conventions
|
||||||
val NO_GET_METHOD by error0<KtArrayAccessExpression>(SourceElementPositioningStrategies.ARRAY_ACCESS)
|
val NO_GET_METHOD by error0<KtArrayAccessExpression>(SourceElementPositioningStrategies.ARRAY_ACCESS)
|
||||||
|
|||||||
+1
@@ -64,6 +64,7 @@ object CommonExpressionCheckers : ExpressionCheckers() {
|
|||||||
FirAssignmentOperatorCallChecker,
|
FirAssignmentOperatorCallChecker,
|
||||||
FirNamedVarargChecker,
|
FirNamedVarargChecker,
|
||||||
FirUnderscoredTypeArgumentSyntaxChecker,
|
FirUnderscoredTypeArgumentSyntaxChecker,
|
||||||
|
FirContractNotFirstStatementChecker,
|
||||||
)
|
)
|
||||||
|
|
||||||
override val propertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker>
|
override val propertyAccessExpressionCheckers: Set<FirPropertyAccessExpressionChecker>
|
||||||
|
|||||||
+37
-8
@@ -6,27 +6,38 @@
|
|||||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||||
|
|
||||||
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
import org.jetbrains.kotlin.KtFakeSourceElementKind
|
||||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
import org.jetbrains.kotlin.KtRealSourceElementKind
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
|
||||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
|
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirPropertyAccessor
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||||
|
|
||||||
object FirContractChecker : FirFunctionChecker() {
|
object FirContractChecker : FirFunctionChecker() {
|
||||||
// TODO: The message should vary. Migrate this to [ConeEffectExtractor] when creating fine-grained errors.
|
// TODO: The message should vary. Migrate this to [ConeEffectExtractor] when creating fine-grained errors.
|
||||||
private const val UNEXPECTED_CONSTRUCTION = "unexpected construction in contract description"
|
private const val UNEXPECTED_CONSTRUCTION = "unexpected construction in contract description"
|
||||||
|
|
||||||
override fun check(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
override fun check(declaration: FirFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
if (declaration !is FirContractDescriptionOwner ||
|
if (declaration !is FirContractDescriptionOwner) return
|
||||||
declaration.contractDescription !is FirResolvedContractDescription
|
val contractDescription = declaration.contractDescription as? FirResolvedContractDescription ?: return
|
||||||
) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
|
checkUnresolvedEffects(contractDescription, context, reporter)
|
||||||
|
checkContractNotAllowed(declaration, contractDescription, context, reporter)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkUnresolvedEffects(
|
||||||
|
contractDescription: FirResolvedContractDescription,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
// Any statements that [ConeEffectExtractor] cannot extract effects will be in `unresolvedEffects`.
|
// Any statements that [ConeEffectExtractor] cannot extract effects will be in `unresolvedEffects`.
|
||||||
for (unresolvedEffect in (declaration.contractDescription as FirResolvedContractDescription).unresolvedEffects) {
|
for (unresolvedEffect in contractDescription.unresolvedEffects) {
|
||||||
val statement = unresolvedEffect.statement
|
val statement = unresolvedEffect.statement
|
||||||
if (statement.source == null || statement.source!!.kind is KtFakeSourceElementKind) continue
|
if (statement.source == null || statement.source!!.kind is KtFakeSourceElementKind) continue
|
||||||
|
|
||||||
@@ -35,4 +46,22 @@ object FirContractChecker : FirFunctionChecker() {
|
|||||||
reporter.reportOn(statement.source, FirErrors.ERROR_IN_CONTRACT_DESCRIPTION, UNEXPECTED_CONSTRUCTION, context)
|
reporter.reportOn(statement.source, FirErrors.ERROR_IN_CONTRACT_DESCRIPTION, UNEXPECTED_CONSTRUCTION, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun checkContractNotAllowed(
|
||||||
|
declaration: FirFunction,
|
||||||
|
contractDescription: FirResolvedContractDescription,
|
||||||
|
context: CheckerContext,
|
||||||
|
reporter: DiagnosticReporter
|
||||||
|
) {
|
||||||
|
val source = contractDescription.source
|
||||||
|
if (source?.kind !is KtRealSourceElementKind) return
|
||||||
|
|
||||||
|
fun contractNotAllowed(message: String) = reporter.reportOn(source, FirErrors.CONTRACT_NOT_ALLOWED, message, context)
|
||||||
|
|
||||||
|
if (declaration is FirPropertyAccessor || declaration is FirAnonymousFunction) contractNotAllowed("Contracts are only allowed for functions")
|
||||||
|
else if (declaration.isAbstract || declaration.isOpen || declaration.isOverride) contractNotAllowed("Contracts are not allowed for open or override functions")
|
||||||
|
else if (declaration.isOperator) contractNotAllowed("Contracts are not allowed for operator functions")
|
||||||
|
else if (declaration.symbol.callableId.isLocal || declaration.visibility == Visibilities.Local) contractNotAllowed("Contracts are not allowed for local functions")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+39
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.analysis.checkers.expression
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||||
|
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
|
||||||
|
import org.jetbrains.kotlin.name.StandardClassIds
|
||||||
|
|
||||||
|
object FirContractNotFirstStatementChecker : FirFunctionCallChecker() {
|
||||||
|
override fun check(expression: FirFunctionCall, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||||
|
if (StandardClassIds.Callables.contract != expression.toResolvedCallableSymbol()?.callableId) return
|
||||||
|
|
||||||
|
val containingDeclaration = context.containingDeclarations.last()
|
||||||
|
if (!(containingDeclaration is FirFunction && expression.isCorrectlyPlacedIn(containingDeclaration))) {
|
||||||
|
val message = if (containingDeclaration is FirFunction && containingDeclaration.body is FirSingleExpressionBlock) {
|
||||||
|
"Contracts are only allowed in function body blocks"
|
||||||
|
} else {
|
||||||
|
"Contract should be the first statement"
|
||||||
|
}
|
||||||
|
|
||||||
|
reporter.reportOn(expression.source, FirErrors.CONTRACT_NOT_ALLOWED, message, context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun FirFunctionCall.isCorrectlyPlacedIn(functionDeclaration: FirFunction): Boolean {
|
||||||
|
val firstStatement = functionDeclaration.body?.statements?.first()
|
||||||
|
return firstStatement is FirContractCallBlock && firstStatement.call == this
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
@@ -134,6 +134,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITHOUT
|
|||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_DELEGATE
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_DELEGATE
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_GETTER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_GETTER
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONST_VAL_WITH_NON_CONST_INITIALIZER
|
||||||
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CONTRACT_NOT_ALLOWED
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_CONSTRUCTOR_DELEGATION_CALL
|
||||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_GENERIC_UPPER_BOUND
|
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.CYCLIC_GENERIC_UPPER_BOUND
|
||||||
@@ -1909,6 +1910,7 @@ object FirErrorsDefaultMessages : BaseDiagnosticRendererFactory() {
|
|||||||
|
|
||||||
// Function contracts
|
// Function contracts
|
||||||
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)
|
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)
|
||||||
|
map.put(CONTRACT_NOT_ALLOWED, "{0}", TO_STRING)
|
||||||
|
|
||||||
// Conventions
|
// Conventions
|
||||||
map.put(NO_GET_METHOD, "No get method providing array access")
|
map.put(NO_GET_METHOD, "No get method providing array access")
|
||||||
|
|||||||
+10
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.descriptors.Visibility
|
|||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
import org.jetbrains.kotlin.fir.declarations.builder.FirConstructorBuilder
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
@@ -44,6 +46,7 @@ class FirJavaConstructor @FirImplementationDetail constructor(
|
|||||||
) : FirConstructor() {
|
) : FirConstructor() {
|
||||||
override val receiverParameter: FirReceiverParameter? get() = null
|
override val receiverParameter: FirReceiverParameter? get() = null
|
||||||
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
|
override var deprecationsProvider: DeprecationsProvider = UnresolvedDeprecationProvider
|
||||||
|
override val contractDescription: FirContractDescription get() = FirEmptyContractDescription
|
||||||
|
|
||||||
init {
|
init {
|
||||||
symbol.bind(this)
|
symbol.bind(this)
|
||||||
@@ -100,6 +103,10 @@ class FirJavaConstructor @FirImplementationDetail constructor(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirConstructor {
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirJavaConstructor {
|
override fun <D> transformStatus(transformer: FirTransformer<D>, data: D): FirJavaConstructor {
|
||||||
status = status.transformSingle(transformer, data)
|
status = status.transformSingle(transformer, data)
|
||||||
return this
|
return this
|
||||||
@@ -152,6 +159,9 @@ class FirJavaConstructor @FirImplementationDetail constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {}
|
override fun replaceControlFlowGraphReference(newControlFlowGraphReference: FirControlFlowGraphReference?) {}
|
||||||
|
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
|
||||||
|
error("Contract description cannot be replaced for FirJavaConstructor")
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceBody(newBody: FirBlock?) {
|
override fun replaceBody(newBody: FirBlock?) {
|
||||||
error("Body cannot be replaced for FirJavaConstructor")
|
error("Body cannot be replaced for FirJavaConstructor")
|
||||||
|
|||||||
+5
-3
@@ -1045,8 +1045,9 @@ class DeclarationsConverter(
|
|||||||
annotations += modifiers.annotations
|
annotations += modifiers.annotations
|
||||||
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
|
typeParameters += constructorTypeParametersFromConstructedClass(classWrapper.classBuilder.typeParameters)
|
||||||
valueParameters += firValueParameters.map { it.firValueParameter }
|
valueParameters += firValueParameters.map { it.firValueParameter }
|
||||||
val (body, _) = convertFunctionBody(block, null, allowLegacyContractDescription = true)
|
val (body, contractDescription) = convertFunctionBody(block, null, allowLegacyContractDescription = true)
|
||||||
this.body = body
|
this.body = body
|
||||||
|
contractDescription?.let { this.contractDescription = it }
|
||||||
context.firFunctionTargets.removeLast()
|
context.firFunctionTargets.removeLast()
|
||||||
this.contextReceivers.addAll(convertContextReceivers(secondaryConstructor.getParent()!!.getParent()!!))
|
this.contextReceivers.addAll(convertContextReceivers(secondaryConstructor.getParent()!!.getParent()!!))
|
||||||
}.also {
|
}.also {
|
||||||
@@ -1736,14 +1737,15 @@ class DeclarationsConverter(
|
|||||||
).map { it.firValueParameter }
|
).map { it.firValueParameter }
|
||||||
}
|
}
|
||||||
|
|
||||||
val allowLegacyContractDescription = outerContractDescription == null && !isLocal
|
val allowLegacyContractDescription = outerContractDescription == null
|
||||||
val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
|
val bodyWithContractDescription = convertFunctionBody(block, expression, allowLegacyContractDescription)
|
||||||
this.body = bodyWithContractDescription.first
|
this.body = bodyWithContractDescription.first
|
||||||
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
||||||
contractDescription?.let {
|
contractDescription?.let {
|
||||||
// TODO: add error reporting for contracts on lambdas
|
|
||||||
if (this is FirSimpleFunctionBuilder) {
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
this.contractDescription = it
|
this.contractDescription = it
|
||||||
|
} else if (this is FirAnonymousFunctionBuilder) {
|
||||||
|
this.contractDescription = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
@@ -30,6 +30,7 @@ import org.jetbrains.kotlin.fir.declarations.impl.FirResolvedDeclarationStatusIm
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.buildSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
import org.jetbrains.kotlin.fir.lightTree.LightTree2Fir
|
||||||
@@ -201,6 +202,13 @@ class ExpressionsConverter(
|
|||||||
body = if (block != null) {
|
body = if (block != null) {
|
||||||
declarationsConverter.withOffset(expressionSource.startOffset) {
|
declarationsConverter.withOffset(expressionSource.startOffset) {
|
||||||
declarationsConverter.convertBlockExpressionWithoutBuilding(block!!).apply {
|
declarationsConverter.convertBlockExpressionWithoutBuilding(block!!).apply {
|
||||||
|
statements.firstOrNull()?.let {
|
||||||
|
if (it.isContractBlockFirCheck()) {
|
||||||
|
this@buildAnonymousFunction.contractDescription = it.toLegacyRawContractDescription()
|
||||||
|
statements[0] = FirContractCallBlock(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (statements.isEmpty()) {
|
if (statements.isEmpty()) {
|
||||||
statements.add(
|
statements.add(
|
||||||
buildReturnExpression {
|
buildReturnExpression {
|
||||||
|
|||||||
+21
-11
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.fir.declarations.utils.*
|
|||||||
import org.jetbrains.kotlin.fir.diagnostics.*
|
import org.jetbrains.kotlin.fir.diagnostics.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
|
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock
|
||||||
import org.jetbrains.kotlin.fir.extensions.extensionService
|
import org.jetbrains.kotlin.fir.extensions.extensionService
|
||||||
import org.jetbrains.kotlin.fir.references.builder.*
|
import org.jetbrains.kotlin.fir.references.builder.*
|
||||||
@@ -365,13 +366,13 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun KtDeclarationWithBody.buildFirBody(allowLegacyContractDescription: Boolean): Pair<FirBlock?, FirContractDescription?> =
|
private fun KtDeclarationWithBody.buildFirBody(): Pair<FirBlock?, FirContractDescription?> =
|
||||||
if (hasBody()) {
|
if (hasBody()) {
|
||||||
buildOrLazyBlock {
|
buildOrLazyBlock {
|
||||||
if (hasBlockBody()) {
|
if (hasBlockBody()) {
|
||||||
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
val block = bodyBlockExpression?.accept(this@Visitor, Unit) as? FirBlock
|
||||||
val contractDescription = when {
|
val contractDescription = when {
|
||||||
allowLegacyContractDescription && !hasContractEffectList() -> block?.let(::processLegacyContractDescription)
|
!hasContractEffectList() -> block?.let(::processLegacyContractDescription)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
return@buildFirBody block to contractDescription
|
return@buildFirBody block to contractDescription
|
||||||
@@ -471,9 +472,9 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription()
|
val outerContractDescription = this@toFirPropertyAccessor.obtainContractDescription()
|
||||||
val bodyWithContractDescription = this@toFirPropertyAccessor.buildFirBody(allowLegacyContractDescription = true)
|
val (body, innerContractDescription) = this@toFirPropertyAccessor.buildFirBody()
|
||||||
this.body = bodyWithContractDescription.first
|
this.body = body
|
||||||
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
val contractDescription = outerContractDescription ?: innerContractDescription
|
||||||
contractDescription?.let {
|
contractDescription?.let {
|
||||||
this.contractDescription = it
|
this.contractDescription = it
|
||||||
}
|
}
|
||||||
@@ -1484,13 +1485,14 @@ open class RawFirBuilder(
|
|||||||
listOf()
|
listOf()
|
||||||
withCapturedTypeParameters(true, functionSource, actualTypeParameters) {
|
withCapturedTypeParameters(true, functionSource, actualTypeParameters) {
|
||||||
val outerContractDescription = function.obtainContractDescription()
|
val outerContractDescription = function.obtainContractDescription()
|
||||||
val bodyWithContractDescription = function.buildFirBody(!isLocalFunction)
|
val (body, innerContractDescription) = function.buildFirBody()
|
||||||
this.body = bodyWithContractDescription.first
|
this.body = body
|
||||||
val contractDescription = outerContractDescription ?: bodyWithContractDescription.second
|
val contractDescription = outerContractDescription ?: innerContractDescription
|
||||||
contractDescription?.let {
|
contractDescription?.let {
|
||||||
// TODO: add error reporting for contracts on lambdas
|
|
||||||
if (this is FirSimpleFunctionBuilder) {
|
if (this is FirSimpleFunctionBuilder) {
|
||||||
this.contractDescription = it
|
this.contractDescription = it
|
||||||
|
} else if (this is FirAnonymousFunctionBuilder) {
|
||||||
|
this.contractDescription = it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1601,6 +1603,13 @@ open class RawFirBuilder(
|
|||||||
FirSingleExpressionBlock(errorExpression.toReturn())
|
FirSingleExpressionBlock(errorExpression.toReturn())
|
||||||
} else {
|
} else {
|
||||||
configureBlockWithoutBuilding(ktBody).apply {
|
configureBlockWithoutBuilding(ktBody).apply {
|
||||||
|
statements.firstOrNull()?.let {
|
||||||
|
if (it.isContractBlockFirCheck()) {
|
||||||
|
this@buildAnonymousFunction.contractDescription = it.toLegacyRawContractDescription()
|
||||||
|
statements[0] = FirContractCallBlock(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (statements.isEmpty()) {
|
if (statements.isEmpty()) {
|
||||||
statements.add(
|
statements.add(
|
||||||
buildReturnExpression {
|
buildReturnExpression {
|
||||||
@@ -1660,7 +1669,8 @@ open class RawFirBuilder(
|
|||||||
extractValueParametersTo(this, symbol, ValueParameterDeclaration.FUNCTION)
|
extractValueParametersTo(this, symbol, ValueParameterDeclaration.FUNCTION)
|
||||||
|
|
||||||
|
|
||||||
val (body, _) = buildFirBody(allowLegacyContractDescription = true)
|
val (body, contractDescription) = buildFirBody()
|
||||||
|
contractDescription?.let { this.contractDescription = it }
|
||||||
this.body = body
|
this.body = body
|
||||||
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
this@RawFirBuilder.context.firFunctionTargets.removeLast()
|
||||||
}.also {
|
}.also {
|
||||||
@@ -2757,7 +2767,7 @@ open class RawFirBuilder(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildErrorTopLevelDeclarationForDanglingModifierList(modifierList : KtModifierList) = buildDanglingModifierList {
|
private fun buildErrorTopLevelDeclarationForDanglingModifierList(modifierList: KtModifierList) = buildDanglingModifierList {
|
||||||
this.source = modifierList.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList)
|
this.source = modifierList.toFirSourceElement(KtFakeSourceElementKind.DanglingModifierList)
|
||||||
moduleData = baseModuleData
|
moduleData = baseModuleData
|
||||||
origin = FirDeclarationOrigin.Source
|
origin = FirDeclarationOrigin.Source
|
||||||
|
|||||||
+19
-5
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|||||||
import org.jetbrains.kotlin.fakeElement
|
import org.jetbrains.kotlin.fakeElement
|
||||||
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.FirLegacyRawContractDescription
|
||||||
import org.jetbrains.kotlin.fir.contracts.builder.buildLegacyRawContractDescription
|
import org.jetbrains.kotlin.fir.contracts.builder.buildLegacyRawContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirCallableDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
|
||||||
@@ -43,6 +44,8 @@ import org.jetbrains.kotlin.name.SpecialNames
|
|||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
import kotlin.contracts.ExperimentalContracts
|
||||||
|
import kotlin.contracts.contract
|
||||||
|
|
||||||
fun String.parseCharacter(): CharacterWithDiagnostic {
|
fun String.parseCharacter(): CharacterWithDiagnostic {
|
||||||
// Strip the quotes
|
// Strip the quotes
|
||||||
@@ -495,18 +498,29 @@ fun <T> FirPropertyBuilder.generateAccessorsByDelegate(
|
|||||||
fun processLegacyContractDescription(block: FirBlock): FirContractDescription? {
|
fun processLegacyContractDescription(block: FirBlock): FirContractDescription? {
|
||||||
if (block.isContractPresentFirCheck()) {
|
if (block.isContractPresentFirCheck()) {
|
||||||
val contractCall = block.replaceFirstStatement<FirFunctionCall> { FirContractCallBlock(it) }
|
val contractCall = block.replaceFirstStatement<FirFunctionCall> { FirContractCallBlock(it) }
|
||||||
return buildLegacyRawContractDescription {
|
return contractCall.toLegacyRawContractDescription()
|
||||||
source = contractCall.source
|
|
||||||
this.contractCall = contractCall
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun FirFunctionCall.toLegacyRawContractDescription(): FirLegacyRawContractDescription {
|
||||||
|
return buildLegacyRawContractDescription {
|
||||||
|
this.source = this@toLegacyRawContractDescription.source
|
||||||
|
this.contractCall = this@toLegacyRawContractDescription
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FirBlock.isContractPresentFirCheck(): Boolean {
|
fun FirBlock.isContractPresentFirCheck(): Boolean {
|
||||||
val firstStatement = statements.firstOrNull() ?: return false
|
val firstStatement = statements.firstOrNull() ?: return false
|
||||||
val contractCall = firstStatement as? FirFunctionCall ?: return false
|
return firstStatement.isContractBlockFirCheck()
|
||||||
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalContracts::class)
|
||||||
|
fun FirStatement.isContractBlockFirCheck(): Boolean {
|
||||||
|
contract { returns(true) implies (this@isContractBlockFirCheck is FirFunctionCall) }
|
||||||
|
|
||||||
|
val contractCall = this as? FirFunctionCall ?: return false
|
||||||
if (contractCall.calleeReference.name.asString() != "contract") return false
|
if (contractCall.calleeReference.name.asString() != "contract") return false
|
||||||
val receiver = contractCall.explicitReceiver as? FirQualifiedAccessExpression ?: return true
|
val receiver = contractCall.explicitReceiver as? FirQualifiedAccessExpression ?: return true
|
||||||
if (!contractCall.checkReceiver("contracts")) return false
|
if (!contractCall.checkReceiver("contracts")) return false
|
||||||
|
|||||||
+11
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.fakeElement
|
import org.jetbrains.kotlin.fakeElement
|
||||||
import org.jetbrains.kotlin.fir.*
|
import org.jetbrains.kotlin.fir.*
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunctionCopy
|
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunctionCopy
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.builder.buildContextReceiver
|
||||||
@@ -36,6 +37,7 @@ import org.jetbrains.kotlin.fir.resolve.inference.extractLambdaInfoFromFunctionT
|
|||||||
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
import org.jetbrains.kotlin.fir.resolve.substitution.createTypeSubstitutorByTypeConstructor
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirCallCompletionResultsWriterTransformer
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolver
|
import org.jetbrains.kotlin.fir.resolve.transformers.FirStatusResolver
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.transformers.contracts.runContractResolveForFunction
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayType
|
import org.jetbrains.kotlin.fir.resolve.transformers.transformVarargTypeToArrayType
|
||||||
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
import org.jetbrains.kotlin.fir.scopes.impl.FirMemberTypeParameterScope
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirValueParameterSymbol
|
||||||
@@ -590,6 +592,10 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
// For class members everything should be already prepared
|
// For class members everything should be already prepared
|
||||||
prepareSignatureForBodyResolve(simpleFunction)
|
prepareSignatureForBodyResolve(simpleFunction)
|
||||||
simpleFunction.transformStatus(this, simpleFunction.resolveStatus().mode())
|
simpleFunction.transformStatus(this, simpleFunction.resolveStatus().mode())
|
||||||
|
|
||||||
|
if (simpleFunction.contractDescription != FirEmptyContractDescription) {
|
||||||
|
simpleFunction.runContractResolveForFunction(session, scopeSession, context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
context.forFunctionBody(simpleFunction, components) {
|
context.forFunctionBody(simpleFunction, components) {
|
||||||
withFullBodyResolve {
|
withFullBodyResolve {
|
||||||
@@ -730,6 +736,11 @@ open class FirDeclarationsResolveTransformer(
|
|||||||
anonymousFunction.transformReceiverParameter(transformer, ResolutionMode.ContextIndependent)
|
anonymousFunction.transformReceiverParameter(transformer, ResolutionMode.ContextIndependent)
|
||||||
anonymousFunction.valueParameters.forEach { it.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) }
|
anonymousFunction.valueParameters.forEach { it.transformReturnTypeRef(transformer, ResolutionMode.ContextIndependent) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (anonymousFunction.contractDescription != FirEmptyContractDescription) {
|
||||||
|
anonymousFunction.runContractResolveForFunction(session, scopeSession, context)
|
||||||
|
}
|
||||||
|
|
||||||
return when (data) {
|
return when (data) {
|
||||||
is ResolutionMode.ContextDependent, is ResolutionMode.ContextDependentDelegate -> {
|
is ResolutionMode.ContextDependent, is ResolutionMode.ContextDependentDelegate -> {
|
||||||
context.storeContextForAnonymousFunction(anonymousFunction)
|
context.storeContextForAnonymousFunction(anonymousFunction)
|
||||||
|
|||||||
+21
-20
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.fir.declarations.*
|
|||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
|
import org.jetbrains.kotlin.fir.declarations.builder.buildReceiverParameter
|
||||||
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
import org.jetbrains.kotlin.fir.declarations.synthetic.FirSyntheticProperty
|
||||||
import org.jetbrains.kotlin.fir.errorTypeFromPrototype
|
|
||||||
import org.jetbrains.kotlin.fir.expressions.*
|
import org.jetbrains.kotlin.fir.expressions.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.builder.*
|
import org.jetbrains.kotlin.fir.expressions.builder.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
import org.jetbrains.kotlin.fir.expressions.impl.FirContractCallBlock
|
||||||
@@ -26,7 +25,6 @@ import org.jetbrains.kotlin.fir.moduleData
|
|||||||
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
import org.jetbrains.kotlin.fir.references.builder.buildSimpleNamedReference
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
import org.jetbrains.kotlin.fir.resolve.diagnostics.ConeContractDescriptionError
|
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.BodyResolveContext
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirAbstractBodyResolveTransformerDispatcher
|
||||||
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.FirDeclarationsResolveTransformer
|
||||||
@@ -72,19 +70,8 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
|
|||||||
simpleFunction: FirSimpleFunction,
|
simpleFunction: FirSimpleFunction,
|
||||||
data: ResolutionMode
|
data: ResolutionMode
|
||||||
): FirSimpleFunction {
|
): FirSimpleFunction {
|
||||||
if (!simpleFunction.hasContractToResolve) {
|
if (!simpleFunction.hasContractToResolve) return simpleFunction
|
||||||
return simpleFunction
|
|
||||||
}
|
|
||||||
val containingDeclaration = context.containerIfAny
|
|
||||||
if (containingDeclaration != null && containingDeclaration !is FirClass) {
|
|
||||||
simpleFunction.replaceReturnTypeRef(
|
|
||||||
simpleFunction.returnTypeRef.errorTypeFromPrototype(
|
|
||||||
ConeContractDescriptionError("Local function can not be used in contract description")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
return simpleFunction
|
|
||||||
}
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
return context.withSimpleFunction(simpleFunction, session) {
|
return context.withSimpleFunction(simpleFunction, session) {
|
||||||
context.forFunctionBody(simpleFunction, components) {
|
context.forFunctionBody(simpleFunction, components) {
|
||||||
transformContractDescriptionOwner(simpleFunction)
|
transformContractDescriptionOwner(simpleFunction)
|
||||||
@@ -92,6 +79,15 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun transformAnonymousFunction(anonymousFunction: FirAnonymousFunction, data: ResolutionMode): FirAnonymousFunction {
|
||||||
|
if (!anonymousFunction.hasContractToResolve) return anonymousFunction
|
||||||
|
|
||||||
|
return context.forFunctionBody(anonymousFunction, components) {
|
||||||
|
transformContractDescriptionOwner(anonymousFunction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun transformScript(script: FirScript, data: ResolutionMode): FirScript {
|
override fun transformScript(script: FirScript, data: ResolutionMode): FirScript {
|
||||||
return script
|
return script
|
||||||
}
|
}
|
||||||
@@ -282,7 +278,14 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
|
override fun transformConstructor(constructor: FirConstructor, data: ResolutionMode): FirConstructor {
|
||||||
return constructor
|
if (!constructor.hasContractToResolve) {
|
||||||
|
return constructor
|
||||||
|
}
|
||||||
|
return context.withConstructor(constructor) {
|
||||||
|
context.forConstructorBody(constructor, session) {
|
||||||
|
transformContractDescriptionOwner(constructor)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
|
override fun transformEnumEntry(enumEntry: FirEnumEntry, data: ResolutionMode): FirEnumEntry {
|
||||||
@@ -302,15 +305,13 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
|
|||||||
|
|
||||||
private val FirContractDescriptionOwner.valueParameters: List<FirValueParameter>
|
private val FirContractDescriptionOwner.valueParameters: List<FirValueParameter>
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is FirSimpleFunction -> valueParameters
|
is FirFunction -> valueParameters
|
||||||
is FirPropertyAccessor -> valueParameters
|
|
||||||
else -> error()
|
else -> error()
|
||||||
}
|
}
|
||||||
|
|
||||||
private val FirContractDescriptionOwner.body: FirBlock
|
private val FirContractDescriptionOwner.body: FirBlock
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is FirSimpleFunction -> body!!
|
is FirFunction -> body!!
|
||||||
is FirPropertyAccessor -> body!!
|
|
||||||
else -> error()
|
else -> error()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.fir.FirElement
|
|||||||
import org.jetbrains.kotlin.fir.FirSession
|
import org.jetbrains.kotlin.fir.FirSession
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirFile
|
import org.jetbrains.kotlin.fir.declarations.FirFile
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
import org.jetbrains.kotlin.fir.resolve.ResolutionMode
|
||||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||||
@@ -52,3 +53,13 @@ fun <F : FirClassLikeDeclaration> F.runContractResolveForLocalClass(
|
|||||||
|
|
||||||
return this.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
return this.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun <F : FirFunction> F.runContractResolveForFunction(
|
||||||
|
session: FirSession,
|
||||||
|
scopeSession: ScopeSession,
|
||||||
|
outerBodyResolveContext: BodyResolveContext,
|
||||||
|
): F {
|
||||||
|
val transformer = FirContractResolveTransformer(session, scopeSession, outerBodyResolveContext)
|
||||||
|
|
||||||
|
return this.transformSingle(transformer, ResolutionMode.ContextIndependent)
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
|||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirLabel
|
import org.jetbrains.kotlin.fir.FirLabel
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
import org.jetbrains.kotlin.fir.references.FirControlFlowGraphReference
|
||||||
@@ -24,7 +25,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirAnonymousFunction : FirFunction(), FirTypeParametersOwner {
|
abstract class FirAnonymousFunction : FirFunction(), FirTypeParametersOwner, FirContractDescriptionOwner {
|
||||||
abstract override val source: KtSourceElement?
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val resolvePhase: FirResolvePhase
|
abstract override val resolvePhase: FirResolvePhase
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
@@ -41,6 +42,7 @@ abstract class FirAnonymousFunction : FirFunction(), FirTypeParametersOwner {
|
|||||||
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
|
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
|
||||||
abstract override val valueParameters: List<FirValueParameter>
|
abstract override val valueParameters: List<FirValueParameter>
|
||||||
abstract override val body: FirBlock?
|
abstract override val body: FirBlock?
|
||||||
|
abstract override val contractDescription: FirContractDescription
|
||||||
abstract override val symbol: FirAnonymousFunctionSymbol
|
abstract override val symbol: FirAnonymousFunctionSymbol
|
||||||
abstract val label: FirLabel?
|
abstract val label: FirLabel?
|
||||||
abstract val invocationKind: EventOccurrencesRange?
|
abstract val invocationKind: EventOccurrencesRange?
|
||||||
@@ -76,6 +78,8 @@ abstract class FirAnonymousFunction : FirFunction(), FirTypeParametersOwner {
|
|||||||
|
|
||||||
abstract override fun replaceBody(newBody: FirBlock?)
|
abstract override fun replaceBody(newBody: FirBlock?)
|
||||||
|
|
||||||
|
abstract override fun replaceContractDescription(newContractDescription: FirContractDescription)
|
||||||
|
|
||||||
abstract fun replaceInvocationKind(newInvocationKind: EventOccurrencesRange?)
|
abstract fun replaceInvocationKind(newInvocationKind: EventOccurrencesRange?)
|
||||||
|
|
||||||
abstract fun replaceInlineStatus(newInlineStatus: InlineStatus)
|
abstract fun replaceInlineStatus(newInlineStatus: InlineStatus)
|
||||||
@@ -94,5 +98,7 @@ abstract class FirAnonymousFunction : FirFunction(), FirTypeParametersOwner {
|
|||||||
|
|
||||||
abstract override fun <D> transformBody(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
|
abstract override fun <D> transformBody(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
|
||||||
|
|
||||||
|
abstract override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
|
||||||
|
|
||||||
abstract override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
|
abstract override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirAnonymousFunction
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.declarations
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirElement
|
import org.jetbrains.kotlin.fir.FirElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
import org.jetbrains.kotlin.fir.expressions.FirBlock
|
||||||
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
import org.jetbrains.kotlin.fir.expressions.FirDelegatedConstructorCall
|
||||||
@@ -23,7 +24,7 @@ import org.jetbrains.kotlin.fir.visitors.*
|
|||||||
* DO NOT MODIFY IT MANUALLY
|
* DO NOT MODIFY IT MANUALLY
|
||||||
*/
|
*/
|
||||||
|
|
||||||
abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner {
|
abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner, FirContractDescriptionOwner {
|
||||||
abstract override val source: KtSourceElement?
|
abstract override val source: KtSourceElement?
|
||||||
abstract override val resolvePhase: FirResolvePhase
|
abstract override val resolvePhase: FirResolvePhase
|
||||||
abstract override val moduleData: FirModuleData
|
abstract override val moduleData: FirModuleData
|
||||||
@@ -39,6 +40,7 @@ abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner {
|
|||||||
abstract override val contextReceivers: List<FirContextReceiver>
|
abstract override val contextReceivers: List<FirContextReceiver>
|
||||||
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
|
abstract override val controlFlowGraphReference: FirControlFlowGraphReference?
|
||||||
abstract override val valueParameters: List<FirValueParameter>
|
abstract override val valueParameters: List<FirValueParameter>
|
||||||
|
abstract override val contractDescription: FirContractDescription
|
||||||
abstract override val annotations: List<FirAnnotation>
|
abstract override val annotations: List<FirAnnotation>
|
||||||
abstract override val symbol: FirConstructorSymbol
|
abstract override val symbol: FirConstructorSymbol
|
||||||
abstract val delegatedConstructor: FirDelegatedConstructorCall?
|
abstract val delegatedConstructor: FirDelegatedConstructorCall?
|
||||||
@@ -67,6 +69,8 @@ abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner {
|
|||||||
|
|
||||||
abstract override fun replaceValueParameters(newValueParameters: List<FirValueParameter>)
|
abstract override fun replaceValueParameters(newValueParameters: List<FirValueParameter>)
|
||||||
|
|
||||||
|
abstract override fun replaceContractDescription(newContractDescription: FirContractDescription)
|
||||||
|
|
||||||
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
abstract override fun replaceAnnotations(newAnnotations: List<FirAnnotation>)
|
||||||
|
|
||||||
abstract fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?)
|
abstract fun replaceDelegatedConstructor(newDelegatedConstructor: FirDelegatedConstructorCall?)
|
||||||
@@ -83,6 +87,8 @@ abstract class FirConstructor : FirFunction(), FirTypeParameterRefsOwner {
|
|||||||
|
|
||||||
abstract override fun <D> transformValueParameters(transformer: FirTransformer<D>, data: D): FirConstructor
|
abstract override fun <D> transformValueParameters(transformer: FirTransformer<D>, data: D): FirConstructor
|
||||||
|
|
||||||
|
abstract override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirConstructor
|
||||||
|
|
||||||
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirConstructor
|
abstract override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirConstructor
|
||||||
|
|
||||||
abstract fun <D> transformDelegatedConstructor(transformer: FirTransformer<D>, data: D): FirConstructor
|
abstract fun <D> transformDelegatedConstructor(transformer: FirTransformer<D>, data: D): FirConstructor
|
||||||
|
|||||||
+2
@@ -10,6 +10,7 @@ package org.jetbrains.kotlin.fir.declarations.builder
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -55,6 +56,7 @@ interface FirAbstractConstructorBuilder : FirFunctionBuilder {
|
|||||||
abstract val typeParameters: MutableList<FirTypeParameterRef>
|
abstract val typeParameters: MutableList<FirTypeParameterRef>
|
||||||
abstract var receiverParameter: FirReceiverParameter?
|
abstract var receiverParameter: FirReceiverParameter?
|
||||||
abstract var controlFlowGraphReference: FirControlFlowGraphReference?
|
abstract var controlFlowGraphReference: FirControlFlowGraphReference?
|
||||||
|
abstract var contractDescription: FirContractDescription
|
||||||
abstract var symbol: FirConstructorSymbol
|
abstract var symbol: FirConstructorSymbol
|
||||||
abstract var delegatedConstructor: FirDelegatedConstructorCall?
|
abstract var delegatedConstructor: FirDelegatedConstructorCall?
|
||||||
override fun build(): FirConstructor
|
override fun build(): FirConstructor
|
||||||
|
|||||||
+5
@@ -15,6 +15,8 @@ import org.jetbrains.kotlin.fir.FirModuleData
|
|||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -61,6 +63,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
|
|||||||
var controlFlowGraphReference: FirControlFlowGraphReference? = null
|
var controlFlowGraphReference: FirControlFlowGraphReference? = null
|
||||||
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
||||||
override var body: FirBlock? = null
|
override var body: FirBlock? = null
|
||||||
|
var contractDescription: FirContractDescription = FirEmptyContractDescription
|
||||||
lateinit var symbol: FirAnonymousFunctionSymbol
|
lateinit var symbol: FirAnonymousFunctionSymbol
|
||||||
var label: FirLabel? = null
|
var label: FirLabel? = null
|
||||||
var invocationKind: EventOccurrencesRange? = null
|
var invocationKind: EventOccurrencesRange? = null
|
||||||
@@ -86,6 +89,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu
|
|||||||
controlFlowGraphReference,
|
controlFlowGraphReference,
|
||||||
valueParameters,
|
valueParameters,
|
||||||
body,
|
body,
|
||||||
|
contractDescription,
|
||||||
symbol,
|
symbol,
|
||||||
label,
|
label,
|
||||||
invocationKind,
|
invocationKind,
|
||||||
@@ -141,6 +145,7 @@ inline fun buildAnonymousFunctionCopy(original: FirAnonymousFunction, init: FirA
|
|||||||
copyBuilder.controlFlowGraphReference = original.controlFlowGraphReference
|
copyBuilder.controlFlowGraphReference = original.controlFlowGraphReference
|
||||||
copyBuilder.valueParameters.addAll(original.valueParameters)
|
copyBuilder.valueParameters.addAll(original.valueParameters)
|
||||||
copyBuilder.body = original.body
|
copyBuilder.body = original.body
|
||||||
|
copyBuilder.contractDescription = original.contractDescription
|
||||||
copyBuilder.symbol = original.symbol
|
copyBuilder.symbol = original.symbol
|
||||||
copyBuilder.label = original.label
|
copyBuilder.label = original.label
|
||||||
copyBuilder.invocationKind = original.invocationKind
|
copyBuilder.invocationKind = original.invocationKind
|
||||||
|
|||||||
+5
@@ -13,6 +13,8 @@ import org.jetbrains.kotlin.fir.FirModuleData
|
|||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -57,6 +59,7 @@ open class FirConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotationC
|
|||||||
override var dispatchReceiverType: ConeSimpleKotlinType? = null
|
override var dispatchReceiverType: ConeSimpleKotlinType? = null
|
||||||
override val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
override val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
||||||
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
||||||
|
override var contractDescription: FirContractDescription = FirEmptyContractDescription
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override lateinit var symbol: FirConstructorSymbol
|
override lateinit var symbol: FirConstructorSymbol
|
||||||
override var delegatedConstructor: FirDelegatedConstructorCall? = null
|
override var delegatedConstructor: FirDelegatedConstructorCall? = null
|
||||||
@@ -78,6 +81,7 @@ open class FirConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotationC
|
|||||||
dispatchReceiverType,
|
dispatchReceiverType,
|
||||||
contextReceivers.toMutableOrEmpty(),
|
contextReceivers.toMutableOrEmpty(),
|
||||||
valueParameters,
|
valueParameters,
|
||||||
|
contractDescription,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
symbol,
|
symbol,
|
||||||
delegatedConstructor,
|
delegatedConstructor,
|
||||||
@@ -122,6 +126,7 @@ inline fun buildConstructorCopy(original: FirConstructor, init: FirConstructorBu
|
|||||||
copyBuilder.dispatchReceiverType = original.dispatchReceiverType
|
copyBuilder.dispatchReceiverType = original.dispatchReceiverType
|
||||||
copyBuilder.contextReceivers.addAll(original.contextReceivers)
|
copyBuilder.contextReceivers.addAll(original.contextReceivers)
|
||||||
copyBuilder.valueParameters.addAll(original.valueParameters)
|
copyBuilder.valueParameters.addAll(original.valueParameters)
|
||||||
|
copyBuilder.contractDescription = original.contractDescription
|
||||||
copyBuilder.annotations.addAll(original.annotations)
|
copyBuilder.annotations.addAll(original.annotations)
|
||||||
copyBuilder.symbol = original.symbol
|
copyBuilder.symbol = original.symbol
|
||||||
copyBuilder.delegatedConstructor = original.delegatedConstructor
|
copyBuilder.delegatedConstructor = original.delegatedConstructor
|
||||||
|
|||||||
+4
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.fir.FirModuleData
|
|||||||
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder
|
||||||
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
import org.jetbrains.kotlin.fir.builder.FirBuilderDsl
|
||||||
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
import org.jetbrains.kotlin.fir.builder.toMutableOrEmpty
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.impl.FirEmptyContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -58,6 +60,7 @@ class FirPrimaryConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotatio
|
|||||||
override var dispatchReceiverType: ConeSimpleKotlinType? = null
|
override var dispatchReceiverType: ConeSimpleKotlinType? = null
|
||||||
override val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
override val contextReceivers: MutableList<FirContextReceiver> = mutableListOf()
|
||||||
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
override val valueParameters: MutableList<FirValueParameter> = mutableListOf()
|
||||||
|
override var contractDescription: FirContractDescription = FirEmptyContractDescription
|
||||||
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
override val annotations: MutableList<FirAnnotation> = mutableListOf()
|
||||||
override lateinit var symbol: FirConstructorSymbol
|
override lateinit var symbol: FirConstructorSymbol
|
||||||
override var delegatedConstructor: FirDelegatedConstructorCall? = null
|
override var delegatedConstructor: FirDelegatedConstructorCall? = null
|
||||||
@@ -80,6 +83,7 @@ class FirPrimaryConstructorBuilder : FirAbstractConstructorBuilder, FirAnnotatio
|
|||||||
dispatchReceiverType,
|
dispatchReceiverType,
|
||||||
contextReceivers.toMutableOrEmpty(),
|
contextReceivers.toMutableOrEmpty(),
|
||||||
valueParameters,
|
valueParameters,
|
||||||
|
contractDescription,
|
||||||
annotations.toMutableOrEmpty(),
|
annotations.toMutableOrEmpty(),
|
||||||
symbol,
|
symbol,
|
||||||
delegatedConstructor,
|
delegatedConstructor,
|
||||||
|
|||||||
+13
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.KtSourceElement
|
|||||||
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
|
||||||
import org.jetbrains.kotlin.fir.FirLabel
|
import org.jetbrains.kotlin.fir.FirLabel
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -54,6 +55,7 @@ internal class FirAnonymousFunctionImpl(
|
|||||||
override var controlFlowGraphReference: FirControlFlowGraphReference?,
|
override var controlFlowGraphReference: FirControlFlowGraphReference?,
|
||||||
override val valueParameters: MutableList<FirValueParameter>,
|
override val valueParameters: MutableList<FirValueParameter>,
|
||||||
override var body: FirBlock?,
|
override var body: FirBlock?,
|
||||||
|
override var contractDescription: FirContractDescription,
|
||||||
override val symbol: FirAnonymousFunctionSymbol,
|
override val symbol: FirAnonymousFunctionSymbol,
|
||||||
override var label: FirLabel?,
|
override var label: FirLabel?,
|
||||||
override var invocationKind: EventOccurrencesRange?,
|
override var invocationKind: EventOccurrencesRange?,
|
||||||
@@ -80,6 +82,7 @@ internal class FirAnonymousFunctionImpl(
|
|||||||
controlFlowGraphReference?.accept(visitor, data)
|
controlFlowGraphReference?.accept(visitor, data)
|
||||||
valueParameters.forEach { it.accept(visitor, data) }
|
valueParameters.forEach { it.accept(visitor, data) }
|
||||||
body?.accept(visitor, data)
|
body?.accept(visitor, data)
|
||||||
|
contractDescription.accept(visitor, data)
|
||||||
label?.accept(visitor, data)
|
label?.accept(visitor, data)
|
||||||
typeParameters.forEach { it.accept(visitor, data) }
|
typeParameters.forEach { it.accept(visitor, data) }
|
||||||
typeRef.accept(visitor, data)
|
typeRef.accept(visitor, data)
|
||||||
@@ -94,6 +97,7 @@ internal class FirAnonymousFunctionImpl(
|
|||||||
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
||||||
transformValueParameters(transformer, data)
|
transformValueParameters(transformer, data)
|
||||||
transformBody(transformer, data)
|
transformBody(transformer, data)
|
||||||
|
transformContractDescription(transformer, data)
|
||||||
label = label?.transform(transformer, data)
|
label = label?.transform(transformer, data)
|
||||||
transformTypeParameters(transformer, data)
|
transformTypeParameters(transformer, data)
|
||||||
typeRef = typeRef.transform(transformer, data)
|
typeRef = typeRef.transform(transformer, data)
|
||||||
@@ -130,6 +134,11 @@ internal class FirAnonymousFunctionImpl(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirAnonymousFunctionImpl {
|
||||||
|
contractDescription = contractDescription.transform(transformer, data)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirAnonymousFunctionImpl {
|
override fun <D> transformTypeParameters(transformer: FirTransformer<D>, data: D): FirAnonymousFunctionImpl {
|
||||||
typeParameters.transformInplace(transformer, data)
|
typeParameters.transformInplace(transformer, data)
|
||||||
return this
|
return this
|
||||||
@@ -176,6 +185,10 @@ internal class FirAnonymousFunctionImpl(
|
|||||||
body = newBody
|
body = newBody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
|
||||||
|
contractDescription = newContractDescription
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceInvocationKind(newInvocationKind: EventOccurrencesRange?) {
|
override fun replaceInvocationKind(newInvocationKind: EventOccurrencesRange?) {
|
||||||
invocationKind = newInvocationKind
|
invocationKind = newInvocationKind
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -9,6 +9,7 @@ package org.jetbrains.kotlin.fir.declarations.impl
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -52,6 +53,7 @@ internal class FirConstructorImpl(
|
|||||||
override val dispatchReceiverType: ConeSimpleKotlinType?,
|
override val dispatchReceiverType: ConeSimpleKotlinType?,
|
||||||
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
||||||
override val valueParameters: MutableList<FirValueParameter>,
|
override val valueParameters: MutableList<FirValueParameter>,
|
||||||
|
override var contractDescription: FirContractDescription,
|
||||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||||
override val symbol: FirConstructorSymbol,
|
override val symbol: FirConstructorSymbol,
|
||||||
override var delegatedConstructor: FirDelegatedConstructorCall?,
|
override var delegatedConstructor: FirDelegatedConstructorCall?,
|
||||||
@@ -72,6 +74,7 @@ internal class FirConstructorImpl(
|
|||||||
contextReceivers.forEach { it.accept(visitor, data) }
|
contextReceivers.forEach { it.accept(visitor, data) }
|
||||||
controlFlowGraphReference?.accept(visitor, data)
|
controlFlowGraphReference?.accept(visitor, data)
|
||||||
valueParameters.forEach { it.accept(visitor, data) }
|
valueParameters.forEach { it.accept(visitor, data) }
|
||||||
|
contractDescription.accept(visitor, data)
|
||||||
annotations.forEach { it.accept(visitor, data) }
|
annotations.forEach { it.accept(visitor, data) }
|
||||||
delegatedConstructor?.accept(visitor, data)
|
delegatedConstructor?.accept(visitor, data)
|
||||||
body?.accept(visitor, data)
|
body?.accept(visitor, data)
|
||||||
@@ -85,6 +88,7 @@ internal class FirConstructorImpl(
|
|||||||
contextReceivers.transformInplace(transformer, data)
|
contextReceivers.transformInplace(transformer, data)
|
||||||
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
||||||
transformValueParameters(transformer, data)
|
transformValueParameters(transformer, data)
|
||||||
|
transformContractDescription(transformer, data)
|
||||||
transformAnnotations(transformer, data)
|
transformAnnotations(transformer, data)
|
||||||
transformDelegatedConstructor(transformer, data)
|
transformDelegatedConstructor(transformer, data)
|
||||||
transformBody(transformer, data)
|
transformBody(transformer, data)
|
||||||
@@ -116,6 +120,11 @@ internal class FirConstructorImpl(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirConstructorImpl {
|
||||||
|
contractDescription = contractDescription.transform(transformer, data)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirConstructorImpl {
|
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirConstructorImpl {
|
||||||
annotations.transformInplace(transformer, data)
|
annotations.transformInplace(transformer, data)
|
||||||
return this
|
return this
|
||||||
@@ -164,6 +173,10 @@ internal class FirConstructorImpl(
|
|||||||
valueParameters.addAll(newValueParameters)
|
valueParameters.addAll(newValueParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
|
||||||
|
contractDescription = newContractDescription
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||||
annotations = newAnnotations.toMutableOrEmpty()
|
annotations = newAnnotations.toMutableOrEmpty()
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -10,6 +10,7 @@ package org.jetbrains.kotlin.fir.declarations.impl
|
|||||||
import org.jetbrains.kotlin.KtSourceElement
|
import org.jetbrains.kotlin.KtSourceElement
|
||||||
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
import org.jetbrains.kotlin.fir.FirImplementationDetail
|
||||||
import org.jetbrains.kotlin.fir.FirModuleData
|
import org.jetbrains.kotlin.fir.FirModuleData
|
||||||
|
import org.jetbrains.kotlin.fir.contracts.FirContractDescription
|
||||||
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
import org.jetbrains.kotlin.fir.declarations.DeprecationsProvider
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
import org.jetbrains.kotlin.fir.declarations.FirConstructor
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
import org.jetbrains.kotlin.fir.declarations.FirContextReceiver
|
||||||
@@ -53,6 +54,7 @@ class FirPrimaryConstructor @FirImplementationDetail constructor(
|
|||||||
override val dispatchReceiverType: ConeSimpleKotlinType?,
|
override val dispatchReceiverType: ConeSimpleKotlinType?,
|
||||||
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
override var contextReceivers: MutableOrEmptyList<FirContextReceiver>,
|
||||||
override val valueParameters: MutableList<FirValueParameter>,
|
override val valueParameters: MutableList<FirValueParameter>,
|
||||||
|
override var contractDescription: FirContractDescription,
|
||||||
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
override var annotations: MutableOrEmptyList<FirAnnotation>,
|
||||||
override val symbol: FirConstructorSymbol,
|
override val symbol: FirConstructorSymbol,
|
||||||
override var delegatedConstructor: FirDelegatedConstructorCall?,
|
override var delegatedConstructor: FirDelegatedConstructorCall?,
|
||||||
@@ -73,6 +75,7 @@ class FirPrimaryConstructor @FirImplementationDetail constructor(
|
|||||||
contextReceivers.forEach { it.accept(visitor, data) }
|
contextReceivers.forEach { it.accept(visitor, data) }
|
||||||
controlFlowGraphReference?.accept(visitor, data)
|
controlFlowGraphReference?.accept(visitor, data)
|
||||||
valueParameters.forEach { it.accept(visitor, data) }
|
valueParameters.forEach { it.accept(visitor, data) }
|
||||||
|
contractDescription.accept(visitor, data)
|
||||||
annotations.forEach { it.accept(visitor, data) }
|
annotations.forEach { it.accept(visitor, data) }
|
||||||
delegatedConstructor?.accept(visitor, data)
|
delegatedConstructor?.accept(visitor, data)
|
||||||
body?.accept(visitor, data)
|
body?.accept(visitor, data)
|
||||||
@@ -86,6 +89,7 @@ class FirPrimaryConstructor @FirImplementationDetail constructor(
|
|||||||
contextReceivers.transformInplace(transformer, data)
|
contextReceivers.transformInplace(transformer, data)
|
||||||
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
controlFlowGraphReference = controlFlowGraphReference?.transform(transformer, data)
|
||||||
transformValueParameters(transformer, data)
|
transformValueParameters(transformer, data)
|
||||||
|
transformContractDescription(transformer, data)
|
||||||
transformAnnotations(transformer, data)
|
transformAnnotations(transformer, data)
|
||||||
transformDelegatedConstructor(transformer, data)
|
transformDelegatedConstructor(transformer, data)
|
||||||
transformBody(transformer, data)
|
transformBody(transformer, data)
|
||||||
@@ -117,6 +121,11 @@ class FirPrimaryConstructor @FirImplementationDetail constructor(
|
|||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <D> transformContractDescription(transformer: FirTransformer<D>, data: D): FirPrimaryConstructor {
|
||||||
|
contractDescription = contractDescription.transform(transformer, data)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirPrimaryConstructor {
|
override fun <D> transformAnnotations(transformer: FirTransformer<D>, data: D): FirPrimaryConstructor {
|
||||||
annotations.transformInplace(transformer, data)
|
annotations.transformInplace(transformer, data)
|
||||||
return this
|
return this
|
||||||
@@ -165,6 +174,10 @@ class FirPrimaryConstructor @FirImplementationDetail constructor(
|
|||||||
valueParameters.addAll(newValueParameters)
|
valueParameters.addAll(newValueParameters)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun replaceContractDescription(newContractDescription: FirContractDescription) {
|
||||||
|
contractDescription = newContractDescription
|
||||||
|
}
|
||||||
|
|
||||||
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
override fun replaceAnnotations(newAnnotations: List<FirAnnotation>) {
|
||||||
annotations = newAnnotations.toMutableOrEmpty()
|
annotations = newAnnotations.toMutableOrEmpty()
|
||||||
}
|
}
|
||||||
|
|||||||
+4
@@ -89,6 +89,8 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
|||||||
parents += abstractConstructorBuilder
|
parents += abstractConstructorBuilder
|
||||||
defaultNull("delegatedConstructor")
|
defaultNull("delegatedConstructor")
|
||||||
defaultNull("body")
|
defaultNull("body")
|
||||||
|
default("contractDescription", "FirEmptyContractDescription")
|
||||||
|
useTypes(emptyContractDescriptionType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,7 +268,9 @@ object BuilderConfigurator : AbstractBuilderConfigurator<FirTreeBuilder>(FirTree
|
|||||||
parents += functionBuilder
|
parents += functionBuilder
|
||||||
defaultNull("invocationKind", "label", "body", "controlFlowGraphReference")
|
defaultNull("invocationKind", "label", "body", "controlFlowGraphReference")
|
||||||
default("inlineStatus", "InlineStatus.Unknown")
|
default("inlineStatus", "InlineStatus.Unknown")
|
||||||
|
default("contractDescription", "FirEmptyContractDescription")
|
||||||
withCopy()
|
withCopy()
|
||||||
|
useTypes(emptyContractDescriptionType)
|
||||||
}
|
}
|
||||||
|
|
||||||
builder(propertyAccessor) {
|
builder(propertyAccessor) {
|
||||||
|
|||||||
+2
-2
@@ -60,12 +60,12 @@ object FirTreeBuilder : AbstractFirTreeBuilder() {
|
|||||||
val simpleFunction by element(Declaration, function, contractDescriptionOwner, typeParametersOwner)
|
val simpleFunction by element(Declaration, function, contractDescriptionOwner, typeParametersOwner)
|
||||||
val propertyAccessor by element(Declaration, function, contractDescriptionOwner, typeParametersOwner)
|
val propertyAccessor by element(Declaration, function, contractDescriptionOwner, typeParametersOwner)
|
||||||
val backingField by element(Declaration, variable, typeParametersOwner, statement)
|
val backingField by element(Declaration, variable, typeParametersOwner, statement)
|
||||||
val constructor by element(Declaration, function, typeParameterRefsOwner)
|
val constructor by element(Declaration, function, typeParameterRefsOwner, contractDescriptionOwner)
|
||||||
val file by element(Declaration, declaration)
|
val file by element(Declaration, declaration)
|
||||||
val script by element(Declaration, declaration)
|
val script by element(Declaration, declaration)
|
||||||
val packageDirective by element(Other)
|
val packageDirective by element(Other)
|
||||||
|
|
||||||
val anonymousFunction by element(Declaration, function, typeParametersOwner)
|
val anonymousFunction by element(Declaration, function, typeParametersOwner, contractDescriptionOwner)
|
||||||
val anonymousFunctionExpression by element(Expression, expression)
|
val anonymousFunctionExpression by element(Expression, expression)
|
||||||
|
|
||||||
val anonymousObject by element(Declaration, klass, controlFlowGraphOwner)
|
val anonymousObject by element(Declaration, klass, controlFlowGraphOwner)
|
||||||
|
|||||||
Vendored
+15
-15
@@ -10,19 +10,19 @@ open class Class {
|
|||||||
fun member(x: Boolean) {
|
fun member(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun inlineMember(x: Boolean) {
|
inline fun inlineMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun abstractMember(x: Boolean) {
|
abstract fun abstractMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun openMemeber(x: Boolean) {
|
open fun openMemeber(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendMember(x: Boolean) {
|
suspend fun suspendMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
@@ -44,43 +44,43 @@ suspend fun suspendTopLevel(x: Boolean) {
|
|||||||
|
|
||||||
// Top-level operator
|
// Top-level operator
|
||||||
operator fun Boolean.plus(x: Boolean): Boolean {
|
operator fun Boolean.plus(x: Boolean): Boolean {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val topLevelAnonymousFunction = fun (x: Boolean) {
|
val topLevelAnonymousFunction = fun (x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
||||||
get() {
|
get() {
|
||||||
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
||||||
return 42
|
return 42
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============= Local =====================
|
// ============= Local =====================
|
||||||
fun test() {
|
fun test() {
|
||||||
fun localDeclaration(x: Boolean) {
|
fun localDeclaration(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendlocalDeclaration(x: Boolean) {
|
suspend fun suspendlocalDeclaration(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val localAnonymousFunction = fun (x: Boolean) {
|
val localAnonymousFunction = fun (x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+5
-5
@@ -10,19 +10,19 @@ open class Class {
|
|||||||
fun member(x: Boolean) {
|
fun member(x: Boolean) {
|
||||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun inlineMember(x: Boolean) {
|
inline fun inlineMember(x: Boolean) {
|
||||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun abstractMember(x: Boolean) {
|
abstract fun abstractMember(x: Boolean) {
|
||||||
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun openMemeber(x: Boolean) {
|
open fun openMemeber(x: Boolean) {
|
||||||
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendMember(x: Boolean) {
|
suspend fun suspendMember(x: Boolean) {
|
||||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
@@ -83,4 +83,4 @@ fun test() {
|
|||||||
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+19
-14
@@ -7,6 +7,11 @@ import kotlin.contracts.*
|
|||||||
|
|
||||||
// ============= Class =====================
|
// ============= Class =====================
|
||||||
open class Class {
|
open class Class {
|
||||||
|
constructor(f: () -> Unit = {}) {
|
||||||
|
contract { callsInPlace(f, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
fun member(x: Boolean) {
|
fun member(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
@@ -16,11 +21,11 @@ open class Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
abstract fun abstractMember(x: Boolean) {
|
abstract fun abstractMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun openMemeber(x: Boolean) {
|
open fun openMemeber(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendMember(x: Boolean) {
|
suspend fun suspendMember(x: Boolean) {
|
||||||
@@ -30,17 +35,17 @@ open class Class {
|
|||||||
|
|
||||||
open class Inheritor : Class() {
|
open class Inheritor : Class() {
|
||||||
override fun openMemeber(x: Boolean) {
|
override fun openMemeber(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
final override fun abstractMember(x: Boolean) {
|
final override fun abstractMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Interface {
|
interface Interface {
|
||||||
fun implicitlyOpenMember(x: Boolean) {
|
fun implicitlyOpenMember(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,43 +64,43 @@ suspend fun suspendTopLevel(x: Boolean) {
|
|||||||
|
|
||||||
// Top-level operator
|
// Top-level operator
|
||||||
operator fun Boolean.plus(x: Boolean): Boolean {
|
operator fun Boolean.plus(x: Boolean): Boolean {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
return x
|
return x
|
||||||
}
|
}
|
||||||
|
|
||||||
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val topLevelAnonymousFunction = fun (x: Boolean) {
|
val topLevelAnonymousFunction = fun (x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
var topLevelPropertyAccessors: Int? = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>42<!>
|
||||||
get() {
|
get() {
|
||||||
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
||||||
return 42
|
return 42
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_REFERENCE!>field<!> != null)<!> }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ============= Local =====================
|
// ============= Local =====================
|
||||||
fun test() {
|
fun test() {
|
||||||
fun localDeclaration(x: Boolean) {
|
fun localDeclaration(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun suspendlocalDeclaration(x: Boolean) {
|
suspend fun suspendlocalDeclaration(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val localAnonymousFunction = fun (x: Boolean) {
|
val localAnonymousFunction = fun (x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|
||||||
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||||
contract { returns() implies (x) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+5
@@ -7,6 +7,11 @@ import kotlin.contracts.*
|
|||||||
|
|
||||||
// ============= Class =====================
|
// ============= Class =====================
|
||||||
open class Class {
|
open class Class {
|
||||||
|
constructor(f: () -> Unit = {}) {
|
||||||
|
contract { callsInPlace(f, InvocationKind.EXACTLY_ONCE) }
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
|
||||||
fun member(x: Boolean) {
|
fun member(x: Boolean) {
|
||||||
contract { returns() implies (x) }
|
contract { returns() implies (x) }
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+1
-1
@@ -16,7 +16,7 @@ public fun topLevel(/*0*/ x: kotlin.Boolean): kotlin.Unit
|
|||||||
public operator fun kotlin.Boolean.plus(/*0*/ x: kotlin.Boolean): kotlin.Boolean
|
public operator fun kotlin.Boolean.plus(/*0*/ x: kotlin.Boolean): kotlin.Boolean
|
||||||
|
|
||||||
public open class Class {
|
public open class Class {
|
||||||
public constructor Class()
|
public constructor Class(/*0*/ f: () -> kotlin.Unit = ...)
|
||||||
public abstract fun abstractMember(/*0*/ x: kotlin.Boolean): kotlin.Unit
|
public abstract fun abstractMember(/*0*/ x: kotlin.Boolean): kotlin.Unit
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
|||||||
Vendored
+11
-11
@@ -7,30 +7,30 @@ import kotlin.contracts.*
|
|||||||
|
|
||||||
fun foo(y: Boolean) {
|
fun foo(y: Boolean) {
|
||||||
val x: Int = 42
|
val x: Int = 42
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED("Contract should be the first statement")!>contract<!> {
|
||||||
returns() implies y
|
returns() implies y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun case1(block: () -> Unit) {
|
inline fun case1(block: () -> Unit) {
|
||||||
val contracts = listOf(
|
val contracts = listOf(
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}, contract {
|
}, <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun case_2(block: () -> Unit) = contract {
|
inline fun case_2(block: () -> Unit) = <!CONTRACT_NOT_ALLOWED("Contracts are only allowed in function body blocks")!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun case_3(block: () -> Unit) {
|
fun case_3(block: () -> Unit) {
|
||||||
class Class {
|
class Class {
|
||||||
fun innerFun(block2: () -> Unit) {
|
fun innerFun(block2: () -> Unit) {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED("Contracts are not allowed for local functions")!>contract<!> {
|
||||||
callsInPlace(block2, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(block2, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
block2()
|
block2()
|
||||||
@@ -41,7 +41,7 @@ fun case_3(block: () -> Unit) {
|
|||||||
|
|
||||||
inline fun case_4(number: Int?): Boolean {
|
inline fun case_4(number: Int?): Boolean {
|
||||||
val cond = number != null
|
val cond = number != null
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(false) implies (cond)
|
returns(false) implies (cond)
|
||||||
} as ContractBuilder
|
} as ContractBuilder
|
||||||
return number == null
|
return number == null
|
||||||
@@ -49,8 +49,8 @@ inline fun case_4(number: Int?): Boolean {
|
|||||||
|
|
||||||
inline fun case_5(cond: Boolean): Boolean {
|
inline fun case_5(cond: Boolean): Boolean {
|
||||||
run {
|
run {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (cond)
|
<!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (cond)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@@ -59,7 +59,7 @@ inline fun case_5(cond: Boolean): Boolean {
|
|||||||
inline fun case_6(cond: Boolean): Boolean {
|
inline fun case_6(cond: Boolean): Boolean {
|
||||||
run {
|
run {
|
||||||
val x = 10
|
val x = 10
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (cond)
|
returns(true) implies (cond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -68,8 +68,8 @@ inline fun case_6(cond: Boolean): Boolean {
|
|||||||
|
|
||||||
fun case_7(cond: Boolean): Boolean {
|
fun case_7(cond: Boolean): Boolean {
|
||||||
fun innerFun() {
|
fun innerFun() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (cond)
|
<!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (cond)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|||||||
+2
-2
@@ -4,13 +4,13 @@ import kotlin.contracts.*
|
|||||||
class A {
|
class A {
|
||||||
var x: Int = 0
|
var x: Int = 0
|
||||||
get() = f(x)
|
get() = f(x)
|
||||||
set(value) contract [returns() implies (value != null)] {
|
set(value) contract <!CONTRACT_NOT_ALLOWED!>[returns() implies (value != null)]<!> {
|
||||||
field = value + 1
|
field = value + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
var y: Double = 0.0
|
var y: Double = 0.0
|
||||||
get() = g(y)
|
get() = g(y)
|
||||||
set(value) contract [returns() implies (value != null)] {
|
set(value) contract <!CONTRACT_NOT_ALLOWED!>[returns() implies (value != null)]<!> {
|
||||||
field = value * 2
|
field = value * 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -6,14 +6,14 @@ import kotlin.contracts.*
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
inline fun case_1(block: () -> Unit) {
|
inline fun case_1(block: () -> Unit) {
|
||||||
val value_1 = 1
|
val value_1 = 1
|
||||||
contract { }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { }
|
||||||
return block()
|
return block()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
inline fun case_2(block: () -> Unit) {
|
inline fun case_2(block: () -> Unit) {
|
||||||
10 - 1
|
10 - 1
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
return block()
|
return block()
|
||||||
@@ -22,7 +22,7 @@ inline fun case_2(block: () -> Unit) {
|
|||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
inline fun case_3(block: () -> Unit) {
|
inline fun case_3(block: () -> Unit) {
|
||||||
throw Exception()
|
throw Exception()
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.UNKNOWN)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.UNKNOWN)
|
||||||
}
|
}
|
||||||
return block()
|
return block()
|
||||||
@@ -34,7 +34,7 @@ inline fun case_3(block: () -> Unit) {
|
|||||||
*/
|
*/
|
||||||
inline fun case_4(block: () -> Unit) {
|
inline fun case_4(block: () -> Unit) {
|
||||||
.0009
|
.0009
|
||||||
return contract {
|
return <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -45,7 +45,7 @@ inline fun case_4(block: () -> Unit) {
|
|||||||
*/
|
*/
|
||||||
fun case_5(value_1: Int?) {
|
fun case_5(value_1: Int?) {
|
||||||
println("!")
|
println("!")
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
}
|
}
|
||||||
@@ -56,7 +56,7 @@ fun case_5(value_1: Int?) {
|
|||||||
*/
|
*/
|
||||||
fun case_6(value_1: Int?) {
|
fun case_6(value_1: Int?) {
|
||||||
100 + 10
|
100 + 10
|
||||||
throw Exception(contract {
|
throw Exception(<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
}.toString())
|
}.toString())
|
||||||
}
|
}
|
||||||
@@ -69,7 +69,7 @@ fun case_7(value_1: Int?) {
|
|||||||
for (i in 0..10) {
|
for (i in 0..10) {
|
||||||
println(i)
|
println(i)
|
||||||
}
|
}
|
||||||
return contract {
|
return <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,7 +80,7 @@ fun case_7(value_1: Int?) {
|
|||||||
*/
|
*/
|
||||||
fun case_8(value_1: Int?) {
|
fun case_8(value_1: Int?) {
|
||||||
val f = 10 - 20
|
val f = 10 - 20
|
||||||
val g = contract {
|
val g = <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(true) implies (value_1 != null)
|
returns(true) implies (value_1 != null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -91,7 +91,7 @@ fun case_8(value_1: Int?) {
|
|||||||
*/
|
*/
|
||||||
fun case_9(number: Int?): Boolean {
|
fun case_9(number: Int?): Boolean {
|
||||||
val value_1 = number != null
|
val value_1 = number != null
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns(false) implies (value_1)
|
returns(false) implies (value_1)
|
||||||
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
||||||
return number == null
|
return number == null
|
||||||
|
|||||||
+5
-5
@@ -5,17 +5,17 @@ import kotlin.contracts.*
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
inline fun case_1(block: () -> Unit) {
|
inline fun case_1(block: () -> Unit) {
|
||||||
return contract {
|
return <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
fun case_2() = contract { }
|
fun case_2() = <!CONTRACT_NOT_ALLOWED!>contract<!> { }
|
||||||
|
|
||||||
// TESTCASE NUMBER: 3
|
// TESTCASE NUMBER: 3
|
||||||
inline fun case_3(block: () -> Unit) {
|
inline fun case_3(block: () -> Unit) {
|
||||||
val value_1 = contract {
|
val value_1 = <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
block()
|
block()
|
||||||
@@ -39,14 +39,14 @@ inline fun case_5(block: () -> Unit) {
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 6
|
// TESTCASE NUMBER: 6
|
||||||
inline fun case_6(block: () -> Unit) {
|
inline fun case_6(block: () -> Unit) {
|
||||||
throw Exception(contract {
|
throw Exception(<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
}.toString())
|
}.toString())
|
||||||
}
|
}
|
||||||
|
|
||||||
// TESTCASE NUMBER: 7
|
// TESTCASE NUMBER: 7
|
||||||
inline fun case_7(block: () -> Unit) {
|
inline fun case_7(block: () -> Unit) {
|
||||||
funWithAnyArg(contract {
|
funWithAnyArg(<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
|
||||||
// !OPT_IN: kotlin.contracts.ExperimentalContracts
|
|
||||||
|
|
||||||
import kotlin.contracts.*
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 1
|
|
||||||
fun case_1(value_1: Int?) {
|
|
||||||
println("!")
|
|
||||||
contract {
|
|
||||||
returns(true) implies (value_1 != null)
|
|
||||||
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 2
|
|
||||||
fun case_2(value_1: Int?) {
|
|
||||||
100 + 10
|
|
||||||
throw Exception(contract {
|
|
||||||
returns(true) implies (value_1 != null)
|
|
||||||
}.toString())
|
|
||||||
}
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 3
|
|
||||||
fun case_3(value_1: Int?) {
|
|
||||||
for (i in 0..10) {
|
|
||||||
println(i)
|
|
||||||
}
|
|
||||||
return contract {
|
|
||||||
returns(true) implies (value_1 != null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 4
|
|
||||||
fun case_4(value_1: Int?) {
|
|
||||||
val f = 10 - 20
|
|
||||||
val g = contract {
|
|
||||||
returns(true) implies (value_1 != null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TESTCASE NUMBER: 5
|
|
||||||
fun case_5(number: Int?): Boolean {
|
|
||||||
val value_1 = number != null
|
|
||||||
contract {
|
|
||||||
returns(false) implies (value_1)
|
|
||||||
} <!CAST_NEVER_SUCCEEDS!>as<!> ContractBuilder
|
|
||||||
return number == null
|
|
||||||
}
|
|
||||||
+1
@@ -1,3 +1,4 @@
|
|||||||
|
// FIR_IDENTICAL
|
||||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||||
// !OPT_IN: kotlin.contracts.ExperimentalContracts
|
// !OPT_IN: kotlin.contracts.ExperimentalContracts
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -38,7 +38,7 @@ fun case_5(): Boolean? {
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 6
|
// TESTCASE NUMBER: 6
|
||||||
fun case_6(value_1: Boolean): Boolean? {
|
fun case_6(value_1: Boolean): Boolean? {
|
||||||
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies <!ARGUMENT_TYPE_MISMATCH!>contract { returns(null) implies (!value_1) }<!><!> }
|
contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies <!ARGUMENT_TYPE_MISMATCH!><!CONTRACT_NOT_ALLOWED!>contract<!> { returns(null) implies (!value_1) }<!><!> }
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ class case_2(value_5: Boolean, val value_1: Boolean) {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
fun case_2_1(): Boolean {
|
fun case_2_1(): Boolean {
|
||||||
contract { returns(false) implies (value_5) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (value_5)<!> }
|
||||||
return !(value_5)
|
return !(value_5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import kotlin.contracts.*
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
fun <T> T?.case_1() {
|
fun <T> T?.case_1() {
|
||||||
fun <K> K?.case_1_1(): Boolean {
|
fun <K> K?.case_1_1(): Boolean {
|
||||||
contract { returns(true) implies (this@case_1 != null) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (this@case_1 != null)<!> }
|
||||||
return this@case_1 != null
|
return this@case_1 != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -5,7 +5,7 @@ import kotlin.contracts.*
|
|||||||
|
|
||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
inline fun case_1(block: () -> Unit) = {
|
inline fun case_1(block: () -> Unit) = {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
<!ERROR_IN_CONTRACT_DESCRIPTION!>callsInPlace(block, InvocationKind.EXACTLY_ONCE)<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -6,7 +6,7 @@ import kotlin.contracts.*
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
fun case_1() {
|
fun case_1() {
|
||||||
val fun_1 = fun(block: () -> Unit) {
|
val fun_1 = fun(block: () -> Unit) {
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
return block()
|
return block()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ fun case_1() {
|
|||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
fun case_2() {
|
fun case_2() {
|
||||||
val lambda_1 = { block: () -> Unit ->
|
val lambda_1 = { block: () -> Unit ->
|
||||||
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,7 +43,7 @@ class case_4 : ClassLevel3() {
|
|||||||
|
|
||||||
fun <T>T.case_4_3_wrap() {
|
fun <T>T.case_4_3_wrap() {
|
||||||
fun case_4_3_contract() {
|
fun case_4_3_contract() {
|
||||||
contract { returns() implies (this@case_4_3_wrap is ClassLevel1) }
|
<!CONTRACT_NOT_ALLOWED!>contract<!> { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (this@case_4_3_wrap is ClassLevel1)<!> }
|
||||||
if (this@case_4_3_wrap !is ClassLevel1) throw Exception()
|
if (this@case_4_3_wrap !is ClassLevel1) throw Exception()
|
||||||
}
|
}
|
||||||
case_4_3_contract()
|
case_4_3_contract()
|
||||||
|
|||||||
+5
-5
@@ -6,7 +6,7 @@ import kotlin.contracts.*
|
|||||||
// TESTCASE NUMBER: 1
|
// TESTCASE NUMBER: 1
|
||||||
val Boolean.case_1: () -> Unit
|
val Boolean.case_1: () -> Unit
|
||||||
get() {
|
get() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns() implies (this@case_1)
|
returns() implies (this@case_1)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
@@ -15,7 +15,7 @@ val Boolean.case_1: () -> Unit
|
|||||||
// TESTCASE NUMBER: 2
|
// TESTCASE NUMBER: 2
|
||||||
val (() -> Unit).case_2: () -> Unit
|
val (() -> Unit).case_2: () -> Unit
|
||||||
get() {
|
get() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(this@case_2, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(this@case_2, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
return {}
|
return {}
|
||||||
@@ -27,7 +27,7 @@ var Boolean.case_3: () -> Unit
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
<!WRONG_INVOCATION_KIND!>contract {
|
<!WRONG_INVOCATION_KIND!><!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(value, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(value, InvocationKind.EXACTLY_ONCE)
|
||||||
}<!>
|
}<!>
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ var (() -> Unit).case_4: () -> Unit
|
|||||||
return {}
|
return {}
|
||||||
}
|
}
|
||||||
set(value) {
|
set(value) {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
callsInPlace(this@case_4, InvocationKind.EXACTLY_ONCE)
|
callsInPlace(this@case_4, InvocationKind.EXACTLY_ONCE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -46,7 +46,7 @@ var (() -> Unit).case_4: () -> Unit
|
|||||||
// TESTCASE NUMBER: 5
|
// TESTCASE NUMBER: 5
|
||||||
val Boolean.case_5: () -> Unit
|
val Boolean.case_5: () -> Unit
|
||||||
get() {
|
get() {
|
||||||
contract {
|
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||||
returns() implies (this@case_5)
|
returns() implies (this@case_5)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ object StandardClassIds {
|
|||||||
val BASE_INTERNAL_IR_PACKAGE = BASE_INTERNAL_PACKAGE.child(Name.identifier("ir"))
|
val BASE_INTERNAL_IR_PACKAGE = BASE_INTERNAL_PACKAGE.child(Name.identifier("ir"))
|
||||||
val BASE_COROUTINES_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("coroutines"))
|
val BASE_COROUTINES_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("coroutines"))
|
||||||
val BASE_ENUMS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("enums"))
|
val BASE_ENUMS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("enums"))
|
||||||
|
val BASE_CONTRACTS_PACKAGE = BASE_KOTLIN_PACKAGE.child(Name.identifier("contracts"))
|
||||||
|
|
||||||
val builtInsPackages = setOf(
|
val builtInsPackages = setOf(
|
||||||
BASE_KOTLIN_PACKAGE,
|
BASE_KOTLIN_PACKAGE,
|
||||||
@@ -216,6 +217,8 @@ object StandardClassIds {
|
|||||||
val clone = "clone".callableId(Cloneable)
|
val clone = "clone".callableId(Cloneable)
|
||||||
|
|
||||||
val not = "not".callableId(Boolean)
|
val not = "not".callableId(Boolean)
|
||||||
|
|
||||||
|
val contract = "contract".callableId(BASE_CONTRACTS_PACKAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
object Java {
|
object Java {
|
||||||
|
|||||||
Reference in New Issue
Block a user