63 lines
2.1 KiB
Kotlin
63 lines
2.1 KiB
Kotlin
/*
|
|
* Copyright 2010-2017 JetBrains s.r.o.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
@file:JvmName("AutoCloseableKt")
|
|
package kotlin
|
|
|
|
/**
|
|
* Executes the given [block] function on this resource and then closes it down correctly whether an exception
|
|
* is thrown or not.
|
|
*
|
|
* In case if the resource is being closed due to an exception occurred in [block], and the closing also fails with an exception,
|
|
* the latter is added to the [suppressed][java.lang.Throwable.addSuppressed] exceptions of the former.
|
|
*
|
|
* @param block a function to process this [AutoCloseable] resource.
|
|
* @return the result of [block] function invoked on this resource.
|
|
*/
|
|
@SinceKotlin("1.1")
|
|
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
|
@kotlin.internal.InlineOnly
|
|
public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R {
|
|
var exception: Throwable? = null
|
|
try {
|
|
return block(this)
|
|
} catch (e: Throwable) {
|
|
exception = e
|
|
throw e
|
|
} finally {
|
|
this.closeFinally(exception)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Closes this [AutoCloseable], suppressing possible exception or error thrown by [AutoCloseable.close] function when
|
|
* it's being closed due to some other [cause] exception occurred.
|
|
*
|
|
* The suppressed exception is added to the list of suppressed exceptions of [cause] exception.
|
|
*/
|
|
@SinceKotlin("1.1")
|
|
@PublishedApi
|
|
internal fun AutoCloseable?.closeFinally(cause: Throwable?) = when {
|
|
this == null -> {}
|
|
cause == null -> close()
|
|
else ->
|
|
try {
|
|
close()
|
|
} catch (closeException: Throwable) {
|
|
cause.addSuppressed(closeException)
|
|
}
|
|
}
|