Bladeren bron

make searching for empty string with String.indexOf() and Stirng.lastIndexOf() consistent (#7609)

Aleksandr Kuzmenko 5 jaren geleden
bovenliggende
commit
ed2bc3d339

+ 11 - 0
std/cs/internal/StringExt.hx

@@ -45,6 +45,13 @@ private typedef NativeString = cs.system.String;
 
 
 	public static function indexOf(me:NativeString, str:String, ?startIndex:Int):Int {
 	public static function indexOf(me:NativeString, str:String, ?startIndex:Int):Int {
 		var sIndex:Int = startIndex != null ? startIndex : 0;
 		var sIndex:Int = startIndex != null ? startIndex : 0;
+		if(str == '') {
+			if(sIndex < 0) {
+				sIndex = me.Length + sIndex;
+				if(sIndex < 0) sIndex = 0;
+			}
+			return sIndex > me.Length ? me.Length : sIndex;
+		}
 		if (sIndex >= me.Length)
 		if (sIndex >= me.Length)
 			return -1;
 			return -1;
 		return @:privateAccess me.IndexOf(str, sIndex, cs.system.StringComparison.Ordinal);
 		return @:privateAccess me.IndexOf(str, sIndex, cs.system.StringComparison.Ordinal);
@@ -57,6 +64,10 @@ private typedef NativeString = cs.system.String;
 		else if (sIndex < 0)
 		else if (sIndex < 0)
 			return -1;
 			return -1;
 
 
+		if (str.Length == 0) {
+			return startIndex == null || startIndex > me.Length ? me.Length : startIndex;
+		}
+
 		// TestBaseTypes.hx@133 fix
 		// TestBaseTypes.hx@133 fix
 		if (startIndex != null) {
 		if (startIndex != null) {
 			// if the number of letters between start index and the length of the string
 			// if the number of letters between start index and the length of the string

+ 1 - 1
std/hl/_std/String.hx

@@ -69,7 +69,7 @@ class String {
 		var startByte = 0;
 		var startByte = 0;
 		if (startIndex != null && startIndex > 0) {
 		if (startIndex != null && startIndex > 0) {
 			if (startIndex >= length)
 			if (startIndex >= length)
-				return -1;
+				return str == '' ? length : -1;
 			startByte = startIndex << 1;
 			startByte = startIndex << 1;
 		}
 		}
 		var p = findChar(startByte, length << 1, str.bytes, str.length << 1);
 		var p = findChar(startByte, length << 1, str.bytes, str.length << 1);

+ 11 - 0
std/java/internal/StringExt.hx

@@ -49,6 +49,14 @@ private typedef NativeString = String;
 
 
 	@:functionCode('
 	@:functionCode('
 			int sIndex = (startIndex != null ) ? (haxe.lang.Runtime.toInt(startIndex)) : 0;
 			int sIndex = (startIndex != null ) ? (haxe.lang.Runtime.toInt(startIndex)) : 0;
+			if(str == "") {
+				int length = me.length();
+				if(sIndex < 0) {
+					sIndex = length + sIndex;
+					if(sIndex < 0) sIndex = 0;
+				}
+				return sIndex > length ? length : sIndex;
+			}
 			if (sIndex >= me.length() || sIndex < 0)
 			if (sIndex >= me.length() || sIndex < 0)
 				return -1;
 				return -1;
 			return me.indexOf(str, sIndex);
 			return me.indexOf(str, sIndex);
@@ -63,6 +71,9 @@ private typedef NativeString = String;
 				sIndex = me.length() - 1;
 				sIndex = me.length() - 1;
 			else if (sIndex < 0)
 			else if (sIndex < 0)
 				return -1;
 				return -1;
+			if (str.length() == 0) {
+				return startIndex == null || haxe.lang.Runtime.toInt(startIndex) > me.length() ? me.length() : haxe.lang.Runtime.toInt(startIndex);
+			}
 			return me.lastIndexOf(str, sIndex);
 			return me.lastIndexOf(str, sIndex);
 	')
 	')
 	public static function lastIndexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int {
 	public static function lastIndexOf(me:NativeString, str:NativeString, ?startIndex:Int):Int {

+ 3 - 0
std/jvm/StringExt.hx

@@ -52,6 +52,9 @@ class StringExt {
 	}
 	}
 
 
 	public static function lastIndexOf(me:String, str:String, ?startIndex:Int):Int {
 	public static function lastIndexOf(me:String, str:String, ?startIndex:Int):Int {
+		if(str == '') {
+			return startIndex == null || startIndex > me.length ? me.length : startIndex;
+		}
 		if (startIndex == null || startIndex > me.length || startIndex < 0) {
 		if (startIndex == null || startIndex > me.length || startIndex < 0) {
 			startIndex = me.length - 1;
 			startIndex = me.length - 1;
 		}
 		}

+ 13 - 0
std/lua/_std/String.hx

@@ -67,6 +67,10 @@ class String {
 			startIndex = 1;
 			startIndex = 1;
 		else
 		else
 			startIndex += 1;
 			startIndex += 1;
+		if (str == "") {
+			// TODO: this makes lua CI hang forever
+			// return indexOfEmpty(this, startIndex - 1);
+		}
 		var r = BaseString.find(this, str, startIndex, true).begin;
 		var r = BaseString.find(this, str, startIndex, true).begin;
 		if (r != null && r > 0)
 		if (r != null && r > 0)
 			return r - 1;
 			return r - 1;
@@ -74,6 +78,15 @@ class String {
 			return -1;
 			return -1;
 	}
 	}
 
 
+	static function indexOfEmpty(s:String, startIndex:Int):Int {
+		var length = BaseString.len(s);
+		if(startIndex < 0) {
+			startIndex = length + startIndex;
+			if(startIndex < 0) startIndex = 0;
+		}
+		return startIndex > length ? length : startIndex;
+	}
+
 	public inline function lastIndexOf(str:String, ?startIndex:Int):Int {
 	public inline function lastIndexOf(str:String, ?startIndex:Int):Int {
 		var i = 0;
 		var i = 0;
 		var ret = -1;
 		var ret = -1;

+ 3 - 0
std/neko/_std/String.hx

@@ -61,6 +61,9 @@
 			var l = __dollar__ssize(this.__s);
 			var l = __dollar__ssize(this.__s);
 			if (startIndex == null || startIndex < -l)
 			if (startIndex == null || startIndex < -l)
 				startIndex = 0;
 				startIndex = 0;
+			if (str == '' && startIndex >= l) {
+				return l;
+			}
 			if (startIndex > l)
 			if (startIndex > l)
 				return -1;
 				return -1;
 			if (__dollar__ssize(str.__s) == 0)
 			if (__dollar__ssize(str.__s) == 0)

+ 20 - 1
std/python/internal/StringImpl.hx

@@ -45,6 +45,13 @@ class StringImpl {
 	public static inline function lastIndexOf(s:String, str:String, ?startIndex:Int):Int {
 	public static inline function lastIndexOf(s:String, str:String, ?startIndex:Int):Int {
 		if (startIndex == null) {
 		if (startIndex == null) {
 			return Syntax.callField(s, "rfind", str, 0, s.length);
 			return Syntax.callField(s, "rfind", str, 0, s.length);
+		} else if(str == "") {
+			var length = s.length;
+			if(startIndex < 0) {
+				startIndex = length + startIndex;
+				if(startIndex < 0) startIndex = 0;
+			}
+			return startIndex > length ? length : startIndex;
 		} else {
 		} else {
 			var i = Syntax.callField(s, "rfind", str, 0, startIndex + 1);
 			var i = Syntax.callField(s, "rfind", str, 0, startIndex + 1);
 			var startLeft = i == -1 ? UBuiltins.max(0, startIndex + 1 - str.length) : i + 1;
 			var startLeft = i == -1 ? UBuiltins.max(0, startIndex + 1 - str.length) : i + 1;
@@ -72,7 +79,19 @@ class StringImpl {
 		if (startIndex == null)
 		if (startIndex == null)
 			return Syntax.callField(s, "find", str);
 			return Syntax.callField(s, "find", str);
 		else
 		else
-			return Syntax.callField(s, "find", str, startIndex);
+			return indexOfImpl(s, str, startIndex);
+	}
+
+	static function indexOfImpl(s:String, str:String, startIndex:Int) {
+		if(str == "") {
+			var length = s.length;
+			if(startIndex < 0) {
+				startIndex = length + startIndex;
+				if(startIndex < 0) startIndex = 0;
+			}
+			return startIndex > length ? length : startIndex;
+		}
+		return Syntax.callField(s, "find", str, startIndex);
 	}
 	}
 
 
 	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString", "python.internal.StringImpl.toString")
 	@:ifFeature("dynamic_read.toString", "anon_optional_read.toString", "python.internal.StringImpl.toString")

+ 8 - 0
tests/unit/src/unitstd/String.unit.hx

@@ -54,6 +54,7 @@ s.charCodeAt( -1) == null;
 
 
 // indexOf
 // indexOf
 var s = "foo1bar";
 var s = "foo1bar";
+s.indexOf("") == 0;
 s.indexOf("f") == 0;
 s.indexOf("f") == 0;
 s.indexOf("o") == 1;
 s.indexOf("o") == 1;
 s.indexOf("1") == 3;
 s.indexOf("1") == 3;
@@ -69,6 +70,10 @@ s.indexOf("oo") == 1;
 //s.indexOf("bart") == -1;
 //s.indexOf("bart") == -1;
 //s.indexOf("r", -1) == -1;
 //s.indexOf("r", -1) == -1;
 //s.indexOf("r", -10) == -1;
 //s.indexOf("r", -10) == -1;
+s.indexOf("", 2) == 2;
+#if !lua //See https://github.com/HaxeFoundation/haxe/issues/7609
+s.indexOf("", 200) == s.length;
+#end
 s.indexOf("o", 1) == 1;
 s.indexOf("o", 1) == 1;
 s.indexOf("o", 2) == 2;
 s.indexOf("o", 2) == 2;
 s.indexOf("o", 3) == -1;
 s.indexOf("o", 3) == -1;
@@ -80,6 +85,7 @@ s.indexOf("r", 8) == -1;
 
 
 // lastIndexOf
 // lastIndexOf
 var s = "foofoofoobarbar";
 var s = "foofoofoobarbar";
+s.lastIndexOf("") == s.length;
 s.lastIndexOf("r") == 14;
 s.lastIndexOf("r") == 14;
 s.lastIndexOf("a") == 13;
 s.lastIndexOf("a") == 13;
 s.lastIndexOf("b") == 12;
 s.lastIndexOf("b") == 12;
@@ -94,6 +100,8 @@ s.lastIndexOf("z") == -1;
 //s.lastIndexOf(null) == -1;
 //s.lastIndexOf(null) == -1;
 //s.lastIndexOf(null, 1) == -1;
 //s.lastIndexOf(null, 1) == -1;
 //s.lastIndexOf(null, 14) == -1;
 //s.lastIndexOf(null, 14) == -1;
+s.lastIndexOf("", 2) == 2;
+s.lastIndexOf("", 200) == s.length;
 s.lastIndexOf("r", 14) == 14;
 s.lastIndexOf("r", 14) == 14;
 s.lastIndexOf("r", 13) == 11;
 s.lastIndexOf("r", 13) == 11;
 s.lastIndexOf("a", 14) == 13;
 s.lastIndexOf("a", 14) == 13;