From d01817ce141a011ae5d14de31c812c4d7242f6da Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Fri, 19 Jun 2020 15:22:31 +0300 Subject: [PATCH] Rename `InvocationKind` to `EventOccurrencesRange` --- .../cfa/FirPropertyInitializationAnalyzer.kt | 18 ++++----- .../serialization/FirContractSerializer.kt | 8 ++-- .../src/org/jetbrains/kotlin/fir/CopyUtils.kt | 6 +-- .../FirContractDeserializer.kt | 12 +++--- .../dfa/cfg/ControlFlowGraphBuilder.kt | 16 ++++---- .../transformers/InvocationKindTransformer.kt | 16 ++++---- .../contracts/ConeEffectExtractor.kt | 14 +++---- .../fir/declarations/FirAnonymousFunction.kt | 6 +-- .../builder/FirAnonymousFunctionBuilder.kt | 10 ++--- .../impl/FirAnonymousFunctionImpl.kt | 8 ++-- .../org/jetbrains/kotlin/fir/FirRenderer.kt | 4 +- .../fir/contracts/description/ConeEffects.kt | 4 +- .../fir/tree/generator/NodeConfigurator.kt | 2 +- .../kotlin/fir/tree/generator/Types.kt | 4 +- .../kotlin/cfg/ControlFlowBuilder.kt | 8 ++-- .../kotlin/cfg/ControlFlowBuilderAdapter.kt | 14 +++---- .../kotlin/cfg/ControlFlowProcessor.kt | 22 +++++------ .../ControlFlowInstructionsGenerator.kt | 22 +++++------ ...inedLocalFunctionDeclarationInstruction.kt | 4 +- .../contracts/ContractDeserializerImpl.kt | 10 ++--- .../parsing/effects/PsiCallsEffectParser.kt | 14 +++---- .../kotlin/resolve/BindingContext.java | 4 +- .../checkers/CapturingInClosureChecker.kt | 4 +- .../kotlin/contracts/description/Effects.kt | 2 +- .../description/EventOccurrencesRange.kt | 38 +++++++++++++++++++ .../contracts/description/InvocationKind.kt | 38 ------------------- .../contracts/model/structure/Effects.kt | 4 +- .../serialization/ContractSerializer.kt | 8 ++-- 28 files changed, 158 insertions(+), 162 deletions(-) create mode 100644 compiler/resolution/src/org/jetbrains/kotlin/contracts/description/EventOccurrencesRange.kt delete mode 100644 compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt index 4f10f0b7bb1..69b6b7483e6 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/cfa/FirPropertyInitializationAnalyzer.kt @@ -7,7 +7,7 @@ package org.jetbrains.kotlin.fir.analysis.cfa import kotlinx.collections.immutable.PersistentMap import kotlinx.collections.immutable.persistentMapOf -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited import org.jetbrains.kotlin.fir.analysis.diagnostics.DiagnosticReporter import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors @@ -37,7 +37,7 @@ class FirPropertyInitializationAnalyzer { val reference = node.fir.calleeReference as? FirResolvedNamedReference ?: return val symbol = reference.resolvedSymbol as? FirPropertySymbol ?: return if (symbol !in localProperties) return - val kind = data.getValue(node)[symbol] ?: InvocationKind.ZERO + val kind = data.getValue(node)[symbol] ?: EventOccurrencesRange.ZERO if (!kind.isDefinitelyVisited()) { node.fir.source?.let { reporter.report(FirErrors.UNINITIALIZED_VARIABLE.on(it, symbol)) @@ -47,20 +47,20 @@ class FirPropertyInitializationAnalyzer { } private class PropertyInitializationInfo( - map: PersistentMap = persistentMapOf() - ) : ControlFlowInfo(map) { + map: PersistentMap = persistentMapOf() + ) : ControlFlowInfo(map) { companion object { val EMPTY = PropertyInitializationInfo() } - override val constructor: (PersistentMap) -> PropertyInitializationInfo = + override val constructor: (PersistentMap) -> PropertyInitializationInfo = ::PropertyInitializationInfo fun merge(other: PropertyInitializationInfo): PropertyInitializationInfo { var result = this for (symbol in keys.union(other.keys)) { - val kind1 = this[symbol] ?: InvocationKind.ZERO - val kind2 = other[symbol] ?: InvocationKind.ZERO + val kind1 = this[symbol] ?: EventOccurrencesRange.ZERO + val kind2 = other[symbol] ?: EventOccurrencesRange.ZERO result = result.put(symbol, kind1 or kind2) } return result @@ -121,8 +121,8 @@ class FirPropertyInitializationAnalyzer { dataForNode: PropertyInitializationInfo, symbol: FirPropertySymbol ): PropertyInitializationInfo { - val existingKind = dataForNode[symbol] ?: InvocationKind.ZERO - val kind = existingKind and InvocationKind.EXACTLY_ONCE + val existingKind = dataForNode[symbol] ?: EventOccurrencesRange.ZERO + val kind = existingKind + EventOccurrencesRange.EXACTLY_ONCE return dataForNode.put(symbol, kind) } } diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt index 48776b68c1d..18e4b00d609 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirContractSerializer.kt @@ -193,10 +193,10 @@ class FirContractSerializer { } } - private fun invocationKindProtobufEnum(kind: InvocationKind): ProtoBuf.Effect.InvocationKind? = when (kind) { - InvocationKind.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE - InvocationKind.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE - InvocationKind.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE + private fun invocationKindProtobufEnum(kind: EventOccurrencesRange): ProtoBuf.Effect.InvocationKind? = when (kind) { + EventOccurrencesRange.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE + EventOccurrencesRange.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE + EventOccurrencesRange.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE else -> null } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt index e9428d01a51..1a770c57186 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/CopyUtils.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin import org.jetbrains.kotlin.fir.declarations.FirTypeParameter @@ -69,7 +69,7 @@ fun FirAnonymousFunction.copy( typeRef: FirTypeRef = this.typeRef, label: FirLabel? = this.label, controlFlowGraphReference: FirControlFlowGraphReference = this.controlFlowGraphReference, - invocationKind: InvocationKind? = this.invocationKind + eventOccurrencesRange: EventOccurrencesRange? = this.eventOccurrencesRange ): FirAnonymousFunction { return buildAnonymousFunction { this.source = source @@ -85,7 +85,7 @@ fun FirAnonymousFunction.copy( this.typeRef = typeRef this.label = label this.controlFlowGraphReference = controlFlowGraphReference - this.invocationKind = invocationKind + this.eventOccurrencesRange = eventOccurrencesRange } } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt index 7f072eea6b5..b87e0e1dc7d 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/deserialization/FirContractDeserializer.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.deserialization -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.contracts.FirContractDescription import org.jetbrains.kotlin.fir.contracts.builder.buildResolvedContractDescription import org.jetbrains.kotlin.fir.contracts.description.* @@ -60,7 +60,7 @@ class FirContractDeserializer(private val c: FirDeserializationContext) { val invocationKind = if (proto.hasKind()) proto.kind.toDescriptorInvocationKind() ?: return null else - InvocationKind.UNKNOWN + EventOccurrencesRange.UNKNOWN ConeCallsEffectDeclaration(callable, invocationKind) } } @@ -141,10 +141,10 @@ class FirContractDeserializer(private val c: FirDeserializationContext) { ConeBooleanValueParameterReference(valueParameterIndex, name) } - private fun ProtoBuf.Effect.InvocationKind.toDescriptorInvocationKind(): InvocationKind? = when (this) { - ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE -> InvocationKind.AT_MOST_ONCE - ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE -> InvocationKind.EXACTLY_ONCE - ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE -> InvocationKind.AT_LEAST_ONCE + private fun ProtoBuf.Effect.InvocationKind.toDescriptorInvocationKind(): EventOccurrencesRange? = when (this) { + ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE -> EventOccurrencesRange.AT_MOST_ONCE + ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE -> EventOccurrencesRange.EXACTLY_ONCE + ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE -> EventOccurrencesRange.AT_LEAST_ONCE } private fun extractType(proto: ProtoBuf.Expression): ConeKotlinType? { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt index 63ce5c0d61d..a7b56622b0f 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/dfa/cfg/ControlFlowGraphBuilder.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.dfa.cfg -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.declarations.* @@ -207,7 +207,7 @@ class ControlFlowGraphBuilder { } fun enterAnonymousFunction(anonymousFunction: FirAnonymousFunction): Pair { - val invocationKind = anonymousFunction.invocationKind + val invocationKind = anonymousFunction.eventOccurrencesRange var previousNodeIsNew = false val symbol = anonymousFunction.symbol @@ -256,15 +256,15 @@ class ControlFlowGraphBuilder { } } - private val InvocationKind?.hasTowardEdge: Boolean + private val EventOccurrencesRange?.hasTowardEdge: Boolean get() = when (this) { - InvocationKind.AT_MOST_ONCE, InvocationKind.UNKNOWN -> true + EventOccurrencesRange.AT_MOST_ONCE, EventOccurrencesRange.UNKNOWN -> true else -> false } - private val InvocationKind?.hasBackEdge: Boolean + private val EventOccurrencesRange?.hasBackEdge: Boolean get() = when (this) { - InvocationKind.AT_LEAST_ONCE, InvocationKind.UNKNOWN -> true + EventOccurrencesRange.AT_LEAST_ONCE, EventOccurrencesRange.UNKNOWN -> true else -> false } @@ -293,7 +293,7 @@ class ControlFlowGraphBuilder { lastNodes.push(postponedExitNode) } - val invocationKind = anonymousFunction.invocationKind + val invocationKind = anonymousFunction.eventOccurrencesRange if (invocationKind != null) { addEdge(exitNode, postponedExitNode, preferredKind = EdgeKind.CfgForward) } else { @@ -301,7 +301,7 @@ class ControlFlowGraphBuilder { CFGNode.addJustKindEdge(postponedEnterNode, postponedExitNode, kind, propagateDeadness = true) } - if (invocationKind == InvocationKind.EXACTLY_ONCE && shouldPassFlowFromInplaceLambda.top()) { + if (invocationKind == EventOccurrencesRange.EXACTLY_ONCE && shouldPassFlowFromInplaceLambda.top()) { exitsFromCompletedPostponedAnonymousFunctions += postponedExitNode } diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/InvocationKindTransformer.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/InvocationKindTransformer.kt index 29c7f2831c7..069f9cbf50c 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/InvocationKindTransformer.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/InvocationKindTransformer.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.contracts.description.ConeCallsEffectDeclaration import org.jetbrains.kotlin.fir.contracts.effects @@ -19,14 +19,14 @@ import org.jetbrains.kotlin.fir.visitors.FirTransformer import org.jetbrains.kotlin.fir.visitors.compose object InvocationKindTransformer : FirTransformer() { - private object ArgumentsTransformer : FirTransformer, InvocationKind?>>() { - override fun transformElement(element: E, data: Pair, InvocationKind?>): CompositeTransformResult { + private object ArgumentsTransformer : FirTransformer, EventOccurrencesRange?>>() { + override fun transformElement(element: E, data: Pair, EventOccurrencesRange?>): CompositeTransformResult { return element.compose() } override fun transformAnonymousFunction( anonymousFunction: FirAnonymousFunction, - data: Pair, InvocationKind?> + data: Pair, EventOccurrencesRange?> ): CompositeTransformResult { val kind = data.second ?: data.first[anonymousFunction] if (kind != null) { @@ -37,7 +37,7 @@ object InvocationKindTransformer : FirTransformer() { override fun transformLambdaArgumentExpression( lambdaArgumentExpression: FirLambdaArgumentExpression, - data: Pair, InvocationKind?> + data: Pair, EventOccurrencesRange?> ): CompositeTransformResult { return data.first[lambdaArgumentExpression]?.let { (lambdaArgumentExpression.transformChildren(this, data.first to it) as FirStatement).compose() @@ -46,7 +46,7 @@ object InvocationKindTransformer : FirTransformer() { override fun transformNamedArgumentExpression( namedArgumentExpression: FirNamedArgumentExpression, - data: Pair, InvocationKind?> + data: Pair, EventOccurrencesRange?> ): CompositeTransformResult { return data.first[namedArgumentExpression]?.let { (namedArgumentExpression.transformChildren(this, data.first to it) as FirStatement).compose() @@ -74,7 +74,7 @@ object InvocationKindTransformer : FirTransformer() { parameter to argument }.toMap() - val invocationKindMapping = mutableMapOf() + val invocationKindMapping = mutableMapOf() for (effect in callsEffects) { // TODO: Support callsInPlace contracts on receivers val valueParameter = function.valueParameters.getOrNull(effect.valueParameterReference.parameterIndex) ?: continue @@ -83,7 +83,7 @@ object InvocationKindTransformer : FirTransformer() { } if (isInline) { for (argument in functionCall.arguments) { - invocationKindMapping.putIfAbsent(argument, InvocationKind.UNKNOWN) + invocationKindMapping.putIfAbsent(argument, EventOccurrencesRange.UNKNOWN) } } if (invocationKindMapping.isEmpty()) { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/ConeEffectExtractor.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/ConeEffectExtractor.kt index b1670f03e88..14348c5f585 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/ConeEffectExtractor.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/contracts/ConeEffectExtractor.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.resolve.transformers.contracts -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.contracts.description.* @@ -65,7 +65,7 @@ class ConeEffectExtractor( FirContractsDslNames.CALLS_IN_PLACE -> { val reference = functionCall.arguments[0].accept(this, null) as? ConeValueParameterReference ?: return null - val kind = functionCall.arguments.getOrNull(1)?.parseInvocationKind() ?: InvocationKind.UNKNOWN + val kind = functionCall.arguments.getOrNull(1)?.parseInvocationKind() ?: EventOccurrencesRange.UNKNOWN ConeCallsEffectDeclaration(reference, kind) } @@ -165,14 +165,14 @@ class ConeEffectExtractor( return ConeIsInstancePredicate(arg, type, isNegated) } - private fun FirExpression.parseInvocationKind(): InvocationKind? { + private fun FirExpression.parseInvocationKind(): EventOccurrencesRange? { if (this !is FirQualifiedAccessExpression) return null val resolvedId = toResolvedCallableSymbol()?.callableId ?: return null return when (resolvedId) { - FirContractsDslNames.EXACTLY_ONCE_KIND -> InvocationKind.EXACTLY_ONCE - FirContractsDslNames.AT_LEAST_ONCE_KIND -> InvocationKind.AT_LEAST_ONCE - FirContractsDslNames.AT_MOST_ONCE_KIND -> InvocationKind.AT_MOST_ONCE - FirContractsDslNames.UNKNOWN_KIND -> InvocationKind.UNKNOWN + FirContractsDslNames.EXACTLY_ONCE_KIND -> EventOccurrencesRange.EXACTLY_ONCE + FirContractsDslNames.AT_LEAST_ONCE_KIND -> EventOccurrencesRange.AT_LEAST_ONCE + FirContractsDslNames.AT_MOST_ONCE_KIND -> EventOccurrencesRange.AT_MOST_ONCE + FirContractsDslNames.UNKNOWN_KIND -> EventOccurrencesRange.UNKNOWN else -> null } } diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt index 4884e43bf2b..607b1640ddd 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/FirAnonymousFunction.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.declarations -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement @@ -37,7 +37,7 @@ abstract class FirAnonymousFunction : FirFunction, FirExpr abstract override val typeRef: FirTypeRef abstract override val symbol: FirAnonymousFunctionSymbol abstract val label: FirLabel? - abstract val invocationKind: InvocationKind? + abstract val eventOccurrencesRange: EventOccurrencesRange? abstract val isLambda: Boolean abstract override val typeParameters: List @@ -53,7 +53,7 @@ abstract class FirAnonymousFunction : FirFunction, FirExpr abstract override fun replaceTypeRef(newTypeRef: FirTypeRef) - abstract fun replaceInvocationKind(newInvocationKind: InvocationKind?) + abstract fun replaceInvocationKind(newEventOccurrencesRange: EventOccurrencesRange?) abstract override fun transformAnnotations(transformer: FirTransformer, data: D): FirAnonymousFunction diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt index b3441496b2d..4dc972c705d 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/builder/FirAnonymousFunctionBuilder.kt @@ -6,19 +6,16 @@ package org.jetbrains.kotlin.fir.declarations.builder import kotlin.contracts.* -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement import org.jetbrains.kotlin.fir.builder.FirAnnotationContainerBuilder import org.jetbrains.kotlin.fir.builder.FirBuilderDsl import org.jetbrains.kotlin.fir.declarations.FirAnonymousFunction -import org.jetbrains.kotlin.fir.declarations.FirDeclarationAttributes import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin -import org.jetbrains.kotlin.fir.declarations.FirResolvePhase import org.jetbrains.kotlin.fir.declarations.FirTypeParameter import org.jetbrains.kotlin.fir.declarations.FirValueParameter -import org.jetbrains.kotlin.fir.declarations.builder.FirFunctionBuilder import org.jetbrains.kotlin.fir.declarations.impl.FirAnonymousFunctionImpl import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall import org.jetbrains.kotlin.fir.expressions.FirBlock @@ -28,7 +25,6 @@ import org.jetbrains.kotlin.fir.references.impl.FirEmptyControlFlowGraphReferenc import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol import org.jetbrains.kotlin.fir.types.FirTypeRef import org.jetbrains.kotlin.fir.types.impl.FirImplicitTypeRefImpl -import org.jetbrains.kotlin.fir.visitors.* /* * This file was generated automatically @@ -49,7 +45,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu override var typeRef: FirTypeRef = FirImplicitTypeRefImpl(null) lateinit var symbol: FirAnonymousFunctionSymbol var label: FirLabel? = null - var invocationKind: InvocationKind? = null + var eventOccurrencesRange: EventOccurrencesRange? = null var isLambda: Boolean by kotlin.properties.Delegates.notNull() val typeParameters: MutableList = mutableListOf() @@ -67,7 +63,7 @@ class FirAnonymousFunctionBuilder : FirFunctionBuilder, FirAnnotationContainerBu typeRef, symbol, label, - invocationKind, + eventOccurrencesRange, isLambda, typeParameters, ) diff --git a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt index 71a98efd00d..73921a03624 100644 --- a/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt +++ b/compiler/fir/tree/gen/org/jetbrains/kotlin/fir/declarations/impl/FirAnonymousFunctionImpl.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.declarations.impl -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.fir.FirLabel import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.FirSourceElement @@ -40,7 +40,7 @@ internal class FirAnonymousFunctionImpl( override var typeRef: FirTypeRef, override val symbol: FirAnonymousFunctionSymbol, override var label: FirLabel?, - override var invocationKind: InvocationKind?, + override var eventOccurrencesRange: EventOccurrencesRange?, override val isLambda: Boolean, override val typeParameters: MutableList, ) : FirAnonymousFunction() { @@ -122,7 +122,7 @@ internal class FirAnonymousFunctionImpl( typeRef = newTypeRef } - override fun replaceInvocationKind(newInvocationKind: InvocationKind?) { - invocationKind = newInvocationKind + override fun replaceInvocationKind(newInvocationKind: EventOccurrencesRange?) { + eventOccurrencesRange = newInvocationKind } } diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt index 1549a8948f9..5ce8d12df2c 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/FirRenderer.kt @@ -449,8 +449,8 @@ class FirRenderer(builder: StringBuilder, private val mode: RenderMode = RenderM anonymousFunction.valueParameters.renderParameters() print(": ") anonymousFunction.returnTypeRef.accept(this) - if (anonymousFunction.invocationKind != null) { - print(" ") + if (anonymousFunction.eventOccurrencesRange != null) { + print(" ") } if (mode.renderLambdaBodies) { anonymousFunction.body?.renderBody() diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/contracts/description/ConeEffects.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/contracts/description/ConeEffects.kt index eb37a89e326..69d6173c075 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/contracts/description/ConeEffects.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/contracts/description/ConeEffects.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.contracts.description -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange /** * Effect with condition attached to it. @@ -41,7 +41,7 @@ class ConeReturnsEffectDeclaration(val value: ConeConstantReference) : ConeEffec * Effect which specifies, that during execution of subroutine, callable [valueParameterReference] will be invoked * [kind] amount of times, and will never be invoked after subroutine call is finished. */ -class ConeCallsEffectDeclaration(val valueParameterReference: ConeValueParameterReference, val kind: InvocationKind) : ConeEffectDeclaration() { +class ConeCallsEffectDeclaration(val valueParameterReference: ConeValueParameterReference, val kind: EventOccurrencesRange) : ConeEffectDeclaration() { override fun accept(contractDescriptionVisitor: ConeContractDescriptionVisitor, data: D): R = contractDescriptionVisitor.visitCallsEffectDeclaration(this, data) } \ No newline at end of file diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt index c2bfc1cc985..5b924d6f503 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/NodeConfigurator.kt @@ -266,7 +266,7 @@ object NodeConfigurator : AbstractFieldConfigurator(FirTreeBuild parentArg(function, "F", anonymousFunction) +symbol("FirAnonymousFunctionSymbol") +field(label, nullable = true) - +field(invocationKindType, nullable = true, withReplace = true).apply { + +field(eventOccurrencesRangeType, nullable = true, withReplace = true).apply { isMutable = true } +booleanField("isLambda") diff --git a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt index a46f0e9e852..ef58046060f 100644 --- a/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt +++ b/compiler/fir/tree/tree-generator/src/org/jetbrains/kotlin/fir/tree/generator/Types.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.fir.tree.generator -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities @@ -25,7 +25,7 @@ val jumpTargetType = type("fir", "FirTarget") val constKindType = generatedType("expressions", "FirConstKind") val operationType = type("fir.expressions", "FirOperation") val classKindType = type(ClassKind::class) -val invocationKindType = type(InvocationKind::class) +val eventOccurrencesRangeType = type(EventOccurrencesRange::class) val varianceType = type(Variance::class) val nameType = type(Name::class) val visibilityType = type(Visibility::class) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt index 6192b8b2570..04feb1e36be 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilder.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cfg import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -28,9 +28,9 @@ import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue interface ControlFlowBuilder { // Subroutines - fun enterSubroutine(subroutine: KtElement, invocationKind: InvocationKind? = null) + fun enterSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange? = null) - fun exitSubroutine(subroutine: KtElement, invocationKind: InvocationKind? = null): Pseudocode + fun exitSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange? = null): Pseudocode val currentSubroutine: KtElement val returnSubroutine: KtElement @@ -50,7 +50,7 @@ interface ControlFlowBuilder { fun declareVariable(property: KtVariableDeclaration) fun declareFunction(subroutine: KtElement, pseudocode: Pseudocode) - fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, invocationKind: InvocationKind) + fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, eventOccurrencesRange: EventOccurrencesRange) fun declareEntryOrObject(entryOrObject: KtClassOrObject) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt index 920102af7fe..182a760b2e0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowBuilderAdapter.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.cfg import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -139,12 +139,12 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder { delegateBuilder.exitTryFinally() } - override fun enterSubroutine(subroutine: KtElement, invocationKind: InvocationKind?) { - delegateBuilder.enterSubroutine(subroutine, invocationKind) + override fun enterSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?) { + delegateBuilder.enterSubroutine(subroutine, eventOccurrencesRange) } - override fun exitSubroutine(subroutine: KtElement, invocationKind: InvocationKind?): Pseudocode = - delegateBuilder.exitSubroutine(subroutine, invocationKind) + override fun exitSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?): Pseudocode = + delegateBuilder.exitSubroutine(subroutine, eventOccurrencesRange) override val currentSubroutine: KtElement get() = delegateBuilder.currentSubroutine @@ -185,8 +185,8 @@ abstract class ControlFlowBuilderAdapter : ControlFlowBuilder { delegateBuilder.declareFunction(subroutine, pseudocode) } - override fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, invocationKind: InvocationKind) { - delegateBuilder.declareInlinedFunction(subroutine, pseudocode, invocationKind) + override fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, eventOccurrencesRange: EventOccurrencesRange) { + delegateBuilder.declareInlinedFunction(subroutine, pseudocode, eventOccurrencesRange) } override fun declareEntryOrObject(entryOrObject: KtClassOrObject) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt index f9160fbad7b..bdeaee6c49c 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/ControlFlowProcessor.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.InstructionWithValu import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.MagicKind import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.description.canBeRevisited import org.jetbrains.kotlin.contracts.description.isDefinitelyVisited import org.jetbrains.kotlin.descriptors.* @@ -79,8 +79,8 @@ class ControlFlowProcessor( return pseudocode } - private fun generate(subroutine: KtElement, invocationKind: InvocationKind? = null): Pseudocode { - builder.enterSubroutine(subroutine, invocationKind) + private fun generate(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange? = null): Pseudocode { + builder.enterSubroutine(subroutine, eventOccurrencesRange) val cfpVisitor = CFPVisitor(builder) if (subroutine is KtDeclarationWithBody && subroutine !is KtSecondaryConstructor) { val valueParameters = subroutine.valueParameters @@ -97,7 +97,7 @@ class ControlFlowProcessor( } else { cfpVisitor.generateInstructions(subroutine) } - return builder.exitSubroutine(subroutine, invocationKind) + return builder.exitSubroutine(subroutine, eventOccurrencesRange) } private fun generateImplicitReturnValue(bodyExpression: KtExpression, subroutine: KtElement) { @@ -1035,11 +1035,11 @@ class ControlFlowProcessor( return parent.parent is KtDoWhileExpression } - private fun visitFunction(function: KtFunction, invocationKind: InvocationKind? = null) { - if (invocationKind == null) { + private fun visitFunction(function: KtFunction, eventOccurrencesRange: EventOccurrencesRange? = null) { + if (eventOccurrencesRange == null) { processLocalDeclaration(function) } else { - visitInlinedFunction(function, invocationKind) + visitInlinedFunction(function, eventOccurrencesRange) } val isAnonymousFunction = function is KtFunctionLiteral || function.name == null @@ -1048,7 +1048,7 @@ class ControlFlowProcessor( } } - private fun visitInlinedFunction(lambdaFunctionLiteral: KtFunction, invocationKind: InvocationKind) { + private fun visitInlinedFunction(lambdaFunctionLiteral: KtFunction, eventOccurrencesRange: EventOccurrencesRange) { // Defer emitting of inlined declaration deferredGeneratorsStack.peek().add({ builder -> val beforeDeclaration = builder.createUnboundLabel("before inlined declaration") @@ -1056,13 +1056,13 @@ class ControlFlowProcessor( builder.bindLabel(beforeDeclaration) - if (!invocationKind.isDefinitelyVisited()) { + if (!eventOccurrencesRange.isDefinitelyVisited()) { builder.nondeterministicJump(afterDeclaration, lambdaFunctionLiteral, null) } - generate(lambdaFunctionLiteral, invocationKind) + generate(lambdaFunctionLiteral, eventOccurrencesRange) - if (invocationKind.canBeRevisited()) { + if (eventOccurrencesRange.canBeRevisited()) { builder.nondeterministicJump(beforeDeclaration, lambdaFunctionLiteral, null) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt index 19dbbfdf51f..56b07322746 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/ControlFlowInstructionsGenerator.kt @@ -24,7 +24,7 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.special.* -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall @@ -64,9 +64,9 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { return worker } - override fun enterSubroutine(subroutine: KtElement, invocationKind: InvocationKind?) { + override fun enterSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?) { val builder = builder - val shouldInlnie = invocationKind != null + val shouldInlnie = eventOccurrencesRange != null if (builder != null && subroutine is KtFunctionLiteral) { pushBuilder(subroutine, builder.returnSubroutine, shouldInlnie) } else { @@ -76,16 +76,16 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { delegateBuilder.enterSubroutine(subroutine) } - override fun exitSubroutine(subroutine: KtElement, invocationKind: InvocationKind?): Pseudocode { - super.exitSubroutine(subroutine, invocationKind) + override fun exitSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?): Pseudocode { + super.exitSubroutine(subroutine, eventOccurrencesRange) delegateBuilder.exitBlockScope(subroutine) val worker = popBuilder() if (!builders.empty()) { val builder = builders.peek() - if (invocationKind == null) { + if (eventOccurrencesRange == null) { builder.declareFunction(subroutine, worker.pseudocode) } else { - builder.declareInlinedFunction(subroutine, worker.pseudocode, invocationKind) + builder.declareInlinedFunction(subroutine, worker.pseudocode, eventOccurrencesRange) } } return worker.pseudocode @@ -154,7 +154,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { override val currentLoop: KtLoopExpression? get() = if (loopInfo.empty()) null else loopInfo.peek().element - override fun enterSubroutine(subroutine: KtElement, invocationKind: InvocationKind?) { + override fun enterSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?) { val blockInfo = SubroutineInfo( subroutine, /* entry point */ createUnboundLabel(), @@ -215,7 +215,7 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { } } - override fun exitSubroutine(subroutine: KtElement, invocationKind: InvocationKind?): Pseudocode { + override fun exitSubroutine(subroutine: KtElement, eventOccurrencesRange: EventOccurrencesRange?): Pseudocode { getSubroutineExitPoint(subroutine)?.let { bindLabel(it) } pseudocode.addExitInstruction(SubroutineExitInstruction(subroutine, currentScope, false)) bindLabel(error) @@ -273,8 +273,8 @@ class ControlFlowInstructionsGenerator : ControlFlowBuilderAdapter() { add(LocalFunctionDeclarationInstruction(subroutine, pseudocode, currentScope)) } - override fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, invocationKind: InvocationKind) { - add(InlinedLocalFunctionDeclarationInstruction(subroutine, pseudocode, currentScope, invocationKind)) + override fun declareInlinedFunction(subroutine: KtElement, pseudocode: Pseudocode, eventOccurrencesRange: EventOccurrencesRange) { + add(InlinedLocalFunctionDeclarationInstruction(subroutine, pseudocode, currentScope, eventOccurrencesRange)) } override fun declareEntryOrObject(entryOrObject: KtClassOrObject) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/InlinedLocalFunctionDeclarationInstruction.kt b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/InlinedLocalFunctionDeclarationInstruction.kt index dd5708f8f7d..3f0ca93644e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/InlinedLocalFunctionDeclarationInstruction.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/cfg/pseudocode/instructions/special/InlinedLocalFunctionDeclarationInstruction.kt @@ -21,14 +21,14 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.BlockScope import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionImpl import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitor import org.jetbrains.kotlin.cfg.pseudocode.instructions.InstructionVisitorWithResult -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.psi.KtElement class InlinedLocalFunctionDeclarationInstruction( element: KtElement, body: Pseudocode, blockScope: BlockScope, - val kind: InvocationKind + val kind: EventOccurrencesRange ) : LocalFunctionDeclarationInstruction(element, body, blockScope) { override fun createCopy(): InstructionImpl = InlinedLocalFunctionDeclarationInstruction(element, body, blockScope, kind) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ContractDeserializerImpl.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ContractDeserializerImpl.kt index c8d11d9aedf..400e9afe8d0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/ContractDeserializerImpl.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/ContractDeserializerImpl.kt @@ -94,7 +94,7 @@ class ContractDeserializerImpl( val invocationKind = if (proto.hasKind()) proto.kind.toDescriptorInvocationKind() ?: return null else - InvocationKind.UNKNOWN + EventOccurrencesRange.UNKNOWN CallsEffectDeclaration(callable, invocationKind) } } @@ -165,10 +165,10 @@ class ContractDeserializerImpl( BooleanVariableReference(parameterDescriptor) } - private fun ProtoBuf.Effect.InvocationKind.toDescriptorInvocationKind(): InvocationKind? = when (this) { - ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE -> InvocationKind.AT_MOST_ONCE - ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE -> InvocationKind.EXACTLY_ONCE - ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE -> InvocationKind.AT_LEAST_ONCE + private fun ProtoBuf.Effect.InvocationKind.toDescriptorInvocationKind(): EventOccurrencesRange? = when (this) { + ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE -> EventOccurrencesRange.AT_MOST_ONCE + ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE -> EventOccurrencesRange.EXACTLY_ONCE + ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE -> EventOccurrencesRange.AT_LEAST_ONCE } private fun extractType(proto: ProtoBuf.Expression): KotlinType? { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiCallsEffectParser.kt b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiCallsEffectParser.kt index 89d310fad4e..1bd33140a00 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiCallsEffectParser.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/contracts/parsing/effects/PsiCallsEffectParser.kt @@ -18,7 +18,7 @@ package org.jetbrains.kotlin.contracts.parsing.effects import org.jetbrains.kotlin.contracts.description.CallsEffectDeclaration import org.jetbrains.kotlin.contracts.description.EffectDeclaration -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.parsing.* import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.resolve.BindingContext @@ -45,7 +45,7 @@ internal class PsiCallsEffectParser( val kindArgument = resolvedCall.valueArgumentsByIndex?.getOrNull(1) val kind = when (kindArgument) { - is DefaultValueArgument -> InvocationKind.UNKNOWN + is DefaultValueArgument -> EventOccurrencesRange.UNKNOWN is ExpressionValueArgument -> kindArgument.valueArgument?.getArgumentExpression()?.toInvocationKind(callContext.bindingContext) else -> null } @@ -59,15 +59,15 @@ internal class PsiCallsEffectParser( return CallsEffectDeclaration(lambda, kind) } - private fun KtExpression.toInvocationKind(bindingContext: BindingContext): InvocationKind? { + private fun KtExpression.toInvocationKind(bindingContext: BindingContext): EventOccurrencesRange? { val descriptor = this.getResolvedCall(bindingContext)?.resultingDescriptor ?: return null if (!descriptor.parents.first().isInvocationKindEnum()) return null return when (descriptor.fqNameSafe.shortName()) { - ContractsDslNames.AT_MOST_ONCE_KIND -> InvocationKind.AT_MOST_ONCE - ContractsDslNames.EXACTLY_ONCE_KIND -> InvocationKind.EXACTLY_ONCE - ContractsDslNames.AT_LEAST_ONCE_KIND -> InvocationKind.AT_LEAST_ONCE - ContractsDslNames.UNKNOWN_KIND -> InvocationKind.UNKNOWN + ContractsDslNames.AT_MOST_ONCE_KIND -> EventOccurrencesRange.AT_MOST_ONCE + ContractsDslNames.EXACTLY_ONCE_KIND -> EventOccurrencesRange.EXACTLY_ONCE + ContractsDslNames.AT_LEAST_ONCE_KIND -> EventOccurrencesRange.AT_LEAST_ONCE + ContractsDslNames.UNKNOWN_KIND -> EventOccurrencesRange.UNKNOWN else -> null } } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java index fc3fc31dda4..b41d8358a78 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/BindingContext.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.TestOnly; import org.jetbrains.kotlin.cfg.LeakingThisDescriptor; import org.jetbrains.kotlin.cfg.TailRecursionKind; -import org.jetbrains.kotlin.contracts.description.InvocationKind; +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange; import org.jetbrains.kotlin.contracts.model.Computation; import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor; @@ -221,7 +221,7 @@ public interface BindingContext { WritableSlice IS_UNINITIALIZED = Slices.createSimpleSetSlice(); WritableSlice MUST_BE_LATEINIT = Slices.createSimpleSetSlice(); - WritableSlice LAMBDA_INVOCATIONS = Slices.createSimpleSlice(); + WritableSlice LAMBDA_INVOCATIONS = Slices.createSimpleSlice(); WritableSlice BLOCK = new SetSlice(DO_NOTHING) { @Override diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt index 5bd166ff038..abdf73ea342 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/calls/checkers/CapturingInClosureChecker.kt @@ -8,7 +8,7 @@ package org.jetbrains.kotlin.resolve.calls.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.contracts.description.CallsEffectDeclaration import org.jetbrains.kotlin.contracts.description.ContractProviderKey -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor @@ -147,7 +147,7 @@ class CapturingInClosureChecker : CallChecker { val contractDescription = function.getUserData(ContractProviderKey)?.getContractDescription() ?: return false val effect = contractDescription.effects.filterIsInstance() .find { it.variableReference.descriptor == parameter.original } ?: return false - return effect.kind == InvocationKind.EXACTLY_ONCE + return effect.kind == EventOccurrencesRange.EXACTLY_ONCE } private fun isExactlyOnceContract(bindingContext: BindingContext, argument: KtFunction): Boolean { diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt index e445e3f1fab..934fd49af5e 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/Effects.kt @@ -53,7 +53,7 @@ class ReturnsEffectDeclaration(val value: ConstantReference) : EffectDeclaration * Effect which specifies, that during execution of subroutine, callable [variableReference] will be invoked * [kind] amount of times, and will never be invoked after subroutine call is finished. */ -class CallsEffectDeclaration(val variableReference: VariableReference, val kind: InvocationKind) : EffectDeclaration { +class CallsEffectDeclaration(val variableReference: VariableReference, val kind: EventOccurrencesRange) : EffectDeclaration { override fun accept(contractDescriptionVisitor: ContractDescriptionVisitor, data: D): R = contractDescriptionVisitor.visitCallsEffectDeclaration(this, data) } \ No newline at end of file diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/EventOccurrencesRange.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/EventOccurrencesRange.kt new file mode 100644 index 00000000000..f8a010a9fb3 --- /dev/null +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/EventOccurrencesRange.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2018 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.contracts.description + +import kotlin.math.max +import kotlin.math.min + +enum class EventOccurrencesRange(private val left: Int, private val right: Int) { + ZERO(0, 0), // 0..0 + AT_MOST_ONCE(0, 1), // 0..1 + EXACTLY_ONCE(1, 1), // 1..1 + AT_LEAST_ONCE(1, 2), // 1..* + UNKNOWN(0, 2); // 0..* + + companion object { + private fun fromRange(left: Int, right: Int): EventOccurrencesRange = when (min(left, 1) to min(right, 2)) { + 0 to 0 -> ZERO + 0 to 1 -> AT_MOST_ONCE + 1 to 1 -> EXACTLY_ONCE + 1 to 2 -> AT_LEAST_ONCE + 0 to 2 -> UNKNOWN + else -> throw IllegalArgumentException() + } + + fun or(x: EventOccurrencesRange, y: EventOccurrencesRange): EventOccurrencesRange = fromRange(min(x.left, y.left), max(x.right, y.right)) + + fun plus(x: EventOccurrencesRange, y: EventOccurrencesRange): EventOccurrencesRange = fromRange(x.left + y.left, x.right + y.right) + } + + infix fun or(other: EventOccurrencesRange): EventOccurrencesRange = Companion.or(this, other) + operator fun plus(other: EventOccurrencesRange): EventOccurrencesRange = Companion.plus(this, other) +} + +fun EventOccurrencesRange.isDefinitelyVisited(): Boolean = this == EventOccurrencesRange.EXACTLY_ONCE || this == EventOccurrencesRange.AT_LEAST_ONCE +fun EventOccurrencesRange.canBeRevisited(): Boolean = this == EventOccurrencesRange.UNKNOWN || this == EventOccurrencesRange.AT_LEAST_ONCE diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt deleted file mode 100644 index 72aef24b2b0..00000000000 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/description/InvocationKind.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2010-2018 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.contracts.description - -import kotlin.math.max -import kotlin.math.min - -enum class InvocationKind(private val left: Int, private val right: Int) { - ZERO(0, 0), // 0..0 - AT_MOST_ONCE(0, 1), // 0..1 - EXACTLY_ONCE(1, 1), // 1..1 - AT_LEAST_ONCE(1, 2), // 1..* - UNKNOWN(0, 2); // 0..* - - companion object { - private fun fromRange(left: Int, right: Int): InvocationKind = when (min(left, 1) to min(right, 2)) { - 0 to 0 -> ZERO - 0 to 1 -> AT_MOST_ONCE - 1 to 1 -> EXACTLY_ONCE - 1 to 2 -> AT_LEAST_ONCE - 0 to 2 -> UNKNOWN - else -> throw IllegalArgumentException() - } - - fun or(x: InvocationKind, y: InvocationKind): InvocationKind = fromRange(min(x.left, y.left), max(x.right, y.right)) - - fun and(x: InvocationKind, y: InvocationKind): InvocationKind = fromRange(x.left + y.left, x.right + y.right) - } - - infix fun or(other: InvocationKind): InvocationKind = Companion.or(this, other) - infix fun and(other: InvocationKind): InvocationKind = Companion.and(this, other) -} - -fun InvocationKind.isDefinitelyVisited(): Boolean = this == InvocationKind.EXACTLY_ONCE || this == InvocationKind.AT_LEAST_ONCE -fun InvocationKind.canBeRevisited(): Boolean = this == InvocationKind.UNKNOWN || this == InvocationKind.AT_LEAST_ONCE diff --git a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt index 284d6dbe370..e4d40a98c82 100644 --- a/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt +++ b/compiler/resolution/src/org/jetbrains/kotlin/contracts/model/structure/Effects.kt @@ -16,12 +16,12 @@ package org.jetbrains.kotlin.contracts.model.structure -import org.jetbrains.kotlin.contracts.description.InvocationKind +import org.jetbrains.kotlin.contracts.description.EventOccurrencesRange import org.jetbrains.kotlin.contracts.model.ESEffect import org.jetbrains.kotlin.contracts.model.ESValue import org.jetbrains.kotlin.contracts.model.SimpleEffect -data class ESCalls(val callable: ESValue, val kind: InvocationKind) : SimpleEffect() { +data class ESCalls(val callable: ESValue, val kind: EventOccurrencesRange) : SimpleEffect() { override fun isImplies(other: ESEffect): Boolean? { if (other !is ESCalls) return null diff --git a/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt b/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt index 72cceb445ae..c421c1e8672 100644 --- a/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt +++ b/compiler/serialization/src/org/jetbrains/kotlin/serialization/ContractSerializer.kt @@ -188,10 +188,10 @@ class ContractSerializer { } } - private fun invocationKindProtobufEnum(kind: InvocationKind): ProtoBuf.Effect.InvocationKind? = when (kind) { - InvocationKind.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE - InvocationKind.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE - InvocationKind.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE + private fun invocationKindProtobufEnum(kind: EventOccurrencesRange): ProtoBuf.Effect.InvocationKind? = when (kind) { + EventOccurrencesRange.AT_MOST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_MOST_ONCE + EventOccurrencesRange.EXACTLY_ONCE -> ProtoBuf.Effect.InvocationKind.EXACTLY_ONCE + EventOccurrencesRange.AT_LEAST_ONCE -> ProtoBuf.Effect.InvocationKind.AT_LEAST_ONCE else -> null }