diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.kt new file mode 100644 index 00000000000..eaed628ce7b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.kt @@ -0,0 +1,9 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER + +import kotlin.contracts.* + +fun emptyContract() { + contract { } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.txt new file mode 100644 index 00000000000..065f3f9c24e --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.txt @@ -0,0 +1,3 @@ +package + +public fun emptyContract(): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.kt new file mode 100644 index 00000000000..b90ac27984b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.kt @@ -0,0 +1,86 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -NOTHING_TO_INLINE -ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS -ABSTRACT_FUNCTION_WITH_BODY -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_FEATURE_WARNING + +import kotlin.contracts.* + + +// ============= Class ===================== +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) } + } + + open fun openMemeber(x: Boolean) { + contract { returns() implies (x) } + } + + suspend fun suspendMember(x: Boolean) { + contract { returns() implies (x) } + } +} + + +// ============= Top-level ===================== +fun topLevel(x: Boolean) { + contract { returns() implies (x) } +} + +inline fun inlineTopLevel(x: Boolean) { + contract { returns() implies (x) } +} + +suspend fun suspendTopLevel(x: Boolean) { + contract { returns() implies (x) } +} + +// Top-level operator +operator fun Boolean.plus(x: Boolean): Boolean { + contract { returns() implies (x) } + return x +} + +val topLevelLambda: (Boolean) -> Unit = { x: Boolean -> + contract { returns() implies (x) } +} + +val topLevelAnonymousFunction = fun (x: Boolean) { + contract { returns() implies (x) } +} + +var topLevelPropertyAccessors: Int? = 42 + get() { + contract { returns() implies (field != null) } + return 42 + } + set(value) { + contract { returns() implies (field != null) } + } + + +// ============= Local ===================== +fun test() { + fun localDeclaration(x: Boolean) { + contract { returns() implies (x) } + } + + suspend fun suspendlocalDeclaration(x: Boolean) { + contract { returns() implies (x) } + } + + val localAnonymousFunction = fun (x: Boolean) { + contract { returns() implies (x) } + } + + val localLambda: (Boolean) -> Unit = { x: Boolean -> + contract { returns() implies (x) } + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.txt new file mode 100644 index 00000000000..e8105057eca --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.txt @@ -0,0 +1,39 @@ +package + +public val topLevelAnonymousFunction: (kotlin.Boolean) -> kotlin.Unit +public val topLevelLambda: (kotlin.Boolean) -> kotlin.Unit +public var topLevelPropertyAccessors: kotlin.Int? +public inline fun inlineTopLevel(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + +public suspend fun suspendTopLevel(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + +public fun test(): kotlin.Unit +public fun topLevel(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + +public operator fun kotlin.Boolean.plus(/*0*/ x: kotlin.Boolean): kotlin.Boolean + Returns(WILDCARD) -> x + +public open class Class { + public constructor Class() + public abstract fun abstractMember(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + + 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 final inline fun inlineMember(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + + public final fun member(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + + public open fun openMemeber(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + + public final suspend fun suspendMember(/*0*/ x: kotlin.Boolean): kotlin.Unit + Returns(WILDCARD) -> x + + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.kt new file mode 100644 index 00000000000..e4745964d0a --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.kt @@ -0,0 +1,55 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -NOTHING_TO_INLINE -ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS -ABSTRACT_FUNCTION_WITH_BODY -UNUSED_PARAMETER -UNUSED_VARIABLE -EXPERIMENTAL_FEATURE_WARNING + +import kotlin.contracts.* + +fun ifInContract(x: Any?, boolean: Boolean) { + contract { + if (boolean) { + returns() implies (x is String) + } else { + returns() implies (x is Int) + } + } +} + +fun whenInContract(x: Any?, boolean: Boolean) { + contract { + when (boolean) { + true -> returns() implies (x is String) + else -> returns() implies (x is Int) + } + } +} + +fun forInContract(x: Any?) { + contract { + for (i in 0..1) { + returns() implies (x is String) + } + } +} + +fun whileInContract(x: Any?) { + contract { + while (false) { + returns() implies (x is String) + } + } +} + +fun doWhileInContract(x: Any?) { + contract { + do { + returns() implies (x is String) + } while (false) + } +} + +fun localValInContract(x: Any?) { + contract { + val y: Int = 42 + returns() implies (x is String) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.txt new file mode 100644 index 00000000000..6a0f6a8b645 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.txt @@ -0,0 +1,10 @@ +package + +public fun doWhileInContract(/*0*/ x: kotlin.Any?): kotlin.Unit +public fun forInContract(/*0*/ x: kotlin.Any?): kotlin.Unit +public fun ifInContract(/*0*/ x: kotlin.Any?, /*1*/ boolean: kotlin.Boolean): kotlin.Unit +public fun localValInContract(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is String + +public fun whenInContract(/*0*/ x: kotlin.Any?, /*1*/ boolean: kotlin.Boolean): kotlin.Unit +public fun whileInContract(/*0*/ x: kotlin.Any?): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.kt new file mode 100644 index 00000000000..c78dd0232f2 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.kt @@ -0,0 +1,30 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER + +import kotlin.contracts.* + +fun equalsWithVariables(x: Any?, y: Any?) { + contract { + returns() implies (x == y) + } +} + +fun identityEqualsWithVariables(x: Any?, y: Any?) { + contract { + returns() implies (x === y) + } +} + +fun equalConstants() { + contract { + returns() implies (null == null) + } +} + +fun get(): Int? = null +fun equalNullWithCall() { + contract { + returns() implies (get() == null) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.txt new file mode 100644 index 00000000000..7be63caade0 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.txt @@ -0,0 +1,7 @@ +package + +public fun equalConstants(): kotlin.Unit +public fun equalNullWithCall(): kotlin.Unit +public fun equalsWithVariables(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit +public fun get(): kotlin.Int? +public fun identityEqualsWithVariables(/*0*/ x: kotlin.Any?, /*1*/ y: kotlin.Any?): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.kt new file mode 100644 index 00000000000..ea05aa00cde --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.kt @@ -0,0 +1,15 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER -EXPOSED_PARAMETER_TYPE + +import kotlin.contracts.* + +fun passLambdaValue(l: ContractBuilder.() -> Unit) { + contract(l) +} + +fun passAnonymousFunction(x: Boolean) { + contract(fun ContractBuilder.() { + returns() implies x + }) +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.txt new file mode 100644 index 00000000000..e6b33ce3c2b --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.txt @@ -0,0 +1,4 @@ +package + +public fun passAnonymousFunction(/*0*/ x: kotlin.Boolean): kotlin.Unit +public fun passLambdaValue(/*0*/ l: kotlin.contracts.ContractBuilder.() -> kotlin.Unit): kotlin.Unit diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.kt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.kt new file mode 100644 index 00000000000..6371e3e46aa --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.kt @@ -0,0 +1,53 @@ +// !LANGUAGE: +AllowContractsForCustomFunctions +UseReturnsEffect +// !USE_EXPERIMENTAL: kotlin.contracts.ExperimentalContracts +// !DIAGNOSTICS: -INVISIBLE_REFERENCE -INVISIBLE_MEMBER + +import kotlin.contracts.* + +inline fun referToReifiedGeneric(x: Any?) { + contract { + returns() implies (x is T) + } +} + +class Generic { + fun referToCaptured(x: Any?) { + contract { + returns() implies (x is T) + } + } +} + +fun referToSubstituted(x: Any?) { + contract { + returns() implies (x is Generic) + } +} + +fun referToSubstitutedWithStar(x: Any?) { + contract { + returns() implies (x is Generic<*>) + } +} + +typealias GenericString = Generic +typealias FunctionalType = () -> Unit +typealias SimpleType = Int + +fun referToAliasedGeneric(x: Any?) { + contract { + returns() implies (x is GenericString) + } +} + +fun referToAliasedFunctionType(x: Any?) { + contract { + returns() implies (x is FunctionalType) + } +} + +fun referToAliasedSimpleType(x: Any?) { + contract { + returns() implies (x is SimpleType) + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.txt b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.txt new file mode 100644 index 00000000000..474d13b27de --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.txt @@ -0,0 +1,32 @@ +package + +public fun referToAliasedFunctionType(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is Function0 + +public fun referToAliasedGeneric(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is Generic + +public fun referToAliasedSimpleType(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is Int + +public inline fun referToReifiedGeneric(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is T + +public fun referToSubstituted(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is Generic + +public fun referToSubstitutedWithStar(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is Generic<*> + +public final class Generic { + public constructor Generic() + 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 final fun referToCaptured(/*0*/ x: kotlin.Any?): kotlin.Unit + Returns(WILDCARD) -> x is T + + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String +} +public typealias FunctionalType = () -> kotlin.Unit +public typealias GenericString = Generic +public typealias SimpleType = kotlin.Int diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java index 7645adebff0..f3a879db661 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/DiagnosticsTestWithStdLibGenerated.java @@ -1134,11 +1134,36 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/callInContractDescription.kt"); } + @TestMetadata("emptyContract.kt") + public void testEmptyContract() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.kt"); + } + + @TestMetadata("illegalCallSites.kt") + public void testIllegalCallSites() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.kt"); + } + + @TestMetadata("illegalConstructionInContractBlock.kt") + public void testIllegalConstructionInContractBlock() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.kt"); + } + + @TestMetadata("illegalEqualsCondition.kt") + public void testIllegalEqualsCondition() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.kt"); + } + @TestMetadata("nestedConditionalEffects.kt") public void testNestedConditionalEffects() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nestedConditionalEffects.kt"); } + @TestMetadata("nonLambdaLiteralAsArgument.kt") + public void testNonLambdaLiteralAsArgument() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.kt"); + } + @TestMetadata("notFirstStatement.kt") public void testNotFirstStatement() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/notFirstStatement.kt"); @@ -1149,6 +1174,11 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/referenceToProperty.kt"); } + @TestMetadata("typeReferences.kt") + public void testTypeReferences() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.kt"); + } + @TestMetadata("unlabeledReceiver.kt") public void testUnlabeledReceiver() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/unlabeledReceiver.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java index 7caefffaa29..8985af4b296 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java @@ -1134,11 +1134,36 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/callInContractDescription.kt"); } + @TestMetadata("emptyContract.kt") + public void testEmptyContract() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/emptyContract.kt"); + } + + @TestMetadata("illegalCallSites.kt") + public void testIllegalCallSites() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalCallSites.kt"); + } + + @TestMetadata("illegalConstructionInContractBlock.kt") + public void testIllegalConstructionInContractBlock() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalConstructionInContractBlock.kt"); + } + + @TestMetadata("illegalEqualsCondition.kt") + public void testIllegalEqualsCondition() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/illegalEqualsCondition.kt"); + } + @TestMetadata("nestedConditionalEffects.kt") public void testNestedConditionalEffects() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nestedConditionalEffects.kt"); } + @TestMetadata("nonLambdaLiteralAsArgument.kt") + public void testNonLambdaLiteralAsArgument() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/nonLambdaLiteralAsArgument.kt"); + } + @TestMetadata("notFirstStatement.kt") public void testNotFirstStatement() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/notFirstStatement.kt"); @@ -1149,6 +1174,11 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/referenceToProperty.kt"); } + @TestMetadata("typeReferences.kt") + public void testTypeReferences() throws Exception { + runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/typeReferences.kt"); + } + @TestMetadata("unlabeledReceiver.kt") public void testUnlabeledReceiver() throws Exception { runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/dsl/errors/unlabeledReceiver.kt");