Relax type parameter constraint for Closeable.use and AutoCloseable.use to allow nullable receiver.
#KT-12894 Fixed
This commit is contained in:
@@ -3,17 +3,17 @@ package kotlin
|
||||
|
||||
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
|
||||
@kotlin.internal.InlineOnly
|
||||
public inline fun <T : AutoCloseable, R> T.use(block: (T) -> R): R {
|
||||
public inline fun <T : AutoCloseable?, R> 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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 <T> 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<Resource>()
|
||||
val e = assertFails {
|
||||
resource.use { requireNotNull(it) }
|
||||
}
|
||||
assertTrue(e is IllegalArgumentException)
|
||||
assertTrue(e.suppressed.isEmpty())
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 <T> 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<Resource>()
|
||||
val e = assertFails {
|
||||
resource.use { requireNotNull(it) }
|
||||
}
|
||||
assertTrue(e is IllegalArgumentException)
|
||||
assertTrue(e.suppressed.isEmpty())
|
||||
}
|
||||
}
|
||||
@@ -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 : Closeable, R> T.use(block: (T) -> R): R {
|
||||
public inline fun <T : Closeable?, R> 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()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +141,15 @@ class ReadWriteTest {
|
||||
assertEquals(arrayListOf("Hello", "World"), list)
|
||||
}
|
||||
|
||||
@test fun testPlatformNullUse() {
|
||||
fun <T> platformNull() = java.util.Collections.singleton(null as T).first()
|
||||
val resource = platformNull<java.io.Closeable>()
|
||||
val result = resource.use {
|
||||
"ok"
|
||||
}
|
||||
assertEquals("ok", result)
|
||||
}
|
||||
|
||||
@test fun testURL() {
|
||||
val url = URL("http://kotlinlang.org")
|
||||
val text = url.readText()
|
||||
|
||||
Reference in New Issue
Block a user