[FIR] Put new contract syntax under feauture flag
^KT-55171 Fixed
This commit is contained in:
committed by
Space Team
parent
2783aa13f5
commit
4c96495eef
+6
@@ -1385,6 +1385,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/contractFromOtherModule_samePackage.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("disabledFeature.kt")
|
||||
public void testDisabledFeature() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/disabledFeature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericContract.kt")
|
||||
public void testGenericContract() throws Exception {
|
||||
|
||||
+5
@@ -1208,6 +1208,11 @@ public class LazyBodyIsNotTouchedTilContractsPhaseTestGenerated extends Abstract
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/contractFromOtherModule_samePackage.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("disabledFeature.kt")
|
||||
public void testDisabledFeature() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/disabledFeature.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("genericContract.kt")
|
||||
public void testGenericContract() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/genericContract.kt");
|
||||
|
||||
+1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
// SKIP_JAVAC
|
||||
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
|
||||
// because it fails to parse module structure of multimodule test
|
||||
|
||||
Vendored
+1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
// SKIP_JAVAC
|
||||
// This directive is needed to skip this test in LazyBodyIsNotTouchedTilContractsPhaseTestGenerated,
|
||||
// because it fails to parse module structure of multimodule test
|
||||
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
FILE: disabledFeature.kt
|
||||
public final inline fun <reified T> requreIsInstance(value: R|kotlin/Any|): R|kotlin/Unit|
|
||||
[R|Contract description]
|
||||
<
|
||||
Returns(WILDCARD) -> value is T
|
||||
>
|
||||
{
|
||||
when () {
|
||||
(R|<local>/value| !is R|T|) -> {
|
||||
throw R|java/lang/IllegalArgumentException.IllegalArgumentException|()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public final val R|kotlin/Any?|.myLength: R|kotlin/Int?|
|
||||
public get(): R|kotlin/Int?|
|
||||
[R|Contract description]
|
||||
<
|
||||
>
|
||||
{
|
||||
^ (this@R|/myLength| as? R|kotlin/String|)?.{ $subj$.R|kotlin/String.length| }
|
||||
}
|
||||
public final fun test_1(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
R|/requreIsInstance|<R|kotlin/String|>(R|<local>/x|)
|
||||
R|<local>/x|.R|kotlin/String.length|
|
||||
}
|
||||
public final fun test_2(x: R|kotlin/Any|): R|kotlin/Unit| {
|
||||
when () {
|
||||
!=(R|<local>/x|.R|/myLength|, Null(null)) -> {
|
||||
R|<local>/x|.<Unresolved name: length>#
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// LANGUAGE: -ContractSyntaxV2
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
inline fun <reified T> requreIsInstance(value: Any) contract <!UNSUPPORTED_FEATURE!>[
|
||||
returns() implies (value is T)
|
||||
]<!> {
|
||||
if (value !is T) throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
val Any?.myLength: Int?
|
||||
get() contract <!UNSUPPORTED_FEATURE!>[
|
||||
<!ERROR_IN_CONTRACT_DESCRIPTION!>returnsNotNull() implies (this@length is String)<!>
|
||||
]<!> = (this as? String)?.length
|
||||
|
||||
fun test_1(x: Any) {
|
||||
requreIsInstance<String>(x)
|
||||
x.length
|
||||
}
|
||||
|
||||
fun test_2(x: Any) {
|
||||
if (x.myLength != null) {
|
||||
x.<!UNRESOLVED_REFERENCE!>length<!>
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
// WITH_STDLIB
|
||||
|
||||
import kotlin.contracts.*
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun test1(arg: Any?) contract [
|
||||
@@ -19,4 +20,4 @@ fun test3(arg: Any?): Boolean contract [
|
||||
] {
|
||||
require(arg != null)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
+6
@@ -1385,6 +1385,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/contractFromOtherModule_samePackage.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("disabledFeature.kt")
|
||||
public void testDisabledFeature() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/disabledFeature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericContract.kt")
|
||||
public void testGenericContract() throws Exception {
|
||||
|
||||
+6
@@ -1385,6 +1385,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/contractFromOtherModule_samePackage.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("disabledFeature.kt")
|
||||
public void testDisabledFeature() throws Exception {
|
||||
runTest("compiler/fir/analysis-tests/testData/resolve/contracts/disabledFeature.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("genericContract.kt")
|
||||
public void testGenericContract() throws Exception {
|
||||
|
||||
+2
@@ -56,6 +56,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirTailrecFunctionChecker,
|
||||
FirMemberFunctionsChecker,
|
||||
FirDataObjectContentChecker,
|
||||
ContractSyntaxV2FunctionChecker,
|
||||
)
|
||||
|
||||
override val propertyCheckers: Set<FirPropertyChecker>
|
||||
@@ -73,6 +74,7 @@ object CommonDeclarationCheckers : DeclarationCheckers() {
|
||||
FirDelegateUsesExtensionPropertyTypeParameterChecker,
|
||||
FirTopLevelPropertiesChecker,
|
||||
FirLocalExtensionPropertyChecker,
|
||||
ContractSyntaxV2PropertyChecker,
|
||||
)
|
||||
|
||||
override val backingFieldCheckers: Set<FirBackingFieldChecker>
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.fir.analysis.checkers.declaration
|
||||
|
||||
import org.jetbrains.kotlin.KtNodeTypes
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
|
||||
import org.jetbrains.kotlin.diagnostics.reportOn
|
||||
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
|
||||
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors
|
||||
import org.jetbrains.kotlin.fir.declarations.FirContractDescriptionOwner
|
||||
import org.jetbrains.kotlin.fir.declarations.FirProperty
|
||||
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
||||
|
||||
object ContractSyntaxV2FunctionChecker : FirSimpleFunctionChecker() {
|
||||
override fun check(declaration: FirSimpleFunction, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
checkFeatureIsEnabled(declaration, context, reporter)
|
||||
}
|
||||
}
|
||||
|
||||
object ContractSyntaxV2PropertyChecker : FirPropertyChecker() {
|
||||
override fun check(declaration: FirProperty, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
declaration.getter?.let { checkFeatureIsEnabled(it, context, reporter) }
|
||||
declaration.setter?.let { checkFeatureIsEnabled(it, context, reporter) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkFeatureIsEnabled(declaration: FirContractDescriptionOwner, context: CheckerContext, reporter: DiagnosticReporter) {
|
||||
val source = declaration.contractDescription.source ?: return
|
||||
if (source.elementType != KtNodeTypes.CONTRACT_EFFECT_LIST) return
|
||||
val languageVersionSettings = context.languageVersionSettings
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.ContractSyntaxV2)) {
|
||||
reporter.reportOn(source, FirErrors.UNSUPPORTED_FEATURE, LanguageFeature.ContractSyntaxV2 to languageVersionSettings, context)
|
||||
}
|
||||
}
|
||||
+1
@@ -245,6 +245,7 @@ abstract class FirAbstractContractResolveTransformerDispatcher(
|
||||
|
||||
val legacyRawContractDescription = buildLegacyRawContractDescription {
|
||||
this.contractCall = contractCall
|
||||
this.source = contractDescription.source
|
||||
}
|
||||
|
||||
owner.replaceContractDescription(legacyRawContractDescription)
|
||||
|
||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
import kotlin.contracts.*
|
||||
@@ -21,4 +22,4 @@ fun bar(arg: Any?, block: () -> Int): Boolean contract [
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
|
||||
import kotlin.contracts.*
|
||||
@@ -21,4 +22,4 @@ fun bar(arg: Any?, block: () -> Int): Boolean contract <!UNSUPPORTED!>[
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
+3
-2
@@ -1,10 +1,11 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
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 [
|
||||
fun <R> calculateResult(num: Int?, calculate: (Int?) -> R): R contract <!WRONG_IMPLIES_CONDITION!>[
|
||||
callsInPlace(calculate, InvocationKind.EXACTLY_ONCE),
|
||||
returns() implies (num != null)
|
||||
] = calculate(num)
|
||||
]<!> = calculate(num)
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun calculateNumber(block: () -> Int): Int contract <!UNSUPPORTED!>[
|
||||
@@ -7,4 +8,4 @@ fun calculateNumber(block: () -> Int): Int contract <!UNSUPPORTED!>[
|
||||
fun <R> calculateResult(num: Int?, calculate: (Int?) -> R): R contract <!UNSUPPORTED!>[
|
||||
callsInPlace(calculate, InvocationKind.EXACTLY_ONCE),
|
||||
returns() implies (num != null)
|
||||
]<!> = calculate(num)
|
||||
]<!> = calculate(num)
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
class A {
|
||||
@@ -15,4 +16,4 @@ class A {
|
||||
|
||||
fun f(arg: Int) = arg * arg
|
||||
fun g(arg: Double) = arg / 2
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
class A {
|
||||
@@ -15,4 +16,4 @@ class A {
|
||||
|
||||
fun f(arg: Int) = arg * arg
|
||||
fun g(arg: Double) = arg / 2
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun printStr(str: String?) contract [
|
||||
@@ -19,4 +20,4 @@ fun calculateNumber(block: () -> Int): Int contract [
|
||||
] {
|
||||
val num = block()
|
||||
return num
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -1,3 +1,4 @@
|
||||
// LANGUAGE: +ContractSyntaxV2
|
||||
import kotlin.contracts.*
|
||||
|
||||
fun printStr(str: String?) contract <!UNSUPPORTED!>[
|
||||
@@ -19,4 +20,4 @@ fun calculateNumber(block: () -> Int): Int contract <!UNSUPPORTED!>[
|
||||
]<!> {
|
||||
val num = block()
|
||||
return num
|
||||
}
|
||||
}
|
||||
|
||||
@@ -325,6 +325,7 @@ enum class LanguageFeature(
|
||||
CustomEqualsInValueClasses(sinceVersion = null, kind = OTHER), // KT-24874
|
||||
InlineLateinit(sinceVersion = null, kind = OTHER), // KT-23814
|
||||
EnableDfaWarningsInK2(sinceVersion = null, kind = OTHER), // KT-50965
|
||||
ContractSyntaxV2(sinceVersion = null, kind = UNSTABLE_FEATURE), // KT-56127
|
||||
;
|
||||
|
||||
init {
|
||||
|
||||
Reference in New Issue
Block a user