From 6f9d3bdd3234f3ec8a0708f5f80386eb9c26c87f Mon Sep 17 00:00:00 2001 From: Andrew Golovashevich Date: Tue, 18 Mar 2025 20:28:29 +0300 Subject: [PATCH] [history] Added contracts and changed names to avoid ambiguous calls --- .../highlevel_try_finally/safe_autoclose.kt | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/src/commonMain/kotlin/ru/landgrafhomyak/utility/highlevel_try_finally/safe_autoclose.kt b/src/commonMain/kotlin/ru/landgrafhomyak/utility/highlevel_try_finally/safe_autoclose.kt index 0d14a03..239852a 100644 --- a/src/commonMain/kotlin/ru/landgrafhomyak/utility/highlevel_try_finally/safe_autoclose.kt +++ b/src/commonMain/kotlin/ru/landgrafhomyak/utility/highlevel_try_finally/safe_autoclose.kt @@ -1,22 +1,47 @@ package ru.landgrafhomyak.utility.highlevel_try_finally -inline fun safeAutoClose( +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract + +inline fun safeAutoClose1( finally: () -> Unit, action: () -> R -): R = safeAutoClose(onError = finally, onSuccess = finally, onCrossReturn = finally, action = action) +): R { + @Suppress("WRONG_INVOCATION_KIND") + contract { + callsInPlace(action, InvocationKind.EXACTLY_ONCE) + callsInPlace(finally, InvocationKind.EXACTLY_ONCE) + } + return safeAutoClose3(onError = finally, onSuccess = finally, onCrossReturn = finally, action = action) +} -inline fun safeAutoClose( +inline fun safeAutoClose2( onError: () -> Unit = {}, onSuccess: () -> Unit = {}, action: () -> R -): R = safeAutoClose(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action) +): R { + @Suppress("WRONG_INVOCATION_KIND") + contract { + callsInPlace(action, InvocationKind.EXACTLY_ONCE) + callsInPlace(onError, InvocationKind.AT_MOST_ONCE) + callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) + } + return safeAutoClose3(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action) +} -inline fun safeAutoClose( +inline fun safeAutoClose3( onError: () -> Unit = {}, onSuccess: () -> Unit = {}, onCrossReturn: () -> Unit = {}, action: () -> R ): R { + contract { + callsInPlace(action, InvocationKind.EXACTLY_ONCE) + callsInPlace(onError, InvocationKind.AT_MOST_ONCE) + callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) + callsInPlace(onCrossReturn, InvocationKind.AT_MOST_ONCE) + } + val ret: R var wasError = false var crossReturned = true