Commonize and generalize JVM-only String.contentEquals #KT-42840

This commit is contained in:
Abduqodiri Qurbonzoda
2020-09-21 02:21:23 +03:00
parent 037505d9f2
commit ed57bcb3b1
9 changed files with 198 additions and 2 deletions
@@ -162,6 +162,12 @@ public operator fun kotlin.CharSequence.contains(other: kotlin.CharSequence, ign
@kotlin.internal.InlineOnly
public inline operator fun kotlin.CharSequence.contains(regex: kotlin.text.Regex): kotlin.Boolean
@kotlin.SinceKotlin(version = "1.5")
public infix fun kotlin.CharSequence?.contentEquals(other: kotlin.CharSequence?): kotlin.Boolean
@kotlin.SinceKotlin(version = "1.5")
public fun kotlin.CharSequence?.contentEquals(other: kotlin.CharSequence?, ignoreCase: kotlin.Boolean): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.count(): kotlin.Int
+6
View File
@@ -162,6 +162,12 @@ public operator fun kotlin.CharSequence.contains(other: kotlin.CharSequence, ign
@kotlin.internal.InlineOnly
public inline operator fun kotlin.CharSequence.contains(regex: kotlin.text.Regex): kotlin.Boolean
@kotlin.SinceKotlin(version = "1.5")
public infix fun kotlin.CharSequence?.contentEquals(other: kotlin.CharSequence?): kotlin.Boolean
@kotlin.SinceKotlin(version = "1.5")
public fun kotlin.CharSequence?.contentEquals(other: kotlin.CharSequence?, ignoreCase: kotlin.Boolean): kotlin.Boolean
@kotlin.internal.InlineOnly
public inline fun kotlin.CharSequence.count(): kotlin.Int
@@ -268,6 +268,30 @@ public actual fun String.compareTo(other: String, ignoreCase: Boolean = false):
}
}
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other],
* i.e. both char sequences contain the same number of the same characters in the same order.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean = contentEqualsImpl(other)
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference.
*
* @param ignoreCase `true` to ignore character case when comparing contents.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean {
return if (ignoreCase)
this.contentEqualsIgnoreCaseImpl(other)
else
this.contentEqualsImpl(other)
}
private val STRING_CASE_INSENSITIVE_ORDER = Comparator<String> { a, b -> a.compareTo(b, ignoreCase = true) }
@@ -544,8 +544,8 @@ public actual fun String.compareTo(other: String, ignoreCase: Boolean = false):
/**
* Returns `true` if this string is equal to the contents of the specified [CharSequence], `false` otherwise.
*
* Unlike the overload that accepts an argument of type [StringBuffer],
* this function does not compare this string and the specified [CharSequence] in a synchronized block.
* Note that if the [CharSequence] argument is a [StringBuffer] then the comparison may be performed in a synchronized block
* that acquires that [StringBuffer]'s monitor.
*/
@kotlin.internal.InlineOnly
public inline fun String.contentEquals(charSequence: CharSequence): Boolean = (this as java.lang.String).contentEquals(charSequence)
@@ -559,6 +559,41 @@ public inline fun String.contentEquals(charSequence: CharSequence): Boolean = (t
@kotlin.internal.InlineOnly
public inline fun String.contentEquals(stringBuilder: StringBuffer): Boolean = (this as java.lang.String).contentEquals(stringBuilder)
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other],
* i.e. both char sequences contain the same number of the same characters in the same order.
*
* If this [CharSequence] is a [String] and [other] is not `null`
* then this function behaves the same as [String.contentEquals].
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean {
return if (this is String && other != null)
contentEquals(other)
else
contentEqualsImpl(other)
}
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference.
*
* If this [CharSequence] is a [String], [other] is not `null` and [ignoreCase] is `false`
* then this function behaves the same as [String.contentEquals].
*
* @param ignoreCase `true` to ignore character case when comparing contents.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean {
return if (ignoreCase)
contentEqualsIgnoreCaseImpl(other)
else
contentEquals(other)
}
/**
* Returns a canonical representation for this string object.
*/
@@ -454,4 +454,17 @@ class Strings {
assertPrints(inputString0.replace('s', 'z'), "Mizzizzippi")
assertPrints(inputString1.replace("data", "information"), "Insufficient information for meaningful answer.")
}
@Sample
fun contentEquals() {
val stringBuilder = StringBuilder()
stringBuilder.append("Kot").append("lin")
assertPrints(stringBuilder, "Kotlin")
assertTrue(stringBuilder contentEquals "Kotlin")
stringBuilder.setCharAt(0, 'k')
assertPrints(stringBuilder, "kotlin")
assertFalse("Kotlin".contentEquals(stringBuilder))
assertTrue("Kotlin".contentEquals(stringBuilder, ignoreCase = true))
}
}
@@ -1378,3 +1378,56 @@ public fun CharSequence.lineSequence(): Sequence<String> = splitToSequence("\r\n
* The lines returned do not include terminating line separators.
*/
public fun CharSequence.lines(): List<String> = lineSequence().toList()
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other],
* i.e. both char sequences contain the same number of the same characters in the same order.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public expect infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference.
*
* @param ignoreCase `true` to ignore character case when comparing contents.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public expect fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean
internal fun CharSequence?.contentEqualsIgnoreCaseImpl(other: CharSequence?): Boolean {
if (this is String && other is String) {
return this.equals(other, ignoreCase = true)
}
if (this === other) return true
if (this == null || other == null || this.length != other.length) return false
for (i in 0 until length) {
if (!this[i].equals(other[i], ignoreCase = true)) {
return false
}
}
return true
}
internal fun CharSequence?.contentEqualsImpl(other: CharSequence?): Boolean {
if (this is String && other is String) {
return this == other
}
if (this === other) return true
if (this == null || other == null || this.length != other.length) return false
for (i in 0 until length) {
if (this[i] != other[i]) {
return false
}
}
return true
}
+38
View File
@@ -1741,4 +1741,42 @@ ${" "}
// Special Casing
assertEquals("\u0399\u0308\u0301\u0053\u0053", "\u0390\u00DF".uppercase())
}
@Test
fun contentEquals() = withTwoCharSequenceArgs { arg1, arg2 ->
infix fun String?.contentEquals(other: String?): Boolean {
return this?.let { arg1(it) } contentEquals other?.let { arg2(it) }
}
assertTrue("" contentEquals "")
assertTrue("1" contentEquals "1")
assertFalse("12" contentEquals "1")
assertFalse("1" contentEquals "12")
assertTrue("sample" contentEquals "sample")
assertFalse("Sample" contentEquals "sample")
assertFalse("sample" contentEquals "Sample")
assertFalse("sample" contentEquals null)
assertFalse(null contentEquals "sample")
assertTrue(null contentEquals null)
}
@Test
fun contentEqualsIgnoreCase() = withTwoCharSequenceArgs { arg1, arg2 ->
fun String.contentEquals(other: String, ignoreCase: Boolean): Boolean {
return arg1(this).contentEquals(arg2(other), ignoreCase)
}
assertTrue("".contentEquals("", ignoreCase = false))
assertTrue("".contentEquals("", ignoreCase = true))
assertTrue("1".contentEquals("1", ignoreCase = false))
assertTrue("1".contentEquals("1", ignoreCase = true))
assertFalse("sample".contentEquals("Sample", ignoreCase = false))
assertTrue("sample".contentEquals("Sample", ignoreCase = true))
assertFalse("sample".contentEquals(null, ignoreCase = false))
assertFalse("sample".contentEquals(null, ignoreCase = true))
assertTrue(null.contentEquals(null, ignoreCase = true))
assertTrue(null.contentEquals(null, ignoreCase = false))
}
}
+19
View File
@@ -425,6 +425,25 @@ actual fun String?.equals(other: String?, ignoreCase: Boolean): Boolean = TODO("
@SinceKotlin("1.2")
actual fun String.compareTo(other: String, ignoreCase: Boolean): Int = TODO("Wasm stdlib: Text")
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other],
* i.e. both char sequences contain the same number of the same characters in the same order.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual infix fun CharSequence?.contentEquals(other: CharSequence?): Boolean = TODO("Wasm stdlib: Text")
/**
* Returns `true` if the contents of this char sequence are equal to the contents of the specified [other], optionally ignoring case difference.
*
* @param ignoreCase `true` to ignore character case when comparing contents.
*
* @sample samples.text.Strings.contentEquals
*/
@SinceKotlin("1.5")
public actual fun CharSequence?.contentEquals(other: CharSequence?, ignoreCase: Boolean): Boolean = TODO("Wasm stdlib: Text")
public actual fun String.startsWith(prefix: String, ignoreCase: Boolean): Boolean = TODO("Wasm stdlib: Text")
public actual fun String.startsWith(prefix: String, startIndex: Int, ignoreCase: Boolean): Boolean = TODO("Wasm stdlib: Text")
@@ -5261,6 +5261,8 @@ public final class kotlin/text/StringsKt {
public static final fun contains (Ljava/lang/CharSequence;Ljava/lang/CharSequence;Z)Z
public static synthetic fun contains$default (Ljava/lang/CharSequence;CZILjava/lang/Object;)Z
public static synthetic fun contains$default (Ljava/lang/CharSequence;Ljava/lang/CharSequence;ZILjava/lang/Object;)Z
public static final fun contentEquals (Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
public static final fun contentEquals (Ljava/lang/CharSequence;Ljava/lang/CharSequence;Z)Z
public static final fun count (Ljava/lang/CharSequence;Lkotlin/jvm/functions/Function1;)I
public static final fun decapitalize (Ljava/lang/String;)Ljava/lang/String;
public static final fun decapitalize (Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;