[FIR] Implement checks for contract not allowed
^KT-55423 Fixed
This commit is contained in:
committed by
Space Team
parent
b2fbf8bed5
commit
f946ddeb40
Vendored
+15
-15
@@ -10,19 +10,19 @@ open class Class {
|
||||
fun member(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
inline fun inlineMember(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
abstract fun abstractMember(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
open fun openMemeber(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
suspend fun suspendMember(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
}
|
||||
@@ -44,43 +44,43 @@ suspend fun suspendTopLevel(x: Boolean) {
|
||||
|
||||
// Top-level operator
|
||||
operator fun Boolean.plus(x: Boolean): Boolean {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
return x
|
||||
}
|
||||
|
||||
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
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<!>
|
||||
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
|
||||
}
|
||||
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 =====================
|
||||
fun test() {
|
||||
fun localDeclaration(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
suspend fun suspendlocalDeclaration(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
val localAnonymousFunction = fun (x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
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) {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
inline fun inlineMember(x: Boolean) {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
abstract fun abstractMember(x: Boolean) {
|
||||
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
open fun openMemeber(x: Boolean) {
|
||||
<!CONTRACT_NOT_ALLOWED, CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
|
||||
suspend fun suspendMember(x: Boolean) {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
@@ -83,4 +83,4 @@ fun test() {
|
||||
val localLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+19
-14
@@ -7,6 +7,11 @@ import kotlin.contracts.*
|
||||
|
||||
// ============= Class =====================
|
||||
open class Class {
|
||||
constructor(f: () -> Unit = {}) {
|
||||
contract { callsInPlace(f, InvocationKind.EXACTLY_ONCE) }
|
||||
f()
|
||||
}
|
||||
|
||||
fun member(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
}
|
||||
@@ -16,11 +21,11 @@ open class Class {
|
||||
}
|
||||
|
||||
abstract fun abstractMember(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
open fun openMemeber(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
suspend fun suspendMember(x: Boolean) {
|
||||
@@ -30,17 +35,17 @@ open class Class {
|
||||
|
||||
open class Inheritor : Class() {
|
||||
override fun openMemeber(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
final override fun abstractMember(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
}
|
||||
|
||||
interface Interface {
|
||||
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
|
||||
operator fun Boolean.plus(x: Boolean): Boolean {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
return x
|
||||
}
|
||||
|
||||
val topLevelLambda: (Boolean) -> Unit = { x: Boolean ->
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
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<!>
|
||||
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
|
||||
}
|
||||
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 =====================
|
||||
fun test() {
|
||||
fun localDeclaration(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
suspend fun suspendlocalDeclaration(x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
val localAnonymousFunction = fun (x: Boolean) {
|
||||
contract { returns() implies (x) }
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> { returns() implies (x) }
|
||||
}
|
||||
|
||||
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 =====================
|
||||
open class Class {
|
||||
constructor(f: () -> Unit = {}) {
|
||||
contract { callsInPlace(f, InvocationKind.EXACTLY_ONCE) }
|
||||
f()
|
||||
}
|
||||
|
||||
fun member(x: Boolean) {
|
||||
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 open class Class {
|
||||
public constructor Class()
|
||||
public constructor Class(/*0*/ f: () -> 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 hashCode(): kotlin.Int
|
||||
|
||||
Vendored
+11
-11
@@ -7,30 +7,30 @@ import kotlin.contracts.*
|
||||
|
||||
fun foo(y: Boolean) {
|
||||
val x: Int = 42
|
||||
contract {
|
||||
<!CONTRACT_NOT_ALLOWED("Contract should be the first statement")!>contract<!> {
|
||||
returns() implies y
|
||||
}
|
||||
}
|
||||
|
||||
inline fun case1(block: () -> Unit) {
|
||||
val contracts = listOf(
|
||||
contract {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||
}, contract {
|
||||
}, <!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
callsInPlace(<!USAGE_IS_NOT_INLINABLE!>block<!>, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
)
|
||||
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)
|
||||
}
|
||||
|
||||
fun case_3(block: () -> Unit) {
|
||||
class Class {
|
||||
fun innerFun(block2: () -> Unit) {
|
||||
contract {
|
||||
<!CONTRACT_NOT_ALLOWED("Contracts are not allowed for local functions")!>contract<!> {
|
||||
callsInPlace(block2, InvocationKind.EXACTLY_ONCE)
|
||||
}
|
||||
block2()
|
||||
@@ -41,7 +41,7 @@ fun case_3(block: () -> Unit) {
|
||||
|
||||
inline fun case_4(number: Int?): Boolean {
|
||||
val cond = number != null
|
||||
contract {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
returns(false) implies (cond)
|
||||
} as ContractBuilder
|
||||
return number == null
|
||||
@@ -49,8 +49,8 @@ inline fun case_4(number: Int?): Boolean {
|
||||
|
||||
inline fun case_5(cond: Boolean): Boolean {
|
||||
run {
|
||||
contract {
|
||||
returns(true) implies (cond)
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
<!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (cond)<!>
|
||||
}
|
||||
}
|
||||
return true
|
||||
@@ -59,7 +59,7 @@ inline fun case_5(cond: Boolean): Boolean {
|
||||
inline fun case_6(cond: Boolean): Boolean {
|
||||
run {
|
||||
val x = 10
|
||||
contract {
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
returns(true) implies (cond)
|
||||
}
|
||||
}
|
||||
@@ -68,8 +68,8 @@ inline fun case_6(cond: Boolean): Boolean {
|
||||
|
||||
fun case_7(cond: Boolean): Boolean {
|
||||
fun innerFun() {
|
||||
contract {
|
||||
returns(true) implies (cond)
|
||||
<!CONTRACT_NOT_ALLOWED!>contract<!> {
|
||||
<!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (cond)<!>
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
||||
+2
-2
@@ -4,13 +4,13 @@ import kotlin.contracts.*
|
||||
class A {
|
||||
var x: Int = 0
|
||||
get() = f(x)
|
||||
set(value) contract [returns() implies (value != null)] {
|
||||
set(value) contract <!CONTRACT_NOT_ALLOWED!>[returns() implies (value != null)]<!> {
|
||||
field = value + 1
|
||||
}
|
||||
|
||||
var y: Double = 0.0
|
||||
get() = g(y)
|
||||
set(value) contract [returns() implies (value != null)] {
|
||||
set(value) contract <!CONTRACT_NOT_ALLOWED!>[returns() implies (value != null)]<!> {
|
||||
field = value * 2
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user