Extracted to separate library, 'tryFinallyChain'

This commit is contained in:
Andrew Golovashevich 2025-03-22 14:29:45 +03:00
parent 87386193ee
commit ef1d72ca10
7 changed files with 99 additions and 2 deletions

9
.gitignore vendored Normal file
View File

@ -0,0 +1,9 @@
/.idea/
gradle/
.gradle/
build/
*.class
*.jar
/out/
/gradlew*
.kotlin/

36
build.gradle.kts Normal file
View File

@ -0,0 +1,36 @@
import org.jetbrains.kotlin.gradle.dsl.KotlinVersion
import ru.landgrafhomyak.kotlin.kmp_gradle_build_helper.*
import ru.landgrafhomyak.kotlin.kmp_gradle_build_helper.plugin.xomrk
buildscript {
repositories {
mavenCentral()
maven("https://maven.landgrafhomyak.ru/")
}
dependencies {
classpath("ru.landgrafhomyak.kotlin:kotlin-mpp-gradle-build:v0.3k2.1.10")
}
}
group = "ru.landgrafhomyak.utility"
version = "0.4"
repositories {
mavenCentral()
}
xomrk {
kotlin {
setCompatibilityWithKotlin(KotlinVersion.KOTLIN_2_0)
optInContracts()
defineAllMultiplatformTargets()
}
publishing {
repositories {
defineXomrkGiteaMavenRepo()
}
}
}

1
gradle.properties Normal file
View File

@ -0,0 +1 @@
kotlin.code.style=official

1
settings.gradle.kts Normal file
View File

@ -0,0 +1 @@
rootProject.name = "highlevel-try-finally"

View File

@ -0,0 +1,25 @@
package ru.landgrafhomyak.utility.highlevel_try_finally
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
class TryFinallyChainScope @PublishedApi internal constructor() {
@PublishedApi
internal var _actualException: Throwable? = null
@PublishedApi
internal fun _throw() {
this._actualException?.let { e -> throw e }
}
inline fun action(fn: () -> Unit) {
contract {
callsInPlace(fn, InvocationKind.EXACTLY_ONCE)
}
safeAutoClose3e(
onCrossReturn = { throw Error("Cross return not allowed in tryFinallyChain{action{}}") },
onError = { err -> this._actualException?.addSuppressed(err) ?: run { this._actualException = err } },
action = fn
)
}
}

View File

@ -1,7 +1,11 @@
@file:Suppress("unused")
@file:JvmName("SafeAutocloseKt")
package ru.landgrafhomyak.utility.highlevel_try_finally package ru.landgrafhomyak.utility.highlevel_try_finally
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmName
@Suppress("WRONG_INVOCATION_KIND") @Suppress("WRONG_INVOCATION_KIND")
inline fun <R> safeAutoClose1( inline fun <R> safeAutoClose1(
@ -43,7 +47,6 @@ inline fun <R> safeAutoClose2e(
return safeAutoClose3e(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action) return safeAutoClose3e(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action)
} }
inline fun <R> safeAutoClose3( inline fun <R> safeAutoClose3(
onError: () -> Unit = {}, onError: () -> Unit = {},
onSuccess: () -> Unit = {}, onSuccess: () -> Unit = {},

View File

@ -0,0 +1,22 @@
@file:Suppress("unused")
@file:JvmName("TryFinallyChainKt")
package ru.landgrafhomyak.utility.highlevel_try_finally
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
import kotlin.jvm.JvmName
inline fun tryFinallyChain(chains: TryFinallyChainScope.() -> Unit) {
contract {
callsInPlace(chains, InvocationKind.EXACTLY_ONCE)
}
val scope = TryFinallyChainScope()
safeAutoClose3e(
onCrossReturn = { throw Error("Cross return not allowed in tryFinallyChain{}") },
onError = { err -> throw Error("Unexpected exception in tryFinallyChain{}; calling anything outside action{} block isn't allowed", err) },
onSuccess = { scope._throw() },
action = { chains(scope) }
)
}