Refactor exception suppression to provide Throwable.addSuppressed extension in kotlin-stdlib.

Place Closeable and AutoCloseable extensions to separate files (CloseableKt and AutoCloseableKt).
#KT-15477 Fixed
This commit is contained in:
Ilya Gorbunov
2016-12-29 08:38:12 +03:00
parent dcd7f3eb57
commit a71b68268d
8 changed files with 142 additions and 74 deletions
@@ -6,15 +6,8 @@ import java.util.regex.MatchResult
internal open class PlatformImplementations {
public open fun closeSuppressed(instance: Closeable, cause: Throwable) {
try {
instance.close()
} catch (closeException: Throwable) {
// eat the closeException as we are already throwing the original cause
// and we don't want to mask the real exception;
// on Java 7 we should call
// e.addSuppressed(closeException)
}
public open fun addSuppressed(cause: Throwable, exception: Throwable) {
// do nothing
}
public open fun getMatchResultNamedGroup(matchResult: MatchResult, name: String): MatchGroup? {
@@ -22,9 +15,11 @@ internal open class PlatformImplementations {
}
}
// TODO: drop before 1.1
@SinceKotlin("1.1")
@PublishedApi
internal fun platformCloseSuppressed(instance: Closeable, cause: Throwable) = IMPLEMENTATIONS.closeSuppressed(instance, cause)
@Deprecated("Provided for binary compatibility", level = DeprecationLevel.HIDDEN)
internal fun platformCloseSuppressed(instance: Closeable, cause: Throwable) = instance.closeSuppressed(cause)
@JvmField
@@ -0,0 +1,56 @@
/*
* Copyright 2010-2016 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("CloseableKt")
@file:JvmVersion
package kotlin.io
import java.io.Closeable
import kotlin.internal.*
/**
* Executes the given [block] function on this resource and then closes it down correctly whether an exception
* is thrown or not.
*
* @param block a function to process this [Closeable] resource.
* @return the result of [block] function invoked on this resource.
*/
@InlineOnly
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Throwable) {
closed = true
this?.closeSuppressed(e)
throw e
} finally {
if (this != null && !closed) {
close()
}
}
}
@SinceKotlin("1.1")
@PublishedApi
internal fun Closeable.closeSuppressed(cause: Throwable) {
try {
close()
} catch (closeException: Throwable) {
// on Java 7 we should call
IMPLEMENTATIONS.addSuppressed(cause, closeException)
}
}
@@ -143,25 +143,3 @@ public inline fun URL.readText(charset: Charset = Charsets.UTF_8): String = read
*/
public fun URL.readBytes(): ByteArray = openStream().use { it.readBytes() }
/**
* Executes the given [block] function on this resource and then closes it down correctly whether an exception
* is thrown or not.
*
* @param block a function to process this [Closeable] resource.
* @return the result of [block] function invoked on this resource.
*/
@kotlin.internal.InlineOnly
public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
var closed = false
try {
return block(this)
} catch (e: Throwable) {
closed = true
if (this != null) platformCloseSuppressed(this, e)
throw e
} finally {
if (this != null && !closed) {
close()
}
}
}
@@ -6,6 +6,7 @@ package kotlin
import java.io.PrintStream
import java.io.PrintWriter
import kotlin.internal.*
/**
* Prints the stack trace of this throwable to the standard output.
@@ -32,3 +33,9 @@ public inline fun Throwable.printStackTrace(stream: PrintStream): Unit = (this a
@Suppress("ConflictingExtensionProperty")
public val Throwable.stackTrace: Array<StackTraceElement>
get() = (this as java.lang.Throwable).stackTrace!!
/**
* When supported by the platform adds the specified exception to the list of exceptions that were
* suppressed in order to deliver this exception.
*/
public fun Throwable.addSuppressed(exception: Throwable) = IMPLEMENTATIONS.addSuppressed(this, exception)