Diagnostics: add diagnostic for reporting contract description blocks in old frontend
This commit is contained in:
+33
@@ -1370,6 +1370,39 @@ public class FirOldFrontendDiagnosticsTestWithStdlibGenerated extends AbstractFi
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NewSyntax extends AbstractFirOldFrontendDiagnosticsTestWithStdlib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNewSyntax() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("complexContractDescription.kt")
|
||||
public void testComplexContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/complexContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onelineFunctionsContractDescription.kt")
|
||||
public void testOnelineFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/onelineFunctionsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorsContractDescription.kt")
|
||||
public void testPropertyAccessorsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/propertyAccessorsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleFunctionsContractDescription.kt")
|
||||
public void testSimpleFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/simpleFunctionsContractDescription.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -37,7 +37,8 @@ private val DEFAULT_DECLARATION_CHECKERS = listOf(
|
||||
TrailingCommaDeclarationChecker,
|
||||
MissingDependencySupertypeChecker.ForDeclarations,
|
||||
FunInterfaceDeclarationChecker(),
|
||||
DeprecatedSinceKotlinAnnotationChecker
|
||||
DeprecatedSinceKotlinAnnotationChecker,
|
||||
ContractDescriptionBlockChecker
|
||||
)
|
||||
|
||||
private val DEFAULT_CALL_CHECKERS = listOf(
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2020 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.resolve.checkers
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtPropertyAccessor
|
||||
|
||||
object ContractDescriptionBlockChecker: DeclarationChecker {
|
||||
override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {
|
||||
val contractDescription = when (declaration) {
|
||||
is KtNamedFunction -> declaration.contractDescription
|
||||
is KtPropertyAccessor -> declaration.contractDescription
|
||||
else -> null
|
||||
}
|
||||
if (contractDescription != null) {
|
||||
context.trace.report(Errors.UNSUPPORTED.on(contractDescription, "Contract description blocks are not supported"))
|
||||
}
|
||||
}
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun foo(arg: Any?, num: Int?, block: () -> Unit) contract [
|
||||
returns() implies (arg is String),
|
||||
returns() implies (num != null),
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
] {
|
||||
require(arg is String)
|
||||
require(num != null)
|
||||
block()
|
||||
}
|
||||
|
||||
fun bar(arg: Any?, block: () -> Int): Boolean contract [
|
||||
returns(true) implies (arg != null),
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
] {
|
||||
val num = block()
|
||||
if (arg != null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun foo(arg: Any?, num: Int?, block: () -> Unit) contract <!UNSUPPORTED!>[
|
||||
returns() implies (arg is String),
|
||||
returns() implies (num != null),
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
]<!> {
|
||||
require(arg is String)
|
||||
require(num != null)
|
||||
block()
|
||||
}
|
||||
|
||||
fun bar(arg: Any?, block: () -> Int): Boolean contract <!UNSUPPORTED!>[
|
||||
returns(true) implies (arg != null),
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
]<!> {
|
||||
val num = block()
|
||||
if (arg != null) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public fun bar(/*0*/ arg: kotlin.Any?, /*1*/ block: () -> kotlin.Int): kotlin.Boolean
|
||||
public fun foo(/*0*/ arg: kotlin.Any?, /*1*/ num: kotlin.Int?, /*2*/ block: () -> kotlin.Unit): kotlin.Unit
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun calculateNumber(block: () -> Int): Int contract [
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
] = block()
|
||||
|
||||
fun <R> calculateResult(num: Int?, calculate: (Int?) -> R): R contract [
|
||||
callsInPlace(calculate, InvocationKind.EXACTLY_ONCE),
|
||||
returns() implies (num != null)
|
||||
] = calculate(num)
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun calculateNumber(block: () -> Int): Int contract <!UNSUPPORTED!>[
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
]<!> = block()
|
||||
|
||||
fun <R> calculateResult(num: Int?, calculate: (Int?) -> R): R contract <!UNSUPPORTED!>[
|
||||
callsInPlace(calculate, InvocationKind.EXACTLY_ONCE),
|
||||
returns() implies (num != null)
|
||||
]<!> = calculate(num)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
package
|
||||
|
||||
public fun calculateNumber(/*0*/ block: () -> kotlin.Int): kotlin.Int
|
||||
public fun </*0*/ R> calculateResult(/*0*/ num: kotlin.Int?, /*1*/ calculate: (kotlin.Int?) -> R): R
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
class A {
|
||||
var x: Int = 0
|
||||
get() = f(x)
|
||||
set(value) contract [returns() implies (value != null)] {
|
||||
field = value + 1
|
||||
}
|
||||
|
||||
var y: Double = 0.0
|
||||
get() = g(y)
|
||||
set(value) contract [returns() implies (value != null)] {
|
||||
field = value * 2
|
||||
}
|
||||
|
||||
fun f(arg: Int) = arg * arg
|
||||
fun g(arg: Double) = arg / 2
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
class A {
|
||||
var x: Int = 0
|
||||
get() = f(x)
|
||||
set(value) contract <!UNSUPPORTED!>[returns() implies (value != null)]<!> {
|
||||
field = value + 1
|
||||
}
|
||||
|
||||
var y: Double = 0.0
|
||||
get() = g(y)
|
||||
set(value) contract <!UNSUPPORTED!>[returns() implies (value != null)]<!> {
|
||||
field = value * 2
|
||||
}
|
||||
|
||||
fun f(arg: Int) = arg * arg
|
||||
fun g(arg: Double) = arg / 2
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
package
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
public final var x: kotlin.Int
|
||||
public final var y: kotlin.Double
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public final fun f(/*0*/ arg: kotlin.Int): kotlin.Int
|
||||
public final fun g(/*0*/ arg: kotlin.Double): kotlin.Double
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun printStr(str: String?) contract [
|
||||
returns() implies (str != null)
|
||||
] {
|
||||
require(str != null)
|
||||
println(str)
|
||||
}
|
||||
|
||||
fun callExactlyOnce(block: () -> Int) contract [
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
] {
|
||||
val num = block()
|
||||
println(num)
|
||||
}
|
||||
|
||||
fun calculateNumber(block: () -> Int): Int contract [
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
] {
|
||||
val num = block()
|
||||
return num
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun printStr(str: String?) contract <!UNSUPPORTED!>[
|
||||
returns() implies (str != null)
|
||||
]<!> {
|
||||
require(str != null)
|
||||
println(str)
|
||||
}
|
||||
|
||||
fun callExactlyOnce(block: () -> Int) contract <!UNSUPPORTED!>[
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
]<!> {
|
||||
val num = block()
|
||||
println(num)
|
||||
}
|
||||
|
||||
fun calculateNumber(block: () -> Int): Int contract <!UNSUPPORTED!>[
|
||||
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
|
||||
]<!> {
|
||||
val num = block()
|
||||
return num
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package
|
||||
|
||||
public fun calculateNumber(/*0*/ block: () -> kotlin.Int): kotlin.Int
|
||||
public fun callExactlyOnce(/*0*/ block: () -> kotlin.Int): kotlin.Unit
|
||||
public fun printStr(/*0*/ str: kotlin.String?): kotlin.Unit
|
||||
+33
@@ -1370,6 +1370,39 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NewSyntax extends AbstractDiagnosticsTestWithStdLib {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNewSyntax() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("complexContractDescription.kt")
|
||||
public void testComplexContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/complexContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onelineFunctionsContractDescription.kt")
|
||||
public void testOnelineFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/onelineFunctionsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorsContractDescription.kt")
|
||||
public void testPropertyAccessorsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/propertyAccessorsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleFunctionsContractDescription.kt")
|
||||
public void testSimpleFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/simpleFunctionsContractDescription.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
compiler/tests/org/jetbrains/kotlin/checkers/javac/DiagnosticsTestWithStdLibUsingJavacGenerated.java
Generated
+33
@@ -1370,6 +1370,39 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class NewSyntax extends AbstractDiagnosticsTestWithStdLibUsingJavac {
|
||||
private void runTest(String testDataFilePath) throws Exception {
|
||||
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
|
||||
}
|
||||
|
||||
public void testAllFilesPresentInNewSyntax() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("complexContractDescription.kt")
|
||||
public void testComplexContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/complexContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onelineFunctionsContractDescription.kt")
|
||||
public void testOnelineFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/onelineFunctionsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("propertyAccessorsContractDescription.kt")
|
||||
public void testPropertyAccessorsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/propertyAccessorsContractDescription.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("simpleFunctionsContractDescription.kt")
|
||||
public void testSimpleFunctionsContractDescription() throws Exception {
|
||||
runTest("compiler/testData/diagnostics/testsWithStdLib/contracts/newSyntax/simpleFunctionsContractDescription.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/testsWithStdLib/contracts/smartcasts")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user