diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f330627d7..7b3b3c63de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ #### :rocket: New Feature - Add experimental command to `rescript-tools` for formatting all ReScript code blocks in markdown. Either in a markdown file directly, or inside of docstrings in ReScript code. https://github.com/rescript-lang/rescript/pull/7598 +- Add `String.getSymbolUnsafe` back to Stdlib. https://github.com/rescript-lang/rescript/pull/7626 #### :house: Internal diff --git a/runtime/Stdlib_String.res b/runtime/Stdlib_String.res index 10f7483b75..11cbe773c7 100644 --- a/runtime/Stdlib_String.res +++ b/runtime/Stdlib_String.res @@ -167,3 +167,5 @@ external splitByRegExpAtMost: (string, Stdlib_RegExp.t, ~limit: int) => array float = "localeCompare" external ignore: string => unit = "%ignore" + +@get_index external getSymbolUnsafe: (string, Stdlib_Symbol.t) => 'a = "" diff --git a/runtime/Stdlib_String.resi b/runtime/Stdlib_String.resi index d828f4f52f..34effcb378 100644 --- a/runtime/Stdlib_String.resi +++ b/runtime/Stdlib_String.resi @@ -1137,3 +1137,17 @@ external localeCompare: (string, string) => float = "localeCompare" without having to store or process it further. */ external ignore: string => unit = "%ignore" + +/** +`getSymbolUnsafe(str, symbol)` returns the value of the symbol property of a string. + +## Examples + +```rescript +let it: Iterator.t = ("foo"->String.getSymbolUnsafe(Symbol.iterator))() +Nullable.make(it)->Nullable.isNullable == false +``` + + */ +@get_index +external getSymbolUnsafe: (string, Stdlib_Symbol.t) => 'a = "" diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt index b8a18d32e3..f19e643299 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt @@ -785,30 +785,6 @@ Path 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, @@ -845,6 +821,42 @@ Path 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, @@ -917,17 +929,5 @@ Path 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 4c826a3c55..8db5129032 100644 --- a/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt +++ b/tests/analysis_tests/tests/src/expected/DotPipeCompletionSpec.res.txt @@ -418,25 +418,25 @@ Path Array.joinWith Path Stdlib.String.includ Path 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": "" diff --git a/tests/tests/src/core/Core_TempTests.mjs b/tests/tests/src/core/Core_TempTests.mjs index e6fae939d7..993e9f63ee 100644 --- a/tests/tests/src/core/Core_TempTests.mjs +++ b/tests/tests/src/core/Core_TempTests.mjs @@ -249,6 +249,10 @@ let x = Symbol.for("Foo"); console.log(x); +let array$1 = "foo"[Symbol.iterator]().toArray(); + +console.log(array$1); + console.info(""); console.info("Global namespace"); @@ -334,7 +338,6 @@ export { _formatter, formatter, segments, - array, date, dict, dict2, @@ -351,6 +354,7 @@ export { set, regexp, x, + array$1 as array, timeout, z, intFromBigInt, diff --git a/tests/tests/src/core/Core_TempTests.res b/tests/tests/src/core/Core_TempTests.res index ff4b3e2c10..e7182d5585 100644 --- a/tests/tests/src/core/Core_TempTests.res +++ b/tests/tests/src/core/Core_TempTests.res @@ -160,6 +160,8 @@ Console.info("Symbol") Console.info("---") let x = Symbol.getFor("Foo") Console.log(x) +let array: array = String.getSymbolUnsafe("foo", Symbol.iterator)()->Iterator.toArray +Console.log(array) Console.info("") Console.info("Global namespace")