1/2 analysis-api: Initial implementation for contracts

Review: https://jetbrains.team/p/kt/reviews/7652

I need this API for KTIJ-22692
This commit is contained in:
Nikita Bobko
2022-11-04 20:40:14 +01:00
parent 6e637e94ca
commit b2397f033b
70 changed files with 2610 additions and 4 deletions
@@ -0,0 +1,109 @@
/*
* Copyright 2010-2022 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.analysis.api.descriptors.contracts
import org.jetbrains.kotlin.analysis.api.contracts.description.*
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractConstantValue.KtContractConstantType
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractReturnsContractEffectDeclaration.*
import org.jetbrains.kotlin.analysis.api.contracts.description.booleans.*
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtSymbol
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtType
import org.jetbrains.kotlin.analysis.api.symbols.KtParameterSymbol
import org.jetbrains.kotlin.contracts.description.*
import org.jetbrains.kotlin.contracts.description.expressions.*
internal fun EffectDeclaration.effectDeclarationToAnalysisApi(analysisContext: Fe10AnalysisContext): KtContractEffectDeclaration =
accept(ContractDescriptionElementToAnalysisApi(analysisContext), Unit) as KtContractEffectDeclaration
private class ContractDescriptionElementToAnalysisApi(val analysisContext: Fe10AnalysisContext) :
ContractDescriptionVisitor<Any, Unit> {
override fun visitConditionalEffectDeclaration(
conditionalEffect: ConditionalEffectDeclaration,
data: Unit
): Any = KtContractConditionalContractEffectDeclaration(
conditionalEffect.effect.accept(),
conditionalEffect.condition.accept(),
)
override fun visitReturnsEffectDeclaration(
returnsEffect: ReturnsEffectDeclaration,
data: Unit
): KtContractReturnsContractEffectDeclaration =
when (val value = returnsEffect.value) {
ConstantReference.NULL ->
KtContractReturnsSpecificValueEffectDeclaration(KtContractConstantValue(KtContractConstantType.NULL, analysisContext.token))
ConstantReference.NOT_NULL -> KtContractReturnsNotNullEffectDeclaration(analysisContext.token)
ConstantReference.WILDCARD -> KtContractReturnsSuccessfullyEffectDeclaration(analysisContext.token)
is BooleanConstantReference -> KtContractReturnsSpecificValueEffectDeclaration(
KtContractConstantValue(
when (value) {
BooleanConstantReference.TRUE -> KtContractConstantType.TRUE
BooleanConstantReference.FALSE -> KtContractConstantType.FALSE
else -> error("Can't convert $value to the Analysis API")
},
analysisContext.token
)
)
else -> error("Can't convert $returnsEffect to the Analysis API")
}
override fun visitCallsEffectDeclaration(callsEffect: CallsEffectDeclaration, data: Unit): Any =
KtContractCallsInPlaceContractEffectDeclaration(callsEffect.variableReference.accept(), callsEffect.kind)
override fun visitLogicalOr(logicalOr: LogicalOr, data: Unit): Any = KtContractBinaryLogicExpression(
logicalOr.left.accept(),
logicalOr.right.accept(),
KtContractBinaryLogicExpression.KtLogicOperation.OR
)
override fun visitLogicalAnd(logicalAnd: LogicalAnd, data: Unit): Any = KtContractBinaryLogicExpression(
logicalAnd.left.accept(),
logicalAnd.right.accept(),
KtContractBinaryLogicExpression.KtLogicOperation.AND
)
override fun visitLogicalNot(logicalNot: LogicalNot, data: Unit): Any =
KtContractLogicalNotExpression(logicalNot.arg.accept())
override fun visitIsInstancePredicate(isInstancePredicate: IsInstancePredicate, data: Unit): Any =
KtContractIsInstancePredicateExpression(
isInstancePredicate.arg.accept(),
isInstancePredicate.type.toKtType(analysisContext),
isInstancePredicate.isNegated
)
override fun visitIsNullPredicate(isNullPredicate: IsNullPredicate, data: Unit): Any =
KtContractIsNullPredicateExpression(isNullPredicate.arg.accept(), isNullPredicate.isNegated)
override fun visitBooleanConstantDescriptor(
booleanConstantDescriptor: BooleanConstantReference,
data: Unit
): KtContractBooleanConstantExpression =
when (booleanConstantDescriptor) {
BooleanConstantReference.TRUE -> KtContractBooleanConstantExpression(true, analysisContext.token)
BooleanConstantReference.FALSE -> KtContractBooleanConstantExpression(false, analysisContext.token)
else -> error("Can't convert $booleanConstantDescriptor to Analysis API")
}
override fun visitVariableReference(variableReference: VariableReference, data: Unit): Any =
visitVariableReference(variableReference, ::KtContractParameterValue)
override fun visitBooleanVariableReference(
booleanVariableReference: BooleanVariableReference,
data: Unit
): Any = visitVariableReference(booleanVariableReference, ::KtContractBooleanValueParameterExpression)
private fun <T> visitVariableReference(
variableReference: VariableReference,
constructor: (KtParameterSymbol) -> T
): T = constructor(variableReference.descriptor.toKtSymbol(analysisContext) as KtParameterSymbol)
// Util function to avoid hard coding names of the classes. Type inference will do a better job figuring out the best type to cast to.
// This visitor isn't type-safe anyway
private inline fun <reified T> ContractDescriptionElement.accept() = accept(this@ContractDescriptionElementToAnalysisApi, Unit) as T
}
@@ -7,12 +7,15 @@ package org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.contracts.effectDeclarationToAnalysisApi
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.calculateHashCode
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.isEqualTo
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10DescFunctionLikeSymbolPointer
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.util.kotlinFunctionInvokeCallableIds
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtFunctionSymbol
@@ -23,6 +26,7 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.name.CallableId
@@ -38,6 +42,12 @@ internal class KtFe10DescFunctionSymbol private constructor(
override val name: Name
get() = withValidityAssertion { descriptor.name }
override val contractEffects: List<KtContractEffectDeclaration> by cached {
descriptor.getUserData(ContractProviderKey)?.getContractDescription()?.effects
?.map { it.effectDeclarationToAnalysisApi(analysisContext) }
.orEmpty()
}
override val symbolKind: KtSymbolKind
get() = withValidityAssertion { descriptor.ktSymbolKind }
@@ -112,4 +122,4 @@ internal class KtFe10DescFunctionSymbol private constructor(
return KtFe10DescFunctionSymbol(descriptor, analysisContext)
}
}
}
}
@@ -7,13 +7,16 @@ package org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisFacade.AnalysisMode
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.calculateHashCode
import org.jetbrains.kotlin.analysis.api.descriptors.contracts.effectDeclarationToAnalysisApi
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.isEqualTo
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.pointers.KtFe10NeverRestoringSymbolPointer
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.psiBased.base.*
import org.jetbrains.kotlin.analysis.api.descriptors.utils.ValidityAwareCachedValue
import org.jetbrains.kotlin.analysis.api.descriptors.utils.cached
import org.jetbrains.kotlin.analysis.api.impl.base.util.kotlinFunctionInvokeCallableIds
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
@@ -25,6 +28,8 @@ import org.jetbrains.kotlin.analysis.api.symbols.markers.KtSymbolKind
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.analysis.api.types.KtType
import org.jetbrains.kotlin.contracts.description.ContractProviderKey
import org.jetbrains.kotlin.contracts.description.EffectDeclaration
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -35,6 +40,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtNamedFunction
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
import org.jetbrains.kotlin.resolve.BindingContext
import kotlin.reflect.KProperty
internal class KtFe10PsiFunctionSymbol(
override val psi: KtNamedFunction,
@@ -45,6 +51,12 @@ internal class KtFe10PsiFunctionSymbol(
bindingContext[BindingContext.FUNCTION, psi]
}
override val contractEffects: List<KtContractEffectDeclaration> by cached {
descriptor?.getUserData(ContractProviderKey)?.getContractDescription()?.effects
?.map { it.effectDeclarationToAnalysisApi(analysisContext) }
.orEmpty()
}
override val isSuspend: Boolean
get() = withValidityAssertion { psi.hasModifier(KtTokens.SUSPEND_KEYWORD) }
@@ -9,11 +9,11 @@ import org.jetbrains.kotlin.analysis.api.KtTypeProjection
import org.jetbrains.kotlin.analysis.api.descriptors.Fe10AnalysisContext
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.ktNullability
import org.jetbrains.kotlin.analysis.api.descriptors.symbols.descriptorBased.base.toKtTypeProjection
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.KtFe10Type
import org.jetbrains.kotlin.analysis.api.descriptors.types.base.asStringForDebugging
import org.jetbrains.kotlin.analysis.api.types.KtCapturedType
import org.jetbrains.kotlin.analysis.api.types.KtTypeNullability
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.resolve.calls.inference.CapturedType
internal class KtFe10CapturedType(
@@ -94,6 +94,118 @@ public class Fe10IdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/setterWithAnnotations.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts")
@TestDataPath("$PROJECT_ROOT")
public class Contracts {
@Test
public void testAllFilesPresentInContracts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("booleanConstReferenceInImplies.kt")
public void testBooleanConstReferenceInImplies() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanConstReferenceInImplies.kt");
}
@Test
@TestMetadata("booleanExprContract.kt")
public void testBooleanExprContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanExprContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtLeastOnceContract.kt")
public void testCallsInPlaceAtLeastOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtLeastOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtMostOnceContract.kt")
public void testCallsInPlaceAtMostOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtMostOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceExactlyOnceContract.kt")
public void testCallsInPlaceExactlyOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceExactlyOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceUnknownContract.kt")
public void testCallsInPlaceUnknownContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceUnknownContract.kt");
}
@Test
@TestMetadata("invalidContractParameterPassedToReturns.kt")
public void testInvalidContractParameterPassedToReturns() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/invalidContractParameterPassedToReturns.kt");
}
@Test
@TestMetadata("isInstancePredicateContract.kt")
public void testIsInstancePredicateContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/isInstancePredicateContract.kt");
}
@Test
@TestMetadata("logicalNotContract.kt")
public void testLogicalNotContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/logicalNotContract.kt");
}
@Test
@TestMetadata("referenceBooleanReceiverInContract.kt")
public void testReferenceBooleanReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceBooleanReceiverInContract.kt");
}
@Test
@TestMetadata("referenceReceiverInContract.kt")
public void testReferenceReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceReceiverInContract.kt");
}
@Test
@TestMetadata("returnsContract.kt")
public void testReturnsContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsContract.kt");
}
@Test
@TestMetadata("returnsFalseContract.kt")
public void testReturnsFalseContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsFalseContract.kt");
}
@Test
@TestMetadata("returnsNotNullContract.kt")
public void testReturnsNotNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNotNullContract.kt");
}
@Test
@TestMetadata("returnsNullContract.kt")
public void testReturnsNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNullContract.kt");
}
@Test
@TestMetadata("returnsTrueContract.kt")
public void testReturnsTrueContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsTrueContract.kt");
}
@Test
@TestMetadata("twoContracts.kt")
public void testTwoContracts() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/twoContracts.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
@TestDataPath("$PROJECT_ROOT")
@@ -0,0 +1,124 @@
/*
* Copyright 2010-2022 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.analysis.api.fir.contracts
import org.jetbrains.kotlin.analysis.api.contracts.description.*
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractConstantValue.KtContractConstantType
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractReturnsContractEffectDeclaration.*
import org.jetbrains.kotlin.analysis.api.contracts.description.booleans.*
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.symbols.KtFirFunctionSymbol
import org.jetbrains.kotlin.analysis.api.symbols.KtParameterSymbol
import org.jetbrains.kotlin.fir.contracts.description.*
import org.jetbrains.kotlin.fir.expressions.LogicOperationKind
internal fun ConeEffectDeclaration.coneEffectDeclarationToAnalysisApi(
builder: KtSymbolByFirBuilder,
firFunctionSymbol: KtFirFunctionSymbol
): KtContractEffectDeclaration =
accept(ConeContractDescriptionElementToAnalysisApi(builder, firFunctionSymbol), Unit) as KtContractEffectDeclaration
private class ConeContractDescriptionElementToAnalysisApi(
private val builder: KtSymbolByFirBuilder,
private val firFunctionSymbol: KtFirFunctionSymbol
) : ConeContractDescriptionVisitor<Any, Unit>() {
override fun visitConditionalEffectDeclaration(
conditionalEffect: ConeConditionalEffectDeclaration,
data: Unit
): KtContractConditionalContractEffectDeclaration = KtContractConditionalContractEffectDeclaration(
conditionalEffect.effect.accept(),
conditionalEffect.condition.accept()
)
override fun visitReturnsEffectDeclaration(
returnsEffect: ConeReturnsEffectDeclaration,
data: Unit
): KtContractReturnsContractEffectDeclaration =
when (val value = returnsEffect.value) {
ConeConstantReference.NULL ->
KtContractReturnsSpecificValueEffectDeclaration(KtContractConstantValue(KtContractConstantType.NULL, builder.token))
ConeConstantReference.NOT_NULL -> KtContractReturnsNotNullEffectDeclaration(builder.token)
ConeConstantReference.WILDCARD -> KtContractReturnsSuccessfullyEffectDeclaration(builder.token)
is ConeBooleanConstantReference -> KtContractReturnsSpecificValueEffectDeclaration(
KtContractConstantValue(
when (value) {
ConeBooleanConstantReference.TRUE -> KtContractConstantType.TRUE
ConeBooleanConstantReference.FALSE -> KtContractConstantType.FALSE
else -> error("Can't convert $value to the Analysis API")
},
builder.token
)
)
else -> error("Can't convert $returnsEffect to the Analysis API")
}
override fun visitCallsEffectDeclaration(callsEffect: ConeCallsEffectDeclaration, data: Unit): KtContractCallsInPlaceContractEffectDeclaration =
KtContractCallsInPlaceContractEffectDeclaration(
callsEffect.valueParameterReference.accept(),
callsEffect.kind
)
override fun visitLogicalBinaryOperationContractExpression(
binaryLogicExpression: ConeBinaryLogicExpression,
data: Unit
): KtContractBinaryLogicExpression = KtContractBinaryLogicExpression(
binaryLogicExpression.left.accept(),
binaryLogicExpression.right.accept(),
when (binaryLogicExpression.kind) {
LogicOperationKind.AND -> KtContractBinaryLogicExpression.KtLogicOperation.AND
LogicOperationKind.OR -> KtContractBinaryLogicExpression.KtLogicOperation.OR
}
)
override fun visitLogicalNot(logicalNot: ConeLogicalNot, data: Unit): KtContractLogicalNotExpression =
KtContractLogicalNotExpression(logicalNot.arg.accept())
override fun visitIsInstancePredicate(isInstancePredicate: ConeIsInstancePredicate, data: Unit): KtContractIsInstancePredicateExpression =
KtContractIsInstancePredicateExpression(
isInstancePredicate.arg.accept(),
builder.typeBuilder.buildKtType(isInstancePredicate.type),
isInstancePredicate.isNegated
)
override fun visitIsNullPredicate(isNullPredicate: ConeIsNullPredicate, data: Unit): KtContractIsNullPredicateExpression =
KtContractIsNullPredicateExpression(isNullPredicate.arg.accept(), isNullPredicate.isNegated)
override fun visitBooleanConstantDescriptor(
booleanConstantDescriptor: ConeBooleanConstantReference,
data: Unit
): KtContractBooleanConstantExpression =
when (booleanConstantDescriptor) {
ConeBooleanConstantReference.TRUE -> KtContractBooleanConstantExpression(true, builder.token)
ConeBooleanConstantReference.FALSE -> KtContractBooleanConstantExpression(false, builder.token)
else -> error("Can't convert $booleanConstantDescriptor to Analysis API")
}
override fun visitValueParameterReference(
valueParameterReference: ConeValueParameterReference,
data: Unit
): Any = visitValueParameterReference(valueParameterReference, ::KtContractParameterValue)
override fun visitBooleanValueParameterReference(
booleanValueParameterReference: ConeBooleanValueParameterReference,
data: Unit
): Any =
visitValueParameterReference(booleanValueParameterReference, ::KtContractBooleanValueParameterExpression)
private fun <T> visitValueParameterReference(
valueParameterReference: ConeValueParameterReference,
constructor: (KtParameterSymbol) -> T
): T = constructor(
if (valueParameterReference.parameterIndex == -1) firFunctionSymbol.receiverParameter
?: error("$firFunctionSymbol should contain a receiver")
else firFunctionSymbol.valueParameters[valueParameterReference.parameterIndex]
)
// Util function to avoid hard coding names of the classes. Type inference will do a better job figuring out the best type to cast to.
// This visitor isn't type-safe anyway
private inline fun <reified T> ConeContractDescriptionElement.accept() =
accept(this@ConeContractDescriptionElementToAnalysisApi, Unit) as T
}
@@ -8,8 +8,10 @@ package org.jetbrains.kotlin.analysis.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.fir.KtSymbolByFirBuilder
import org.jetbrains.kotlin.analysis.api.fir.annotations.KtFirAnnotationListForDeclaration
import org.jetbrains.kotlin.analysis.api.fir.contracts.coneEffectDeclarationToAnalysisApi
import org.jetbrains.kotlin.analysis.api.fir.findPsi
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.FirCallableSignature
import org.jetbrains.kotlin.analysis.api.fir.symbols.pointers.KtFirMemberFunctionSymbolPointer
@@ -32,6 +34,7 @@ import org.jetbrains.kotlin.analysis.low.level.api.fir.api.LLFirResolveSession
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.contracts.FirEffectDeclaration
import org.jetbrains.kotlin.fir.declarations.utils.*
import org.jetbrains.kotlin.fir.resolve.getHasStableParameterNames
import org.jetbrains.kotlin.fir.symbols.impl.FirNamedFunctionSymbol
@@ -51,6 +54,13 @@ internal class KtFirFunctionSymbol(
override val isBuiltinFunctionInvoke: Boolean
get() = withValidityAssertion { callableIdIfNonLocal in kotlinFunctionInvokeCallableIds }
override val contractEffects: List<KtContractEffectDeclaration> by cached {
firSymbol.resolvedContractDescription?.effects
?.map(FirEffectDeclaration::effect)
?.map { it.coneEffectDeclarationToAnalysisApi(builder, this) }
.orEmpty()
}
override val returnType: KtType get() = withValidityAssertion { firSymbol.returnType(builder) }
override val receiverParameter: KtReceiverParameterSymbol? get() = withValidityAssertion { firSymbol.receiver(builder) }
override val contextReceivers: List<KtContextReceiver> by cached { firSymbol.createContextReceivers(builder) }
@@ -94,6 +94,118 @@ public class FirIdeNormalAnalysisSourceModuleSingleSymbolByPsiGenerated extends
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/setterWithAnnotations.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts")
@TestDataPath("$PROJECT_ROOT")
public class Contracts {
@Test
public void testAllFilesPresentInContracts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("booleanConstReferenceInImplies.kt")
public void testBooleanConstReferenceInImplies() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanConstReferenceInImplies.kt");
}
@Test
@TestMetadata("booleanExprContract.kt")
public void testBooleanExprContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanExprContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtLeastOnceContract.kt")
public void testCallsInPlaceAtLeastOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtLeastOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtMostOnceContract.kt")
public void testCallsInPlaceAtMostOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtMostOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceExactlyOnceContract.kt")
public void testCallsInPlaceExactlyOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceExactlyOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceUnknownContract.kt")
public void testCallsInPlaceUnknownContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceUnknownContract.kt");
}
@Test
@TestMetadata("invalidContractParameterPassedToReturns.kt")
public void testInvalidContractParameterPassedToReturns() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/invalidContractParameterPassedToReturns.kt");
}
@Test
@TestMetadata("isInstancePredicateContract.kt")
public void testIsInstancePredicateContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/isInstancePredicateContract.kt");
}
@Test
@TestMetadata("logicalNotContract.kt")
public void testLogicalNotContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/logicalNotContract.kt");
}
@Test
@TestMetadata("referenceBooleanReceiverInContract.kt")
public void testReferenceBooleanReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceBooleanReceiverInContract.kt");
}
@Test
@TestMetadata("referenceReceiverInContract.kt")
public void testReferenceReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceReceiverInContract.kt");
}
@Test
@TestMetadata("returnsContract.kt")
public void testReturnsContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsContract.kt");
}
@Test
@TestMetadata("returnsFalseContract.kt")
public void testReturnsFalseContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsFalseContract.kt");
}
@Test
@TestMetadata("returnsNotNullContract.kt")
public void testReturnsNotNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNotNullContract.kt");
}
@Test
@TestMetadata("returnsNullContract.kt")
public void testReturnsNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNullContract.kt");
}
@Test
@TestMetadata("returnsTrueContract.kt")
public void testReturnsTrueContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsTrueContract.kt");
}
@Test
@TestMetadata("twoContracts.kt")
public void testTwoContracts() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/twoContracts.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
@TestDataPath("$PROJECT_ROOT")
@@ -94,6 +94,118 @@ public class FirStandaloneNormalAnalysisSourceModuleSingleSymbolByPsiGenerated e
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/setterWithAnnotations.kt");
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts")
@TestDataPath("$PROJECT_ROOT")
public class Contracts {
@Test
public void testAllFilesPresentInContracts() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts"), Pattern.compile("^(.+)\\.kt$"), null, true);
}
@Test
@TestMetadata("booleanConstReferenceInImplies.kt")
public void testBooleanConstReferenceInImplies() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanConstReferenceInImplies.kt");
}
@Test
@TestMetadata("booleanExprContract.kt")
public void testBooleanExprContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/booleanExprContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtLeastOnceContract.kt")
public void testCallsInPlaceAtLeastOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtLeastOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceAtMostOnceContract.kt")
public void testCallsInPlaceAtMostOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceAtMostOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceExactlyOnceContract.kt")
public void testCallsInPlaceExactlyOnceContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceExactlyOnceContract.kt");
}
@Test
@TestMetadata("callsInPlaceUnknownContract.kt")
public void testCallsInPlaceUnknownContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/callsInPlaceUnknownContract.kt");
}
@Test
@TestMetadata("invalidContractParameterPassedToReturns.kt")
public void testInvalidContractParameterPassedToReturns() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/invalidContractParameterPassedToReturns.kt");
}
@Test
@TestMetadata("isInstancePredicateContract.kt")
public void testIsInstancePredicateContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/isInstancePredicateContract.kt");
}
@Test
@TestMetadata("logicalNotContract.kt")
public void testLogicalNotContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/logicalNotContract.kt");
}
@Test
@TestMetadata("referenceBooleanReceiverInContract.kt")
public void testReferenceBooleanReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceBooleanReceiverInContract.kt");
}
@Test
@TestMetadata("referenceReceiverInContract.kt")
public void testReferenceReceiverInContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/referenceReceiverInContract.kt");
}
@Test
@TestMetadata("returnsContract.kt")
public void testReturnsContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsContract.kt");
}
@Test
@TestMetadata("returnsFalseContract.kt")
public void testReturnsFalseContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsFalseContract.kt");
}
@Test
@TestMetadata("returnsNotNullContract.kt")
public void testReturnsNotNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNotNullContract.kt");
}
@Test
@TestMetadata("returnsNullContract.kt")
public void testReturnsNullContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsNullContract.kt");
}
@Test
@TestMetadata("returnsTrueContract.kt")
public void testReturnsTrueContract() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/returnsTrueContract.kt");
}
@Test
@TestMetadata("twoContracts.kt")
public void testTwoContracts() throws Exception {
runTest("analysis/analysis-api/testData/symbols/singleSymbolByPsi/contracts/twoContracts.kt");
}
}
@Nested
@TestMetadata("analysis/analysis-api/testData/symbols/singleSymbolByPsi/errors")
@TestDataPath("$PROJECT_ROOT")
@@ -0,0 +1,102 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractReturnsContractEffectDeclaration.*
import org.jetbrains.kotlin.analysis.api.contracts.description.booleans.*
import org.jetbrains.kotlin.analysis.api.symbols.DebugSymbolRenderer
import org.jetbrains.kotlin.analysis.api.symbols.KtParameterSymbol
import org.jetbrains.kotlin.analysis.utils.printer.PrettyPrinter
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
internal fun Context.renderKtContractEffectDeclaration(value: KtContractEffectDeclaration, endWithNewLine: Boolean = true): Unit =
printer.appendHeader(value::class) {
when (value) {
is KtContractCallsInPlaceContractEffectDeclaration -> {
appendProperty(value::valueParameterReference, ::renderKtContractParameterValue)
appendSimpleProperty(value::occurrencesRange, endWithNewLine)
}
is KtContractConditionalContractEffectDeclaration -> {
appendProperty(value::effect, ::renderKtContractEffectDeclaration)
appendProperty(value::condition, ::renderKtContractBooleanExpression, endWithNewLine)
}
is KtContractReturnsContractEffectDeclaration -> {
when (value) {
is KtContractReturnsNotNullEffectDeclaration, is KtContractReturnsSuccessfullyEffectDeclaration -> Unit
is KtContractReturnsSpecificValueEffectDeclaration ->
appendProperty(value::value, ::renderKtContractConstantValue, endWithNewLine)
}
}
}
}
private fun Context.renderKtContractConstantValue(value: KtContractConstantValue, endWithNewLine: Boolean = true): Unit =
printer.appendHeader(value::class) {
appendSimpleProperty(value::constantType, endWithNewLine)
}
private fun Context.renderKtContractParameterValue(value: KtContractParameterValue, endWithNewLine: Boolean = true): Unit =
printer.appendHeader(value::class) {
appendProperty(value::parameterSymbol, ::renderKtParameterSymbol, endWithNewLine)
}
private fun Context.renderKtContractBooleanExpression(value: KtContractBooleanExpression, endWithNewLine: Boolean = true): Unit =
printer.appendHeader(value::class) {
when (value) {
is KtContractLogicalNotExpression -> appendProperty(value::argument, ::renderKtContractBooleanExpression, endWithNewLine)
is KtContractBooleanConstantExpression -> appendSimpleProperty(value::booleanConstant, endWithNewLine)
is KtContractBinaryLogicExpression -> {
appendProperty(value::left, ::renderKtContractBooleanExpression)
appendProperty(value::right, ::renderKtContractBooleanExpression)
appendSimpleProperty(value::operation, endWithNewLine)
}
is KtContractIsInstancePredicateExpression -> {
appendProperty(value::argument, ::renderKtContractParameterValue)
appendProperty(value::type, renderer = { type, _ ->
appendLine(with(session) { symbolRenderer.renderType(type) })
})
appendSimpleProperty(value::isNegated, endWithNewLine)
}
is KtContractIsNullPredicateExpression -> {
appendProperty(value::argument, ::renderKtContractParameterValue)
appendSimpleProperty(value::isNegated, endWithNewLine)
}
is KtContractBooleanValueParameterExpression -> {
appendProperty(value::parameterSymbol, ::renderKtParameterSymbol, endWithNewLine)
}
}
}
private fun Context.renderKtParameterSymbol(value: KtParameterSymbol, endWithNewLine: Boolean = true) {
val renderedValue = with(session) { symbolRenderer.render(value) }
if (endWithNewLine) printer.appendLine(renderedValue) else printer.append(renderedValue)
}
internal data class Context(val session: KtAnalysisSession, val printer: PrettyPrinter, val symbolRenderer: DebugSymbolRenderer)
private fun PrettyPrinter.appendHeader(clazz: KClass<*>, body: PrettyPrinter.() -> Unit) {
appendLine(clazz.simpleName + ":")
withIndent { body() }
}
private fun <T> PrettyPrinter.appendProperty(
prop: KProperty<T>,
renderer: (T, Boolean) -> Unit,
endWithNewLine: Boolean = true
) {
appendLine(prop.name + ":")
withIndent {
renderer(prop.call(), endWithNewLine)
}
}
private fun PrettyPrinter.appendSimpleProperty(prop: KProperty<Any>, endWithNewLine: Boolean = true) {
append(prop.name + ": ")
append(prop.call().toString())
if (endWithNewLine) appendLine()
}
@@ -0,0 +1,91 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description
import com.google.common.base.Objects
import org.jetbrains.kotlin.analysis.api.contracts.description.booleans.KtContractBooleanExpression
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange
/**
* Represents [kotlin.contracts.Effect].
*/
public sealed interface KtContractEffectDeclaration : KtLifetimeOwner
/**
* Represents [kotlin.contracts.ContractBuilder.callsInPlace].
*/
public class KtContractCallsInPlaceContractEffectDeclaration(
private val _valueParameterReference: KtContractParameterValue,
private val _occurrencesRange: EventOccurrencesRange,
) : KtContractEffectDeclaration {
override val token: KtLifetimeToken get() = _valueParameterReference.token
public val valueParameterReference: KtContractParameterValue get() = withValidityAssertion { _valueParameterReference }
public val occurrencesRange: EventOccurrencesRange get() = withValidityAssertion { _occurrencesRange }
override fun hashCode(): Int = Objects.hashCode(_valueParameterReference, _occurrencesRange)
override fun equals(other: Any?): Boolean =
other is KtContractCallsInPlaceContractEffectDeclaration && other._valueParameterReference == _valueParameterReference &&
other._occurrencesRange == _occurrencesRange
}
/**
* Represents [kotlin.contracts.SimpleEffect.implies].
*/
public class KtContractConditionalContractEffectDeclaration(
private val _effect: KtContractEffectDeclaration,
private val _condition: KtContractBooleanExpression
) : KtContractEffectDeclaration {
override val token: KtLifetimeToken get() = _effect.token
public val effect: KtContractEffectDeclaration get() = withValidityAssertion { _effect }
public val condition: KtContractBooleanExpression get() = withValidityAssertion { _condition }
override fun hashCode(): Int = Objects.hashCode(_effect, _condition)
override fun equals(other: Any?): Boolean =
other is KtContractConditionalContractEffectDeclaration && other._effect == _effect && other._condition == _condition
}
/**
* Represents [kotlin.contracts.ContractBuilder.returnsNotNull] & [kotlin.contracts.ContractBuilder.returns].
*/
public sealed class KtContractReturnsContractEffectDeclaration : KtContractEffectDeclaration {
/**
* Represent [kotlin.contracts.ContractBuilder.returnsNotNull].
*/
public class KtContractReturnsNotNullEffectDeclaration(
override val token: KtLifetimeToken
) : KtContractReturnsContractEffectDeclaration() {
override fun equals(other: Any?): Boolean = other is KtContractReturnsNotNullEffectDeclaration
override fun hashCode(): Int = javaClass.hashCode()
}
/**
* Represents [kotlin.contracts.ContractBuilder.returns] with a `value` argument.
*/
public class KtContractReturnsSpecificValueEffectDeclaration(
private val _value: KtContractConstantValue
) : KtContractReturnsContractEffectDeclaration() {
override val token: KtLifetimeToken get() = _value.token
public val value: KtContractConstantValue get() = withValidityAssertion { _value }
override fun equals(other: Any?): Boolean = other is KtContractReturnsSpecificValueEffectDeclaration && other._value == _value
override fun hashCode(): Int = _value.hashCode()
}
/**
* Represents [kotlin.contracts.ContractBuilder.returns] without arguments.
*/
public class KtContractReturnsSuccessfullyEffectDeclaration(
override val token: KtLifetimeToken
) : KtContractReturnsContractEffectDeclaration() {
override fun equals(other: Any?): Boolean = other is KtContractReturnsSuccessfullyEffectDeclaration
override fun hashCode(): Int = javaClass.hashCode()
}
}
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtParameterSymbol
/**
* Represents constant reference that can be passed to `value` argument of [kotlin.contracts.ContractBuilder.returns].
*
* See: [org.jetbrains.kotlin.analysis.api.contracts.description.KtContractReturnsContractEffectDeclaration.KtContractReturnsSpecificValueEffectDeclaration.value]
*/
public class KtContractConstantValue(
private val _constantType: KtContractConstantType,
override val token: KtLifetimeToken,
) : KtLifetimeOwner {
public enum class KtContractConstantType {
NULL, TRUE, FALSE;
}
public val constantType: KtContractConstantType get() = withValidityAssertion { _constantType }
override fun equals(other: Any?): Boolean = other is KtContractConstantValue && other._constantType == _constantType
override fun hashCode(): Int = _constantType.hashCode()
}
/**
* Represents parameter that can be passed to `value` argument of [kotlin.contracts.ContractBuilder.callsInPlace].
*/
public class KtContractParameterValue(private val _parameterSymbol: KtParameterSymbol) : KtLifetimeOwner {
override val token: KtLifetimeToken get() = _parameterSymbol.token
public val parameterSymbol: KtParameterSymbol get() = withValidityAssertion { _parameterSymbol }
override fun hashCode(): Int = _parameterSymbol.hashCode()
override fun equals(other: Any?): Boolean = other is KtContractParameterValue && other._parameterSymbol == _parameterSymbol
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description.booleans
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeOwner
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.KtParameterSymbol
/**
* Represents `booleanExpression` argument of [kotlin.contracts.SimpleEffect.implies].
*
* `booleanExpression` forms a boolean condition for
* [org.jetbrains.kotlin.analysis.api.contracts.description.KtContractConditionalContractEffectDeclaration]. See
* [org.jetbrains.kotlin.analysis.api.contracts.description.KtContractConditionalContractEffectDeclaration.condition]
*/
public sealed interface KtContractBooleanExpression : KtLifetimeOwner
/**
* Represents boolean parameter reference passed to `booleanExpression` argument of [kotlin.contracts.SimpleEffect.implies].
*/
public class KtContractBooleanValueParameterExpression(
private val _parameterSymbol: KtParameterSymbol
) : KtContractBooleanExpression {
override val token: KtLifetimeToken get() = _parameterSymbol.token
public val parameterSymbol: KtParameterSymbol get() = withValidityAssertion { _parameterSymbol }
override fun hashCode(): Int = _parameterSymbol.hashCode()
override fun equals(other: Any?): Boolean =
other is KtContractBooleanValueParameterExpression && other._parameterSymbol == _parameterSymbol
}
/**
* Represents boolean constant reference. The boolean constant can be passed to `booleanExpression` argument of
* [kotlin.contracts.SimpleEffect.implies].
*/
public class KtContractBooleanConstantExpression(
private val _booleanConstant: Boolean,
override val token: KtLifetimeToken
) : KtContractBooleanExpression {
public val booleanConstant: Boolean get() = withValidityAssertion { _booleanConstant }
override fun equals(other: Any?): Boolean = other is KtContractBooleanConstantExpression && other._booleanConstant == _booleanConstant
override fun hashCode(): Int = _booleanConstant.hashCode()
}
@@ -0,0 +1,47 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description.booleans
import com.google.common.base.Objects
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
/**
* See: [KtContractBooleanExpression].
*/
public class KtContractBinaryLogicExpression(
private val _left: KtContractBooleanExpression,
private val _right: KtContractBooleanExpression,
private val _operation: KtLogicOperation
) : KtContractBooleanExpression {
init {
check(left.token === right.token) { "$left and $right should have the same lifetime token" }
}
override val token: KtLifetimeToken get() = _left.token
public val left: KtContractBooleanExpression get() = withValidityAssertion { _left }
public val right: KtContractBooleanExpression get() = withValidityAssertion { _right }
public val operation: KtLogicOperation get() = withValidityAssertion { _operation }
override fun hashCode(): Int = Objects.hashCode(_left, _right, _operation)
override fun equals(other: Any?): Boolean =
other is KtContractBinaryLogicExpression && other._left == _left && other._right == _right && other._operation == _operation
public enum class KtLogicOperation {
AND, OR
}
}
/**
* See: [KtContractBooleanExpression].
*/
public class KtContractLogicalNotExpression(private val _argument: KtContractBooleanExpression) : KtContractBooleanExpression {
override val token: KtLifetimeToken get() = _argument.token
public val argument: KtContractBooleanExpression get() = withValidityAssertion { _argument }
override fun equals(other: Any?): Boolean = other is KtContractLogicalNotExpression && other._argument == _argument
override fun hashCode(): Int = _argument.hashCode()
}
@@ -0,0 +1,49 @@
/*
* Copyright 2010-2022 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.analysis.api.contracts.description.booleans
import com.google.common.base.Objects
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractParameterValue
import org.jetbrains.kotlin.analysis.api.lifetime.KtLifetimeToken
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.types.KtType
/**
* See: [KtContractBooleanExpression].
*/
public class KtContractIsInstancePredicateExpression(
private val _argument: KtContractParameterValue,
private val _type: KtType,
private val _isNegated: Boolean
) : KtContractBooleanExpression {
override val token: KtLifetimeToken get() = _type.token
public val argument: KtContractParameterValue get() = withValidityAssertion { _argument }
public val type: KtType get() = withValidityAssertion { _type }
public val isNegated: Boolean get() = withValidityAssertion { _isNegated }
public fun negated(): KtContractIsInstancePredicateExpression = KtContractIsInstancePredicateExpression(argument, type, !isNegated)
override fun hashCode(): Int = Objects.hashCode(_argument, _type, _isNegated)
override fun equals(other: Any?): Boolean =
other is KtContractIsInstancePredicateExpression && other._argument == _argument && other._type == _type && other._isNegated
&& _isNegated
}
/**
* See: [KtContractBooleanExpression].
*/
public class KtContractIsNullPredicateExpression(
private val _argument: KtContractParameterValue,
private val _isNegated: Boolean
) : KtContractBooleanExpression {
override val token: KtLifetimeToken get() = _argument.token
public val argument: KtContractParameterValue get() = withValidityAssertion { _argument }
public val isNegated: Boolean get() = withValidityAssertion { _isNegated }
public fun negated(): KtContractIsNullPredicateExpression = KtContractIsNullPredicateExpression(argument, !isNegated)
override fun hashCode(): Int = Objects.hashCode(_argument, _isNegated)
override fun equals(other: Any?): Boolean =
other is KtContractIsNullPredicateExpression && other._argument == _argument && other._isNegated == _isNegated
}
@@ -11,6 +11,9 @@ import org.jetbrains.kotlin.analysis.api.annotations.*
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.components.KtSymbolContainingDeclarationProviderMixIn
import org.jetbrains.kotlin.analysis.api.components.KtSymbolInfoProviderMixIn
import org.jetbrains.kotlin.analysis.api.contracts.description.Context
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.contracts.description.renderKtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtNamedSymbol
import org.jetbrains.kotlin.analysis.api.symbols.markers.KtPossiblyNamedSymbol
import org.jetbrains.kotlin.analysis.api.types.KtClassErrorType
@@ -227,6 +230,8 @@ public class DebugSymbolRenderer(
is KtSymbol -> renderSymbolTag(value, renderSymbolsFully)
is KtType -> renderType(value)
is KtAnnotationValue -> renderAnnotationValue(value)
is KtContractEffectDeclaration -> Context(this@KtAnalysisSession, this@renderValue, this@DebugSymbolRenderer)
.renderKtContractEffectDeclaration(value, endWithNewLine = false)
is KtNamedAnnotationValue -> renderNamedConstantValue(value)
is KtInitializerValue -> renderKtInitializerValue(value)
is KtContextReceiver -> rendeContextReceiver(value)
@@ -32,7 +32,7 @@ public val KtCallableSymbol.receiverType: KtType?
* Symbol for a receiver parameter of a function or property. For example, consider code `fun String.foo() {...}`, the declaration of
* `String` receiver parameter is such a symbol.
*/
public abstract class KtReceiverParameterSymbol : KtAnnotatedSymbol {
public abstract class KtReceiverParameterSymbol : KtAnnotatedSymbol, KtParameterSymbol {
public abstract val type: KtType
/**
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.analysis.api.symbols
import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.analysis.api.base.KtContextReceiver
import org.jetbrains.kotlin.analysis.api.contracts.description.KtContractEffectDeclaration
import org.jetbrains.kotlin.analysis.api.lifetime.withValidityAssertion
import org.jetbrains.kotlin.analysis.api.symbols.markers.*
import org.jetbrains.kotlin.analysis.api.symbols.pointers.KtSymbolPointer
@@ -58,6 +59,7 @@ public abstract class KtFunctionSymbol : KtFunctionLikeSymbol(),
public abstract val isOverride: Boolean
public abstract val isInfix: Boolean
public abstract val isStatic: Boolean
public abstract val contractEffects: List<KtContractEffectDeclaration>
/**
* Whether this symbol is the `invoke` method defined on the Kotlin builtin functional type.
@@ -176,7 +176,10 @@ public abstract class KtLocalVariableSymbol : KtVariableSymbol(), KtSymbolWithKi
abstract override fun createPointer(): KtSymbolPointer<KtLocalVariableSymbol>
}
public abstract class KtValueParameterSymbol : KtVariableLikeSymbol(), KtSymbolWithKind, KtAnnotatedSymbol {
// TODO design common ancestor of parameter and receiver KTIJ-23745
public sealed interface KtParameterSymbol : KtAnnotatedSymbol
public abstract class KtValueParameterSymbol : KtVariableLikeSymbol(), KtParameterSymbol, KtSymbolWithKind, KtAnnotatedSymbol {
final override val symbolKind: KtSymbolKind get() = withValidityAssertion { KtSymbolKind.LOCAL }
final override val callableIdIfNonLocal: CallableId? get() = withValidityAssertion { null }
final override val isExtension: Boolean get() = withValidityAssertion { false }
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun booleanConstReferenceInImplies(): Boolean {
contr<caret>act {
returns(true) implies true
}
return true
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun booleanConstReferenceInImplies(): kotlin.Boolean
@@ -0,0 +1,39 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /booleanConstReferenceInImplies
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: TRUE
condition:
KtContractBooleanConstantExpression:
booleanConstant: true
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: booleanConstReferenceInImplies
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun boolenExprContract(foo: Any?, bar: Any?): Boolean {
contr<caret>act {
returns(true) implies (foo == null && bar != null)
}
return foo == null && bar != null
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun boolenExprContract(foo: kotlin.Any?, bar: kotlin.Any?): kotlin.Boolean
@@ -0,0 +1,128 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /boolenExprContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: TRUE
condition:
KtContractBinaryLogicExpression:
left:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: false
right:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: bar
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: true
operation: AND
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: boolenExprContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: bar
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun atLeastOnceContract(block: () -> Unit) {
contr<caret>act {
callsInPlace(block, InvocationKind.AT_LEAST_ONCE)
}
block()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun atLeastOnceContract(block: () -> kotlin.Unit)
@@ -0,0 +1,74 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /atLeastOnceContract
contextReceivers: []
contractEffects: [
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: AT_LEAST_ONCE
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: atLeastOnceContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun atMostOnceContract(block: () -> Unit) {
contr<caret>act {
callsInPlace(block, InvocationKind.AT_MOST_ONCE)
}
block()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun atMostOnceContract(block: () -> kotlin.Unit)
@@ -0,0 +1,74 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /atMostOnceContract
contextReceivers: []
contractEffects: [
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: AT_MOST_ONCE
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: atMostOnceContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun exactlyOnceContract(block: () -> Unit) {
contr<caret>act {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun exactlyOnceContract(block: () -> kotlin.Unit)
@@ -0,0 +1,74 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /exactlyOnceContract
contextReceivers: []
contractEffects: [
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: EXACTLY_ONCE
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: exactlyOnceContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun unknownContract(block: () -> Unit) {
contr<caret>act {
callsInPlace(block, InvocationKind.UNKNOWN)
}
block()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun unknownContract(block: () -> kotlin.Unit)
@@ -0,0 +1,74 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /unknownContract
contextReceivers: []
contractEffects: [
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: UNKNOWN
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: unknownContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun invalidContract(foo: Any, bar: Boolean) {
cont<caret>ract {
returns(foo) implies bar
}
return if (bar) foo else null
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun invalidContract(foo: kotlin.Any, bar: kotlin.Boolean)
@@ -0,0 +1,68 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /invalidContract
contextReceivers: []
contractEffects: []
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: invalidContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: bar
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,17 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
class Foo
@OptIn(ExperimentalContracts::class)
fun isInstancePredicateContract(value: Any) {
contr<caret>act {
returns() implies (value is Foo)
}
if (value !is Foo) {
throw IllegalStateException()
}
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun isInstancePredicateContract(value: kotlin.Any)
@@ -0,0 +1,80 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /isInstancePredicateContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSuccessfullyEffectDeclaration:
condition:
KtContractIsInstancePredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
type:
Foo
isNegated: false
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: isInstancePredicateContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,15 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun logicalNotContract(value: Boolean) {
contr<caret>act {
returns() implies !value
}
if (value) {
throw IllegalStateException()
}
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun logicalNotContract(value: kotlin.Boolean)
@@ -0,0 +1,77 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /logicalNotContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSuccessfullyEffectDeclaration:
condition:
KtContractLogicalNotExpression:
argument:
KtContractBooleanValueParameterExpression:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: logicalNotContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,14 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import java.lang.IllegalStateException
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun Boolean.referenceReceiverInContract() {
contr<caret>act {
returns() implies this@referenceReceiverInContract
}
if (!this) throw IllegalStateException()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun kotlin.Boolean.referenceReceiverInContract()
@@ -0,0 +1,49 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /referenceReceiverInContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSuccessfullyEffectDeclaration:
condition:
KtContractBooleanValueParameterExpression:
parameterSymbol:
KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/referenceReceiverInContract)
type: kotlin/Boolean
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: true
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: referenceReceiverInContract
origin: SOURCE
receiverParameter: KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/referenceReceiverInContract)
type: kotlin/Boolean
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun (() -> Unit).referenceReceiverInContract() {
contr<caret>act {
callsInPlace(this@referenceReceiverInContract, InvocationKind.EXACTLY_ONCE)
}
this()
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun () -> kotlin.Unit.referenceReceiverInContract()
@@ -0,0 +1,48 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /referenceReceiverInContract
contextReceivers: []
contractEffects: [
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/referenceReceiverInContract)
type: kotlin/Function0<kotlin/Unit>
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: EXACTLY_ONCE
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: true
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: referenceReceiverInContract
origin: SOURCE
receiverParameter: KtReceiverParameterSymbol:
annotationsList: []
origin: SOURCE
owningCallableSymbol: KtFunctionSymbol(/referenceReceiverInContract)
type: kotlin/Function0<kotlin/Unit>
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: []
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,15 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
inline fun check(value: Boolean) {
contr<caret>act {
returns() implies value
}
if (!value) {
throw IllegalStateException()
}
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
inline fun check(value: kotlin.Boolean)
@@ -0,0 +1,75 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /check
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSuccessfullyEffectDeclaration:
condition:
KtContractBooleanValueParameterExpression:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: true
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: check
origin: SOURCE
receiverParameter: null
returnType: kotlin/Unit
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: value
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun returnsFalseContract(foo: Any?): Boolean {
contr<caret>act {
returns(false) implies (foo != null)
}
return foo == null
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun returnsFalseContract(foo: kotlin.Any?): kotlin.Boolean
@@ -0,0 +1,81 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /returnsFalseContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: FALSE
condition:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: true
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: returnsFalseContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun returnsNotNullContract(foo: Any?): Any? {
contr<caret>act {
returnsNotNull() implies (foo != null)
}
return foo
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun returnsNotNullContract(foo: kotlin.Any?): kotlin.Any?
@@ -0,0 +1,78 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /returnsNotNullContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsNotNullEffectDeclaration:
condition:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: true
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: returnsNotNullContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun returnsNullContract(foo: Any?): Any? {
contr<caret>act {
returns(null) implies (foo == null)
}
return foo
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun returnsNullContract(foo: kotlin.Any?): kotlin.Any?
@@ -0,0 +1,81 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /returnsNullContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: NULL
condition:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: false
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: returnsNullContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,13 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun returnsTrueContract(foo: Any?): Boolean {
contr<caret>act {
returns(true) implies (foo == null)
}
return foo == null
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun returnsTrueContract(foo: kotlin.Any?): kotlin.Boolean
@@ -0,0 +1,81 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /returnsTrueContract
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: TRUE
condition:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: false
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: returnsTrueContract
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
@@ -0,0 +1,15 @@
// WITH_STDLIB
// DO_NOT_CHECK_NON_PSI_SYMBOL_RESTORE_K1
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
@OptIn(ExperimentalContracts::class)
fun twoContracts(foo: Any?, bar: Any?, block: () -> Unit): Boolean {
contr<caret>act {
returns(true) implies (foo == null && bar != null)
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
block()
return foo == null && bar != null
}
@@ -0,0 +1,2 @@
@kotlin.OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
fun twoContracts(foo: kotlin.Any?, bar: kotlin.Any?, block: () -> kotlin.Unit): kotlin.Boolean
@@ -0,0 +1,171 @@
KtFunctionSymbol:
annotationsList: [
kotlin/OptIn(markerClass = [kotlin.contracts.ExperimentalContracts::class])
psi: KtAnnotationEntry
]
callableIdIfNonLocal: /twoContracts
contextReceivers: []
contractEffects: [
KtContractConditionalContractEffectDeclaration:
effect:
KtContractReturnsSpecificValueEffectDeclaration:
value:
KtContractConstantValue:
constantType: TRUE
condition:
KtContractBinaryLogicExpression:
left:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: false
right:
KtContractIsNullPredicateExpression:
argument:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: bar
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
isNegated: true
operation: AND
KtContractCallsInPlaceContractEffectDeclaration:
valueParameterReference:
KtContractParameterValue:
parameterSymbol:
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
occurrencesRange: EXACTLY_ONCE
]
hasStableParameterNames: true
isBuiltinFunctionInvoke: false
isExtension: false
isExternal: false
isInfix: false
isInline: false
isOperator: false
isOverride: false
isStatic: false
isSuspend: false
modality: FINAL
name: twoContracts
origin: SOURCE
receiverParameter: null
returnType: kotlin/Boolean
symbolKind: TOP_LEVEL
typeParameters: []
valueParameters: [
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: foo
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: bar
origin: SOURCE
receiverParameter: null
returnType: kotlin/Any?
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
KtValueParameterSymbol:
annotationsList: []
callableIdIfNonLocal: null
contextReceivers: []
generatedPrimaryConstructorProperty: null
hasDefaultValue: false
isCrossinline: false
isExtension: false
isImplicitLambdaParameter: false
isNoinline: false
isVararg: false
name: block
origin: SOURCE
receiverParameter: null
returnType: kotlin/Function0<kotlin/Unit>
symbolKind: LOCAL
typeParameters: []
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null
]
visibility: Public
getContainingModule: KtSourceModule "Sources of main"
deprecationStatus: null