diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index 27e4e7d604b..7f33d7778f2 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -879,7 +879,7 @@ task string_builder0(type: RunKonanTest) { } task string0(type: RunKonanTest) { - goldValue = "true\ntrue\nПРИВЕТ\nпривет\nПока\n" + goldValue = "true\ntrue\nПРИВЕТ\nпривет\nПока\ntrue\n" source = "runtime/text/string0.kt" } diff --git a/backend.native/tests/runtime/text/string0.kt b/backend.native/tests/runtime/text/string0.kt index 069c3d47f9e..eb0a4b42dbf 100644 --- a/backend.native/tests/runtime/text/string0.kt +++ b/backend.native/tests/runtime/text/string0.kt @@ -6,4 +6,5 @@ fun main(args: Array) { println(strI18n.toUpperCase()) println(strI18n.toLowerCase()) println("пока".capitalize()) + println("http://jetbrains.com".startsWith("http://")) } \ No newline at end of file diff --git a/runtime/src/main/kotlin/konan/internal/Strings.kt b/runtime/src/main/kotlin/konan/internal/Strings.kt index 240d9cae55e..1f4d63d8819 100644 --- a/runtime/src/main/kotlin/konan/internal/Strings.kt +++ b/runtime/src/main/kotlin/konan/internal/Strings.kt @@ -75,28 +75,6 @@ public fun String.replaceFirst(oldValue: String, newValue: String, ignoreCase: B return if (index < 0) this else this.replaceRange(index, index + oldValue.length, newValue) } -/** - * Returns a copy of this string converted to upper case using the rules of the default locale. - */ -@SymbolName("Kotlin_String_toUpperCase") -external public fun String.toUpperCase(): String - -/** - * Returns a copy of this string converted to lower case using the rules of the default locale. - */ -@SymbolName("Kotlin_String_toLowerCase") -external public inline fun String.toLowerCase(): String - -/** - * Returns a copy of this string having its first letter uppercased, or the original string, - * if it's empty or already starts with an upper case letter. - * - * @sample samples.text.Strings.captialize - */ -public fun String.capitalize(): String { - return if (isNotEmpty() && this[0].isLowerCase()) substring(0, 1).toUpperCase() + substring(1) else this -} - /** * Returns a copy of this string having its first letter lowercased, or the original string, * if it's empty or already starts with a lower case letter. @@ -112,6 +90,34 @@ public fun String.decapitalize(): String { */ public fun CharSequence.isBlank(): Boolean = length == 0 || indices.all { this[it].isWhitespace() } +/** + * Returns the substring of this string starting at the [startIndex] and ending right before the [endIndex]. + * + * @param startIndex the start index (inclusive). + * @param endIndex the end index (exclusive). + */ +@kotlin.internal.InlineOnly +public inline fun String.substring(startIndex: Int, endIndex: Int): String = + subSequence(startIndex, endIndex) as String + +/** + * Returns `true` if this string starts with the specified prefix. + */ +public fun String.startsWith(prefix: String, ignoreCase: Boolean = false): Boolean = + regionMatches(0, prefix, 0, prefix.length, ignoreCase) + +/** + * Returns `true` if a substring of this string starting at the specified offset [startIndex] starts with the specified prefix. + */ +public fun String.startsWith(prefix: String, startIndex: Int, ignoreCase: Boolean = false): Boolean = + regionMatches(startIndex, prefix, 0, prefix.length, ignoreCase) + +/** + * Returns `true` if this string ends with the specified suffix. + */ +public fun String.endsWith(suffix: String, ignoreCase: Boolean = false): Boolean = + regionMatches(length - suffix.length, suffix, 0, suffix.length, ignoreCase) + /** * Returns `true` if the specified range in this char sequence is equal to the specified range in another char sequence. * @param thisOffset the start offset in this char sequence of the substring to compare. @@ -136,3 +142,25 @@ external public fun CharSequence.regionMatches( external public fun String.regionMatches( thisOffset: Int, other: String, otherOffset: Int, length: Int, ignoreCase: Boolean = false): Boolean + +/** + * Returns a copy of this string converted to upper case using the rules of the default locale. + */ +@SymbolName("Kotlin_String_toUpperCase") +external public fun String.toUpperCase(): String + +/** + * Returns a copy of this string converted to lower case using the rules of the default locale. + */ +@SymbolName("Kotlin_String_toLowerCase") +external public inline fun String.toLowerCase(): String + +/** + * Returns a copy of this string having its first letter uppercased, or the original string, + * if it's empty or already starts with an upper case letter. + * + * @sample samples.text.Strings.captialize + */ +public fun String.capitalize(): String { + return if (isNotEmpty() && this[0].isLowerCase()) substring(0, 1).toUpperCase() + substring(1) else this +} \ No newline at end of file diff --git a/runtime/src/main/kotlin/kotlin/text/Strings.kt b/runtime/src/main/kotlin/kotlin/text/Strings.kt index 0d1e5db58f9..b913143f903 100644 --- a/runtime/src/main/kotlin/kotlin/text/Strings.kt +++ b/runtime/src/main/kotlin/kotlin/text/Strings.kt @@ -712,7 +712,7 @@ public fun CharSequence.endsWith(char: Char, ignoreCase: Boolean = false): Boole */ public fun CharSequence.startsWith(prefix: CharSequence, ignoreCase: Boolean = false): Boolean { if (!ignoreCase && this is String && prefix is String) - return this.startsWith(prefix) + return (this as String).startsWith(prefix) else return regionMatchesImpl(0, prefix, 0, prefix.length, ignoreCase) } @@ -722,7 +722,7 @@ public fun CharSequence.startsWith(prefix: CharSequence, ignoreCase: Boolean = f */ public fun CharSequence.startsWith(prefix: CharSequence, startIndex: Int, ignoreCase: Boolean = false): Boolean { if (!ignoreCase && this is String && prefix is String) - return this.startsWith(prefix, startIndex) + return (this as String).startsWith(prefix, startIndex) else return regionMatchesImpl(startIndex, prefix, 0, prefix.length, ignoreCase) } @@ -732,7 +732,7 @@ public fun CharSequence.startsWith(prefix: CharSequence, startIndex: Int, ignore */ public fun CharSequence.endsWith(suffix: CharSequence, ignoreCase: Boolean = false): Boolean { if (!ignoreCase && this is String && suffix is String) - return this.endsWith(suffix) + return (this as String).endsWith(suffix) else return regionMatchesImpl(length - suffix.length, suffix, 0, suffix.length, ignoreCase) }