diff --git a/libraries/stdlib/jre7/src/kotlin/Standard.kt b/libraries/stdlib/jre7/src/kotlin/Standard.kt index 4e0cb01d6f2..00f23986da8 100644 --- a/libraries/stdlib/jre7/src/kotlin/Standard.kt +++ b/libraries/stdlib/jre7/src/kotlin/Standard.kt @@ -3,17 +3,17 @@ package kotlin @Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER") @kotlin.internal.InlineOnly -public inline fun T.use(block: (T) -> R): R { +public inline fun T.use(block: (T) -> R): R { var closed = false try { return block(this) } catch (e: Throwable) { closed = true @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") - closeSuppressed(e) + this?.closeSuppressed(e) throw e } finally { - if (!closed) { + if (this != null && !closed) { close() } } diff --git a/libraries/stdlib/jre7/test/TryWithResourcesAutoCloseableTest.kt b/libraries/stdlib/jre7/test/TryWithResourcesAutoCloseableTest.kt index fa2f1fafeb2..a98d6193ec7 100644 --- a/libraries/stdlib/jre7/test/TryWithResourcesAutoCloseableTest.kt +++ b/libraries/stdlib/jre7/test/TryWithResourcesAutoCloseableTest.kt @@ -2,11 +2,14 @@ package kotlin.jdk7.test import java.io.* import org.junit.Test +import java.util.* import kotlin.test.* class TryWithResourcesAutoCloseableTest { + @Suppress("HasPlatformType") fun platformNull() = Collections.singletonList(null as T).first() + class Resource(val faultyClose: Boolean = false) : AutoCloseable { var isClosed = false @@ -80,7 +83,31 @@ class TryWithResourcesAutoCloseableTest { assertEquals("nonLocal", result) assertTrue(resource.isClosed) } + } + + @Test fun nullableResourceSuccess() { + val resource: Resource? = null + val result = resource.use { "ok" } + assertEquals("ok", result) + } + + @Test fun nullableResourceOpFails() { + val resource: Resource? = null + val e = assertFails { + resource.use { requireNotNull(it) } + } + assertTrue(e is IllegalArgumentException) + assertTrue(e.suppressed.isEmpty()) + } + + @Test fun platformResourceOpFails() { + val resource = platformNull() + val e = assertFails { + resource.use { requireNotNull(it) } + } + assertTrue(e is IllegalArgumentException) + assertTrue(e.suppressed.isEmpty()) } } \ No newline at end of file diff --git a/libraries/stdlib/jre7/test/TryWithResourcesCloseableTest.kt b/libraries/stdlib/jre7/test/TryWithResourcesCloseableTest.kt index 7ba7736b658..d26101a09d4 100644 --- a/libraries/stdlib/jre7/test/TryWithResourcesCloseableTest.kt +++ b/libraries/stdlib/jre7/test/TryWithResourcesCloseableTest.kt @@ -2,10 +2,13 @@ package kotlin.jdk7.test import java.io.* import org.junit.Test +import java.util.* import kotlin.test.* class TryWithResourcesCloseableTest { + @Suppress("HasPlatformType") fun platformNull() = Collections.singletonList(null as T).first() + class Resource(val faultyClose: Boolean = false) : Closeable { var isClosed = false @@ -81,4 +84,27 @@ class TryWithResourcesCloseableTest { } + @Test fun nullableResourceSuccess() { + val resource: Resource? = null + val result = resource.use { "ok" } + assertEquals("ok", result) + } + + @Test fun nullableResourceOpFails() { + val resource: Resource? = null + val e = assertFails { + resource.use { requireNotNull(it) } + } + assertTrue(e is IllegalArgumentException) + assertTrue(e.suppressed.isEmpty()) + } + + @Test fun platformResourceOpFails() { + val resource = platformNull() + val e = assertFails { + resource.use { requireNotNull(it) } + } + assertTrue(e is IllegalArgumentException) + assertTrue(e.suppressed.isEmpty()) + } } \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/io/ReadWrite.kt b/libraries/stdlib/src/kotlin/io/ReadWrite.kt index c0fec9c66f6..3f74f10db6c 100644 --- a/libraries/stdlib/src/kotlin/io/ReadWrite.kt +++ b/libraries/stdlib/src/kotlin/io/ReadWrite.kt @@ -152,17 +152,17 @@ public fun URL.readBytes(): ByteArray = openStream().use { it.readBytes() } * @return the result of [block] function on this closable resource. */ @kotlin.internal.InlineOnly -public inline fun T.use(block: (T) -> R): R { +public inline fun T.use(block: (T) -> R): R { var closed = false try { return block(this) } catch (e: Throwable) { closed = true @Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE") - platformCloseSuppressed(this, e) + if (this != null) platformCloseSuppressed(this, e) throw e } finally { - if (!closed) { + if (this != null && !closed) { close() } } diff --git a/libraries/stdlib/test/io/ReadWrite.kt b/libraries/stdlib/test/io/ReadWrite.kt index 9a556dfad1b..1bba4bf76ca 100644 --- a/libraries/stdlib/test/io/ReadWrite.kt +++ b/libraries/stdlib/test/io/ReadWrite.kt @@ -141,6 +141,15 @@ class ReadWriteTest { assertEquals(arrayListOf("Hello", "World"), list) } + @test fun testPlatformNullUse() { + fun platformNull() = java.util.Collections.singleton(null as T).first() + val resource = platformNull() + val result = resource.use { + "ok" + } + assertEquals("ok", result) + } + @test fun testURL() { val url = URL("http://kotlinlang.org") val text = url.readText()