Rename InvocationKind to EventOccurrencesRange
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -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) {
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
|
||||
@@ -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? {
|
||||
|
||||
+7
-7
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<PropertyDescriptor, Boolean> IS_UNINITIALIZED = Slices.createSimpleSetSlice();
|
||||
WritableSlice<PropertyDescriptor, Boolean> MUST_BE_LATEINIT = Slices.createSimpleSetSlice();
|
||||
|
||||
WritableSlice<KtLambdaExpression, InvocationKind> LAMBDA_INVOCATIONS = Slices.createSimpleSlice();
|
||||
WritableSlice<KtLambdaExpression, EventOccurrencesRange> LAMBDA_INVOCATIONS = Slices.createSimpleSlice();
|
||||
|
||||
WritableSlice<KtLambdaExpression, Boolean> BLOCK = new SetSlice<KtLambdaExpression>(DO_NOTHING) {
|
||||
@Override
|
||||
|
||||
+2
-2
@@ -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<CallsEffectDeclaration>()
|
||||
.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 {
|
||||
|
||||
Reference in New Issue
Block a user