diff --git a/CHANGELOG.md b/CHANGELOG.md index a9582b35bd..c2ba1d0c1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ - Deprecate JSON.Classify.classify. https://github.com/rescript-lang/rescript/pull/7315 - Hide stdlib modules in output. https://github.com/rescript-lang/rescript/pull/7305 - Deprecate unsafe host-specific bindings from stdlib. https://github.com/rescript-lang/rescript/pull/7334 +- Make unsafe function names consistent in Stdlib.String. https://github.com/rescript-lang/rescript/pull/7337 #### :bug: Bug fix diff --git a/runtime/Stdlib_String.res b/runtime/Stdlib_String.res index 3d25372be1..0fd636d742 100644 --- a/runtime/Stdlib_String.res +++ b/runtime/Stdlib_String.res @@ -94,6 +94,41 @@ external unsafeReplaceRegExpBy3: ( ) => string, ) => string = "replace" +@send +external replaceRegExpBy0Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +@send +external replaceRegExpBy1Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~group1: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +@send +external replaceRegExpBy2Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~group1: string, ~group2: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +@send +external replaceRegExpBy3Unsafe: ( + string, + Stdlib_RegExp.t, + ( + ~match: string, + ~group1: string, + ~group2: string, + ~group3: string, + ~offset: int, + ~input: string, + ) => string, +) => string = "replace" + @send external search: (string, Stdlib_RegExp.t) => int = "search" let searchOpt = (s, re) => switch search(s, re) { diff --git a/runtime/Stdlib_String.resi b/runtime/Stdlib_String.resi index 3ce6614296..2bb378656b 100644 --- a/runtime/Stdlib_String.resi +++ b/runtime/Stdlib_String.resi @@ -595,6 +595,7 @@ let matchFn = (~match, ~offset as _, ~input as _) => String.toUpperCase(match) String.unsafeReplaceRegExpBy0(str, re, matchFn) == "bEAUtIfUl vOwEls" ``` */ +@deprecated("Use `replaceRegExpBy0Unsafe` instead") @send external unsafeReplaceRegExpBy0: ( string, @@ -618,6 +619,7 @@ let matchFn = (~match as _, ~group1, ~offset as _, ~input as _) => { String.unsafeReplaceRegExpBy1(str, re, matchFn) == "Jony is 41" ``` */ +@deprecated("Use `replaceRegExpBy1Unsafe` instead") @send external unsafeReplaceRegExpBy1: ( string, @@ -644,6 +646,7 @@ let matchFn = (~match as _, ~group1, ~group2, ~offset as _, ~input as _) => { String.unsafeReplaceRegExpBy2(str, re, matchFn) == "42" ``` */ +@deprecated("Use `replaceRegExpBy2Unsafe` instead") @send external unsafeReplaceRegExpBy2: ( string, @@ -652,10 +655,11 @@ external unsafeReplaceRegExpBy2: ( ) => string = "replace" /** -`unsafeReplaceRegExpBy3(str, regexp, f)`. Like `unsafeReplaceRegExpBy1`, but `f` +`unsafeReplaceRegExpBy3(str, regexp, f)`. Like `unsafeReplaceRegExpBy2`, but `f` has three group parameters. See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. */ +@deprecated("Use `replaceRegExpBy3Unsafe` instead") @send external unsafeReplaceRegExpBy3: ( string, @@ -670,6 +674,98 @@ external unsafeReplaceRegExpBy3: ( ) => string, ) => string = "replace" +/** +`replaceRegExpBy0Unsafe(str, regex, f)` returns a new `string` with some or all +matches of a pattern with no capturing parentheses replaced by the value +returned from the given function. The function receives as its parameters the +matched string, the offset at which the match begins, and the whole string being +matched. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. + +## Examples + +```rescript +let str = "beautiful vowels" +let re = %re("/[aeiou]/g") +let matchFn = (~match, ~offset as _, ~input as _) => String.toUpperCase(match) +String.replaceRegExpBy0Unsafe(str, re, matchFn) == "bEAUtIfUl vOwEls" +``` +*/ +@send +external replaceRegExpBy0Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +/** +`replaceRegExpBy1Unsafe(str, regexp, f)`. Like `replaceRegExpBy0Unsafe`, but `f` +has `group1` parameter. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. + +## Examples + +```rescript +let str = "Jony is 40" +let re = %re("/(Jony is )\d+/g") +let matchFn = (~match as _, ~group1, ~offset as _, ~input as _) => { + group1 ++ "41" +} +String.replaceRegExpBy1Unsafe(str, re, matchFn) == "Jony is 41" +``` +*/ +@send +external replaceRegExpBy1Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~group1: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +/** +`replaceRegExpBy2Unsafe(str, regexp, f)`. Like `replaceRegExpBy1Unsafe`, but `f` +has two group parameters. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. + +## Examples + +```rescript +let str = "7 times 6" +let re = %re("/(\d+) times (\d+)/") +let matchFn = (~match as _, ~group1, ~group2, ~offset as _, ~input as _) => { + switch (Int.fromString(group1), Int.fromString(group2)) { + | (Some(x), Some(y)) => Int.toString(x * y) + | _ => "???" + } +} +String.replaceRegExpBy2Unsafe(str, re, matchFn) == "42" +``` +*/ +@send +external replaceRegExpBy2Unsafe: ( + string, + Stdlib_RegExp.t, + (~match: string, ~group1: string, ~group2: string, ~offset: int, ~input: string) => string, +) => string = "replace" + +/** +`replaceRegExpBy3Unsafe(str, regexp, f)`. Like `replaceRegExpBy2Unsafe`, but `f` +has three group parameters. +See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. +*/ +@send +external replaceRegExpBy3Unsafe: ( + string, + Stdlib_RegExp.t, + ( + ~match: string, + ~group1: string, + ~group2: string, + ~group3: string, + ~offset: int, + ~input: string, + ) => string, +) => string = "replace" + /** `search(str, regexp)` returns the starting position of the first match of `regexp` in the given `str`, or -1 if there is no match. diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt index be01749479..4a00e61ba5 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt @@ -723,30 +723,6 @@ Path Stdlib.String.s "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, "newText": "" }] - }, { - "label": "->String.startsWith", - "kind": 12, - "tags": [], - "detail": "(string, string) => bool", - "documentation": {"kind": "markdown", "value": "\n`startsWith(str, substr)` returns `true` if the `str` starts with `substr`,\n`false` otherwise.\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) on MDN.\n\n## Examples\n\n```rescript\nString.startsWith(\"BuckleScript\", \"Buckle\") == true\nString.startsWith(\"BuckleScript\", \"\") == true\nString.startsWith(\"JavaScript\", \"Buckle\") == false\n```\n"}, - "sortText": "startsWith", - "insertText": "->String.startsWith", - "additionalTextEdits": [{ - "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, - "newText": "" - }] - }, { - "label": "->String.splitAtMost", - "kind": 12, - "tags": [], - "detail": "(string, string, ~limit: int) => array", - "documentation": {"kind": "markdown", "value": "\n`splitAtMost(str, delimiter, ~limit)` splits the given `str` at every\noccurrence of `delimiter` and returns an array of the first `limit` resulting\nsubstrings. If `limit` is negative or greater than the number of substrings,\nthe array will contain all the substrings.\n\n## Examples\n\n```rescript\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=3) == [\"ant\", \"bee\", \"cat\"]\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=0) == []\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=9) == [\"ant\", \"bee\", \"cat\", \"dog\", \"elk\"]\n```\n"}, - "sortText": "splitAtMost", - "insertText": "->String.splitAtMost", - "additionalTextEdits": [{ - "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, - "newText": "" - }] }, { "label": "->String.searchOpt", "kind": 12, @@ -783,6 +759,42 @@ Path Stdlib.String.s "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, "newText": "" }] + }, { + "label": "->String.substringToEnd", + "kind": 12, + "tags": [], + "detail": "(string, ~start: int) => string", + "documentation": {"kind": "markdown", "value": "\n`substringToEnd(str, ~start)` returns the substring of `str` from position\n`start` to the end.\n- If `start` is less than or equal to zero, the entire string is returned.\n- If `start` is greater than or equal to the length of `str`, the empty string\nis returned.\nSee [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN.\n\n## Examples\n\n```rescript\nString.substringToEnd(\"playground\", ~start=4) == \"ground\"\nString.substringToEnd(\"playground\", ~start=-3) == \"playground\"\nString.substringToEnd(\"playground\", ~start=12) == \"\"\n```\n"}, + "sortText": "substringToEnd", + "insertText": "->String.substringToEnd", + "additionalTextEdits": [{ + "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, + "newText": "" + }] + }, { + "label": "->String.startsWith", + "kind": 12, + "tags": [], + "detail": "(string, string) => bool", + "documentation": {"kind": "markdown", "value": "\n`startsWith(str, substr)` returns `true` if the `str` starts with `substr`,\n`false` otherwise.\nSee [`String.startsWith`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith) on MDN.\n\n## Examples\n\n```rescript\nString.startsWith(\"BuckleScript\", \"Buckle\") == true\nString.startsWith(\"BuckleScript\", \"\") == true\nString.startsWith(\"JavaScript\", \"Buckle\") == false\n```\n"}, + "sortText": "startsWith", + "insertText": "->String.startsWith", + "additionalTextEdits": [{ + "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, + "newText": "" + }] + }, { + "label": "->String.splitAtMost", + "kind": 12, + "tags": [], + "detail": "(string, string, ~limit: int) => array", + "documentation": {"kind": "markdown", "value": "\n`splitAtMost(str, delimiter, ~limit)` splits the given `str` at every\noccurrence of `delimiter` and returns an array of the first `limit` resulting\nsubstrings. If `limit` is negative or greater than the number of substrings,\nthe array will contain all the substrings.\n\n## Examples\n\n```rescript\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=3) == [\"ant\", \"bee\", \"cat\"]\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=0) == []\nString.splitAtMost(\"ant/bee/cat/dog/elk\", \"/\", ~limit=9) == [\"ant\", \"bee\", \"cat\", \"dog\", \"elk\"]\n```\n"}, + "sortText": "splitAtMost", + "insertText": "->String.splitAtMost", + "additionalTextEdits": [{ + "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, + "newText": "" + }] }, { "label": "->String.sliceToEnd", "kind": 12, @@ -867,17 +879,5 @@ Path Stdlib.String.s "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, "newText": "" }] - }, { - "label": "->String.substringToEnd", - "kind": 12, - "tags": [], - "detail": "(string, ~start: int) => string", - "documentation": {"kind": "markdown", "value": "\n`substringToEnd(str, ~start)` returns the substring of `str` from position\n`start` to the end.\n- If `start` is less than or equal to zero, the entire string is returned.\n- If `start` is greater than or equal to the length of `str`, the empty string\nis returned.\nSee [`String.substring`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substring) on MDN.\n\n## Examples\n\n```rescript\nString.substringToEnd(\"playground\", ~start=4) == \"ground\"\nString.substringToEnd(\"playground\", ~start=-3) == \"playground\"\nString.substringToEnd(\"playground\", ~start=12) == \"\"\n```\n"}, - "sortText": "substringToEnd", - "insertText": "->String.substringToEnd", - "additionalTextEdits": [{ - "range": {"start": {"line": 93, "character": 17}, "end": {"line": 93, "character": 18}}, - "newText": "" - }] }] diff --git a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt index 3d8952608c..6341bc3ee4 100644 --- a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt +++ b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt @@ -384,25 +384,25 @@ ContextPath Value[Array, joinWith] Path Array.joinWith Path Stdlib.String.includ [{ - "label": "->String.includesFrom", + "label": "->String.includes", "kind": 12, "tags": [], - "detail": "(string, string, int) => bool", - "documentation": {"kind": "markdown", "value": "\n`includesFrom(str, searchValue, start)` returns `true` if `searchValue` is found\nanywhere within `str` starting at character number `start` (where 0 is the\nfirst character), `false` otherwise.\nSee [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) on MDN.\n\n## Examples\n\n```rescript\nString.includesFrom(\"programmer\", \"gram\", 1) == true\nString.includesFrom(\"programmer\", \"gram\", 4) == false\nString.includesFrom(`대한민국`, `한`, 1) == true\n```\n"}, - "sortText": "includesFrom", - "insertText": "->String.includesFrom", + "detail": "(string, string) => bool", + "documentation": {"kind": "markdown", "value": "\n`includes(str, searchValue)` returns `true` if `searchValue` is found anywhere\nwithin `str`, `false` otherwise.\nSee [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) on MDN.\n\n## Examples\n\n```rescript\nString.includes(\"programmer\", \"gram\") == true\nString.includes(\"programmer\", \"er\") == true\nString.includes(\"programmer\", \"pro\") == true\nString.includes(\"programmer.dat\", \"xyz\") == false\n```\n"}, + "sortText": "includes", + "insertText": "->String.includes", "additionalTextEdits": [{ "range": {"start": {"line": 89, "character": 55}, "end": {"line": 89, "character": 56}}, "newText": "" }] }, { - "label": "->String.includes", + "label": "->String.includesFrom", "kind": 12, "tags": [], - "detail": "(string, string) => bool", - "documentation": {"kind": "markdown", "value": "\n`includes(str, searchValue)` returns `true` if `searchValue` is found anywhere\nwithin `str`, `false` otherwise.\nSee [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) on MDN.\n\n## Examples\n\n```rescript\nString.includes(\"programmer\", \"gram\") == true\nString.includes(\"programmer\", \"er\") == true\nString.includes(\"programmer\", \"pro\") == true\nString.includes(\"programmer.dat\", \"xyz\") == false\n```\n"}, - "sortText": "includes", - "insertText": "->String.includes", + "detail": "(string, string, int) => bool", + "documentation": {"kind": "markdown", "value": "\n`includesFrom(str, searchValue, start)` returns `true` if `searchValue` is found\nanywhere within `str` starting at character number `start` (where 0 is the\nfirst character), `false` otherwise.\nSee [`String.includes`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes) on MDN.\n\n## Examples\n\n```rescript\nString.includesFrom(\"programmer\", \"gram\", 1) == true\nString.includesFrom(\"programmer\", \"gram\", 4) == false\nString.includesFrom(`대한민국`, `한`, 1) == true\n```\n"}, + "sortText": "includesFrom", + "insertText": "->String.includesFrom", "additionalTextEdits": [{ "range": {"start": {"line": 89, "character": 55}, "end": {"line": 89, "character": 56}}, "newText": ""