From 0cb7e5ba72f90ce1e29b23054430672ad3e9527f Mon Sep 17 00:00:00 2001 From: Ilya Matveev Date: Thu, 20 Apr 2017 17:17:10 +0700 Subject: [PATCH] stdlib: StringBuilder: insert "null" if the argument is null This patch changes the behaviour of StringBuilder.append and StringBuilder.insert methods if the argument is null in accordance with Kotlin JVM. --- .../tests/runtime/text/string_builder0.kt | 36 ++++++++++++------- .../main/kotlin/kotlin/text/StringBuilder.kt | 28 +++++++-------- 2 files changed, 37 insertions(+), 27 deletions(-) diff --git a/backend.native/tests/runtime/text/string_builder0.kt b/backend.native/tests/runtime/text/string_builder0.kt index c965fd5edb1..dfb009bf62a 100644 --- a/backend.native/tests/runtime/text/string_builder0.kt +++ b/backend.native/tests/runtime/text/string_builder0.kt @@ -21,7 +21,7 @@ fun assertEquals(value1: Int, value2: Int) { fun assertEquals(builder: StringBuilder, content: String) = assertEquals(builder.toString(), content) -// IndexOutOfBoundsException +// IndexOutOfBoundsException. fun assertException(body: () -> Unit) { try { body() @@ -101,7 +101,7 @@ fun testInsertSingle(value: Char) { } fun testInsert() { - // String/CharSequence/CharArray + // String/CharSequence/CharArray. testInsertString("abcd", 0, "12", "12abcd") testInsertString("abcd", 4, "12", "abcd12") testInsertString("abcd", 2, "12", "ab12cd") @@ -109,31 +109,39 @@ fun testInsert() { testInsertStringException("a", -1, "1") testInsertStringException("a", 2, "1") - // Subsequence of CharSequence - // Insert in the beginning - assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 0), "abcd") // 0 symbols - assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 1), "1abcd") // 1 symbol - assertEquals(StringBuilder("abcd").insert(0, "1234", 1, 3), "23abcd") // 2 symbols + // Null inserting. + assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?), "nullabcd") + assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?), "abcdnull") + assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?), "abnullcd") + assertEquals(StringBuilder("").insert(0, null as CharSequence?), "null") - // Insert in the end + // Subsequence of CharSequence. + // Insert in the beginning. + assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 0), "abcd") // 0 symbols + assertEquals(StringBuilder("abcd").insert(0, "1234", 0, 1), "1abcd") // 1 symbol + assertEquals(StringBuilder("abcd").insert(0, "1234", 1, 3), "23abcd") // 2 symbols + assertEquals(StringBuilder("abcd").insert(0, null as CharSequence?, 1, 3), "ulabcd") // 2 symbols of null + + // Insert in the end. assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 0), "abcd") assertEquals(StringBuilder("abcd").insert(4, "1234", 0, 1), "abcd1") assertEquals(StringBuilder("abcd").insert(4, "1234", 1, 3), "abcd23") + assertEquals(StringBuilder("abcd").insert(4, null as CharSequence?, 1, 3), "abcdul") - // Insert in the middle + // Insert in the middle. assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 0), "abcd") assertEquals(StringBuilder("abcd").insert(2, "1234", 0, 1), "ab1cd") assertEquals(StringBuilder("abcd").insert(2, "1234", 1, 3), "ab23cd") + assertEquals(StringBuilder("abcd").insert(2, null as CharSequence?, 1, 3), "abulcd") - // Incorrect indices + // Incorrect indices. assertException { StringBuilder("a").insert(-1, "1", 0, 0) } assertException { StringBuilder("a").insert(2, "1", 0, 0) } assertException { StringBuilder("a").insert(1, "1", -1, 0) } assertException { StringBuilder("a").insert(1, "1", 0, 2) } assertException { StringBuilder("a").insert(1, "123", 2, 0) } - - // Other types + // Other types. testInsertSingle(true) testInsertSingle(42.toByte()) testInsertSingle(42.toShort()) @@ -147,7 +155,6 @@ fun testInsert() { } }) testInsertSingle('a') - } // Reverse ================================================================================================== @@ -248,6 +255,9 @@ fun testBasic() { sb.append(12345678L) assertEquals(15, sb.length) assertEquals("1, true12345678", sb.toString()) + sb.append(null as CharSequence?) + assertEquals(19, sb.length) + assertEquals("1, true12345678null", sb.toString()) sb.length = 0 assertEquals(0, sb.length) diff --git a/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt b/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt index 5b1124d5937..5a666e26c3b 100644 --- a/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt +++ b/runtime/src/main/kotlin/kotlin/text/StringBuilder.kt @@ -146,15 +146,15 @@ class StringBuilder private constructor ( } fun insert(index: Int, csq: CharSequence?): StringBuilder { - // TODO: how to treat nulls properly? - if (csq == null) return this - return insert(index, csq, 0, csq.length) + // Kotlin JVM inserts the "null" string if the argument is null. + val toInsert = csq ?: "null" + return insert(index, toInsert, 0, toInsert.length) } fun insert(index: Int, csq: CharSequence?, start: Int, end: Int): StringBuilder { - // TODO: how to treat nulls properly? - if (csq == null) return this - if (start < 0 || end < start || start > csq.length) throw IndexOutOfBoundsException() + // Kotlin JVM processes null as if the argument was "null" char sequence. + val toInsert = csq ?: "null" + if (start < 0 || end < start || start > toInsert.length) throw IndexOutOfBoundsException() checkInsertIndex(index) val extraLength = end - start @@ -168,7 +168,7 @@ class StringBuilder private constructor ( from = start to = index while (from < end) { - array[to++] = csq[from++] + array[to++] = toInsert[from++] } length += extraLength @@ -214,19 +214,19 @@ class StringBuilder private constructor ( } override fun append(csq: CharSequence?): StringBuilder { - // TODO: how to treat nulls properly? - if (csq == null) return this - return append(csq, 0, csq.length) + // Kotlin JVM processes null as if the argument was "null" char sequence. + val toAppend = csq ?: "null" + return append(toAppend, 0, toAppend.length) } override fun append(csq: CharSequence?, start: Int, end: Int): StringBuilder { - // TODO: how to treat nulls properly? - if (csq == null) return this - if (start < 0 || end < start || start > csq.length) throw IndexOutOfBoundsException() + // Kotlin JVM processes null as if the argument was "null" char sequence. + val toAppend = csq ?: "null" + if (start < 0 || end < start || start > toAppend.length) throw IndexOutOfBoundsException() ensureExtraCapacity(end - start) var index = start while (index < end) - array[length++] = csq[index++] + array[length++] = toAppend[index++] return this }