diff --git a/js/js.libraries/src/core/javalang.kt b/js/js.libraries/src/core/javalang.kt index fa927038af5..df87315b7f0 100644 --- a/js/js.libraries/src/core/javalang.kt +++ b/js/js.libraries/src/core/javalang.kt @@ -40,7 +40,7 @@ public trait Comparable { library public trait Appendable { public open fun append(csq: CharSequence?): Appendable - //public open fun append(csq: CharSequence?, start: Int, end: Int): Appendable + public open fun append(csq: CharSequence?, start: Int, end: Int): Appendable public open fun append(c: Char): Appendable } @@ -48,8 +48,7 @@ library public class StringBuilder() : Appendable { override fun append(c: Char): StringBuilder = js.noImpl override fun append(csq: CharSequence?): StringBuilder = js.noImpl - //TODO - //override fun append(csq: CharSequence?, start: Int, end: Int): StringBuilder = js.noImpl + override fun append(csq: CharSequence?, start: Int, end: Int): StringBuilder = js.noImpl public fun append(obj: Any?): StringBuilder = js.noImpl public fun reverse(): StringBuilder = js.noImpl override fun toString(): String = js.noImpl diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringBuilderTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringBuilderTest.java new file mode 100644 index 00000000000..3c4bf9c0755 --- /dev/null +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringBuilderTest.java @@ -0,0 +1,10 @@ +package org.jetbrains.k2js.test.semantics; + +import junit.framework.Test; + +@SuppressWarnings("JUnitTestCaseWithNoTests") +public final class StdLibStringBuilderTest extends JsUnitTestBase { + public static Test suite() throws Exception { + return createTestSuiteForFile("libraries/stdlib/test/text/StringBuilderTest.kt"); + } +} diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringTest.java new file mode 100644 index 00000000000..1a05014230a --- /dev/null +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/StdLibStringTest.java @@ -0,0 +1,10 @@ +package org.jetbrains.k2js.test.semantics; + +import junit.framework.Test; + +@SuppressWarnings("JUnitTestCaseWithNoTests") +public final class StdLibStringTest extends JsUnitTestBase { + public static Test suite() throws Exception { + return createTestSuiteForFile("libraries/stdlib/test/text/StringTest.kt"); + } +} diff --git a/js/js.translator/src/org/jetbrains/k2js/config/Config.java b/js/js.translator/src/org/jetbrains/k2js/config/Config.java index e570c104029..aea3607710f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/config/Config.java +++ b/js/js.translator/src/org/jetbrains/k2js/config/Config.java @@ -139,6 +139,7 @@ public abstract class Config { "/kotlin/Ranges.kt", "/kotlin/Numbers.kt", "/kotlin/text/Strings.kt", + "/kotlin/text/StringBuilder.kt", "/kotlin/dom/Dom.kt", "/kotlin/test/Test.kt" ); diff --git a/js/js.translator/testData/kotlin_lib.js b/js/js.translator/testData/kotlin_lib.js index 39e358bd7df..0e9d42c1081 100644 --- a/js/js.translator/testData/kotlin_lib.js +++ b/js/js.translator/testData/kotlin_lib.js @@ -649,8 +649,15 @@ function () { this.string = ""; }, { - append: function (obj) { - this.string = this.string + obj.toString(); + append: function (obj, from, to) { + if (from == undefined && to == undefined) { + this.string = this.string + obj.toString(); + } else if (to == undefined) { + this.string = this.string + obj.toString().substring(from); + } else { + this.string = this.string + obj.toString().substring(from, to); + } + return this; }, reverse: function () { diff --git a/libraries/stdlib/src/kotlin/text/StringBuilder.kt b/libraries/stdlib/src/kotlin/text/StringBuilder.kt new file mode 100644 index 00000000000..de8fffe04f6 --- /dev/null +++ b/libraries/stdlib/src/kotlin/text/StringBuilder.kt @@ -0,0 +1,37 @@ +package kotlin + +/** + * Builds newly created StringBuilder using provided body. + */ +public inline fun StringBuilder(body: StringBuilder.() -> Unit): StringBuilder { + val sb = StringBuilder() + sb.body() + return sb +} + +/** + * Appends all arguments to the given Appendable + */ +public fun T.append(vararg value: CharSequence?): T { + for (item in value) + append(item) + return this +} + +/** + * Appends all arguments to the given StringBuilder + */ +public fun StringBuilder.append(vararg value: String?): StringBuilder { + for (item in value) + append(item) + return this +} + +/** + * Appends all arguments to the given StringBuilder + */ +public fun StringBuilder.append(vararg value: Any?): StringBuilder { + for (item in value) + append(item) + return this +} diff --git a/libraries/stdlib/src/kotlin/text/StringBuilderJVM.kt b/libraries/stdlib/src/kotlin/text/StringBuilderJVM.kt new file mode 100644 index 00000000000..cf06ad96032 --- /dev/null +++ b/libraries/stdlib/src/kotlin/text/StringBuilderJVM.kt @@ -0,0 +1,59 @@ +package kotlin + +/** Line separator for current system. */ +val LINE_SEPARATOR: String = System.getProperty("line.separator")!! + +/** Appends line separator to Appendable. */ +public fun Appendable.appendln(): Appendable = append(LINE_SEPARATOR) + +/** Appends value to the given Appendable and line separator after it. */ +public fun Appendable.appendln(value: CharSequence?): Appendable = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given Appendable and line separator after it. */ +public fun Appendable.appendln(value: Char): Appendable = append(value).append(LINE_SEPARATOR) + +/** Appends line separator to StringBuilder. */ + +public fun StringBuilder.appendln(): StringBuilder = append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: StringBuffer?): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: CharSequence?): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: String?): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Any?): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: StringBuilder?): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: CharArray): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Char): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Boolean): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Int): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Short): StringBuilder = append(value.toInt()).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Byte): StringBuilder = append(value.toInt()).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Long): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Float): StringBuilder = append(value).append(LINE_SEPARATOR) + +/** Appends value to the given StringBuilder and line separator after it. */ +public fun StringBuilder.appendln(value: Double): StringBuilder = append(value).append(LINE_SEPARATOR) diff --git a/libraries/stdlib/src/kotlin/text/Strings.kt b/libraries/stdlib/src/kotlin/text/Strings.kt index 6256563df74..4de2122fcd9 100644 --- a/libraries/stdlib/src/kotlin/text/Strings.kt +++ b/libraries/stdlib/src/kotlin/text/Strings.kt @@ -57,11 +57,11 @@ public val String.indices: IntRange * Returns a subsequence specified by given set of indices. */ public fun CharSequence.slice(indices: Iterable): CharSequence { - val result = StringBuilder() + val sb = StringBuilder() for (i in indices) { - result.append(get(i)) + sb.append(get(i)) } - return result.toString() + return sb.toString() } /** diff --git a/libraries/stdlib/test/text/StringBuilderTest.kt b/libraries/stdlib/test/text/StringBuilderTest.kt new file mode 100644 index 00000000000..90677c70e42 --- /dev/null +++ b/libraries/stdlib/test/text/StringBuilderTest.kt @@ -0,0 +1,28 @@ +package test.text + +import kotlin.test.* +import org.junit.Test as test + +class StringBuilderTest { + + test fun stringBuild() { + val s = StringBuilder { + append("a") + append(true) + }.toString() + assertEquals("atrue", s) + } + + test fun appendMany() { + assertEquals("a1", StringBuilder().append("a", "1").toString()) + assertEquals("a1", StringBuilder().append("a", 1).toString()) + assertEquals("a1", StringBuilder().append("a", StringBuilder().append("1")).toString()) + } + + test fun append() { + // this test is needed for JS implementation + assertEquals("em", StringBuilder { + append("element", 2, 4) + }.toString()) + } +} diff --git a/libraries/stdlib/test/text/StringTest.kt b/libraries/stdlib/test/text/StringTest.kt index d8d9a9942cb..10c6b50c78f 100644 --- a/libraries/stdlib/test/text/StringTest.kt +++ b/libraries/stdlib/test/text/StringTest.kt @@ -123,5 +123,4 @@ class StringTest { assertEquals("new name", s.replaceBefore("=", "new name")) assertEquals("/new/path", s.replaceBeforeLast("=", "/new/path")) } - } diff --git a/libraries/tools/kotlin-js-library/pom.xml b/libraries/tools/kotlin-js-library/pom.xml index 01c94c1834f..6d90531bcd6 100644 --- a/libraries/tools/kotlin-js-library/pom.xml +++ b/libraries/tools/kotlin-js-library/pom.xml @@ -71,6 +71,7 @@ --> +