Manually inlined 'safeAutoClose' implementations to reduce debug info size and generated code size

This commit is contained in:
Andrew Golovashevich 2025-08-24 16:18:01 +03:00
parent 7d947fb9e3
commit 538bf7a76a

View File

@ -1,4 +1,4 @@
@file:Suppress("unused") @file:Suppress("unused", "DuplicatedCode")
@file:JvmName("SafeAutocloseKt") @file:JvmName("SafeAutocloseKt")
package ru.landgrafhomyak.utility.highlevel_try_finally package ru.landgrafhomyak.utility.highlevel_try_finally
@ -9,49 +9,97 @@ import kotlin.jvm.JvmName
@Suppress("WRONG_INVOCATION_KIND") @Suppress("WRONG_INVOCATION_KIND")
inline fun <R> safeAutoClose1( inline fun <R> safeAutoClose1(
finally: () -> Unit, `finally`: () -> Unit,
action: () -> R action: () -> R,
): R { ): R {
contract { contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE) callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(finally, InvocationKind.EXACTLY_ONCE) callsInPlace(`finally`, InvocationKind.EXACTLY_ONCE)
} }
return safeAutoClose3(onError = finally, onSuccess = finally, onCrossReturn = finally, action = action) val ret: R
var wasError = false
try {
ret = action()
} catch (e1: Throwable) {
wasError = true
try {
`finally`()
} catch (e2: Throwable) {
ExceptionsKt.addSuppressed(e1, e2)
}
throw e1;
} finally {
if (!wasError)
`finally`()
}
return ret
} }
@Suppress("WRONG_INVOCATION_KIND") @Suppress("WRONG_INVOCATION_KIND")
inline fun <R> safeAutoClose2( inline fun <R> safeAutoClose2(
onError: () -> Unit = {}, onError: () -> Unit = {},
onSuccess: () -> Unit = {}, onSuccess: () -> Unit = {},
action: () -> R action: () -> R,
): R { ): R {
contract { contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE) callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(onError, InvocationKind.AT_MOST_ONCE) callsInPlace(onError, InvocationKind.AT_MOST_ONCE)
callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE)
} }
return safeAutoClose3(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action) val ret: R
var wasError = false
try {
ret = action()
} catch (e1: Throwable) {
wasError = true
try {
onError()
} catch (e2: Throwable) {
ExceptionsKt.addSuppressed(e1, e2)
}
throw e1;
} finally {
if (!wasError)
onSuccess()
}
return ret
} }
@Suppress("WRONG_INVOCATION_KIND") @Suppress("WRONG_INVOCATION_KIND")
inline fun <R> safeAutoClose2e( inline fun <R> safeAutoClose2e(
onError: (Throwable) -> Unit = { _ -> }, onError: (Throwable) -> Unit = { _ -> },
onSuccess: () -> Unit = {}, onSuccess: () -> Unit = {},
action: () -> R action: () -> R,
): R { ): R {
contract { contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE) callsInPlace(action, InvocationKind.EXACTLY_ONCE)
callsInPlace(onError, InvocationKind.AT_MOST_ONCE) callsInPlace(onError, InvocationKind.AT_MOST_ONCE)
callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE)
} }
return safeAutoClose3e(onError = onError, onSuccess = onSuccess, onCrossReturn = onSuccess, action = action) val ret: R
var wasError = false
try {
ret = action()
} catch (e1: Throwable) {
wasError = true
try {
onError(e1)
} catch (e2: Throwable) {
ExceptionsKt.addSuppressed(e1, e2)
}
throw e1;
} finally {
if (!wasError)
onSuccess()
}
return ret
} }
inline fun <R> safeAutoClose3( inline fun <R> safeAutoClose3(
onError: () -> Unit = {}, onError: () -> Unit = {},
onSuccess: () -> Unit = {}, onSuccess: () -> Unit = {},
onCrossReturn: () -> Unit = {}, onCrossReturn: () -> Unit = {},
action: () -> R action: () -> R,
): R { ): R {
contract { contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE) callsInPlace(action, InvocationKind.EXACTLY_ONCE)
@ -59,14 +107,36 @@ inline fun <R> safeAutoClose3(
callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE) callsInPlace(onSuccess, InvocationKind.AT_MOST_ONCE)
callsInPlace(onCrossReturn, InvocationKind.AT_MOST_ONCE) callsInPlace(onCrossReturn, InvocationKind.AT_MOST_ONCE)
} }
return safeAutoClose3e(onError = { t -> onError() }, onSuccess = onSuccess, onCrossReturn = onCrossReturn, action = action) val ret: R
var wasError = false
var crossReturned = true
try {
ret = action()
crossReturned = false
} catch (e1: Throwable) {
wasError = true
try {
onError()
} catch (e2: Throwable) {
ExceptionsKt.addSuppressed(e1, e2)
}
throw e1
} finally {
if (!wasError) {
if (crossReturned)
onCrossReturn()
else
onSuccess()
}
}
return ret
} }
inline fun <R> safeAutoClose3e( inline fun <R> safeAutoClose3e(
onError: (Throwable) -> Unit = { _ -> }, onError: (Throwable) -> Unit = { _ -> },
onSuccess: () -> Unit = {}, onSuccess: () -> Unit = {},
onCrossReturn: () -> Unit = {}, onCrossReturn: () -> Unit = {},
action: () -> R action: () -> R,
): R { ): R {
contract { contract {
callsInPlace(action, InvocationKind.EXACTLY_ONCE) callsInPlace(action, InvocationKind.EXACTLY_ONCE)