From c0f3e5f9e81f6d92852d13817da61f429dfd5867 Mon Sep 17 00:00:00 2001 From: Pavel Punegov Date: Thu, 31 May 2018 16:55:55 +0300 Subject: [PATCH] Fix KT-24370. Make indexOf consistent with Kotlin/JVM --- backend.native/tests/build.gradle | 3 ++ backend.native/tests/runtime/text/indexof.kt | 49 ++++++++++++++++++++ runtime/src/main/cpp/KString.cpp | 14 ++++-- 3 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 backend.native/tests/runtime/text/indexof.kt diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index fb166d3c38b..9eb0af6f2f1 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -1720,6 +1720,9 @@ task chars0(type: RunKonanTest) { expectedExitStatus = 0 } +task indexof(type: RunKonanTest) { + source = "runtime/text/indexof.kt" +} task utf8(type: RunKonanTest) { expectedFail = (project.testTarget == 'wasm32') // Uses exceptions. diff --git a/backend.native/tests/runtime/text/indexof.kt b/backend.native/tests/runtime/text/indexof.kt new file mode 100644 index 00000000000..c3e02aae9a2 --- /dev/null +++ b/backend.native/tests/runtime/text/indexof.kt @@ -0,0 +1,49 @@ +/* + * Copyright 2010-2018 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package runtime.text.indexof + +import kotlin.test.* + +@Test fun runTest() { + var str = "Hello World!!" // for indexOf String + var ch = 'a' // for indexOf Char + + assertEquals(6, str.indexOf("World", 0)) + assertEquals(6, str.indexOf("World", -1)) + + assertEquals(-1, str.indexOf(ch, 0)) + + str = "Kotlin/Native" + assertEquals(-1, str.indexOf("/", str.length + 1)) + assertEquals(-1, str.indexOf("/", Int.MAX_VALUE)) + assertEquals(str.length, str.indexOf("", Int.MAX_VALUE)) + assertEquals(1, str.indexOf("", 1)) + + assertEquals(8, str.indexOf(ch, 1)) + assertEquals(-1, str.indexOf(ch, str.length - 1)) + + str = "" + assertEquals(-1, str.indexOf("a", -3)) + assertEquals(0, str.indexOf("", 0)) + + assertEquals(-1, str.indexOf(ch, -3)) + assertEquals(-1, str.indexOf(ch, 10)) + + ch = 0.toChar() + assertEquals(-1, str.indexOf(ch, -3)) + assertEquals(-1, str.indexOf(ch, 10)) +} \ No newline at end of file diff --git a/runtime/src/main/cpp/KString.cpp b/runtime/src/main/cpp/KString.cpp index 29222616e2d..890885b2fba 100644 --- a/runtime/src/main/cpp/KString.cpp +++ b/runtime/src/main/cpp/KString.cpp @@ -1056,7 +1056,10 @@ KInt Kotlin_Char_digitOfChecked(KChar ch, KInt radix) { } KInt Kotlin_String_indexOfChar(KString thiz, KChar ch, KInt fromIndex) { - if (fromIndex < 0 || fromIndex > thiz->count_) { + if (fromIndex < 0) { + fromIndex = 0; + } + if (fromIndex > thiz->count_) { return -1; } KInt count = thiz->count_; @@ -1087,8 +1090,13 @@ KInt Kotlin_String_lastIndexOfChar(KString thiz, KChar ch, KInt fromIndex) { // TODO: or code up Knuth-Moris-Pratt. KInt Kotlin_String_indexOfString(KString thiz, KString other, KInt fromIndex) { - if (fromIndex < 0 || fromIndex > thiz->count_ || - other->count_ > thiz->count_ - fromIndex) { + if (fromIndex < 0) { + fromIndex = 0; + } + if (fromIndex >= thiz->count_) { + return (other->count_ == 0) ? thiz->count_ : -1; + } + if (other->count_ > thiz->count_ - fromIndex) { return -1; } // An empty string can be always found.