diff --git a/libraries/stdlib/jdk7/src/kotlin/io/path/PathReadWrite.kt b/libraries/stdlib/jdk7/src/kotlin/io/path/PathReadWrite.kt index 20eab88422a..2ecd893accb 100644 --- a/libraries/stdlib/jdk7/src/kotlin/io/path/PathReadWrite.kt +++ b/libraries/stdlib/jdk7/src/kotlin/io/path/PathReadWrite.kt @@ -16,6 +16,7 @@ import java.nio.file.Files import java.nio.file.OpenOption import java.nio.file.Path import java.nio.file.StandardOpenOption +import kotlin.contracts.* import kotlin.jvm.Throws /** @@ -277,6 +278,9 @@ public inline fun Path.readLines(charset: Charset = Charsets.UTF_8): List Path.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence) -> T): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } return Files.newBufferedReader(this, charset).use { block(it.lineSequence()) } } diff --git a/libraries/stdlib/jdk7/test/PathReadWriteTest.kt b/libraries/stdlib/jdk7/test/PathReadWriteTest.kt index b45ecb2926c..e9ca1f5de9b 100644 --- a/libraries/stdlib/jdk7/test/PathReadWriteTest.kt +++ b/libraries/stdlib/jdk7/test/PathReadWriteTest.kt @@ -158,9 +158,13 @@ class PathReadWriteTest : AbstractPathTest() { assertEquals(listOf("Hello", "World"), file.readLines()) - file.useLines { - assertEquals(listOf("Hello", "World"), it.toList()) + val lines: List + val linesResult = file.useLines { + lines = it.toList() + lines } + assertEquals(listOf("Hello", "World"), lines) + assertEquals(lines, linesResult) val text = file.inputStream().reader().readText() assertTrue("Hello" in text) diff --git a/libraries/stdlib/jvm/src/kotlin/io/FileReadWrite.kt b/libraries/stdlib/jvm/src/kotlin/io/FileReadWrite.kt index b5102f4b44e..115927dab6b 100644 --- a/libraries/stdlib/jvm/src/kotlin/io/FileReadWrite.kt +++ b/libraries/stdlib/jvm/src/kotlin/io/FileReadWrite.kt @@ -15,6 +15,8 @@ import java.util.* import java.nio.charset.Charset import java.nio.charset.CharsetEncoder import java.nio.charset.CodingErrorAction +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.math.ceil @@ -279,5 +281,9 @@ public fun File.readLines(charset: Charset = Charsets.UTF_8): List { * @param charset character set to use. By default uses UTF-8 charset. * @return the value returned by [block]. */ -public inline fun File.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence) -> T): T = - bufferedReader(charset).use { block(it.lineSequence()) } +public inline fun File.useLines(charset: Charset = Charsets.UTF_8, block: (Sequence) -> T): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return bufferedReader(charset).use { block(it.lineSequence()) } +} diff --git a/libraries/stdlib/jvm/src/kotlin/io/ReadWrite.kt b/libraries/stdlib/jvm/src/kotlin/io/ReadWrite.kt index 84358cbdfa5..372c94a2b5f 100644 --- a/libraries/stdlib/jvm/src/kotlin/io/ReadWrite.kt +++ b/libraries/stdlib/jvm/src/kotlin/io/ReadWrite.kt @@ -11,6 +11,8 @@ import java.io.* import java.nio.charset.Charset import java.net.URL import java.util.NoSuchElementException +import kotlin.contracts.InvocationKind +import kotlin.contracts.contract import kotlin.internal.* @@ -48,8 +50,12 @@ public fun Reader.readLines(): List { * the processing is complete. * @return the value returned by [block]. */ -public inline fun Reader.useLines(block: (Sequence) -> T): T = - buffered().use { block(it.lineSequence()) } +public inline fun Reader.useLines(block: (Sequence) -> T): T { + contract { + callsInPlace(block, InvocationKind.EXACTLY_ONCE) + } + return buffered().use { block(it.lineSequence()) } +} /** Creates a new reader for the string. */ @kotlin.internal.InlineOnly diff --git a/libraries/stdlib/jvm/test/io/ReadWrite.kt b/libraries/stdlib/jvm/test/io/ReadWrite.kt index fc57ed1fb49..89738f0a4c7 100644 --- a/libraries/stdlib/jvm/test/io/ReadWrite.kt +++ b/libraries/stdlib/jvm/test/io/ReadWrite.kt @@ -47,9 +47,13 @@ class ReadWriteTest { assertEquals(listOf("Hello", "World"), sample().readLines()) - sample().useLines { - assertEquals(listOf("Hello", "World"), it.toList()) + val lines: List + val linesResult = sample().useLines { + lines = it.toList() + lines } + assertEquals(listOf("Hello", "World"), lines) + assertEquals(lines, linesResult) var reader = StringReader("") @@ -94,9 +98,13 @@ class ReadWriteTest { assertEquals(arrayListOf("Hello", "World"), file.readLines()) - file.useLines { - assertEquals(arrayListOf("Hello", "World"), it.toList()) + val lines: List + val linesResult = file.useLines { + lines = it.toList() + lines } + assertEquals(listOf("Hello", "World"), lines) + assertEquals(lines, linesResult) val text = file.inputStream().reader().readText() assertTrue(text.contains("Hello"))