提交 20f9787c 编写于 作者: J Jinseong Jeon 提交者: TeamCityServer

FIR checker: report errors in contract description

上级 3d635b6a
...@@ -381,6 +381,12 @@ val DIAGNOSTICS_LIST = DiagnosticListBuilder.buildDiagnosticList { ...@@ -381,6 +381,12 @@ val DIAGNOSTICS_LIST = DiagnosticListBuilder.buildDiagnosticList {
val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION) val INVALID_IF_AS_EXPRESSION by error<FirSourceElement, KtIfExpression>(PositioningStrategy.IF_EXPRESSION)
} }
group("Function contracts") {
val ERROR_IN_CONTRACT_DESCRIPTION by error<FirSourceElement, KtElement> {
parameter<String>("reason")
}
}
group("Extended checkers") { group("Extended checkers") {
val REDUNDANT_VISIBILITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER) val REDUNDANT_VISIBILITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.VISIBILITY_MODIFIER)
val REDUNDANT_MODALITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER) val REDUNDANT_MODALITY_MODIFIER by warning<FirSourceElement, KtModifierListOwner>(PositioningStrategy.MODALITY_MODIFIER)
......
...@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.name.Name ...@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtIfExpression
...@@ -239,6 +240,9 @@ object FirErrors { ...@@ -239,6 +240,9 @@ object FirErrors {
val NO_ELSE_IN_WHEN by error1<FirSourceElement, KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION) val NO_ELSE_IN_WHEN by error1<FirSourceElement, KtWhenExpression, List<WhenMissingCase>>(SourceElementPositioningStrategies.WHEN_EXPRESSION)
val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION) val INVALID_IF_AS_EXPRESSION by error0<FirSourceElement, KtIfExpression>(SourceElementPositioningStrategies.IF_EXPRESSION)
// Function contracts
val ERROR_IN_CONTRACT_DESCRIPTION by error1<FirSourceElement, KtElement, String>()
// Extended checkers // Extended checkers
val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER) val REDUNDANT_VISIBILITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.VISIBILITY_MODIFIER)
val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER) val REDUNDANT_MODALITY_MODIFIER by warning0<FirSourceElement, KtModifierListOwner>(SourceElementPositioningStrategies.MODALITY_MODIFIER)
......
/*
* Copyright 2010-2021 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.declaration
import org.jetbrains.kotlin.fir.FirFakeSourceElementKind
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
import org.jetbrains.kotlin.fir.contracts.FirResolvedContractDescription
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
import org.jetbrains.kotlin.fir.declarations.FirFunction
object FirContractChecker : FirFunctionChecker() {
// TODO: The message should vary. Migrate this to [ConeEffectExtractor] when creating fine-grained errors.
private const val UNEXPECTED_CONSTRUCTION = "unexpected construction in contract description"
override fun check(declaration: FirFunction<*>, context: CheckerContext, reporter: DiagnosticReporter) {
if (declaration !is FirContractDescriptionOwner ||
declaration.contractDescription !is FirResolvedContractDescription
) {
return
}
// Any statements that [ConeEffectExtractor] cannot extract effects will be in `unresolvedEffects`.
for (statement in (declaration.contractDescription as FirResolvedContractDescription).unresolvedEffects) {
if (statement.source == null || statement.source!!.kind is FirFakeSourceElementKind) continue
// TODO: report on fine-grained locations, e.g., ... implies unresolved => report on unresolved, not the entire statement.
// but, sometimes, it's just reported on `contract`...
reporter.report(FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(statement.source!!, UNEXPECTED_CONSTRUCTION), context)
}
}
}
...@@ -60,6 +60,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_E ...@@ -60,6 +60,7 @@ import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.DESERIALIZATION_E
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_RANGE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EMPTY_RANGE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_AS_SUPERTYPE import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ENUM_AS_SUPERTYPE
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_FROM_JAVA_RESOLUTION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_FROM_JAVA_RESOLUTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.ERROR_IN_CONTRACT_DESCRIPTION
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DECLARATION_WITH_BODY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DECLARATION_WITH_BODY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DELEGATED_PROPERTY import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_DELEGATED_PROPERTY
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.EXPECTED_PRIVATE_DECLARATION
...@@ -535,6 +536,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension { ...@@ -535,6 +536,9 @@ class FirDefaultErrorMessages : DefaultErrorMessages.Extension {
map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES) map.put(NO_ELSE_IN_WHEN, "''when'' expression must be exhaustive, add necessary {0}", WHEN_MISSING_CASES)
map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression") map.put(INVALID_IF_AS_EXPRESSION, "'if' must have both main and 'else' branches if used as an expression")
// Function contracts
map.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description", TO_STRING)
// Extended checkers group // Extended checkers group
map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier") map.put(REDUNDANT_VISIBILITY_MODIFIER, "Redundant visibility modifier")
map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier") map.put(REDUNDANT_MODALITY_MODIFIER, "Redundant modality modifier")
......
...@@ -46,6 +46,7 @@ fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic<FirS ...@@ -46,6 +46,7 @@ fun ConeDiagnostic.toFirDiagnostic(source: FirSourceElement): FirDiagnostic<FirS
is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(source, this.target) is ConeInstanceAccessBeforeSuperCall -> FirErrors.INSTANCE_ACCESS_BEFORE_SUPER_CALL.on(source, this.target)
is ConeStubDiagnostic -> null is ConeStubDiagnostic -> null
is ConeIntermediateDiagnostic -> null is ConeIntermediateDiagnostic -> null
is ConeContractDescriptionError -> FirErrors.ERROR_IN_CONTRACT_DESCRIPTION.on(source, this.reason)
else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}") else -> throw IllegalArgumentException("Unsupported diagnostic type: ${this.javaClass}")
} }
......
...@@ -27,6 +27,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() { ...@@ -27,6 +27,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
) )
override val functionCheckers: Set<FirFunctionChecker> = setOf( override val functionCheckers: Set<FirFunctionChecker> = setOf(
FirContractChecker,
FirFunctionNameChecker, FirFunctionNameChecker,
) )
......
...@@ -181,7 +181,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() { ...@@ -181,7 +181,7 @@ class FirTypeResolverImpl(private val session: FirSession) : FirTypeResolver() {
} }
is FirFunctionTypeRef -> createFunctionalType(typeRef) is FirFunctionTypeRef -> createFunctionalType(typeRef)
is FirDynamicTypeRef -> ConeKotlinErrorType(ConeIntermediateDiagnostic("Not supported: ${typeRef::class.simpleName}")) is FirDynamicTypeRef -> ConeKotlinErrorType(ConeIntermediateDiagnostic("Not supported: ${typeRef::class.simpleName}"))
else -> error("!") else -> error(typeRef.render())
} }
} }
} }
...@@ -10,19 +10,19 @@ class Foo { ...@@ -10,19 +10,19 @@ class Foo {
inner class Bar { inner class Bar {
fun good() { fun good() {
contract { contract {
returns() implies (<!UNRESOLVED_LABEL!>this@Bar<!> != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_LABEL!>this@Bar<!> != null)<!>
} }
} }
fun badOuter() { fun badOuter() {
contract { contract {
returns() implies (<!UNRESOLVED_LABEL!>this@Foo<!> != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_LABEL!>this@Foo<!> != null)<!>
} }
} }
fun badInner() { fun badInner() {
contract { contract {
returns() implies (this != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (this != null)<!>
} }
} }
...@@ -34,7 +34,7 @@ class Foo { ...@@ -34,7 +34,7 @@ class Foo {
fun A?.badWithReceiver() { fun A?.badWithReceiver() {
contract { contract {
returns() implies (<!UNRESOLVED_LABEL!>this@Bar<!> != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_LABEL!>this@Bar<!> != null)<!>
} }
} }
} }
......
...@@ -7,7 +7,7 @@ import kotlin.contracts.* ...@@ -7,7 +7,7 @@ import kotlin.contracts.*
fun foo(b: Boolean): Boolean { fun foo(b: Boolean): Boolean {
contract { contract {
// pointless, can be reduced to just "b" // pointless, can be reduced to just "b"
returns(true) implies (b == true) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (b == true)<!>
} }
return b return b
...@@ -16,7 +16,7 @@ fun foo(b: Boolean): Boolean { ...@@ -16,7 +16,7 @@ fun foo(b: Boolean): Boolean {
fun bar(b: Boolean?): Boolean { fun bar(b: Boolean?): Boolean {
contract { contract {
// not pointless, but not supported yet // not pointless, but not supported yet
returns(true) implies (b == true) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (b == true)<!>
} }
if (b == null) throw java.lang.IllegalArgumentException("") if (b == null) throw java.lang.IllegalArgumentException("")
return b return b
......
...@@ -8,7 +8,7 @@ fun bar(x: Int): Boolean = x == 0 ...@@ -8,7 +8,7 @@ fun bar(x: Int): Boolean = x == 0
fun foo(x: Int): Boolean { fun foo(x: Int): Boolean {
contract { contract {
returns(true) implies (bar(x)) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (bar(x))<!>
} }
return x == 0 return x == 0
} }
\ No newline at end of file
...@@ -6,26 +6,26 @@ import kotlin.contracts.* ...@@ -6,26 +6,26 @@ import kotlin.contracts.*
fun ifInContract(x: Any?, boolean: Boolean) { fun ifInContract(x: Any?, boolean: Boolean) {
contract { contract {
if (boolean) { <!ERROR_IN_CONTRACT_DESCRIPTION!>if (boolean) {
returns() implies (x is String) returns() implies (x is String)
} else { } else {
returns() implies (x is Int) returns() implies (x is Int)
} }<!>
} }
} }
fun whenInContract(x: Any?, boolean: Boolean) { fun whenInContract(x: Any?, boolean: Boolean) {
contract { contract {
when (boolean) { <!ERROR_IN_CONTRACT_DESCRIPTION!>when (boolean) {
true -> returns() implies (x is String) true -> returns() implies (x is String)
else -> returns() implies (x is Int) else -> returns() implies (x is Int)
} }<!>
} }
} }
fun forInContract(x: Any?) { fun forInContract(x: Any?) {
contract { contract {
<!UNRESOLVED_REFERENCE!>for (i in 0..1) { <!ERROR_IN_CONTRACT_DESCRIPTION, UNRESOLVED_REFERENCE!>for (i in 0..1) {
returns() implies (x is String) returns() implies (x is String)
}<!> }<!>
} }
...@@ -33,23 +33,23 @@ fun forInContract(x: Any?) { ...@@ -33,23 +33,23 @@ fun forInContract(x: Any?) {
fun whileInContract(x: Any?) { fun whileInContract(x: Any?) {
contract { contract {
while (false) { <!ERROR_IN_CONTRACT_DESCRIPTION!>while (false) {
returns() implies (x is String) returns() implies (x is String)
} }<!>
} }
} }
fun doWhileInContract(x: Any?) { fun doWhileInContract(x: Any?) {
contract { contract {
do { <!ERROR_IN_CONTRACT_DESCRIPTION!>do {
returns() implies (x is String) returns() implies (x is String)
} while (false) } while (false)<!>
} }
} }
fun localValInContract(x: Any?) { fun localValInContract(x: Any?) {
<!WRONG_IMPLIES_CONDITION!>contract { <!WRONG_IMPLIES_CONDITION!>contract {
val y: Int = 42 <!ERROR_IN_CONTRACT_DESCRIPTION!>val y: Int = 42<!>
returns() implies (x is String) returns() implies (x is String)
}<!> }<!>
} }
\ No newline at end of file
...@@ -6,25 +6,25 @@ import kotlin.contracts.* ...@@ -6,25 +6,25 @@ import kotlin.contracts.*
fun equalsWithVariables(x: Any?, y: Any?) { fun equalsWithVariables(x: Any?, y: Any?) {
contract { contract {
returns() implies (x == y) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (x == y)<!>
} }
} }
fun identityEqualsWithVariables(x: Any?, y: Any?) { fun identityEqualsWithVariables(x: Any?, y: Any?) {
contract { contract {
returns() implies (x === y) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (x === y)<!>
} }
} }
fun equalConstants() { fun equalConstants() {
contract { contract {
returns() implies (null == null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (null == null)<!>
} }
} }
fun get(): Int? = null fun get(): Int? = null
fun equalNullWithCall() { fun equalNullWithCall() {
contract { contract {
returns() implies (get() == null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (get() == null)<!>
} }
} }
\ No newline at end of file
...@@ -6,6 +6,6 @@ import kotlin.contracts.* ...@@ -6,6 +6,6 @@ import kotlin.contracts.*
fun foo(boolean: Boolean) { fun foo(boolean: Boolean) {
contract { contract {
(returns() implies (boolean)) <!UNRESOLVED_REFERENCE!>implies<!> (!boolean) <!ERROR_IN_CONTRACT_DESCRIPTION!>(returns() implies (boolean)) <!UNRESOLVED_REFERENCE!>implies<!> (!boolean)<!>
} }
} }
\ No newline at end of file
...@@ -5,21 +5,21 @@ ...@@ -5,21 +5,21 @@
import kotlin.contracts.* import kotlin.contracts.*
fun case_1(): Boolean { fun case_1(): Boolean {
contract { returns(null) implies case_1() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies case_1()<!> }
return true return true
} }
fun case_2(): Boolean { fun case_2(): Boolean {
contract { returns(null) implies case_3() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies case_3()<!> }
return true return true
} }
fun case_3(): Boolean { fun case_3(): Boolean {
contract { returns(null) implies case_2() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies case_2()<!> }
return true return true
} }
fun case_4(): Boolean { fun case_4(): Boolean {
kotlin.contracts.contract { returns(null) implies case_1() } kotlin.contracts.contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies case_1()<!> }
return true return true
} }
\ No newline at end of file
...@@ -7,7 +7,7 @@ import kotlin.contracts.* ...@@ -7,7 +7,7 @@ import kotlin.contracts.*
class Foo(val x: Int?) { class Foo(val x: Int?) {
fun isXNull(): Boolean { fun isXNull(): Boolean {
contract { contract {
returns(false) implies (<!UNRESOLVED_REFERENCE!>x<!> != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (<!UNRESOLVED_REFERENCE!>x<!> != null)<!>
} }
return x != null return x != null
} }
......
...@@ -7,7 +7,7 @@ import kotlin.contracts.* ...@@ -7,7 +7,7 @@ import kotlin.contracts.*
class Foo(val x: Int?) { class Foo(val x: Int?) {
fun isXNull(): Boolean { fun isXNull(): Boolean {
contract { contract {
returns(false) implies (<!UNRESOLVED_REFERENCE!>x<!> != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (<!UNRESOLVED_REFERENCE!>x<!> != null)<!>
} }
return x != null return x != null
} }
......
...@@ -6,7 +6,7 @@ import kotlin.contracts.* ...@@ -6,7 +6,7 @@ import kotlin.contracts.*
fun Any?.foo(): Boolean { fun Any?.foo(): Boolean {
contract { contract {
returns(true) implies (this != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (this != null)<!>
} }
return this != null return this != null
} }
\ No newline at end of file
...@@ -26,7 +26,7 @@ inline fun case_1(block: () -> Unit) { ...@@ -26,7 +26,7 @@ inline fun case_1(block: () -> Unit) {
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
inline fun case_2(block: () -> Unit) { inline fun case_2(block: () -> Unit) {
contract { callsInPlaceEffectBuilder(block) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>callsInPlaceEffectBuilder(block)<!> }
return block() return block()
} }
......
...@@ -5,6 +5,6 @@ import kotlin.contracts.* ...@@ -5,6 +5,6 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(value_1: Any?, block: () -> Unit) { fun case_1(value_1: Any?, block: () -> Unit) {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) <!UNRESOLVED_REFERENCE!>implies<!> (value_1 != null) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>callsInPlace(block, InvocationKind.EXACTLY_ONCE) <!UNRESOLVED_REFERENCE!>implies<!> (value_1 != null)<!> }
if (value_1 != null) block() if (value_1 != null) block()
} }
...@@ -5,7 +5,7 @@ import kotlin.contracts.* ...@@ -5,7 +5,7 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(): Boolean { fun case_1(): Boolean {
contract { returns(null) implies throw Exception() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies throw Exception()<!> }
return true return true
} }
...@@ -17,6 +17,6 @@ fun case_2(): Boolean { ...@@ -17,6 +17,6 @@ fun case_2(): Boolean {
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(): Boolean { fun case_3(): Boolean {
contract { returns(null) implies return return return false && throw throw throw throw Exception() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies return return return false && throw throw throw throw Exception()<!> }
return true return true
} }
...@@ -5,24 +5,24 @@ import kotlin.contracts.* ...@@ -5,24 +5,24 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(value_1: Boolean): Boolean { fun case_1(value_1: Boolean): Boolean {
contract { returns(true) implies (value_1 == true) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (value_1 == true)<!> }
return value_1 == true return value_1 == true
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(value_1: Boolean): Boolean? { fun case_2(value_1: Boolean): Boolean? {
contract { returnsNotNull() implies (value_1 != false) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (value_1 != false)<!> }
return if (value_1 != false) true else null return if (value_1 != false) true else null
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(value_1: String): Boolean { fun case_3(value_1: String): Boolean {
contract { returns(false) implies (value_1 != "") } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (value_1 != "")<!> }
return !(value_1 != "") return !(value_1 != "")
} }
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
fun case_4(value_1: Int): Boolean? { fun case_4(value_1: Int): Boolean? {
contract { returns(null) implies (value_1 == 0) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (value_1 == 0)<!> }
return if (value_1 == 0) null else true return if (value_1 == 0) null else true
} }
...@@ -5,36 +5,36 @@ import kotlin.contracts.* ...@@ -5,36 +5,36 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(value_1: Boolean?): Boolean { fun case_1(value_1: Boolean?): Boolean {
contract { returns(true) implies (value_1 != null && value_1 == false) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (value_1 != null && value_1 == false)<!> }
return value_1 != null && value_1 == false return value_1 != null && value_1 == false
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(value_1: Boolean, value_2: Boolean): Boolean? { fun case_2(value_1: Boolean, value_2: Boolean): Boolean? {
contract { returnsNotNull() implies (value_1 != false || value_2) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (value_1 != false || value_2)<!> }
return if (value_1 != false || value_2) true else null return if (value_1 != false || value_2) true else null
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(value_1: String?, value_2: Boolean): Boolean { fun case_3(value_1: String?, value_2: Boolean): Boolean {
contract { returns(false) implies (value_1 != null && value_2 != true) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (value_1 != null && value_2 != true)<!> }
return !(value_1 != null && value_2 != true) return !(value_1 != null && value_2 != true)
} }
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
fun case_4(value_1: Nothing?, value_2: Boolean?): Boolean? { fun case_4(value_1: Nothing?, value_2: Boolean?): Boolean? {
contract { returns(null) implies (value_1 == null || value_2 != null || value_2 == false) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (value_1 == null || value_2 != null || value_2 == false)<!> }
return if (value_1 == null || value_2 != null || value_2 == false) null else true return if (value_1 == null || value_2 != null || value_2 == false) null else true
} }
// TESTCASE NUMBER: 5 // TESTCASE NUMBER: 5
fun case_5(value_1: Any?, value_2: String?): Boolean? { fun case_5(value_1: Any?, value_2: String?): Boolean? {
contract { returns(null) implies (value_1 != null && value_2 != null || value_2 == ".") } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (value_1 != null && value_2 != null || value_2 == ".")<!> }
return if (value_1 != null && value_2 != null || value_2 == ".") null else true return if (value_1 != null && value_2 != null || value_2 == ".") null else true
} }
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
fun case_6(value_1: Boolean, value_2: Int?): Boolean? { fun case_6(value_1: Boolean, value_2: Int?): Boolean? {
contract { returns(null) implies (value_2 == null && value_1 || value_2 == 0) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (value_2 == null && value_1 || value_2 == 0)<!> }
return if (value_2 == null && value_1 || value_2 == 0) null else true return if (value_2 == null && value_1 || value_2 == 0) null else true
} }
...@@ -6,18 +6,18 @@ import kotlin.contracts.* ...@@ -6,18 +6,18 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(): Boolean? { fun case_1(): Boolean? {
contract { returnsNotNull() <!INAPPLICABLE_CANDIDATE!>implies<!> (null) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() <!INAPPLICABLE_CANDIDATE!>implies<!> (null)<!> }
return true return true
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(): Boolean { fun case_2(): Boolean {
contract { returns(false) <!INAPPLICABLE_CANDIDATE!>implies<!> 0.000001 } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) <!INAPPLICABLE_CANDIDATE!>implies<!> 0.000001<!> }
return true return true
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(): Boolean? { fun case_3(): Boolean? {
contract { returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> "" } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> ""<!> }
return null return null
} }
...@@ -6,7 +6,7 @@ import kotlin.contracts.* ...@@ -6,7 +6,7 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(): Boolean { fun case_1(): Boolean {
contract { returns(true) <!INAPPLICABLE_CANDIDATE!>implies<!> (-10) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) <!INAPPLICABLE_CANDIDATE!>implies<!> (-10)<!> }
return true return true
} }
...@@ -18,7 +18,7 @@ fun case_2(): Boolean { ...@@ -18,7 +18,7 @@ fun case_2(): Boolean {
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(): Boolean { fun case_3(): Boolean {
contract { returns(false) <!INAPPLICABLE_CANDIDATE!>implies<!> ("..." + "$<!UNRESOLVED_REFERENCE!>value_1<!>") } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) <!INAPPLICABLE_CANDIDATE!>implies<!> ("..." + "$<!UNRESOLVED_REFERENCE!>value_1<!>")<!> }
return true return true
} }
...@@ -27,26 +27,26 @@ fun case_3(): Boolean { ...@@ -27,26 +27,26 @@ fun case_3(): Boolean {
* ISSUES: KT-26386 * ISSUES: KT-26386
*/ */
fun case_4(): Boolean? { fun case_4(): Boolean? {
contract { returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> case_4() } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> case_4()<!> }
return null return null
} }
// TESTCASE NUMBER: 5 // TESTCASE NUMBER: 5
fun case_5(): Boolean? { fun case_5(): Boolean? {
contract { returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> listOf(0) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> listOf(0)<!> }
return null return null
} }
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
fun case_6(value_1: Boolean): Boolean? { fun case_6(value_1: Boolean): Boolean? {
contract { returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> contract { returns(null) implies (!value_1) } } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) <!INAPPLICABLE_CANDIDATE!>implies<!> contract { returns(null) implies (!value_1) }<!> }
return null return null
} }
// TESTCASE NUMBER: 7 // TESTCASE NUMBER: 7
fun case_7(): Int { fun case_7(): Int {
contract { contract {
callsInPlace(::case_7, InvocationKind.EXACTLY_ONCE) <!ERROR_IN_CONTRACT_DESCRIPTION!>callsInPlace(::case_7, InvocationKind.EXACTLY_ONCE)<!>
} }
return 1 return 1
} }
...@@ -57,7 +57,7 @@ fun case_7(): Int { ...@@ -57,7 +57,7 @@ fun case_7(): Int {
*/ */
fun case_8(): () -> Unit { fun case_8(): () -> Unit {
contract { contract {
callsInPlace(case_8(), InvocationKind.EXACTLY_ONCE) <!ERROR_IN_CONTRACT_DESCRIPTION!>callsInPlace(case_8(), InvocationKind.EXACTLY_ONCE)<!>
} }
return {} return {}
} }
...@@ -11,16 +11,16 @@ object case_1 { ...@@ -11,16 +11,16 @@ object case_1 {
private const val value_3 = false private const val value_3 = false
fun case_1_1(): Boolean? { fun case_1_1(): Boolean? {
contract { returnsNotNull() implies (<!UNRESOLVED_REFERENCE!>value_1<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (<!UNRESOLVED_REFERENCE!>value_1<!>)<!> }
return if (value_1) true else null return if (value_1) true else null
} }
fun case_1_2(): Boolean? { fun case_1_2(): Boolean? {
contract { returns(null) implies (<!UNRESOLVED_REFERENCE!>value_2<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (<!UNRESOLVED_REFERENCE!>value_2<!>)<!> }
return if (value_2) null else true return if (value_2) null else true
} }
fun case_1_3(): Boolean { fun case_1_3(): Boolean {
contract { returns(true) implies (<!UNRESOLVED_REFERENCE!>value_3<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (<!UNRESOLVED_REFERENCE!>value_3<!>)<!> }
return value_3 return value_3
} }
} }
...@@ -42,22 +42,22 @@ class case_2(value_5: Boolean, val value_1: Boolean) { ...@@ -42,22 +42,22 @@ class case_2(value_5: Boolean, val value_1: Boolean) {
} }
fun case_2_2(): Boolean? { fun case_2_2(): Boolean? {
contract { returns(null) implies (<!UNRESOLVED_REFERENCE!>value_1<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (<!UNRESOLVED_REFERENCE!>value_1<!>)<!> }
return if (value_1) null else true return if (value_1) null else true
} }
fun case_2_3(): Boolean { fun case_2_3(): Boolean {
contract { returns(true) implies (<!UNRESOLVED_REFERENCE!>value_2<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (<!UNRESOLVED_REFERENCE!>value_2<!>)<!> }
return value_2 return value_2
} }
fun case_2_4(): Boolean { fun case_2_4(): Boolean {
contract { returns(false) implies (<!UNRESOLVED_REFERENCE!>value_3<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (<!UNRESOLVED_REFERENCE!>value_3<!>)<!> }
return !(value_3) return !(value_3)
} }
inline fun <reified K : Number> K.case_2_5(): Boolean? { inline fun <reified K : Number> K.case_2_5(): Boolean? {
contract { returnsNotNull() implies (<!UNRESOLVED_REFERENCE!>value_4<!>) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (<!UNRESOLVED_REFERENCE!>value_4<!>)<!> }
return if (value_4) true else null return if (value_4) true else null
} }
} }
...@@ -6,7 +6,7 @@ import kotlin.contracts.* ...@@ -6,7 +6,7 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
inline fun case_1(block: () -> Unit) { inline fun case_1(block: () -> Unit) {
contract { contract {
{ callsInPlace(block, InvocationKind.EXACTLY_ONCE) }() <!ERROR_IN_CONTRACT_DESCRIPTION!>{ callsInPlace(block, InvocationKind.EXACTLY_ONCE) }()<!>
} }
return block() return block()
} }
...@@ -14,7 +14,7 @@ inline fun case_1(block: () -> Unit) { ...@@ -14,7 +14,7 @@ inline fun case_1(block: () -> Unit) {
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(x: Any?): Boolean { fun case_2(x: Any?): Boolean {
contract { contract {
returns(true).apply { implies (x is Number) } // 'Returns' as result returns(true).<!ERROR_IN_CONTRACT_DESCRIPTION!>apply { implies (x is Number) }<!> // 'Returns' as result
} }
return x is Number return x is Number
} }
...@@ -22,7 +22,7 @@ fun case_2(x: Any?): Boolean { ...@@ -22,7 +22,7 @@ fun case_2(x: Any?): Boolean {
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(x: Any?): Boolean { fun case_3(x: Any?): Boolean {
contract { contract {
returns(true).also { it implies (x is Number) } // 'Returns' as result returns(true).<!ERROR_IN_CONTRACT_DESCRIPTION!>also { it implies (x is Number) }<!> // 'Returns' as result
} }
return x is Number return x is Number
} }
...@@ -30,7 +30,7 @@ fun case_3(x: Any?): Boolean { ...@@ -30,7 +30,7 @@ fun case_3(x: Any?): Boolean {
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
fun case_4(x: Any?): Boolean { fun case_4(x: Any?): Boolean {
contract { contract {
returns(true).let { it implies (x is Number) } // 'ConditionalEffect' as result returns(true).<!ERROR_IN_CONTRACT_DESCRIPTION!>let { it implies (x is Number) }<!> // 'ConditionalEffect' as result
} }
return x is Number return x is Number
} }
...@@ -38,7 +38,7 @@ fun case_4(x: Any?): Boolean { ...@@ -38,7 +38,7 @@ fun case_4(x: Any?): Boolean {
// TESTCASE NUMBER: 5 // TESTCASE NUMBER: 5
fun case_5(x: Any?): Boolean { fun case_5(x: Any?): Boolean {
contract { contract {
returns(true).run { implies (x is Number) } // 'ConditionalEffect' as result returns(true).<!ERROR_IN_CONTRACT_DESCRIPTION!>run { implies (x is Number) }<!> // 'ConditionalEffect' as result
} }
return x is Number return x is Number
} }
...@@ -46,7 +46,7 @@ fun case_5(x: Any?): Boolean { ...@@ -46,7 +46,7 @@ fun case_5(x: Any?): Boolean {
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
fun case_6(x: Any?): Boolean { fun case_6(x: Any?): Boolean {
contract { contract {
returns(true).takeIf { it implies (x is Number); false } // null, must be unrecognized effect returns(true).<!ERROR_IN_CONTRACT_DESCRIPTION!>takeIf { it implies (x is Number); false }<!> // null, must be unrecognized effect
} }
return x is Number return x is Number
} }
...@@ -4,24 +4,24 @@ import kotlin.contracts.* ...@@ -4,24 +4,24 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(x: Any?): Boolean { fun case_1(x: Any?): Boolean {
contract { returns(true) implies (x == -.15f) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x == -.15f)<!> }
return x !is Number return x !is Number
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(x: Any?): Boolean { fun case_2(x: Any?): Boolean {
contract { returns(true) implies (x == "..." + ".") } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x == "..." + ".")<!> }
return x !is Number return x !is Number
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(x: Int, y: Int): Boolean { fun case_3(x: Int, y: Int): Boolean {
contract { returns(true) implies (x > y) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x > y)<!> }
return x > y return x > y
} }
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
fun case_4(x: Any?, y: Any?): Boolean { fun case_4(x: Any?, y: Any?): Boolean {
contract { returns(true) implies (x == y.toString()) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x == y.toString())<!> }
return x !is Number return x !is Number
} }
...@@ -5,7 +5,7 @@ import kotlin.contracts.* ...@@ -5,7 +5,7 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun Any?.case_1(): Boolean { fun Any?.case_1(): Boolean {
contract { contract {
returns(true) implies (this != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (this != null)<!>
} }
return this != null return this != null
} }
...@@ -13,7 +13,7 @@ fun Any?.case_1(): Boolean { ...@@ -13,7 +13,7 @@ fun Any?.case_1(): Boolean {
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun Any?.case_2(): Boolean { fun Any?.case_2(): Boolean {
contract { contract {
returnsNotNull() implies (this is Number?) <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this is Number?)<!>
} }
return this is Number? return this is Number?
} }
...@@ -21,7 +21,7 @@ fun Any?.case_2(): Boolean { ...@@ -21,7 +21,7 @@ fun Any?.case_2(): Boolean {
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun <T> T?.case_3(): Boolean { fun <T> T?.case_3(): Boolean {
contract { contract {
returnsNotNull() implies (this != null) <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this != null)<!>
} }
return this != null return this != null
} }
...@@ -29,7 +29,7 @@ fun <T> T?.case_3(): Boolean { ...@@ -29,7 +29,7 @@ fun <T> T?.case_3(): Boolean {
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
inline fun <reified T : Number> T.case_4(): Boolean { inline fun <reified T : Number> T.case_4(): Boolean {
contract { contract {
returns(null) implies (this is Int) <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (this is Int)<!>
} }
return this is Int return this is Int
} }
...@@ -5,7 +5,7 @@ import kotlin.contracts.* ...@@ -5,7 +5,7 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(x: Any?): Boolean { fun case_1(x: Any?): Boolean {
contract { contract {
returns(true) implies (x === EmptyObject) // should be not allowed <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x === EmptyObject)<!> // should be not allowed
} }
return x === EmptyObject return x === EmptyObject
} }
...@@ -4,18 +4,18 @@ import kotlin.contracts.* ...@@ -4,18 +4,18 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun case_1(x: Any?): Boolean { fun case_1(x: Any?): Boolean {
contract { returns(true) implies (x == .15f) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x == .15f)<!> }
return x == .15f return x == .15f
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun case_2(x: Any?) { fun case_2(x: Any?) {
contract { returns() implies (x == "...") } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (x == "...")<!> }
if (x != "...") throw Exception() if (x != "...") throw Exception()
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun case_3(x: Any?): Boolean { fun case_3(x: Any?): Boolean {
contract { returns(true) implies (x == '-') } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (x == '-')<!> }
return x == '-' return x == '-'
} }
...@@ -4,6 +4,6 @@ import kotlin.contracts.* ...@@ -4,6 +4,6 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun <T : Boolean>T.case_1(): Boolean? { fun <T : Boolean>T.case_1(): Boolean? {
contract { returns(null) implies (!this@case_1) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(null) implies (!this@case_1)<!> }
return if (!this) null else true return if (!this) null else true
} }
...@@ -4,42 +4,42 @@ import kotlin.contracts.* ...@@ -4,42 +4,42 @@ import kotlin.contracts.*
// TESTCASE NUMBER: 1 // TESTCASE NUMBER: 1
fun Boolean?.case_1(): Boolean { fun Boolean?.case_1(): Boolean {
contract { returns(true) implies (this@case_1 != null && this@case_1) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (this@case_1 != null && this@case_1)<!> }
return this != null && this return this != null && this
} }
// TESTCASE NUMBER: 2 // TESTCASE NUMBER: 2
fun <T : Boolean>T?.case_2(): Boolean { fun <T : Boolean>T?.case_2(): Boolean {
contract { returns(true) implies (this@case_2 != null && this@case_2 !is Nothing && this@case_2) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (this@case_2 != null && this@case_2 !is Nothing && this@case_2)<!> }
return this != null && this !is Nothing && this return this != null && this !is Nothing && this
} }
// TESTCASE NUMBER: 3 // TESTCASE NUMBER: 3
fun <T>T?.case_3() { fun <T>T?.case_3() {
contract { returns() implies (this@case_3 == null || this@case_3 is Boolean? && !this@case_3) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (this@case_3 == null || this@case_3 is Boolean? && !this@case_3)<!> }
if (!(this == null || this is Boolean? && !this)) throw Exception() if (!(this == null || this is Boolean? && !this)) throw Exception()
} }
// TESTCASE NUMBER: 4 // TESTCASE NUMBER: 4
fun case_4(value_1: Boolean?): Boolean { fun case_4(value_1: Boolean?): Boolean {
contract { returns(true) implies (value_1 != null && !value_1) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(true) implies (value_1 != null && !value_1)<!> }
return value_1 != null && !value_1 return value_1 != null && !value_1
} }
// TESTCASE NUMBER: 5 // TESTCASE NUMBER: 5
fun Boolean.case_5(value_1: Any?): Boolean? { fun Boolean.case_5(value_1: Any?): Boolean? {
contract { returnsNotNull() implies (value_1 is Boolean? && value_1 != null && value_1) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (value_1 is Boolean? && value_1 != null && value_1)<!> }
return if (value_1 is Boolean? && value_1 != null && value_1) true else null return if (value_1 is Boolean? && value_1 != null && value_1) true else null
} }
// TESTCASE NUMBER: 6 // TESTCASE NUMBER: 6
fun Boolean?.case_6(): Boolean? { fun Boolean?.case_6(): Boolean? {
contract { returnsNotNull() implies (this@case_6 != null && this@case_6) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this@case_6 != null && this@case_6)<!> }
return if (this@case_6 != null && this@case_6) true else null return if (this@case_6 != null && this@case_6) true else null
} }
// TESTCASE NUMBER: 7 // TESTCASE NUMBER: 7
fun <T : Boolean?> T.case_7(value_1: Any?): Boolean? { fun <T : Boolean?> T.case_7(value_1: Any?): Boolean? {
contract { returnsNotNull() implies (value_1 is Boolean? && value_1 != null && value_1 && this@case_7 != null && this@case_7) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (value_1 is Boolean? && value_1 != null && value_1 && this@case_7 != null && this@case_7)<!> }
return if (value_1 is Boolean? && value_1 != null && value_1 && this@case_7 != null && this@case_7) true else null return if (value_1 is Boolean? && value_1 != null && value_1 && this@case_7 != null && this@case_7) true else null
} }
...@@ -32,12 +32,12 @@ fun case_2() { ...@@ -32,12 +32,12 @@ fun case_2() {
class case_4 : ClassLevel3() { class case_4 : ClassLevel3() {
fun <T : Number?>T.case_4_1(): Boolean { fun <T : Number?>T.case_4_1(): Boolean {
contract { returns(false) implies (<!UNRESOLVED_LABEL!>this@case_4<!> !is ClassLevel1) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns(false) implies (<!UNRESOLVED_LABEL!>this@case_4<!> !is ClassLevel1)<!> }
return this == null return this == null
} }
fun <T : Boolean>T.case_4_2() { fun <T : Boolean>T.case_4_2() {
contract { returns() implies (!this@case_4_2) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (!this@case_4_2)<!> }
if (this) throw Exception() if (this) throw Exception()
} }
...@@ -60,12 +60,12 @@ class case_4 : ClassLevel3() { ...@@ -60,12 +60,12 @@ class case_4 : ClassLevel3() {
class case_5<T> : ClassLevel5() { class case_5<T> : ClassLevel5() {
inner class case_5_1 { inner class case_5_1 {
fun <K : Number?>K.case_5_1_1() { fun <K : Number?>K.case_5_1_1() {
contract { returns() implies (<!UNRESOLVED_LABEL!>this@case_5_1<!> !is ClassLevel1 && <!UNRESOLVED_LABEL!>this@case_5_1<!> != null || <!UNRESOLVED_LABEL!>this@case_5<!> is ClassLevel1 && this@case_5_1_1 is Float) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_LABEL!>this@case_5_1<!> !is ClassLevel1 && <!UNRESOLVED_LABEL!>this@case_5_1<!> != null || <!UNRESOLVED_LABEL!>this@case_5<!> is ClassLevel1 && this@case_5_1_1 is Float)<!> }
if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception() if (!(this@case_5_1 !is ClassLevel1 && this@case_5_1 != null || this@case_5 is ClassLevel1 && this is Float)) throw Exception()
} }
fun case_5_1_2() { fun case_5_1_2() {
contract { returns() implies (<!UNRESOLVED_LABEL!>this@case_5_1<!> !is ClassLevel1 || <!UNRESOLVED_LABEL!>this@case_5<!> is ClassLevel1 || <!UNRESOLVED_LABEL!>this@case_5_1<!> == null) } contract { <!ERROR_IN_CONTRACT_DESCRIPTION!>returns() implies (<!UNRESOLVED_LABEL!>this@case_5_1<!> !is ClassLevel1 || <!UNRESOLVED_LABEL!>this@case_5<!> is ClassLevel1 || <!UNRESOLVED_LABEL!>this@case_5_1<!> == null)<!> }
if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception() if (!(this@case_5_1 !is ClassLevel1 || this@case_5 is ClassLevel1 || this@case_5_1 == null)) throw Exception()
} }
} }
......
...@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.psi ...@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtIfExpression
...@@ -1033,6 +1034,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert ...@@ -1033,6 +1034,13 @@ internal val KT_DIAGNOSTIC_CONVERTER = KtDiagnosticConverterBuilder.buildConvert
token, token,
) )
} }
add(FirErrors.ERROR_IN_CONTRACT_DESCRIPTION) { firDiagnostic ->
ErrorInContractDescriptionImpl(
firDiagnostic.a,
firDiagnostic as FirPsiDiagnostic<*>,
token,
)
}
add(FirErrors.REDUNDANT_VISIBILITY_MODIFIER) { firDiagnostic -> add(FirErrors.REDUNDANT_VISIBILITY_MODIFIER) { firDiagnostic ->
RedundantVisibilityModifierImpl( RedundantVisibilityModifierImpl(
firDiagnostic as FirPsiDiagnostic<*>, firDiagnostic as FirPsiDiagnostic<*>,
......
...@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.name.Name ...@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtIfExpression
...@@ -729,6 +730,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> { ...@@ -729,6 +730,11 @@ sealed class KtFirDiagnostic<PSI: PsiElement> : KtDiagnosticWithPsi<PSI> {
override val diagnosticClass get() = InvalidIfAsExpression::class override val diagnosticClass get() = InvalidIfAsExpression::class
} }
abstract class ErrorInContractDescription : KtFirDiagnostic<KtElement>() {
override val diagnosticClass get() = ErrorInContractDescription::class
abstract val reason: String
}
abstract class RedundantVisibilityModifier : KtFirDiagnostic<KtModifierListOwner>() { abstract class RedundantVisibilityModifier : KtFirDiagnostic<KtModifierListOwner>() {
override val diagnosticClass get() = RedundantVisibilityModifier::class override val diagnosticClass get() = RedundantVisibilityModifier::class
} }
......
...@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.Name ...@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtClassOrObject
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtDestructuringDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtFunction
import org.jetbrains.kotlin.psi.KtIfExpression import org.jetbrains.kotlin.psi.KtIfExpression
...@@ -1174,6 +1175,14 @@ internal class InvalidIfAsExpressionImpl( ...@@ -1174,6 +1175,14 @@ internal class InvalidIfAsExpressionImpl(
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic) override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
} }
internal class ErrorInContractDescriptionImpl(
override val reason: String,
firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken,
) : KtFirDiagnostic.ErrorInContractDescription(), KtAbstractFirDiagnostic<KtElement> {
override val firDiagnostic: FirPsiDiagnostic<*> by weakRef(firDiagnostic)
}
internal class RedundantVisibilityModifierImpl( internal class RedundantVisibilityModifierImpl(
firDiagnostic: FirPsiDiagnostic<*>, firDiagnostic: FirPsiDiagnostic<*>,
override val token: ValidityToken, override val token: ValidityToken,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册