From 677822d4eee46963fe74e207dec68ebd1f963288 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 24 Aug 2025 10:14:10 +0200 Subject: [PATCH 01/41] migrate wip --- CHANGELOG.md | 2 + analysis/src/Cmt.ml | 14 + compiler/ext/ext_list.ml | 4 + compiler/ext/ext_list.mli | 2 + compiler/ml/builtin_attributes.ml | 54 +- compiler/ml/builtin_attributes.mli | 7 +- compiler/ml/cmt_format.ml | 11 +- compiler/ml/cmt_format.mli | 9 + compiler/ml/cmt_utils.ml | 26 + compiler/ml/typecore.ml | 27 +- compiler/ml/typetexp.ml | 5 +- compiler/ml/typetexp.mli | 6 +- packages/@rescript/runtime/Js.res | 40 +- packages/@rescript/runtime/Js_array2.res | 248 +++++++- packages/@rescript/runtime/Js_bigint.res | 44 ++ packages/@rescript/runtime/Js_console.res | 224 ++++++- packages/@rescript/runtime/Js_json.resi | 7 + packages/@rescript/runtime/Js_string2.res | 218 ++++++- packages/@rescript/runtime/Stdlib_Array.res | 4 +- packages/@rescript/runtime/Stdlib_Array.resi | 56 +- packages/@rescript/runtime/Stdlib_BigInt.resi | 47 +- packages/@rescript/runtime/Stdlib_Int.res | 12 + packages/@rescript/runtime/Stdlib_Int.resi | 41 +- packages/@rescript/runtime/Stdlib_String.resi | 2 +- .../@rescript/runtime/lib/es6/Stdlib_Array.js | 5 - .../@rescript/runtime/lib/es6/Stdlib_Int.js | 9 + .../@rescript/runtime/lib/js/Stdlib_Array.js | 5 - .../@rescript/runtime/lib/js/Stdlib_Int.js | 9 + rewatch/testrepo/packages/main/src/Main2.mjs | 20 + .../new-namespace/src/Other_module2.mjs | 11 + ...-dev-dependency-used-by-non-dev-source.txt | 69 +- rewatch/tests/snapshots/dependency-cycle.txt | 69 +- rewatch/tests/snapshots/remove-file.txt | 119 +++- .../rename-file-internal-dep-namespace.txt | 147 ++++- .../snapshots/rename-file-internal-dep.txt | 129 +++- .../snapshots/rename-file-with-interface.txt | 129 +++- rewatch/tests/snapshots/rename-file.txt | 129 +++- .../tests/snapshots/rename-interface-file.txt | 129 +++- .../tests/src/expected/Completion.res.txt | 20 +- .../expected/CompletionInferValues.res.txt | 4 +- .../tests/src/expected/CompletionJsx.res.txt | 4 +- .../src/expected/CompletionPipeChain.res.txt | 2 +- .../expected/warnings4.res.expected | 2 +- .../expected/warnings5.res.expected | 12 +- .../fixtures/curry_in_uncurry.res | 2 +- ...lyvariant_constructors_mismatch_second.res | 4 +- .../fixtures/todo_with_no_payload.res | 2 +- .../fixtures/todo_with_payload.res | 2 +- .../super_errors/fixtures/warnings4.res | 2 +- .../super_errors/fixtures/warnings5.res | 8 +- tests/tools_tests/Makefile | 1 + tests/tools_tests/package.json | 2 +- .../src/expected/DeprecatedStuff.res.expected | 12 + .../expected/DeprecatedStuff.resi.expected | 27 + .../src/expected/FileToMigrate.res.expected | 11 + ...tdlibMigrationNoCompile_Array.res.expected | 4 + ...dlibMigrationNoCompile_String.res.expected | 12 + .../StdlibMigration_Array.res.expected | 169 +++++ .../StdlibMigration_BigInt.res.expected | 48 ++ .../StdlibMigration_Console.res.expected | 29 + .../expected/StdlibMigration_Int.res.expected | 8 + .../StdlibMigration_JSON.res.expected | 19 + .../expected/StdlibMigration_Js.res.expected | 6 + .../StdlibMigration_String.res.expected | 126 ++++ .../src/migrate/DeprecatedStuff.res | 11 + .../src/migrate/DeprecatedStuff.resi | 26 + .../tools_tests/src/migrate/FileToMigrate.res | 14 + .../StdlibMigrationNoCompile_Array.res | 3 + .../StdlibMigrationNoCompile_String.res | 11 + .../src/migrate/StdlibMigration_Array.res | 169 +++++ .../src/migrate/StdlibMigration_BigInt.res | 47 ++ .../src/migrate/StdlibMigration_Console.res | 28 + .../src/migrate/StdlibMigration_Int.res | 7 + .../src/migrate/StdlibMigration_JSON.res | 11 + .../src/migrate/StdlibMigration_Js.res | 5 + .../src/migrate/StdlibMigration_String.res | 125 ++++ .../Migrated_StdlibMigration_Array.res | 170 +++++ .../Migrated_StdlibMigration_BigInt.res | 49 ++ .../Migrated_StdlibMigration_Console.res | 30 + .../migrated/Migrated_StdlibMigration_Int.res | 9 + .../Migrated_StdlibMigration_JSON.res | 20 + .../migrated/Migrated_StdlibMigration_Js.res | 7 + .../Migrated_StdlibMigration_String.res | 127 ++++ tests/tools_tests/test.sh | 18 + tools/bin/main.ml | 10 + tools/src/tools.ml | 588 ++++++++++++++++++ 86 files changed, 3917 insertions(+), 195 deletions(-) create mode 100644 compiler/ml/cmt_utils.ml create mode 100644 rewatch/testrepo/packages/main/src/Main2.mjs create mode 100644 rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs create mode 100644 tests/tools_tests/src/expected/DeprecatedStuff.res.expected create mode 100644 tests/tools_tests/src/expected/DeprecatedStuff.resi.expected create mode 100644 tests/tools_tests/src/expected/FileToMigrate.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigrationNoCompile_Array.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigrationNoCompile_String.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Array.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Console.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Int.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_String.res.expected create mode 100644 tests/tools_tests/src/migrate/DeprecatedStuff.res create mode 100644 tests/tools_tests/src/migrate/DeprecatedStuff.resi create mode 100644 tests/tools_tests/src/migrate/FileToMigrate.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Array.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigrationNoCompile_String.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Array.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_BigInt.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Console.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Int.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_JSON.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_String.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Console.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Int.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res diff --git a/CHANGELOG.md b/CHANGELOG.md index 66de9f1385..a6ac1ac21d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -165,6 +165,7 @@ Do not use, npm package broken. - Add optional `message` argument to `Result.getOrThrow` and improve default error message. https://github.com/rescript-lang/rescript/pull/7630 - Add `RegExp.escape` binding. https://github.com/rescript-lang/rescript/pull/7695 +- Add `Array.fromString`. https://github.com/rescript-lang/rescript/pull/7693 #### :bug: Bug fix @@ -183,6 +184,7 @@ Do not use, npm package broken. - Suggest related functions with the expected arity in errors when it makes sense. https://github.com/rescript-lang/rescript/pull/7712 - Improve error when a constructor expects an inline record. https://github.com/rescript-lang/rescript/pull/7713 - Remove `@meth` attribute. https://github.com/rescript-lang/rescript/pull/7684 + > > > > > > > 00815832f (changelog) #### :house: Internal diff --git a/analysis/src/Cmt.ml b/analysis/src/Cmt.ml index a433d12908..ac1d5ae595 100644 --- a/analysis/src/Cmt.ml +++ b/analysis/src/Cmt.ml @@ -51,3 +51,17 @@ let fullsFromModule ~package ~moduleName = let loadFullCmtFromPath ~path = let uri = Uri.fromPath path in fullFromUri ~uri + +let loadCmtInfosFromPath ~path = + let uri = Uri.fromPath path in + match Packages.getPackage ~uri with + | None -> None + | Some package -> ( + let moduleName = + BuildSystem.namespacedName package.namespace (FindFiles.getName path) + in + match Hashtbl.find_opt package.pathsForModule moduleName with + | Some paths -> + let cmt = getCmtPath ~uri paths in + Shared.tryReadCmt cmt + | None -> None) diff --git a/compiler/ext/ext_list.ml b/compiler/ext/ext_list.ml index 7066f301ba..e7681aee30 100644 --- a/compiler/ext/ext_list.ml +++ b/compiler/ext/ext_list.ml @@ -774,3 +774,7 @@ let filter lst p = | x :: l -> if p x then find (x :: accu) l ~p else find accu l ~p in find [] lst ~p + +let is_empty = function + | [] -> true + | _ :: _ -> false diff --git a/compiler/ext/ext_list.mli b/compiler/ext/ext_list.mli index 61a07c7b38..c5e65149e9 100644 --- a/compiler/ext/ext_list.mli +++ b/compiler/ext/ext_list.mli @@ -231,3 +231,5 @@ val filter : 'a list -> ('a -> bool) -> 'a list val array_list_filter_map : 'a array -> 'b list -> ('a -> 'b -> 'c option) -> 'c list + +val is_empty : 'a list -> bool diff --git a/compiler/ml/builtin_attributes.ml b/compiler/ml/builtin_attributes.ml index 5d110eda75..8dea16c662 100644 --- a/compiler/ml/builtin_attributes.ml +++ b/compiler/ml/builtin_attributes.ml @@ -79,10 +79,58 @@ let rec deprecated_of_attrs = function Some (string_of_opt_payload p) | _ :: tl -> deprecated_of_attrs tl -let check_deprecated loc attrs s = - match deprecated_of_attrs attrs with +let rec deprecated_of_attrs_with_migrate = function + | [] -> None + | ( {txt = "deprecated"; _}, + PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_record (fields, _)}, _)}] + ) + :: _ -> ( + let reason = + fields + |> List.find_map (fun field -> + match field with + | { + lid = {txt = Lident "reason"}; + x = {pexp_desc = Pexp_constant (Pconst_string (reason, _))}; + } -> + Some reason + | _ -> None) + in + let migration_template = + fields + |> List.find_map (fun field -> + match field with + | {lid = {txt = Lident "migrate"}; x = migration_template} -> + Some migration_template + | _ -> None) + in + let migration_piped_template = + fields + |> List.find_map (fun field -> + match field with + | { + lid = {txt = Lident "migratePiped"}; + x = migration_piped_template; + } -> + Some migration_piped_template + | _ -> None) + in + + (* TODO: Validate and error if expected shape mismatches *) + match reason with + | Some reason -> Some (reason, migration_template, migration_piped_template) + | None -> None) + | ({txt = "ocaml.deprecated" | "deprecated"; _}, p) :: _ -> + Some (string_of_opt_payload p, None, None) + | _ :: tl -> deprecated_of_attrs_with_migrate tl + +let check_deprecated ?deprecated_context loc attrs s = + match deprecated_of_attrs_with_migrate attrs with | None -> () - | Some txt -> Location.deprecated loc (cat s txt) + | Some (txt, migration_template, migration_piped_template) -> + !Cmt_utils.record_deprecated_used + ?deprecated_context ?migration_template ?migration_piped_template loc txt; + Location.deprecated loc (cat s txt) let check_deprecated_inclusion ~def ~use loc attrs1 attrs2 s = match (deprecated_of_attrs attrs1, deprecated_of_attrs attrs2) with diff --git a/compiler/ml/builtin_attributes.mli b/compiler/ml/builtin_attributes.mli index fd898388c7..63bf762331 100644 --- a/compiler/ml/builtin_attributes.mli +++ b/compiler/ml/builtin_attributes.mli @@ -27,7 +27,12 @@ ocaml.boxed / ocaml.unboxed *) -val check_deprecated : Location.t -> Parsetree.attributes -> string -> unit +val check_deprecated : + ?deprecated_context:Cmt_utils.deprecated_used_context -> + Location.t -> + Parsetree.attributes -> + string -> + unit val check_deprecated_inclusion : def:Location.t -> use:Location.t -> diff --git a/compiler/ml/cmt_format.ml b/compiler/ml/cmt_format.ml index 907f2e7122..4b9fb2b054 100644 --- a/compiler/ml/cmt_format.ml +++ b/compiler/ml/cmt_format.ml @@ -63,6 +63,7 @@ type cmt_infos = { cmt_imports : (string * Digest.t option) list; cmt_interface_digest : Digest.t option; cmt_use_summaries : bool; + cmt_extra_info: Cmt_utils.cmt_extra_info; } type error = @@ -154,15 +155,22 @@ let read_cmi filename = let saved_types = ref [] let value_deps = ref [] +let deprecated_used = ref [] let clear () = saved_types := []; - value_deps := [] + value_deps := []; + deprecated_used := [] let add_saved_type b = saved_types := b :: !saved_types let get_saved_types () = !saved_types let set_saved_types l = saved_types := l +let record_deprecated_used ?deprecated_context ?migration_template ?migration_piped_template source_loc deprecated_text = + deprecated_used := {Cmt_utils.source_loc; deprecated_text; migration_template; migration_piped_template; context = deprecated_context} :: !deprecated_used + +let _ = Cmt_utils.record_deprecated_used := record_deprecated_used + let record_value_dependency vd1 vd2 = if vd1.Types.val_loc <> vd2.Types.val_loc then value_deps := (vd1, vd2) :: !value_deps @@ -197,6 +205,7 @@ let save_cmt filename modname binary_annots sourcefile initial_env cmi = cmt_imports = List.sort compare (Env.imports ()); cmt_interface_digest = this_crc; cmt_use_summaries = need_to_clear_env; + cmt_extra_info = {deprecated_used = !deprecated_used}; } in output_cmt oc cmt) end; diff --git a/compiler/ml/cmt_format.mli b/compiler/ml/cmt_format.mli index 1a84aa68d0..620be12e50 100644 --- a/compiler/ml/cmt_format.mli +++ b/compiler/ml/cmt_format.mli @@ -63,6 +63,7 @@ type cmt_infos = { cmt_imports: (string * Digest.t option) list; cmt_interface_digest: Digest.t option; cmt_use_summaries: bool; + cmt_extra_info: Cmt_utils.cmt_extra_info; } type error = Not_a_typedtree of string @@ -111,6 +112,14 @@ val set_saved_types : binary_part list -> unit val record_value_dependency : Types.value_description -> Types.value_description -> unit +val record_deprecated_used : + ?deprecated_context:Cmt_utils.deprecated_used_context -> + ?migration_template:Parsetree.expression -> + ?migration_piped_template:Parsetree.expression -> + Location.t -> + string -> + unit + (* val is_magic_number : string -> bool diff --git a/compiler/ml/cmt_utils.ml b/compiler/ml/cmt_utils.ml new file mode 100644 index 0000000000..f06a268427 --- /dev/null +++ b/compiler/ml/cmt_utils.ml @@ -0,0 +1,26 @@ +type deprecated_used_context = FunctionCall | Reference + +type deprecated_used = { + source_loc: Location.t; + deprecated_text: string; + migration_template: Parsetree.expression option; + migration_piped_template: Parsetree.expression option; + context: deprecated_used_context option; +} + +type cmt_extra_info = {deprecated_used: deprecated_used list} + +let record_deprecated_used : + (?deprecated_context:deprecated_used_context -> + ?migration_template:Parsetree.expression -> + ?migration_piped_template:Parsetree.expression -> + Location.t -> + string -> + unit) + ref = + ref + (fun + ?deprecated_context ?migration_template ?migration_piped_template _ _ -> + ignore deprecated_context; + ignore migration_template; + ignore migration_piped_template) diff --git a/compiler/ml/typecore.ml b/compiler/ml/typecore.ml index 90522f13d2..e8aa3dc914 100644 --- a/compiler/ml/typecore.ml +++ b/compiler/ml/typecore.ml @@ -2246,9 +2246,9 @@ type lazy_args = (Asttypes.Noloc.arg_label * (unit -> Typedtree.expression) option) list type targs = (Asttypes.Noloc.arg_label * Typedtree.expression option) list -let rec type_exp ~context ?recarg env sexp = +let rec type_exp ?deprecated_context ~context ?recarg env sexp = (* We now delegate everything to type_expect *) - type_expect ~context ?recarg env sexp (newvar ()) + type_expect ?deprecated_context ~context ?recarg env sexp (newvar ()) (* Typing of an expression with an expected type. This provide better error messages, and allows controlled @@ -2256,7 +2256,8 @@ let rec type_exp ~context ?recarg env sexp = In the principal case, [type_expected'] may be at generic_level. *) -and type_expect ~context ?in_function ?recarg env sexp ty_expected = +and type_expect ~context ?deprecated_context ?in_function ?recarg env sexp + ty_expected = (* Special errors for braced identifiers passed to records *) let context = match sexp.pexp_desc with @@ -2271,14 +2272,15 @@ and type_expect ~context ?in_function ?recarg env sexp ty_expected = let previous_saved_types = Cmt_format.get_saved_types () in let exp = Builtin_attributes.warning_scope sexp.pexp_attributes (fun () -> - type_expect_ ~context ?in_function ?recarg env sexp ty_expected) + type_expect_ ?deprecated_context ~context ?in_function ?recarg env sexp + ty_expected) in Cmt_format.set_saved_types (Cmt_format.Partial_expression exp :: previous_saved_types); exp -and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected - = +and type_expect_ ?deprecated_context ~context ?in_function ?(recarg = Rejected) + env sexp ty_expected = let loc = sexp.pexp_loc in (* Record the expression type before unifying it with the expected type *) let rue exp = @@ -2295,7 +2297,14 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected in match sexp.pexp_desc with | Pexp_ident lid -> - let path, desc = Typetexp.find_value env lid.loc lid.txt in + let path, desc = + Typetexp.find_value + ?deprecated_context: + (match deprecated_context with + | None -> Some Reference + | v -> v) + env lid.loc lid.txt + in (if !Clflags.annotations then let dloc = desc.Types.val_loc in let annot = @@ -2433,7 +2442,9 @@ and type_expect_ ~context ?in_function ?(recarg = Rejected) env sexp ty_expected assert (sargs <> []); begin_def (); (* one more level for non-returning functions *) - let funct = type_exp ~context:None env sfunct in + let funct = + type_exp ~deprecated_context:FunctionCall ~context:None env sfunct + in let ty = instance env funct.exp_type in end_def (); wrap_trace_gadt_instances env (lower_args env []) ty; diff --git a/compiler/ml/typetexp.ml b/compiler/ml/typetexp.ml index 53758e26c1..33b543b285 100644 --- a/compiler/ml/typetexp.ml +++ b/compiler/ml/typetexp.ml @@ -131,12 +131,13 @@ let find_all_constructors = let find_all_labels = find_component Env.lookup_all_labels (fun lid -> Unbound_label (lid, None)) -let find_value env loc lid = +let find_value ?deprecated_context env loc lid = Env.check_value_name (Longident.last lid) loc; let ((path, decl) as r) = find_component Env.lookup_value (fun lid -> Unbound_value lid) env loc lid in - Builtin_attributes.check_deprecated loc decl.val_attributes (Path.name path); + Builtin_attributes.check_deprecated ?deprecated_context loc + decl.val_attributes (Path.name path); r let lookup_module ?(load = false) env loc lid = diff --git a/compiler/ml/typetexp.mli b/compiler/ml/typetexp.mli index 19f7fa46b9..8f40096392 100644 --- a/compiler/ml/typetexp.mli +++ b/compiler/ml/typetexp.mli @@ -89,7 +89,11 @@ val find_all_labels : Longident.t -> (label_description * (unit -> unit)) list val find_value : - Env.t -> Location.t -> Longident.t -> Path.t * value_description + ?deprecated_context:Cmt_utils.deprecated_used_context -> + Env.t -> + Location.t -> + Longident.t -> + Path.t * value_description val find_module : Env.t -> Location.t -> Longident.t -> Path.t * module_declaration val lookup_module : ?load:bool -> Env.t -> Location.t -> Longident.t -> Path.t diff --git a/packages/@rescript/runtime/Js.res b/packages/@rescript/runtime/Js.res index 4bdfdf03d1..833462bac9 100644 --- a/packages/@rescript/runtime/Js.res +++ b/packages/@rescript/runtime/Js.res @@ -203,16 +203,46 @@ external undefined: undefined<'a> = "%undefined" external typeof: 'a => string = "%typeof" /** Equivalent to console.log any value. */ -@val @scope("console") +@deprecated({ + reason: "Use `Console.log` instead.", + migrate: Console.log(), +}) +@val +@scope("console") external log: 'a => unit = "log" -@val @scope("console") external log2: ('a, 'b) => unit = "log" -@val @scope("console") external log3: ('a, 'b, 'c) => unit = "log" +@deprecated({ + reason: "Use `Console.log2` instead.", + migrate: Console.log2(), +}) +@val +@scope("console") +external log2: ('a, 'b) => unit = "log" + +@deprecated({ + reason: "Use `Console.log3` instead.", + migrate: Console.log3(), +}) +@val +@scope("console") +external log3: ('a, 'b, 'c) => unit = "log" -@val @scope("console") external log4: ('a, 'b, 'c, 'd) => unit = "log" +@deprecated({ + reason: "Use `Console.log4` instead.", + migrate: Console.log4(), +}) +@val +@scope("console") +external log4: ('a, 'b, 'c, 'd) => unit = "log" /** A convenience function to console.log more than 4 arguments */ -@val @scope("console") @variadic +@deprecated({ + reason: "Use `Console.logMany` instead.", + migrate: Console.logMany(), +}) +@val +@scope("console") +@variadic external logMany: array<'a> => unit = "log" external eqNull: ('a, null<'a>) => bool = "%equal_null" diff --git a/packages/@rescript/runtime/Js_array2.res b/packages/@rescript/runtime/Js_array2.res index 78b7afdf3a..79d89a950a 100644 --- a/packages/@rescript/runtime/Js_array2.res +++ b/packages/@rescript/runtime/Js_array2.res @@ -77,6 +77,10 @@ let strArr = Js.String.castToArrayLike("abcd") Js.Array2.from(strArr) == ["a", "b", "c", "d"] ``` */ +@deprecated({ + reason: "Use `Array.fromArrayLike` instead.", + migrate: Array.fromArrayLike(), +}) @val external from: array_like<'a> => array<'a> = "Array.from" @@ -96,6 +100,10 @@ let code = s => Js.String.charCodeAt(0, s) Js.Array2.fromMap(strArr, code) == [97.0, 98.0, 99.0, 100.0] ``` */ +@deprecated({ + reason: "Use `Array.fromArrayLikeWithMap` instead.", + migrate: Array.fromArrayLikeWithMap(), +}) @val external fromMap: (array_like<'a>, 'a => 'b) => array<'b> = "Array.from" @@ -112,6 +120,10 @@ Js.Array2.isArray(list{5, 2, 3, 1, 4}) == true Js.Array2.isArray("abcd") == false ``` */ +@deprecated({ + reason: "Use `Array.isArray` instead.", + migrate: Array.isArray(), +}) @val external isArray: 'a => bool = "Array.isArray" @@ -120,6 +132,10 @@ Returns the number of elements in the array. See [`Array.length`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length) on MDN. */ +@deprecated({ + reason: "Use `Array.length` instead.", + migrate: Array.length(), +}) @get external length: array<'a> => int = "length" @@ -140,6 +156,10 @@ Js.Array2.copyWithin(arr, ~to_=2) == [100, 101, 100, 101, 102] arr == [100, 101, 100, 101, 102] ``` */ +@deprecated({ + reason: "Use `Array.copyAllWithin` instead.", + migrate: Array.copyAllWithin(~target=%insert.labelledArgument("to_")), +}) @send external copyWithin: (t<'a>, ~to_: int) => t<'a> = "copyWithin" @@ -160,6 +180,13 @@ Js.Array2.copyWithinFrom(arr, ~from=2, ~to_=0) == [102, 103, 104, 103, 104] arr == [102, 103, 104, 103, 104] ``` */ +@deprecated({ + reason: "Use `Array.copyWithinToEnd` instead.", + migrate: Array.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), +}) @send external copyWithinFrom: (t<'a>, ~to_: int, ~from: int) => t<'a> = "copyWithin" @@ -180,6 +207,13 @@ Js.Array2.copyWithinFromRange(arr, ~start=2, ~end_=5, ~to_=1) == [100, 102, 103, arr == [100, 102, 103, 104, 104, 105] ``` */ +@deprecated({ + reason: "Use `Array.copyWithin` instead.", + migrate: Array.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~end=%insert.labelledArgument("end_"), + ), +}) @send external copyWithinFromRange: (t<'a>, ~to_: int, ~start: int, ~end_: int) => t<'a> = "copyWithin" @@ -202,6 +236,10 @@ Js.Array2.fillInPlace(arr, 99) == [99, 99, 99, 99, 99] arr == [99, 99, 99, 99, 99] ``` */ +@deprecated({ + reason: "Use `Array.fillAll` instead.", + migrate: Array.fillAll(), +}) @send external fillInPlace: (t<'a>, 'a) => t<'a> = "fill" @@ -222,6 +260,10 @@ Js.Array2.fillFromInPlace(arr, 99, ~from=2) == [100, 101, 99, 99, 99] arr == [100, 101, 99, 99, 99] ``` */ +@deprecated({ + reason: "Use `Array.fillToEnd` instead.", + migrate: Array.fillToEnd(~start=%insert.labelledArgument("from")), +}) @send external fillFromInPlace: (t<'a>, 'a, ~from: int) => t<'a> = "fill" @@ -243,6 +285,10 @@ Js.Array2.fillRangeInPlace(arr, 99, ~start=1, ~end_=4) == [100, 99, 99, 99, 104] arr == [100, 99, 99, 99, 104] ``` */ +@deprecated({ + reason: "Use `Array.fill` instead.", + migrate: Array.fill(~end=%insert.labelledArgument("end_")), +}) @send external fillRangeInPlace: (t<'a>, 'a, ~start: int, ~end_: int) => t<'a> = "fill" @@ -266,6 +312,10 @@ let empty: array = [] Js.Array2.pop(empty) == None ``` */ +@deprecated({ + reason: "Use `Array.pop` instead.", + migrate: Array.pop(), +}) @send external pop: t<'a> => option<'a> = "pop" @@ -283,6 +333,10 @@ Js.Array2.push(arr, "dog") == 4 arr == ["ant", "bee", "cat", "dog"] ``` */ +@deprecated({ + reason: "Use `Array.push` instead. Note: `Array.push` returns `unit`, not the array length.", + migrate: Array.push(), +}) @send external push: (t<'a>, 'a) => int = "push" @@ -301,7 +355,12 @@ Js.Array2.pushMany(arr, ["dog", "elk"]) == 5 arr == ["ant", "bee", "cat", "dog", "elk"] ``` */ -@send @variadic +@deprecated({ + reason: "Use `Array.pushMany` instead. Note: `Array.pushMany` returns `unit`, not the array length.", + migrate: Array.pushMany(), +}) +@send +@variadic external pushMany: (t<'a>, array<'a>) => int = "push" /** @@ -318,6 +377,10 @@ Js.Array2.reverseInPlace(arr) == ["cat", "bee", "ant"] arr == ["cat", "bee", "ant"] ``` */ +@deprecated({ + reason: "Use `Array.reverse` instead.", + migrate: Array.reverse(), +}) @send external reverseInPlace: t<'a> => t<'a> = "reverse" @@ -339,6 +402,10 @@ let empty: array = [] Js.Array2.shift(empty) == None ``` */ +@deprecated({ + reason: "Use `Array.shift` instead.", + migrate: Array.shift(), +}) @send external shift: t<'a> => option<'a> = "shift" @@ -362,6 +429,12 @@ Js.Array2.sortInPlace(numbers) == [1, 10, 2, 20, 3, 30] numbers == [1, 10, 2, 20, 3, 30] ``` */ +@deprecated({ + reason: "Use `Array.toSorted` instead.", + migrate: Array.toSorted((a, b) => + %todo_("This needs a comparator function. Use `String.compare` for strings, etc.") + ), +}) @send external sortInPlace: t<'a> => t<'a> = "sort" @@ -395,6 +468,10 @@ let reverseNumeric = (n1, n2) => n2 - n1 Js.Array2.sortInPlaceWith(numbers, reverseNumeric) == [30, 20, 10, 3, 2, 1] ``` */ +@deprecated({ + reason: "Use `Array.sort` instead.", + migrate: Array.sort(), +}) @send external sortInPlaceWith: (t<'a>, ('a, 'a) => int) => t<'a> = "sort" @@ -421,7 +498,16 @@ Js.Array2.spliceInPlace(arr3, ~pos=9, ~remove=2, ~add=["x", "y", "z"]) == [] arr3 == ["a", "b", "c", "d", "e", "f", "x", "y", "z"] ``` */ -@send @variadic +@send +@variadic +@deprecated({ + reason: "Use `Array.splice` instead.", + migrate: Array.splice( + ~start=%insert.labelledArgument("pos"), + ~remove=%insert.labelledArgument("remove"), + ~insert=%insert.labelledArgument("add"), + ), +}) external spliceInPlace: (t<'a>, ~pos: int, ~remove: int, ~add: array<'a>) => t<'a> = "splice" /** @@ -440,6 +526,10 @@ arr == ["a", "b", "c", "d"] ``` */ @send +@deprecated({ + reason: "Use `Array.removeInPlace` instead.", + migrate: Array.removeInPlace(%insert.labelledArgument("pos")), +}) external removeFromInPlace: (t<'a>, ~pos: int) => t<'a> = "splice" /** @@ -458,6 +548,14 @@ arr == ["a", "b", "f"] ``` */ @send +@deprecated({ + reason: "Use `Array.splice` instead.", + migrate: Array.splice( + ~start=%insert.labelledArgument("pos"), + ~remove=%insert.labelledArgument("count"), + ~insert=[], + ), +}) external removeCountInPlace: (t<'a>, ~pos: int, ~count: int) => t<'a> = "splice" /** @@ -474,6 +572,10 @@ Js.Array2.unshift(arr, "a") == 4 arr == ["a", "b", "c", "d"] ``` */ +@deprecated({ + reason: "Use `Array.unshift` instead.", + migrate: Array.unshift(), +}) @send external unshift: (t<'a>, 'a) => int = "unshift" @@ -492,7 +594,12 @@ Js.Array2.unshiftMany(arr, ["a", "b", "c"]) == 5 arr == ["a", "b", "c", "d", "e"] ``` */ -@send @variadic +@deprecated({ + reason: "Use `Array.unshiftMany` instead.", + migrate: Array.unshiftMany(), +}) +@send +@variadic external unshiftMany: (t<'a>, array<'a>) => int = "unshift" /* Accessor functions @@ -512,6 +619,10 @@ on MDN. Js.Array2.concat(["a", "b"], ["c", "d", "e"]) == ["a", "b", "c", "d", "e"] ``` */ +@deprecated({ + reason: "Use `Array.concat` instead.", + migrate: Array.concat(), +}) @send external concat: (t<'a>, t<'a>) => t<'a> = "concat" @@ -536,7 +647,12 @@ Js.Array2.concatMany(["a", "b", "c"], [["d", "e"], ["f", "g", "h"]]) == [ ] ``` */ -@send @variadic +@deprecated({ + reason: "Use `Array.concatMany` instead.", + migrate: Array.concatMany(), +}) +@send +@variadic external concatMany: (t<'a>, array>) => t<'a> = "concat" /** @@ -551,6 +667,10 @@ Js.Array2.includes(["a", "b", "c"], "b") == true Js.Array2.includes(["a", "b", "c"], "x") == false ``` */ +@deprecated({ + reason: "Use `Array.includes` instead.", + migrate: Array.includes(), +}) @send external includes: (t<'a>, 'a) => bool = "includes" @@ -567,6 +687,10 @@ Js.Array2.indexOf([100, 101, 102, 103], 102) == 2 Js.Array2.indexOf([100, 101, 102, 103], 999) == -1 ``` */ +@deprecated({ + reason: "Use `Array.indexOf` instead.", + migrate: Array.indexOf(), +}) @send external indexOf: (t<'a>, 'a) => int = "indexOf" @@ -584,6 +708,10 @@ Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "a", ~from=3) == 4 Js.Array2.indexOfFrom(["a", "b", "a", "c", "a"], "b", ~from=2) == -1 ``` */ +@deprecated({ + reason: "Use `Array.indexOfFrom` instead.", + migrate: Array.indexOfFrom(%insert.labelledArgument("from")), +}) @send external indexOfFrom: (t<'a>, 'a, ~from: int) => int = "indexOf" @@ -603,6 +731,10 @@ Js.Array2.joinWith([2020, 9, 4], "/") == "2020/9/4" Js.Array2.joinWith([2.5, 3.6, 3e-2], ";") == "2.5;3.6;0.03" ``` */ +@deprecated({ + reason: "Use `Array.joinUnsafe` instead.", + migrate: Array.joinUnsafe(), +}) @send external joinWith: (t<'a>, string) => string = "join" @@ -619,6 +751,10 @@ Js.Array2.lastIndexOf(["a", "b", "a", "c"], "a") == 2 Js.Array2.lastIndexOf(["a", "b", "a", "c"], "x") == -1 ``` */ +@deprecated({ + reason: "Use `Array.lastIndexOf` instead.", + migrate: Array.lastIndexOf(), +}) @send external lastIndexOf: (t<'a>, 'a) => int = "lastIndexOf" @@ -636,6 +772,10 @@ Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "a", ~from=3) == 2 Js.Array2.lastIndexOfFrom(["a", "b", "a", "c", "a", "d"], "c", ~from=2) == -1 ``` */ +@deprecated({ + reason: "Use `Array.lastIndexOfFrom` instead.", + migrate: Array.lastIndexOfFrom(%insert.labelledArgument("from")), +}) @send external lastIndexOfFrom: (t<'a>, 'a, ~from: int) => int = "lastIndexOf" @@ -655,6 +795,10 @@ Js.Array2.slice(arr, ~start=-3, ~end_=-1) == [104, 105] Js.Array2.slice(arr, ~start=9, ~end_=10) == [] ``` */ +@deprecated({ + reason: "Use `Array.slice` instead.", + migrate: Array.slice(~end=%insert.labelledArgument("end_")), +}) @send external slice: (t<'a>, ~start: int, ~end_: int) => t<'a> = "slice" @@ -664,6 +808,10 @@ Returns a copy of the entire array. Same as `Js.Array2.Slice(arr, ~start=0, [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. */ +@deprecated({ + reason: "Use `Array.copy` instead.", + migrate: Array.copy(), +}) @send external copy: t<'a> => t<'a> = "slice" @@ -672,6 +820,10 @@ Returns a shallow copy of the given array from the given index to the end. See [`Array.slice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice) on MDN. */ +@deprecated({ + reason: "Use `Array.sliceToEnd` instead.", + migrate: Array.sliceToEnd(~start=%insert.unlabelledArgument(1)), +}) @send external sliceFrom: (t<'a>, int) => t<'a> = "slice" @@ -689,6 +841,10 @@ Js.Array2.toString([3.5, 4.6, 7.8]) == "3.5,4.6,7.8" Js.Array2.toString(["a", "b", "c"]) == "a,b,c" ``` */ +@deprecated({ + reason: "Use `Array.toString` instead.", + migrate: Array.toString(), +}) @send external toString: t<'a> => string = "toString" @@ -708,6 +864,10 @@ Js.Array2.toLocaleString([Js.Date.make()]) // returns "2020-3-19 10:52:11" for locale de_DE.utf8 ``` */ +@deprecated({ + reason: "Use `Array.toLocaleString` instead.", + migrate: Array.toLocaleString(), +}) @send external toLocaleString: t<'a> => string = "toLocaleString" @@ -733,6 +893,10 @@ Js.Array2.every([6, 22, 8, 4], isEven) == true Js.Array2.every([6, 22, 7, 4], isEven) == false ``` */ +@deprecated({ + reason: "Use `Array.every` instead.", + migrate: Array.every(), +}) @send external every: (t<'a>, 'a => bool) => bool = "every" @@ -755,6 +919,10 @@ Js.Array2.everyi([6, -3, 5, 8], evenIndexPositive) == true Js.Array2.everyi([6, 3, -5, 8], evenIndexPositive) == false ``` */ +@deprecated({ + reason: "Use `Array.everyWithIndex` instead.", + migrate: Array.everyWithIndex(), +}) @send external everyi: (t<'a>, ('a, int) => bool) => bool = "every" @@ -772,6 +940,10 @@ let nonEmpty = s => s != "" Js.Array2.filter(["abc", "", "", "def", "ghi"], nonEmpty) == ["abc", "def", "ghi"] ``` */ +@deprecated({ + reason: "Use `Array.filter` instead.", + migrate: Array.filter(), +}) @send external filter: (t<'a>, 'a => bool) => t<'a> = "filter" @@ -793,6 +965,10 @@ let positiveOddElement = (item, index) => mod(index, 2) == 1 && item > 0 Js.Array2.filteri([6, 3, 5, 8, 7, -4, 1], positiveOddElement) == [3, 8] ``` */ +@deprecated({ + reason: "Use `Array.filterWithIndex` instead.", + migrate: Array.filterWithIndex(), +}) @send external filteri: (t<'a>, ('a, int) => bool) => t<'a> = "filter" @@ -810,6 +986,10 @@ Js.Array2.find([33, 22, -55, 77, -44], x => x < 0) == Some(-55) Js.Array2.find([33, 22, 55, 77, 44], x => x < 0) == None ``` */ +@deprecated({ + reason: "Use `Array.find` instead.", + migrate: Array.find(), +}) @send external find: (t<'a>, 'a => bool) => option<'a> = "find" @@ -832,6 +1012,10 @@ Js.Array2.findi([66, -33, 55, 88, 22], positiveOddElement) == Some(88) Js.Array2.findi([66, -33, 55, -88, 22], positiveOddElement) == None ``` */ +@deprecated({ + reason: "Use `Array.findWithIndex` instead.", + migrate: Array.findWithIndex(), +}) @send external findi: (t<'a>, ('a, int) => bool) => option<'a> = "find" @@ -850,6 +1034,10 @@ Js.Array2.findIndex([33, 22, -55, 77, -44], x => x < 0) == 2 Js.Array2.findIndex([33, 22, 55, 77, 44], x => x < 0) == -1 ``` */ +@deprecated({ + reason: "Use `Array.findIndex` instead.", + migrate: Array.findIndex(), +}) @send external findIndex: (t<'a>, 'a => bool) => int = "findIndex" @@ -872,6 +1060,10 @@ Js.Array2.findIndexi([66, -33, 55, 88, 22], positiveOddElement) == 3 Js.Array2.findIndexi([66, -33, 55, -88, 22], positiveOddElement) == -1 ``` */ +@deprecated({ + reason: "Use `Array.findIndexWithIndex` instead.", + migrate: Array.findIndexWithIndex(), +}) @send external findIndexi: (t<'a>, ('a, int) => bool) => int = "findIndex" @@ -893,6 +1085,10 @@ on MDN. Js.Array2.forEach(["a", "b", "c"], x => Js.log(x)) == () ``` */ +@deprecated({ + reason: "Use `Array.forEach` instead.", + migrate: Array.forEach(), +}) @send external forEach: (t<'a>, 'a => unit) => unit = "forEach" @@ -913,6 +1109,10 @@ on MDN. Js.Array2.forEachi(["a", "b", "c"], (item, index) => Js.log2(index + 1, item)) == () ``` */ +@deprecated({ + reason: "Use `Array.forEachWithIndex` instead.", + migrate: Array.forEachWithIndex(), +}) @send external forEachi: (t<'a>, ('a, int) => unit) => unit = "forEach" @@ -934,6 +1134,10 @@ Js.Array2.map([12, 4, 8], x => x * x) == [144, 16, 64] Js.Array2.map(["animal", "vegetable", "mineral"], Js.String.length) == [6, 9, 7] ``` */ +@deprecated({ + reason: "Use `Array.map` instead.", + migrate: Array.map(), +}) @send external map: (t<'a>, 'a => 'b) => t<'b> = "map" @@ -953,6 +1157,10 @@ let product = (item, index) => item * index Js.Array2.mapi([10, 11, 12], product) == [0, 11, 24] ``` */ +@deprecated({ + reason: "Use `Array.mapWithIndex` instead.", + migrate: Array.mapWithIndex(), +}) @send external mapi: (t<'a>, ('a, int) => 'b) => t<'b> = "map" @@ -987,6 +1195,10 @@ Js.Array2.reduce( Js.Array2.reduce([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 2.0 // 4.0 / (2.0 / 1.0) ``` */ +@deprecated({ + reason: "Use `Array.reduce` instead.", + migrate: Array.reduce(%insert.unlabelledArgument(2), %insert.unlabelledArgument(1)), +}) @send external reduce: (t<'a>, ('b, 'a) => 'b, 'b) => 'b = "reduce" @@ -1023,6 +1235,10 @@ Js.Array2.reducei([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 ``` */ @send +@deprecated({ + reason: "Use `Array.reduceWithIndex` instead.", + migrate: Array.reduceWithIndex(%insert.unlabelledArgument(2), %insert.unlabelledArgument(1)), +}) external reducei: (t<'a>, ('b, 'a, int) => 'b, 'b) => 'b = "reduce" /** @@ -1055,6 +1271,10 @@ Js.Array2.reduceRight([2.0, 4.0], (acc, item) => item /. acc, 1.0) == 0.5 // 2.0 ``` */ @send +@deprecated({ + reason: "Use `Array.reduceRight` instead.", + migrate: Array.reduceRight(%insert.unlabelledArgument(2), %insert.unlabelledArgument(1)), +}) external reduceRight: (t<'a>, ('b, 'a) => 'b, 'b) => 'b = "reduceRight" /** @@ -1092,6 +1312,10 @@ Js.Array2.reduceRighti([2, 5, 1, 4, 3], sumOfEvens, 0) == 6 ``` */ @send +@deprecated({ + reason: "Use `Array.reduceRightWithIndex` instead.", + migrate: Array.reduceRightWithIndex(%insert.unlabelledArgument(2), %insert.unlabelledArgument(1)), +}) external reduceRighti: (t<'a>, ('b, 'a, int) => 'b, 'b) => 'b = "reduceRight" /** @@ -1107,6 +1331,10 @@ Js.Array2.some([3, 7, 5, 2, 9], isEven) == true Js.Array2.some([3, 7, 5, 1, 9], isEven) == false ``` */ +@deprecated({ + reason: "Use `Array.some` instead.", + migrate: Array.some(), +}) @send external some: (t<'a>, 'a => bool) => bool = "some" @@ -1130,6 +1358,10 @@ Js.Array2.somei(["ab", "cd", "ef", "gh"], sameLength) == true Js.Array2.somei(["a", "bc", "def", "gh"], sameLength) == false ``` */ +@deprecated({ + reason: "Use `Array.someWithIndex` instead.", + migrate: Array.someWithIndex(), +}) @send external somei: (t<'a>, ('a, int) => bool) => bool = "some" @@ -1149,6 +1381,10 @@ Js.Array2.unsafe_get(arr, 3) == 103 Js.Array2.unsafe_get(arr, 4) // returns undefined ``` */ +@deprecated({ + reason: "Use `Array.getUnsafe` instead.", + migrate: Array.getUnsafe(), +}) external unsafe_get: (array<'a>, int) => 'a = "%array_unsafe_get" /** @@ -1174,4 +1410,8 @@ Js.Array2.unsafe_set(arr, -1, 66) // you don't want to know. ``` */ +@deprecated({ + reason: "Use `Array.setUnsafe` instead.", + migrate: Array.setUnsafe(), +}) external unsafe_set: (array<'a>, int, 'a) => unit = "%array_unsafe_set" diff --git a/packages/@rescript/runtime/Js_bigint.res b/packages/@rescript/runtime/Js_bigint.res index e19daff867..4695f8128b 100644 --- a/packages/@rescript/runtime/Js_bigint.res +++ b/packages/@rescript/runtime/Js_bigint.res @@ -30,6 +30,10 @@ try { } ``` */ +@deprecated({ + reason: "Use `fromStringOrThrow` instead", + migrate: BigInt.fromStringOrThrow(), +}) @val external fromStringExn: string => bigint = "BigInt" @@ -44,13 +48,45 @@ external \"/": (bigint, bigint) => bigint = "%divbigint" external mod: (bigint, bigint) => bigint = "%modbigint" external \"**": (bigint, bigint) => bigint = "%powbigint" +@deprecated({ + reason: "Use `&` operator or `BigInt.bitwiseAnd` instead.", + migrate: %insert.unlabelledArgument(0) & %insert.unlabelledArgument(1), + migratePiped: BigInt.bitwiseAnd(), +}) external land: (bigint, bigint) => bigint = "%andbigint" + +@deprecated({ + reason: "Use `bitwiseOr` instead.", + migrate: BigInt.bitwiseOr(), +}) external lor: (bigint, bigint) => bigint = "%orbigint" + +@deprecated({ + reason: "Use `^` operator or `BigInt.bitwiseXor` instead.", + migrate: %insert.unlabelledArgument(0) ^ %insert.unlabelledArgument(1), + migratePiped: BigInt.bitwiseXor(), +}) external lxor: (bigint, bigint) => bigint = "%xorbigint" +@deprecated({ + reason: "Use `~` operator or `BigInt.bitwiseNot` instead.", + migrate: ~(%insert.unlabelledArgument(0)), + migratePiped: BigInt.bitwiseNot(), +}) let lnot = x => lxor(x, -1n) +@deprecated({ + reason: "Use `<<` operator or `BigInt.shiftLeft` instead.", + migrate: %insert.unlabelledArgument(0) << %insert.unlabelledArgument(1), + migratePiped: BigInt.shiftLeft(), +}) external lsl: (bigint, bigint) => bigint = "%lslbigint" + +@deprecated({ + reason: "Use `>>` operator or `BigInt.shiftRight` instead.", + migrate: %insert.unlabelledArgument(0) >> %insert.unlabelledArgument(1), + migratePiped: BigInt.shiftRight(), +}) external asr: (bigint, bigint) => bigint = "%asrbigint" /** @@ -64,6 +100,10 @@ See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen Js.BigInt.toString(123n)->Js.log ``` */ +@deprecated({ + reason: "Use `BigInt.toString` instead.", + migrate: BigInt.toString(), +}) @send external toString: bigint => string = "toString" @@ -77,5 +117,9 @@ Returns a string with a language-sensitive representation of this BigInt value. Js.BigInt.toString(123n)->Js.log ``` */ +@deprecated({ + reason: "Use `BigInt.toLocaleString` instead.", + migrate: BigInt.toLocaleString(), +}) @send external toLocaleString: bigint => string = "toLocaleString" diff --git a/packages/@rescript/runtime/Js_console.res b/packages/@rescript/runtime/Js_console.res index 9e0eda90c7..594ff1bb61 100644 --- a/packages/@rescript/runtime/Js_console.res +++ b/packages/@rescript/runtime/Js_console.res @@ -1,29 +1,195 @@ -@val @scope("console") external log: 'a => unit = "log" -@val @scope("console") external log2: ('a, 'b) => unit = "log" -@val @scope("console") external log3: ('a, 'b, 'c) => unit = "log" -@val @scope("console") external log4: ('a, 'b, 'c, 'd) => unit = "log" -@val @scope("console") @variadic external logMany: array<'a> => unit = "log" - -@val @scope("console") external info: 'a => unit = "info" -@val @scope("console") external info2: ('a, 'b) => unit = "info" -@val @scope("console") external info3: ('a, 'b, 'c) => unit = "info" -@val @scope("console") external info4: ('a, 'b, 'c, 'd) => unit = "info" -@val @scope("console") @variadic external infoMany: array<'a> => unit = "info" - -@val @scope("console") external warn: 'a => unit = "warn" -@val @scope("console") external warn2: ('a, 'b) => unit = "warn" -@val @scope("console") external warn3: ('a, 'b, 'c) => unit = "warn" -@val @scope("console") external warn4: ('a, 'b, 'c, 'd) => unit = "warn" -@val @scope("console") @variadic external warnMany: array<'a> => unit = "warn" - -@val @scope("console") external error: 'a => unit = "error" -@val @scope("console") external error2: ('a, 'b) => unit = "error" -@val @scope("console") external error3: ('a, 'b, 'c) => unit = "error" -@val @scope("console") external error4: ('a, 'b, 'c, 'd) => unit = "error" -@val @scope("console") @variadic external errorMany: array<'a> => unit = "error" - -@val @scope("console") external trace: unit => unit = "trace" - -@val @scope("console") external timeStart: string => unit = "time" - -@val @scope("console") external timeEnd: string => unit = "timeEnd" +@deprecated({ + reason: "Use `Console.log` instead.", + migrate: Console.log(), +}) +@val +@scope("console") +external log: 'a => unit = "log" + +@deprecated({ + reason: "Use `Console.log2` instead.", + migrate: Console.log2(), +}) +@val +@scope("console") +external log2: ('a, 'b) => unit = "log" + +@deprecated({ + reason: "Use `Console.log3` instead.", + migrate: Console.log3(), +}) +@val +@scope("console") +external log3: ('a, 'b, 'c) => unit = "log" + +@deprecated({ + reason: "Use `Console.log4` instead.", + migrate: Console.log4(), +}) +@val +@scope("console") +external log4: ('a, 'b, 'c, 'd) => unit = "log" + +@deprecated({ + reason: "Use `Console.logMany` instead.", + migrate: Console.logMany(), +}) +@val +@scope("console") +@variadic +external logMany: array<'a> => unit = "log" + +@deprecated({ + reason: "Use `Console.info` instead.", + migrate: Console.info(), +}) +@val +@scope("console") +external info: 'a => unit = "info" + +@deprecated({ + reason: "Use `Console.info2` instead.", + migrate: Console.info2(), +}) +@val +@scope("console") +external info2: ('a, 'b) => unit = "info" + +@deprecated({ + reason: "Use `Console.info3` instead.", + migrate: Console.info3(), +}) +@val +@scope("console") +external info3: ('a, 'b, 'c) => unit = "info" + +@deprecated({ + reason: "Use `Console.info4` instead.", + migrate: Console.info4(), +}) +@val +@scope("console") +external info4: ('a, 'b, 'c, 'd) => unit = "info" + +@deprecated({ + reason: "Use `Console.infoMany` instead.", + migrate: Console.infoMany(), +}) +@val +@scope("console") +@variadic +external infoMany: array<'a> => unit = "info" + +@deprecated({ + reason: "Use `Console.warn` instead.", + migrate: Console.warn(), +}) +@val +@scope("console") +external warn: 'a => unit = "warn" + +@deprecated({ + reason: "Use `Console.warn2` instead.", + migrate: Console.warn2(), +}) +@val +@scope("console") +external warn2: ('a, 'b) => unit = "warn" + +@deprecated({ + reason: "Use `Console.warn3` instead.", + migrate: Console.warn3(), +}) +@val +@scope("console") +external warn3: ('a, 'b, 'c) => unit = "warn" + +@deprecated({ + reason: "Use `Console.warn4` instead.", + migrate: Console.warn4(), +}) +@val +@scope("console") +external warn4: ('a, 'b, 'c, 'd) => unit = "warn" + +@deprecated({ + reason: "Use `Console.warnMany` instead.", + migrate: Console.warnMany(), +}) +@val +@scope("console") +@variadic +external warnMany: array<'a> => unit = "warn" + +@deprecated({ + reason: "Use `Console.error` instead.", + migrate: Console.error(), +}) +@val +@scope("console") +external error: 'a => unit = "error" + +@deprecated({ + reason: "Use `Console.error2` instead.", + migrate: Console.error2(), +}) +@val +@scope("console") +external error2: ('a, 'b) => unit = "error" + +@deprecated({ + reason: "Use `Console.error3` instead.", + migrate: Console.error3(), +}) +@val +@scope("console") +external error3: ('a, 'b, 'c) => unit = "error" + +@deprecated({ + reason: "Use `Console.error4` instead.", + migrate: Console.error4(), +}) +@val +@scope("console") +external error4: ('a, 'b, 'c, 'd) => unit = "error" + +@deprecated({ + reason: "Use `Console.errorMany` instead.", + migrate: Console.errorMany(), +}) +@val +@scope("console") +@variadic +external errorMany: array<'a> => unit = "error" + +@deprecated({ + reason: "Use `Console.trace` instead.", + migrate: Console.trace(), +}) +@val +@scope("console") +external trace: unit => unit = "trace" + +@deprecated({ + reason: "Use `Console.time` instead.", + migrate: Console.time(), +}) +@val +@scope("console") +external timeStart: string => unit = "time" + +@deprecated({ + reason: "Use `Console.timeEnd` instead.", + migrate: Console.timeEnd(), +}) +@val +@scope("console") +external timeEnd: string => unit = "timeEnd" + +@deprecated({ + reason: "Use `Console.table` instead.", + migrate: Console.table(), +}) +@val +@scope("console") +external table: 'a => unit = "table" diff --git a/packages/@rescript/runtime/Js_json.resi b/packages/@rescript/runtime/Js_json.resi index 4dce84f7ea..7e18bf6828 100644 --- a/packages/@rescript/runtime/Js_json.resi +++ b/packages/@rescript/runtime/Js_json.resi @@ -73,6 +73,13 @@ let test: ('a, Kind.t<'b>) => bool /** `decodeString(json)` returns `Some(s)` if `json` is a `string`, `None` otherwise. */ +@deprecated({ + reason: "Use pattern matching instead.", + migrate: switch %insert.unlabelledArgument(0) { + | JSON.String(str) => Some(str) + | _ => None + }, +}) let decodeString: t => option /** diff --git a/packages/@rescript/runtime/Js_string2.res b/packages/@rescript/runtime/Js_string2.res index 700b54a0c4..34257c5a3b 100644 --- a/packages/@rescript/runtime/Js_string2.res +++ b/packages/@rescript/runtime/Js_string2.res @@ -36,6 +36,10 @@ Js.String2.make(3.5) == "3.5" Js.String2.make([1, 2, 3]) == "1,2,3" ``` */ +@deprecated({ + reason: "Use `String.make` instead", + migrate: String.make(), +}) @val external make: 'a => t = "String" @@ -57,6 +61,10 @@ Js.String2.fromCharCode(0xd55c) == `한` Js.String2.fromCharCode(-64568) == `ψ` ``` */ +@deprecated({ + reason: "Use `String.fromCharCode` instead", + migrate: String.fromCharCode(), +}) @val external fromCharCode: int => t = "String.fromCharCode" @@ -67,7 +75,12 @@ corresponding to the given numbers, using the same rules as `fromCharCode`. See [`String.fromCharCode`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCharCode) on MDN. */ -@val @variadic +@deprecated({ + reason: "Use `String.fromCharCodeMany` instead", + migrate: String.fromCharCodeMany(), +}) +@val +@variadic external fromCharCodeMany: array => t = "String.fromCharCode" /** @@ -89,6 +102,10 @@ Js.String2.fromCodePoint(0xd55c) == `한` Js.String2.fromCodePoint(0x1f63a) == `😺` ``` */ +@deprecated({ + reason: "Use `String.fromCodePoint` instead", + migrate: String.fromCodePoint(), +}) @val external fromCodePoint: int => t = "String.fromCodePoint" @@ -106,7 +123,12 @@ on MDN. Js.String2.fromCodePointMany([0xd55c, 0xae00, 0x1f63a]) == `한글😺` ``` */ -@val @variadic +@deprecated({ + reason: "Use `String.fromCodePointMany` instead", + migrate: String.fromCodePointMany(), +}) +@val +@variadic external fromCodePointMany: array => t = "String.fromCodePoint" /* String.raw: ES2015, meant to be used with template strings, not directly */ @@ -123,6 +145,10 @@ on MDN. Js.String2.length("abcd") == 4 ``` */ +@deprecated({ + reason: "Use `String.length` instead", + migrate: String.length(), +}) @get external length: t => int = "length" @@ -139,6 +165,10 @@ Js.String2.get("Reason", 4) == "o" Js.String2.get(`Rẽasöń`, 5) == `ń` ``` */ +@deprecated({ + reason: "Use `String.getUnsafe` instead. Or use `String.get` for a safe version that returns an option.", + migrate: String.getUnsafe(), +}) @get_index external get: (t, int) => t = "" @@ -159,6 +189,10 @@ Js.String2.charAt("Reason", 12) == "" Js.String2.charAt(`Rẽasöń`, 5) == `ń` ``` */ +@deprecated({ + reason: "Use `String.charAt` instead", + migrate: String.charAt(), +}) @send external charAt: (t, int) => t = "charAt" @@ -179,6 +213,10 @@ Js.String2.charCodeAt(`😺`, 0) == 0xd83d->Belt.Int.toFloat Js.String2.codePointAt(`😺`, 0) == Some(0x1f63a) ``` */ +@deprecated({ + reason: "Use `String.charCodeAt` instead", + migrate: String.charCodeAt(), +}) @send external charCodeAt: (t, int) => float = "charCodeAt" @@ -198,6 +236,10 @@ Js.String2.codePointAt(`¿😺?`, 1) == Some(0x1f63a) Js.String2.codePointAt("abc", 5) == None ``` */ +@deprecated({ + reason: "Use `String.codePointAt` instead", + migrate: String.codePointAt(), +}) @send external codePointAt: (t, int) => option = "codePointAt" @@ -214,6 +256,10 @@ on MDN. Js.String2.concat("cow", "bell") == "cowbell" ``` */ +@deprecated({ + reason: "Use `String.concat` instead", + migrate: String.concat(), +}) @send external concat: (t, t) => t = "concat" @@ -230,7 +276,12 @@ on MDN. Js.String2.concatMany("1st", ["2nd", "3rd", "4th"]) == "1st2nd3rd4th" ``` */ -@send @variadic +@deprecated({ + reason: "Use `String.concatMany` instead", + migrate: String.concatMany(), +}) +@send +@variadic external concatMany: (t, array) => t = "concat" /** @@ -247,6 +298,10 @@ Js.String2.endsWith("ReScript", "Script") == true Js.String2.endsWith("C++", "Script") == false ``` */ +@deprecated({ + reason: "Use `String.endsWith` instead", + migrate: String.endsWith(), +}) @send external endsWith: (t, t) => bool = "endsWith" @@ -268,6 +323,10 @@ Js.String2.endsWithFrom("abcde", "cde", 99) == true Js.String2.endsWithFrom("example.dat", "ple", 7) == true ``` */ +@deprecated({ + reason: "Use `String.endsWithFrom` instead", + migrate: String.endsWithFrom(), +}) @send external endsWithFrom: (t, t, int) => bool = "endsWith" @@ -287,6 +346,10 @@ Js.String2.includes("programmer", "pro") == true Js.String2.includes("programmer.dat", "xyz") == false ``` */ +@deprecated({ + reason: "Use `String.includes` instead", + migrate: String.includes(), +}) @send external includes: (t, t) => bool = "includes" @@ -306,6 +369,10 @@ Js.String2.includesFrom("programmer", "gram", 4) == false Js.String2.includesFrom(`대한민국`, `한`, 1) == true ``` */ +@deprecated({ + reason: "Use `String.includesFrom` instead", + migrate: String.includesFrom(), +}) @send external includesFrom: (t, t, int) => bool = "includes" @@ -325,6 +392,10 @@ Js.String2.indexOf("beekeeper", "ee") == 1 Js.String2.indexOf("bookseller", "xyz") == -1 ``` */ +@deprecated({ + reason: "Use `String.indexOf` instead", + migrate: String.indexOf(), +}) @send external indexOf: (t, t) => int = "indexOf" @@ -346,6 +417,10 @@ Js.String2.indexOfFrom("bookseller", "sell", 2) == 4 Js.String2.indexOfFrom("bookseller", "sell", 5) == -1 ``` */ +@deprecated({ + reason: "Use `String.indexOfFrom` instead", + migrate: String.indexOfFrom(), +}) @send external indexOfFrom: (t, t, int) => int = "indexOf" @@ -366,6 +441,10 @@ Js.String2.lastIndexOf("beekeeper", "ee") == 4 Js.String2.lastIndexOf("abcdefg", "xyz") == -1 ``` */ +@deprecated({ + reason: "Use `String.lastIndexOf` instead", + migrate: String.lastIndexOf(), +}) @send external lastIndexOf: (t, t) => int = "lastIndexOf" @@ -387,6 +466,10 @@ Js.String2.lastIndexOfFrom("beekeeper", "ee", 3) == 1 Js.String2.lastIndexOfFrom("abcdefg", "xyz", 4) == -1 ``` */ +@deprecated({ + reason: "Use `String.lastIndexOfFrom` instead", + migrate: String.lastIndexOfFrom(), +}) @send external lastIndexOfFrom: (t, t, int) => int = "lastIndexOf" @@ -409,6 +492,10 @@ Js.String2.localeCompare("cat", "cat") == 0.0 Js.String2.localeCompare("CAT", "cat") > 0.0 ``` */ +@deprecated({ + reason: "Use `String.localeCompare` instead", + migrate: String.localeCompare(), +}) @send external localeCompare: (t, t) => float = "localeCompare" @@ -434,7 +521,12 @@ Js.String2.match_("Today is 2018-04-05.", /(\d+)-(\d+)-(\d+)/) == Js.String2.match_("The large container.", /b[aeiou]g/) == None ``` */ -@send @return({null_to_opt: null_to_opt}) +@deprecated({ + reason: "Use `String.match` instead", + migrate: String.match(), +}) +@send +@return({null_to_opt: null_to_opt}) external match_: (t, Js_re.t) => option>> = "match" /** @@ -448,6 +540,10 @@ See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript on MDN. See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. */ +@deprecated({ + reason: "Use `String.normalize` instead", + migrate: String.normalize(), +}) @send external normalize: t => t = "normalize" @@ -462,6 +558,10 @@ specified form of normalization, which may be one of: See [`String.normalize`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize) on MDN. See also [Unicode technical report #15](https://unicode.org/reports/tr15/) for details. */ +@deprecated({ + reason: "Use `String.normalizeByForm` instead", + migrate: String.normalizeByForm(), +}) @send external normalizeByForm: (t, t) => t = "normalize" @@ -479,6 +579,10 @@ Js.String2.repeat("ha", 3) == "hahaha" Js.String2.repeat("empty", 0) == "" ``` */ +@deprecated({ + reason: "Use `String.repeat` instead", + migrate: String.repeat(), +}) @send external repeat: (t, int) => t = "repeat" @@ -498,6 +602,10 @@ Js.String2.replace("old string", "old", "new") == "new string" Js.String2.replace("the cat and the dog", "the", "this") == "this cat and the dog" ``` */ +@deprecated({ + reason: "Use `String.replace` instead", + migrate: String.replace(), +}) @send external replace: (t, t, t) => t = "replace" @@ -515,6 +623,10 @@ Js.String2.replaceByRe("vowels be gone", /[aeiou]/g, "x") == "vxwxls bx gxnx" Js.String2.replaceByRe("Juan Fulano", /(\w+) (\w+)/, "$2, $1") == "Fulano, Juan" ``` */ +@deprecated({ + reason: "Use `String.replaceRegExp` instead", + migrate: String.replaceRegExp(), +}) @send external replaceByRe: (t, Js_re.t, t) => t = "replace" @@ -537,6 +649,10 @@ let matchFn = (matchPart, _offset, _wholeString) => Js.String2.toUpperCase(match Js.String2.unsafeReplaceBy0(str, re, matchFn) == "bEAUtIfUl vOwEls" ``` */ +@deprecated({ + reason: "Use `String.replaceRegExpBy0Unsafe` instead", + migrate: String.replaceRegExpBy0Unsafe(), +}) @send external unsafeReplaceBy0: (t, Js_re.t, (t, int, t) => t) => t = "replace" @@ -562,6 +678,10 @@ let matchFn = (_match, part1, _offset, _wholeString) => { Js.String2.unsafeReplaceBy1(str, re, matchFn) == "Jony is 41" ``` */ +@deprecated({ + reason: "Use `String.replaceRegExpBy1Unsafe` instead", + migrate: String.replaceRegExpBy1Unsafe(), +}) @send external unsafeReplaceBy1: (t, Js_re.t, (t, t, int, t) => t) => t = "replace" @@ -590,6 +710,10 @@ let matchFn = (_match, p1, p2, _offset, _wholeString) => { Js.String2.unsafeReplaceBy2(str, re, matchFn) == "42" ``` */ +@deprecated({ + reason: "Use `String.replaceRegExpBy2Unsafe` instead", + migrate: String.replaceRegExpBy2Unsafe(), +}) @send external unsafeReplaceBy2: (t, Js_re.t, (t, t, t, int, t) => t) => t = "replace" @@ -603,6 +727,10 @@ matched. See [`String.replace`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace) on MDN. */ +@deprecated({ + reason: "Use `String.replaceRegExpBy3Unsafe` instead", + migrate: String.replaceRegExpBy3Unsafe(), +}) @send external unsafeReplaceBy3: (t, Js_re.t, (t, t, t, t, int, t) => t) => t = "replace" @@ -620,6 +748,10 @@ Js.String2.search("testing 1 2 3", /\d+/) == 8 Js.String2.search("no numbers", /\d+/) == -1 ``` */ +@deprecated({ + reason: "Use `String.search` instead", + migrate: String.search(), +}) @send external search: (t, Js_re.t) => int = "search" @@ -641,6 +773,13 @@ Js.String2.slice("abcdefg", ~from=-4, ~to_=-2) == "de" Js.String2.slice("abcdefg", ~from=5, ~to_=1) == "" ``` */ +@deprecated({ + reason: "Use `String.slice` instead", + migrate: String.slice( + ~start=%insert.labelledArgument("from"), + ~end=%insert.labelledArgument("to_"), + ), +}) @send external slice: (t, ~from: int, ~to_: int) => t = "slice" @@ -660,6 +799,10 @@ Js.String2.sliceToEnd("abcdefg", ~from=-2) == "fg" Js.String2.sliceToEnd("abcdefg", ~from=7) == "" ``` */ +@deprecated({ + reason: "Use `String.sliceToEnd` instead", + migrate: String.sliceToEnd(~start=%insert.labelledArgument("from")), +}) @send external sliceToEnd: (t, ~from: int) => t = "slice" @@ -679,6 +822,10 @@ Js.String2.split("good::bad as great::awful", "::") == ["good", "bad as great", Js.String2.split("has-no-delimiter", ";") == ["has-no-delimiter"] ``` */ +@deprecated({ + reason: "Use `String.split` instead", + migrate: String.split(), +}) @send external split: (t, t) => array = "split" @@ -691,6 +838,10 @@ splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 0 = [| |];; splitAtMost "ant/bee/cat/dog/elk" "/" ~limit: 9 = [|"ant"; "bee"; "cat"; "dog"; "elk"|];; ``` */ +@deprecated({ + reason: "Use `String.splitAtMost` instead", + migrate: String.splitAtMost(), +}) @send external splitAtMost: (t, t, ~limit: int) => array = "split" @@ -712,6 +863,10 @@ Js.String2.splitByRe("art; bed , cog ;dad", /\s*[,;]\s*TODO/) == [ ] ``` */ +@deprecated({ + reason: "Use `String.splitByRegExp` instead", + migrate: String.splitByRegExp(), +}) @send external splitByRe: (t, Js_re.t) => array> = "split" @@ -743,6 +898,10 @@ Js.String2.splitByReAtMost("one: two: three: four", /\s*:\s*TODO/, ~limit=8) == ] ``` */ +@deprecated({ + reason: "Use `String.splitByRegExpAtMost` instead", + migrate: String.splitByRegExpAtMost(), +}) @send external splitByReAtMost: (t, Js_re.t, ~limit: int) => array> = "split" @@ -761,6 +920,10 @@ Js.String2.startsWith("ReScript", "") == true Js.String2.startsWith("JavaScript", "Re") == false ``` */ +@deprecated({ + reason: "Use `String.startsWith` instead", + migrate: String.startsWith(), +}) @send external startsWith: (t, t) => bool = "startsWith" @@ -780,6 +943,10 @@ Js.String2.startsWithFrom("ReScript", "", 2) == true Js.String2.startsWithFrom("JavaScript", "Scri", 2) == false ``` */ +@deprecated({ + reason: "Use `String.startsWithFrom` instead", + migrate: String.startsWithFrom(), +}) @send external startsWithFrom: (t, t, int) => bool = "startsWith" @@ -803,7 +970,7 @@ Js.String2.substr("abcdefghij", ~from=-3) == "hij" Js.String2.substr("abcdefghij", ~from=12) == "" ``` */ -@send +@deprecated("Use `String.substring` instead") @send external substr: (t, ~from: int) => t = "substr" /** @@ -827,7 +994,7 @@ Js.String2.substrAtMost("abcdefghij", ~from=-3, ~length=4) == "hij" Js.String2.substrAtMost("abcdefghij", ~from=12, ~length=2) == "" ``` */ -@send +@deprecated("Use `String.substringAtMost` instead") @send external substrAtMost: (t, ~from: int, ~length: int) => t = "substr" /** @@ -847,6 +1014,13 @@ Js.String2.substring("playground", ~from=6, ~to_=3) == "ygr" Js.String2.substring("playground", ~from=4, ~to_=12) == "ground" ``` */ +@deprecated({ + reason: "Use `String.substring` instead", + migrate: String.substring( + ~start=%insert.labelledArgument("from"), + ~end=%insert.labelledArgument("to_"), + ), +}) @send external substring: (t, ~from: int, ~to_: int) => t = "substring" @@ -866,6 +1040,10 @@ Js.String2.substringToEnd("playground", ~from=-3) == "playground" Js.String2.substringToEnd("playground", ~from=12) == "" ``` */ +@deprecated({ + reason: "Use `String.substringToEnd` instead", + migrate: String.substringToEnd(~start=%insert.labelledArgument("from")), +}) @send external substringToEnd: (t, ~from: int) => t = "substring" @@ -887,6 +1065,10 @@ Js.String2.toLowerCase(`ΣΠ`) == `σπ` Js.String2.toLowerCase(`ΠΣ`) == `πς` ``` */ +@deprecated({ + reason: "Use `String.toLowerCase` instead", + migrate: String.toLowerCase(), +}) @send external toLowerCase: t => t = "toLowerCase" @@ -895,6 +1077,10 @@ external toLowerCase: t => t = "toLowerCase" See [`String.toLocaleLowerCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleLowerCase) on MDN. */ +@deprecated({ + reason: "Use `String.toLocaleLowerCase` instead", + migrate: String.toLocaleLowerCase(), +}) @send external toLocaleLowerCase: t => t = "toLocaleLowerCase" @@ -915,6 +1101,10 @@ Js.String2.toUpperCase(`Straße`) == `STRASSE` Js.String2.toUpperCase(`πς`) == `ΠΣ` ``` */ +@deprecated({ + reason: "Use `String.toUpperCase` instead", + migrate: String.toUpperCase(), +}) @send external toUpperCase: t => t = "toUpperCase" @@ -923,6 +1113,10 @@ external toUpperCase: t => t = "toUpperCase" See [`String.to:LocaleUpperCase`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/toLocaleUpperCase) on MDN. */ +@deprecated({ + reason: "Use `String.toLocaleUpperCase` instead", + migrate: String.toLocaleUpperCase(), +}) @send external toLocaleUpperCase: t => t = "toLocaleUpperCase" @@ -940,6 +1134,10 @@ Js.String2.trim(" abc def ") == "abc def" Js.String2.trim("\n\r\t abc def \n\n\t\r ") == "abc def" ``` */ +@deprecated({ + reason: "Use `String.trim` instead", + migrate: String.trim(), +}) @send external trim: t => t = "trim" @@ -959,7 +1157,7 @@ on MDN. Js.String2.anchor("Page One", "page1") == "Page One" ``` */ -@send +@deprecated("This function has been removed from the relevant web standards.") @send external anchor: (t, t) => t = "anchor" /** @@ -975,7 +1173,7 @@ on MDN. Js.String2.link("Go to page two", "page2.html") == "Go to page two" ``` */ -@send +@deprecated("This function has been removed from the relevant web standards.") @send external link: (t, t) => t = "link" /* FIXME: we should not encourage people to use [%identity], better @@ -994,4 +1192,8 @@ let arr = Js.Array2.fromMap(Js.String2.castToArrayLike(s), x => x) arr == ["a", "b", "c", "d", "e"] ``` */ +@deprecated({ + reason: "Use `Array.fromString` instead", + migrate: Array.fromString(), +}) external castToArrayLike: t => Js_array2.array_like = "%identity" diff --git a/packages/@rescript/runtime/Stdlib_Array.res b/packages/@rescript/runtime/Stdlib_Array.res index 6591ae8928..87454eae72 100644 --- a/packages/@rescript/runtime/Stdlib_Array.res +++ b/packages/@rescript/runtime/Stdlib_Array.res @@ -15,6 +15,8 @@ external fromArrayLikeWithMap: (arrayLike<'a>, 'a => 'b) => array<'b> = "Array.f @deprecated("Use `fill` instead") @send external fillAll: (array<'a>, 'a) => unit = "fill" +@val external fromString: string => array = "Array.from" + @deprecated("Use `fill` instead") @send external fillToEnd: (array<'a>, 'a, ~start: int) => unit = "fill" @@ -44,8 +46,6 @@ let fromInitializer = (~length, f) => @get external length: array<'a> => int = "length" -let isEmpty = arr => arr->length === 0 - let rec equalFromIndex = (a, b, i, eq, len) => if i === len { true diff --git a/packages/@rescript/runtime/Stdlib_Array.resi b/packages/@rescript/runtime/Stdlib_Array.resi index 99dc5aecfd..1cd985ea86 100644 --- a/packages/@rescript/runtime/Stdlib_Array.resi +++ b/packages/@rescript/runtime/Stdlib_Array.resi @@ -31,6 +31,17 @@ external fromIterator: Stdlib_Iterator.t<'a> => array<'a> = "Array.from" @val external fromArrayLikeWithMap: (arrayLike<'a>, 'a => 'b) => array<'b> = "Array.from" +/** +`fromString(str)` creates an array of each character as a separate string from the provided `str`. + +## Examples + +```rescript +Array.fromString("abcde") == ["a", "b", "c", "d", "e"] +``` +*/ +@val external fromString: string => array = "Array.from" + /** `make(~length, init)` creates an array of length `length` initialized with the value of `init`. @@ -86,28 +97,35 @@ external length: array<'a> => int = "length" ## Examples ```rescript -[]->Array.isEmpty->assertEqual(true) -[1, 2, 3]->Array.isEmpty->assertEqual(false) - -let emptyArray = [] -emptyArray->Array.isEmpty->assertEqual(true) - -let nonEmptyArray = ["hello"] -nonEmptyArray->Array.isEmpty->assertEqual(false) +let arr = [100, 101, 102, 103, 104] +arr->Array.copyAllWithin(~target=2) == [100, 101, 100, 101, 102] +arr == [100, 101, 100, 101, 102] ``` */ -let isEmpty: array<'a> => bool +@deprecated("Use `copyWithin` instead") +@send external copyAllWithin: (array<'a>, ~target: int) => array<'a> = "copyWithin" -// TODO: Docs -@deprecated("Use `copyWithin` instead") @send -external copyAllWithin: (array<'a>, ~target: int) => array<'a> = "copyWithin" +/** +`copyWithinToEnd(array, ~target, ~start)` copies starting at element `start` in the given array to the designated `target` position, returning the resulting array. -// TODO: Docs -@deprecated("Use `copyWithin` instead") @send +Beware this will *mutate* the array. + +See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN. + +## Examples + +```rescript +let arr = [100, 101, 102, 103, 104] +arr->Array.copyWithinToEnd(~target=0, ~start=2) == [102, 103, 104, 103, 104] +arr == [102, 103, 104, 103, 104] +``` +*/ +@deprecated("Use `copyWithin` instead") +@send external copyWithinToEnd: (array<'a>, ~target: int, ~start: int) => array<'a> = "copyWithin" /** -`copyWithin(array, ~target, ~start, ~end)` copies the sequence of array elements within the array to the position starting at `target`. The copy is taken from the index positions `start` to `end`. +`copyWithin(array, ~target, ~start, ~end)` copies starting at element `start` in the given array up to but not including `end` to the designated `target` position, returning the resulting array. Beware this will *mutate* the array. @@ -116,11 +134,9 @@ See [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript ## Examples ```rescript -let myArray = [1, 2, 3, 4, 5] -myArray->Array.copyWithin(~target=0, ~start=3) == [4, 5, 3, 4, 5] - -let myArray = [1, 2, 3, 4, 5] -myArray->Array.copyWithin(~target=1, ~start=3, ~end=4) == [1, 4, 3, 4, 5] +let arr = [100, 101, 102, 103, 104, 105] +arr->Array.copyWithin(~target=1, ~start=2, ~end=5) == [100, 102, 103, 104, 104, 105] +arr == [100, 102, 103, 104, 104, 105] ``` */ @send diff --git a/packages/@rescript/runtime/Stdlib_BigInt.resi b/packages/@rescript/runtime/Stdlib_BigInt.resi index 41d8421ad5..690307f96b 100644 --- a/packages/@rescript/runtime/Stdlib_BigInt.resi +++ b/packages/@rescript/runtime/Stdlib_BigInt.resi @@ -80,7 +80,11 @@ BigInt.fromString("invalid") == None */ let fromString: string => option -@deprecated("Use `fromStringOrThrow` instead") @val +@deprecated({ + reason: "Use `fromStringOrThrow` instead", + migrate: BigInt.fromStringOrThrow(), +}) +@val external fromStringExn: string => bigint = "BigInt" /** @@ -147,7 +151,11 @@ BigInt.toString(123n) == "123" @send external toString: (bigint, ~radix: int=?) => string = "toString" -@deprecated("Use `toString` with `~radix` instead") @send +@deprecated({ + reason: "Use `toString` with `~radix` instead", + migrate: BigInt.toString(), +}) +@send external toStringWithRadix: (bigint, ~radix: int) => string = "toString" /** @@ -339,7 +347,11 @@ external ignore: bigint => unit = "%ignore" BigInt.land(7n, 4n) == 4n ``` */ -@deprecated("Use `&` operator or `bitwiseAnd` instead.") +@deprecated({ + reason: "Use `&` operator or `bitwiseAnd` instead.", + migrate: %insert.unlabelledArgument(0) & %insert.unlabelledArgument(1), + migratePiped: BigInt.bitwiseAnd(), +}) external land: (bigint, bigint) => bigint = "%andbigint" /** @@ -353,7 +365,10 @@ external land: (bigint, bigint) => bigint = "%andbigint" BigInt.lor(7n, 4n) == 7n ``` */ -@deprecated("Use `bitwiseOr` instead.") +@deprecated({ + reason: "Use `bitwiseOr` instead.", + migrate: BigInt.bitwiseOr(), +}) external lor: (bigint, bigint) => bigint = "%orbigint" /** @@ -367,7 +382,11 @@ external lor: (bigint, bigint) => bigint = "%orbigint" BigInt.lxor(7n, 4n) == 3n ``` */ -@deprecated("Use `^` operator or `bitwiseXor` instead.") +@deprecated({ + reason: "Use `^` operator or `bitwiseXor` instead.", + migrate: %insert.unlabelledArgument(0) ^ %insert.unlabelledArgument(1), + migratePiped: BigInt.bitwiseXor(), +}) external lxor: (bigint, bigint) => bigint = "%xorbigint" /** @@ -381,7 +400,11 @@ external lxor: (bigint, bigint) => bigint = "%xorbigint" BigInt.lnot(2n) == -3n ``` */ -@deprecated("Use `~` operator or `bitwiseNot` instead.") +@deprecated({ + reason: "Use `~` operator or `bitwiseNot` instead.", + migrate: ~(%insert.unlabelledArgument(0)), + migratePiped: BigInt.bitwiseNot(), +}) external lnot: bigint => bigint = "%bitnot_bigint" /** @@ -395,7 +418,11 @@ external lnot: bigint => bigint = "%bitnot_bigint" BigInt.lsl(4n, 1n) == 8n ``` */ -@deprecated("Use `<<` operator or `shiftLeft` instead.") +@deprecated({ + reason: "Use `<<` operator or `shiftLeft` instead.", + migrate: %insert.unlabelledArgument(0) << %insert.unlabelledArgument(1), + migratePiped: BigInt.shiftLeft(), +}) external lsl: (bigint, bigint) => bigint = "%lslbigint" /** @@ -409,5 +436,9 @@ external lsl: (bigint, bigint) => bigint = "%lslbigint" BigInt.asr(8n, 1n) == 4n ``` */ -@deprecated("Use `>>` operator or `shiftRight` instead.") +@deprecated({ + reason: "Use `>>` operator or `shiftRight` instead.", + migrate: %insert.unlabelledArgument(0) >> %insert.unlabelledArgument(1), + migratePiped: BigInt.shiftRight(), +}) external asr: (bigint, bigint) => bigint = "%asrbigint" diff --git a/packages/@rescript/runtime/Stdlib_Int.res b/packages/@rescript/runtime/Stdlib_Int.res index 3228ed4114..cef0ee6b27 100644 --- a/packages/@rescript/runtime/Stdlib_Int.res +++ b/packages/@rescript/runtime/Stdlib_Int.res @@ -105,6 +105,18 @@ external shiftLeft: (int, int) => int = "%lslint" external shiftRight: (int, int) => int = "%asrint" external shiftRightUnsigned: (int, int) => int = "%lsrint" +module Bitwise = { + external land: (int, int) => int = "%andint" + external lor: (int, int) => int = "%orint" + external lxor: (int, int) => int = "%xorint" + + external lsl: (int, int) => int = "%lslint" + external lsr: (int, int) => int = "%lsrint" + external asr: (int, int) => int = "%asrint" + + let lnot = x => lxor(x, -1) +} + external ignore: int => unit = "%ignore" module Ref = { diff --git a/packages/@rescript/runtime/Stdlib_Int.resi b/packages/@rescript/runtime/Stdlib_Int.resi index 384e351287..9959990901 100644 --- a/packages/@rescript/runtime/Stdlib_Int.resi +++ b/packages/@rescript/runtime/Stdlib_Int.resi @@ -186,7 +186,6 @@ Int.toPrecisionWithPrecision(1, ~digits=2) // "1.0" - `RangeError`: If `digits` is not between 1 and 100 (inclusive). Implementations are allowed to support larger and smaller values as well. ECMA-262 only requires a precision of up to 21 significant digits. - */ @send @deprecated("Use `toPrecision` instead") external toPrecisionWithPrecision: (int, ~digits: int) => string = "toPrecision" @@ -471,6 +470,46 @@ Int.shiftRightUnsigned(4, 1) == 2 */ external shiftRightUnsigned: (int, int) => int = "%lsrint" +module Bitwise: { + @deprecated({ + reason: "Use `Int.bitwiseAnd` instead", + migrate: Int.bitwiseAnd(), + }) + external land: (int, int) => int = "%andint" + @deprecated({ + reason: "Use `Int.bitwiseOr` instead", + migrate: Int.bitwiseOr(), + }) + external lor: (int, int) => int = "%orint" + @deprecated({ + reason: "Use `Int.bitwiseXor` instead", + migrate: Int.bitwiseXor(), + }) + external lxor: (int, int) => int = "%xorint" + + @deprecated({ + reason: "Use `Int.shiftLeft` instead", + migrate: Int.shiftLeft(), + }) + external lsl: (int, int) => int = "%lslint" + @deprecated({ + reason: "Use `Int.shiftRightUnsigned` instead", + migrate: Int.shiftRightUnsigned(), + }) + external lsr: (int, int) => int = "%lsrint" + @deprecated({ + reason: "Use `Int.shiftRight` instead", + migrate: Int.shiftRight(), + }) + external asr: (int, int) => int = "%asrint" + + @deprecated({ + reason: "Use `Int.bitwiseNot` instead", + migrate: Int.bitwiseNot(), + }) + let lnot: int => int +} + /** `ignore(int)` ignores the provided int and returns unit. diff --git a/packages/@rescript/runtime/Stdlib_String.resi b/packages/@rescript/runtime/Stdlib_String.resi index b0b76dce38..f42182a0ee 100644 --- a/packages/@rescript/runtime/Stdlib_String.resi +++ b/packages/@rescript/runtime/Stdlib_String.resi @@ -1104,7 +1104,7 @@ String.trimStart(" Hello world! ") == "Hello world! " external trimStart: string => string = "trimStart" /** -`trinEnd(str)` returns a string that is `str` with whitespace stripped from the +`trimEnd(str)` returns a string that is `str` with whitespace stripped from the end of a string. Internal whitespace is not removed. See [`String.trimEnd`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd) on MDN. diff --git a/packages/@rescript/runtime/lib/es6/Stdlib_Array.js b/packages/@rescript/runtime/lib/es6/Stdlib_Array.js index f733d81a00..b1bbc32728 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib_Array.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib_Array.js @@ -22,10 +22,6 @@ function fromInitializer(length, f) { return arr; } -function isEmpty(arr) { - return arr.length === 0; -} - function equal(a, b, eq) { let len = a.length; if (len === b.length) { @@ -187,7 +183,6 @@ export { fromInitializer, equal, compare, - isEmpty, indexOfOpt, lastIndexOfOpt, reduce, diff --git a/packages/@rescript/runtime/lib/es6/Stdlib_Int.js b/packages/@rescript/runtime/lib/es6/Stdlib_Int.js index 4993a6297c..fda2d75c1f 100644 --- a/packages/@rescript/runtime/lib/es6/Stdlib_Int.js +++ b/packages/@rescript/runtime/lib/es6/Stdlib_Int.js @@ -62,6 +62,14 @@ function clamp(min, max, value) { } } +function lnot(x) { + return x ^ -1; +} + +let Bitwise = { + lnot: lnot +}; + let Ref = {}; let Constants = { @@ -75,6 +83,7 @@ export { range, rangeWithOptions, clamp, + Bitwise, Ref, } /* No side effect */ diff --git a/packages/@rescript/runtime/lib/js/Stdlib_Array.js b/packages/@rescript/runtime/lib/js/Stdlib_Array.js index e62a6efb4e..f5313a3e3b 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib_Array.js +++ b/packages/@rescript/runtime/lib/js/Stdlib_Array.js @@ -22,10 +22,6 @@ function fromInitializer(length, f) { return arr; } -function isEmpty(arr) { - return arr.length === 0; -} - function equal(a, b, eq) { let len = a.length; if (len === b.length) { @@ -186,7 +182,6 @@ exports.make = make; exports.fromInitializer = fromInitializer; exports.equal = equal; exports.compare = compare; -exports.isEmpty = isEmpty; exports.indexOfOpt = indexOfOpt; exports.lastIndexOfOpt = lastIndexOfOpt; exports.reduce = reduce; diff --git a/packages/@rescript/runtime/lib/js/Stdlib_Int.js b/packages/@rescript/runtime/lib/js/Stdlib_Int.js index 5e6dbb7ced..cece54b2a0 100644 --- a/packages/@rescript/runtime/lib/js/Stdlib_Int.js +++ b/packages/@rescript/runtime/lib/js/Stdlib_Int.js @@ -62,6 +62,14 @@ function clamp(min, max, value) { } } +function lnot(x) { + return x ^ -1; +} + +let Bitwise = { + lnot: lnot +}; + let Ref = {}; let Constants = { @@ -74,5 +82,6 @@ exports.fromString = fromString; exports.range = range; exports.rangeWithOptions = rangeWithOptions; exports.clamp = clamp; +exports.Bitwise = Bitwise; exports.Ref = Ref; /* No side effect */ diff --git a/rewatch/testrepo/packages/main/src/Main2.mjs b/rewatch/testrepo/packages/main/src/Main2.mjs new file mode 100644 index 0000000000..e4df550c4b --- /dev/null +++ b/rewatch/testrepo/packages/main/src/Main2.mjs @@ -0,0 +1,20 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + +import * as Dep01 from "@testrepo/dep01/src/Dep01.mjs"; +import * as InternalDep from "./InternalDep.mjs"; + +console.log("01"); + +Dep01.log(); + +console.log(InternalDep.value); + +let $$Array; + +let $$String; + +export { + $$Array, + $$String, +} +/* Not a pure module */ diff --git a/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs b/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs new file mode 100644 index 0000000000..0f2f321053 --- /dev/null +++ b/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs @@ -0,0 +1,11 @@ +// Generated by ReScript, PLEASE EDIT WITH CARE + + +function bla() { + console.log("bla"); +} + +export { + bla, +} +/* No side effect */ diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index fcf2118183..e919bf8438 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -1,6 +1,69 @@ -Cleaned 0/115 -Parsed 2 source files -Compiled 2 modules +Cleaned 0/113 +Parsed 4 source files +Compiled 3 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 2b90a0c8e2..2e2412a38f 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,6 +1,69 @@ -Cleaned 0/115 -Parsed 1 source files -Compiled 0 modules +Cleaned 0/110 +Parsed 6 source files +Compiled 2 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index 10f05cb95e..d1ed672e27 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,30 +1,111 @@ -Cleaned 1/115 -Parsed 0 source files -Compiled 1 modules +Cleaned 0/110 +Parsed 4 source files +Compiled 5 modules -The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dependencies' instead. + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 -The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dev-dependencies' instead. + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) -The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'compiler-flags' instead. + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 - We've found a bug for you! - /packages/dep01/src/Dep01.res:3:9-17 + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() + 2 │ Js.log("02") + 3 │ Dep02.log() 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + - The module or file Dep02 can't be found. - - If it's a third-party dependency: - - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? - - Did you include the file's directory to the "sources" in rescript.json? - +The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dependencies' instead. + +The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dev-dependencies' instead. -Incremental build failed. Error:  Failed to Compile. See Errors Above +The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'compiler-flags' instead. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt index 17dcaaf94c..c54b428e24 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt @@ -1,30 +1,135 @@ -Cleaned 2/115 -Parsed 2 source files -Compiled 3 modules +Cleaned 1/111 +Parsed 5 source files +Compiled 7 modules -The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dependencies' instead. + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 -The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dev-dependencies' instead. + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) -The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'compiler-flags' instead. + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module2.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ - We've found a bug for you! - /packages/new-namespace/src/NS_alias.res:2:1-16 + deprecated: Js.log + Use `Console.log` instead. - 1 │ let hello_world = () => "Hello world" - 2 │ Other_module.bla() + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + - The module or file Other_module can't be found. - - If it's a third-party dependency: - - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? - - Did you include the file's directory to the "sources" in rescript.json? - - - Hint: Did you mean Other_module2? +The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dependencies' instead. +The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dev-dependencies' instead. -Incremental build failed. Error:  Failed to Compile. See Errors Above +The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'compiler-flags' instead. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index bebcb52cfd..06ab229ea1 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,6 +1,105 @@ -Cleaned 2/115 -Parsed 2 source files -Compiled 2 modules +Cleaned 1/110 +Parsed 6 source files +Compiled 8 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -11,6 +110,30 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + We've found a bug for you! /packages/main/src/Main.res:4:8-24 diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index 3202fc9a0c..a4e563ccaa 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,7 +1,130 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/115 -Parsed 1 source files -Compiled 2 modules +Cleaned 2/110 +Parsed 6 source files +Compiled 7 modules + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index 760b9fda3b..b4c542aab9 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,6 +1,129 @@ -Cleaned 1/115 -Parsed 1 source files -Compiled 1 modules +Cleaned 0/110 +Parsed 5 source files +Compiled 5 modules + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main2.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main2.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index 621f151afb..ef2ff1a174 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,7 +1,130 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/115 -Parsed 1 source files -Compiled 2 modules +Cleaned 1/110 +Parsed 6 source files +Compiled 7 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index 85b675f957..7382dab649 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -285,7 +285,7 @@ Path Array. "kind": 12, "tags": [], "detail": "(\n array<'a>,\n ~target: int,\n ~start: int,\n ~end: int=?,\n) => array<'a>", - "documentation": {"kind": "markdown", "value": "\n`copyWithin(array, ~target, ~start, ~end)` copies the sequence of array elements within the array to the position starting at `target`. The copy is taken from the index positions `start` to `end`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN.\n\n## Examples\n\n```rescript\nlet myArray = [1, 2, 3, 4, 5]\nmyArray->Array.copyWithin(~target=0, ~start=3) == [4, 5, 3, 4, 5]\n\nlet myArray = [1, 2, 3, 4, 5]\nmyArray->Array.copyWithin(~target=1, ~start=3, ~end=4) == [1, 4, 3, 4, 5]\n```\n"} + "documentation": {"kind": "markdown", "value": "\n`copyWithin(array, ~target, ~start, ~end)` copies starting at element `start` in the given array up to but not including `end` to the designated `target` position, returning the resulting array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN.\n\n## Examples\n\n```rescript\nlet arr = [100, 101, 102, 103, 104, 105]\narr->Array.copyWithin(~target=1, ~start=2, ~end=5) == [100, 102, 103, 104, 104, 105]\narr == [100, 102, 103, 104, 104, 105]\n```\n"} }, { "label": "toString", "kind": 12, @@ -316,6 +316,12 @@ Path Array. "tags": [], "detail": "array<'a> => unit", "documentation": {"kind": "markdown", "value": "\n`reverse(array)` reverses the order of the items in `array`.\n\nBeware this will *mutate* the array.\n\nSee [`Array.reverse`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse) on MDN.\n\n## Examples\n\n```rescript\nlet someArray = [\"hi\", \"hello\"]\nsomeArray->Array.reverse\n\nsomeArray == [\"hello\", \"hi\"]\n```\n"} + }, { + "label": "fromString", + "kind": 12, + "tags": [], + "detail": "string => array", + "documentation": {"kind": "markdown", "value": "\n`fromString(str)` creates an array of each character as a separate string from the provided `str`.\n\n## Examples\n\n```rescript\nArray.fromString(\"abcde\") == [\"a\", \"b\", \"c\", \"d\", \"e\"]\n```\n"} }, { "label": "findLastIndexWithIndex", "kind": 12, @@ -430,12 +436,6 @@ Path Array. "tags": [], "detail": "(array<'a>, int, 'a) => unit", "documentation": {"kind": "markdown", "value": "\n`set(array, index, item)` sets the provided `item` at `index` of `array`.\n\nBeware this will *mutate* the array.\n\n## Examples\n\n```rescript\nlet array = [\"Hello\", \"Hi\", \"Good bye\"]\narray->Array.set(1, \"Hello\")\n\narray[1] == Some(\"Hello\")\n```\n"} - }, { - "label": "isEmpty", - "kind": 12, - "tags": [], - "detail": "array<'a> => bool", - "documentation": {"kind": "markdown", "value": "\n`isEmpty(array)` returns `true` if the array is empty (has length 0), `false` otherwise.\n\n## Examples\n\n```rescript\n[]->Array.isEmpty->assertEqual(true)\n[1, 2, 3]->Array.isEmpty->assertEqual(false)\n\nlet emptyArray = []\nemptyArray->Array.isEmpty->assertEqual(true)\n\nlet nonEmptyArray = [\"hello\"]\nnonEmptyArray->Array.isEmpty->assertEqual(false)\n```\n"} }, { "label": "filterWithIndex", "kind": 12, @@ -483,7 +483,7 @@ Path Array. "kind": 12, "tags": [1], "detail": "(array<'a>, ~target: int, ~start: int) => array<'a>", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `copyWithin` instead\n\n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `copyWithin` instead\n\n\n`copyWithinToEnd(array, ~target, ~start)` copies starting at element `start` in the given array to the designated `target` position, returning the resulting array.\n\nBeware this will *mutate* the array.\n\nSee [`Array.copyWithin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin) on MDN.\n\n## Examples\n\n```rescript\nlet arr = [100, 101, 102, 103, 104]\narr->Array.copyWithinToEnd(~target=0, ~start=2) == [102, 103, 104, 103, 104]\narr == [102, 103, 104, 103, 104]\n```\n"} }, { "label": "unshift", "kind": 12, @@ -531,7 +531,7 @@ Path Array. "kind": 12, "tags": [1], "detail": "(array<'a>, ~target: int) => array<'a>", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `copyWithin` instead\n\n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `copyWithin` instead\n\n\n`isEmpty(array)` returns `true` if the array is empty (has length 0), `false` otherwise.\n\n## Examples\n\n```rescript\nlet arr = [100, 101, 102, 103, 104]\narr->Array.copyAllWithin(~target=2) == [100, 101, 100, 101, 102]\narr == [100, 101, 100, 101, 102]\n```\n"} }, { "label": "keepSome", "kind": 12, @@ -2480,7 +2480,7 @@ Path t "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.toPrecision", "kind": 12, diff --git a/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt b/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt index 898253f44f..5d72fc9174 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionInferValues.res.txt @@ -34,7 +34,7 @@ Path t "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.toPrecision", "kind": 12, @@ -352,7 +352,7 @@ Path t "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.toPrecision", "kind": 12, diff --git a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt index cd4f01377d..509e1bb249 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionJsx.res.txt @@ -243,7 +243,7 @@ Path "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.bitwiseAnd", "kind": 12, @@ -413,7 +413,7 @@ Path "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.bitwiseAnd", "kind": 12, diff --git a/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt b/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt index 4fb8e0849f..1519636e45 100644 --- a/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt +++ b/tests/analysis_tests/tests/src/expected/CompletionPipeChain.res.txt @@ -347,7 +347,7 @@ Path t "kind": 12, "tags": [1], "detail": "(int, ~digits: int) => string", - "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n \n"} + "documentation": {"kind": "markdown", "value": "Deprecated: Use `toPrecision` instead\n\n\n`toPrecisionWithPrecision(n, ~digits)` return a `string` representing the giver value with\nprecision. `digits` specifies the number of significant digits. See [`Number.toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toPrecision) on MDN.\n\n## Examples\n\n```rescript\nInt.toPrecisionWithPrecision(100, ~digits=2) // \"1.0e+2\"\nInt.toPrecisionWithPrecision(1, ~digits=2) // \"1.0\"\n```\n\n## Exceptions\n\n- `RangeError`: If `digits` is not between 1 and 100 (inclusive).\n Implementations are allowed to support larger and smaller values as well.\n ECMA-262 only requires a precision of up to 21 significant digits.\n"} }, { "label": "Int.toPrecision", "kind": 12, diff --git a/tests/build_tests/super_errors/expected/warnings4.res.expected b/tests/build_tests/super_errors/expected/warnings4.res.expected index 0e45f5b371..9eec05e9d6 100644 --- a/tests/build_tests/super_errors/expected/warnings4.res.expected +++ b/tests/build_tests/super_errors/expected/warnings4.res.expected @@ -5,7 +5,7 @@ 9 │ @val external x: myType = "myVariable" 10 │ 11 │ switch x { - 12 │ | #first => Js.log("first") + 12 │ | #first => Console.log("first") 13 │ } 14 │ diff --git a/tests/build_tests/super_errors/expected/warnings5.res.expected b/tests/build_tests/super_errors/expected/warnings5.res.expected index 204f9f1608..23302e6c3f 100644 --- a/tests/build_tests/super_errors/expected/warnings5.res.expected +++ b/tests/build_tests/super_errors/expected/warnings5.res.expected @@ -4,7 +4,7 @@ 10 │ 11 │ switch y { - 12 │ | {otherValue: false} => Js.log("first") + 12 │ | {otherValue: false} => Console.log("first") 13 │ } 14 │ @@ -18,7 +18,7 @@ Either bind these labels explicitly or add ', _' to the pattern. 9 │ @val external y: someRecord = "otherVariable" 10 │ 11 │ switch y { - 12 │ | {otherValue: false} => Js.log("first") + 12 │ | {otherValue: false} => Console.log("first") 13 │ } 14 │ 15 │ switch y { @@ -32,7 +32,7 @@ Either bind these labels explicitly or add ', _' to the pattern. 14 │ 15 │ switch y { - 16 │ | {typ: WithPayload(true)} => Js.log("first") + 16 │ | {typ: WithPayload(true)} => Console.log("first") 17 │ } 18 │ @@ -46,7 +46,7 @@ Either bind these labels explicitly or add ', _' to the pattern. 13 │ } 14 │ 15 │ switch y { - 16 │ | {typ: WithPayload(true)} => Js.log("first") + 16 │ | {typ: WithPayload(true)} => Console.log("first") 17 │ } 18 │ 19 │ let arr = [1] @@ -62,7 +62,7 @@ Either bind these labels explicitly or add ', _' to the pattern. 19 │ let arr = [1] 20 │ 21 │ switch arr { - 22 │ | [] => Js.log("") + 22 │ | [] => Console.log("") 23 │ } 24 │ 25 │ switch arr { @@ -77,7 +77,7 @@ Either bind these labels explicitly or add ', _' to the pattern. 23 │ } 24 │ 25 │ switch arr { - 26 │ | [one] => Js.log(one) + 26 │ | [one] => Console.log(one) 27 │ } 28 │ 29 │ switch arr { diff --git a/tests/build_tests/super_errors/fixtures/curry_in_uncurry.res b/tests/build_tests/super_errors/fixtures/curry_in_uncurry.res index 0c0c3b67e1..92e656deef 100644 --- a/tests/build_tests/super_errors/fixtures/curry_in_uncurry.res +++ b/tests/build_tests/super_errors/fixtures/curry_in_uncurry.res @@ -1,3 +1,3 @@ let f = (a, b) => a + b -f(2, 2)->Js.log +f(2, 2)->Console.log diff --git a/tests/build_tests/super_errors/fixtures/polyvariant_constructors_mismatch_second.res b/tests/build_tests/super_errors/fixtures/polyvariant_constructors_mismatch_second.res index d8eace4719..11299b95c3 100644 --- a/tests/build_tests/super_errors/fixtures/polyvariant_constructors_mismatch_second.res +++ b/tests/build_tests/super_errors/fixtures/polyvariant_constructors_mismatch_second.res @@ -1,7 +1,7 @@ let handle = (ev: [#Click | #KeyDown]) => switch ev { - | #Click => Js.log("clicked") - | #KeyDown => Js.log("key down") + | #Click => Console.log("clicked") + | #KeyDown => Console.log("key down") } let _ = handle(#Resize) diff --git a/tests/build_tests/super_errors/fixtures/todo_with_no_payload.res b/tests/build_tests/super_errors/fixtures/todo_with_no_payload.res index d7aa60688c..e6ef3d533f 100644 --- a/tests/build_tests/super_errors/fixtures/todo_with_no_payload.res +++ b/tests/build_tests/super_errors/fixtures/todo_with_no_payload.res @@ -2,4 +2,4 @@ let implementMeLater = (): string => %todo let x = implementMeLater() -Js.log(x->Js.String2.includes("x")) +Console.log(x->String.includes("x")) diff --git a/tests/build_tests/super_errors/fixtures/todo_with_payload.res b/tests/build_tests/super_errors/fixtures/todo_with_payload.res index a52d80d5c1..d13d745dc7 100644 --- a/tests/build_tests/super_errors/fixtures/todo_with_payload.res +++ b/tests/build_tests/super_errors/fixtures/todo_with_payload.res @@ -2,4 +2,4 @@ let implementMeLater = (): string => %todo("This should return a string eventual let x = implementMeLater() -Js.log(x->Js.String2.includes("x")) +Console.log(x->String.includes("x")) diff --git a/tests/build_tests/super_errors/fixtures/warnings4.res b/tests/build_tests/super_errors/fixtures/warnings4.res index 3c65caefe2..94de143aa1 100644 --- a/tests/build_tests/super_errors/fixtures/warnings4.res +++ b/tests/build_tests/super_errors/fixtures/warnings4.res @@ -9,5 +9,5 @@ type myType = [ @val external x: myType = "myVariable" switch x { -| #first => Js.log("first") +| #first => Console.log("first") } diff --git a/tests/build_tests/super_errors/fixtures/warnings5.res b/tests/build_tests/super_errors/fixtures/warnings5.res index 9e69c5076d..a3739d03b6 100644 --- a/tests/build_tests/super_errors/fixtures/warnings5.res +++ b/tests/build_tests/super_errors/fixtures/warnings5.res @@ -9,21 +9,21 @@ type someRecord = { @val external y: someRecord = "otherVariable" switch y { -| {otherValue: false} => Js.log("first") +| {otherValue: false} => Console.log("first") } switch y { -| {typ: WithPayload(true)} => Js.log("first") +| {typ: WithPayload(true)} => Console.log("first") } let arr = [1] switch arr { -| [] => Js.log("") +| [] => Console.log("") } switch arr { -| [one] => Js.log(one) +| [one] => Console.log(one) } switch arr { diff --git a/tests/tools_tests/Makefile b/tests/tools_tests/Makefile index 4d26df85bb..e8d2c1f3fc 100644 --- a/tests/tools_tests/Makefile +++ b/tests/tools_tests/Makefile @@ -5,6 +5,7 @@ build: test: build ./test.sh + yarn build clean: yarn clean diff --git a/tests/tools_tests/package.json b/tests/tools_tests/package.json index 2bf38e72e8..63fd369df9 100644 --- a/tests/tools_tests/package.json +++ b/tests/tools_tests/package.json @@ -2,7 +2,7 @@ "name": "@tests/tools", "private": true, "scripts": { - "build": "rescript legacy build", + "build": "rescript legacy build -warn-error -3", "clean": "rescript clean", "dev": "rescript -w" }, diff --git a/tests/tools_tests/src/expected/DeprecatedStuff.res.expected b/tests/tools_tests/src/expected/DeprecatedStuff.res.expected new file mode 100644 index 0000000000..3a9e14c4f2 --- /dev/null +++ b/tests/tools_tests/src/expected/DeprecatedStuff.res.expected @@ -0,0 +1,12 @@ +@send +external slice: (string, ~from: int, ~to_: int) => string = "slice" + +@send +external shift: array<'a> => option<'a> = "shift" + +module Constants = { + let otherThing = [2, 3] +} + +let deprecatedThing = [1, 2] + diff --git a/tests/tools_tests/src/expected/DeprecatedStuff.resi.expected b/tests/tools_tests/src/expected/DeprecatedStuff.resi.expected new file mode 100644 index 0000000000..df7f2f270f --- /dev/null +++ b/tests/tools_tests/src/expected/DeprecatedStuff.resi.expected @@ -0,0 +1,27 @@ +@deprecated({ + reason: "Use `String.slice` instead", + migrate: String.slice( + ~start=%insert.labelledArgument("from"), + ~end=%insert.labelledArgument("to_"), + ), +}) +@send +external slice: (string, ~from: int, ~to_: int) => string = "slice" + +@send +@deprecated({ + reason: "Use `Array.shift` instead.", + migrate: Array.shift(), +}) +external shift: array<'a> => option<'a> = "shift" + +module Constants: { + let otherThing: array +} + +@deprecated({ + reason: "Use `otherThing` instead.", + migrate: DeprecatedStuff.Constants.otherThing, +}) +let deprecatedThing: array + diff --git a/tests/tools_tests/src/expected/FileToMigrate.res.expected b/tests/tools_tests/src/expected/FileToMigrate.res.expected new file mode 100644 index 0000000000..2572499f87 --- /dev/null +++ b/tests/tools_tests/src/expected/FileToMigrate.res.expected @@ -0,0 +1,11 @@ +let someNiceString = String.slice("abcdefg", ~start=2, ~end=5) + +let someNiceString2 = String.slice(String.slice("abcdefg", ~start=0, ~end=1), ~start=2, ~end=5) + +let someNiceString3 = "abcdefg"->String.slice(~start=2, ~end=5) + +let shift1 = Array.shift([1, 2, 3]) +let shift2 = [1, 2, 3]->Array.shift + +let deprecatedThing1 = DeprecatedStuff.Constants.otherThing + diff --git a/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Array.res.expected new file mode 100644 index 0000000000..009a006db0 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Array.res.expected @@ -0,0 +1,4 @@ +// Migrations that will not compile after migration (by design) +let sortInPlaceWith1 = [3, 1, 2]->Array.sort((a, b) => a - b) +let sortInPlaceWith2 = Array.sort([3, 1, 2], (a, b) => a - b) + diff --git a/tests/tools_tests/src/expected/StdlibMigrationNoCompile_String.res.expected b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_String.res.expected new file mode 100644 index 0000000000..c99e65e613 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_String.res.expected @@ -0,0 +1,12 @@ +let normalizeByForm1 = "abcde"->String.normalizeByForm("a") +let normalizeByForm2 = String.normalizeByForm("abcde", "a") + +let unsafeReplaceBy01 = "abcde"->String.replaceRegExpBy0Unsafe(/d/, (_, _, _) => "f") +let unsafeReplaceBy02 = String.replaceRegExpBy0Unsafe("abcde", /d/, (_, _, _) => "f") + +let unsafeReplaceBy11 = "abcde"->String.replaceRegExpBy1Unsafe(/d/, (_, _, _, _) => "f") +let unsafeReplaceBy12 = String.replaceRegExpBy1Unsafe("abcde", /d/, (_, _, _, _) => "f") + +let unsafeReplaceBy21 = "abcde"->String.replaceRegExpBy2Unsafe(/d/, (_, _, _, _, _) => "f") +let unsafeReplaceBy22 = String.replaceRegExpBy2Unsafe("abcde", /d/, (_, _, _, _, _) => "f") + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected new file mode 100644 index 0000000000..4f18613d4e --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected @@ -0,0 +1,169 @@ +let shift1 = [1, 2, 3]->Array.shift +let shift2 = Array.shift([1, 2, 3]) + +let slice1 = [1, 2, 3]->Array.slice(~start=1, ~end=2) +let slice2 = Array.slice([1, 2, 3], ~start=1, ~end=2) + +external someArrayLike: Js_array2.array_like = "whatever" + +let from1 = someArrayLike->Array.fromArrayLike +let from2 = Array.fromArrayLike(someArrayLike) + +let fromMap1 = someArrayLike->Array.fromArrayLikeWithMap(s => s ++ "!") +let fromMap2 = Array.fromArrayLikeWithMap(someArrayLike, s => s ++ "!") + +let isArray1 = [1, 2, 3]->Array.isArray +let isArray2 = Array.isArray([1, 2, 3]) + +let length1 = [1, 2, 3]->Array.length +let length2 = Array.length([1, 2, 3]) + +let fillInPlace1 = [1, 2, 3]->Array.fillAll(0) +let fillInPlace2 = Array.fillAll([1, 2, 3], 0) + +let fillFromInPlace1 = [1, 2, 3, 4]->Array.fillToEnd(0, ~start=2) +let fillFromInPlace2 = Array.fillToEnd([1, 2, 3, 4], 0, ~start=2) + +let fillRangeInPlace1 = [1, 2, 3, 4]->Array.fill(0, ~start=1, ~end=3) +let fillRangeInPlace2 = Array.fill([1, 2, 3, 4], 0, ~start=1, ~end=3) + +let pop1 = [1, 2, 3]->Array.pop +let pop2 = Array.pop([1, 2, 3]) + +let reverseInPlace1 = [1, 2, 3]->Array.reverse +let reverseInPlace2 = Array.reverse([1, 2, 3]) + +let concat1 = [1, 2]->Array.concat([3, 4]) +let concat2 = Array.concat([1, 2], [3, 4]) + +let concatMany1 = [1, 2]->Array.concatMany([[3, 4], [5, 6]]) +let concatMany2 = Array.concatMany([1, 2], [[3, 4], [5, 6]]) + +let includes1 = [1, 2, 3]->Array.includes(2) +let includes2 = Array.includes([1, 2, 3], 2) + +let indexOf1 = [1, 2, 3]->Array.indexOf(2) +let indexOf2 = Array.indexOf([1, 2, 3], 2) + +let indexOfFrom1 = [1, 2, 1, 3]->Array.indexOfFrom(1, 2) +let indexOfFrom2 = Array.indexOfFrom([1, 2, 1, 3], 1, 2) + +let joinWith1 = [1, 2, 3]->Array.joinUnsafe(",") +let joinWith2 = Array.joinUnsafe([1, 2, 3], ",") + +let lastIndexOf1 = [1, 2, 1, 3]->Array.lastIndexOf(1) +let lastIndexOf2 = Array.lastIndexOf([1, 2, 1, 3], 1) + +let lastIndexOfFrom1 = [1, 2, 1, 3, 1]->Array.lastIndexOfFrom(1, 3) +let lastIndexOfFrom2 = Array.lastIndexOfFrom([1, 2, 1, 3, 1], 1, 3) + +let copy1 = [1, 2, 3]->Array.copy +let copy2 = Array.copy([1, 2, 3]) + +let sliceFrom1 = [1, 2, 3, 4]->Array.sliceToEnd(~start=2) +let sliceFrom2 = Array.sliceToEnd([1, 2, 3, 4], ~start=2) + +let toString1 = [1, 2, 3]->Array.toString +let toString2 = Array.toString([1, 2, 3]) + +let toLocaleString1 = [1, 2, 3]->Array.toLocaleString +let toLocaleString2 = Array.toLocaleString([1, 2, 3]) + +let every1 = [2, 4, 6]->Array.every(x => mod(x, 2) == 0) +let every2 = Array.every([2, 4, 6], x => mod(x, 2) == 0) + +let everyi1 = [0, 1, 2]->Array.everyWithIndex((x, i) => x == i) +let everyi2 = Array.everyWithIndex([0, 1, 2], (x, i) => x == i) + +let filter1 = [1, 2, 3, 4]->Array.filter(x => x > 2) +let filter2 = Array.filter([1, 2, 3, 4], x => x > 2) + +let filteri1 = [0, 1, 2, 3]->Array.filterWithIndex((_x, i) => i > 1) +let filteri2 = Array.filterWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let find1 = [1, 2, 3, 4]->Array.find(x => x > 2) +let find2 = Array.find([1, 2, 3, 4], x => x > 2) + +let findi1 = [0, 1, 2, 3]->Array.findWithIndex((_x, i) => i > 1) +let findi2 = Array.findWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let findIndex1 = [1, 2, 3, 4]->Array.findIndex(x => x > 2) +let findIndex2 = Array.findIndex([1, 2, 3, 4], x => x > 2) + +let findIndexi1 = [0, 1, 2, 3]->Array.findIndexWithIndex((_x, i) => i > 1) +let findIndexi2 = Array.findIndexWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let forEach1 = [1, 2, 3]->Array.forEach(x => ignore(x)) +let forEach2 = Array.forEach([1, 2, 3], x => ignore(x)) + +let forEachi1 = [1, 2, 3]->Array.forEachWithIndex((x, i) => ignore(x + i)) +let forEachi2 = Array.forEachWithIndex([1, 2, 3], (x, i) => ignore(x + i)) + +let map1 = [1, 2, 3]->Array.map(x => x * 2) +let map2 = Array.map([1, 2, 3], x => x * 2) + +let mapi1 = [1, 2, 3]->Array.mapWithIndex((x, i) => x + i) +let mapi2 = Array.mapWithIndex([1, 2, 3], (x, i) => x + i) + +let some1 = [1, 2, 3, 4]->Array.some(x => x > 3) +let some2 = Array.some([1, 2, 3, 4], x => x > 3) + +let somei1 = [0, 1, 2, 3]->Array.someWithIndex((_x, i) => i > 2) +let somei2 = Array.someWithIndex([0, 1, 2, 3], (_x, i) => i > 2) + +let unsafeGet1 = [1, 2, 3]->Array.getUnsafe(1) +let unsafeGet2 = Array.getUnsafe([1, 2, 3], 1) + +let unsafeSet1 = [1, 2, 3]->Array.setUnsafe(1, 5) +let unsafeSet2 = Array.setUnsafe([1, 2, 3], 1, 5) + +let copyWithin1 = [1, 2, 3, 4, 5]->Array.copyAllWithin(~target=2) +let copyWithin2 = Array.copyAllWithin([1, 2, 3, 4, 5], ~target=2) + +let copyWithinFrom1 = [1, 2, 3, 4, 5]->Array.copyWithinToEnd(~target=0, ~start=2) +let copyWithinFrom2 = Array.copyWithinToEnd([1, 2, 3, 4, 5], ~target=0, ~start=2) + +let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~target=1, ~start=2, ~end=5) +let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~target=1, ~start=2, ~end=5) + +let push1 = [1, 2, 3]->Array.push(4) +let push2 = Array.push([1, 2, 3], 4) + +let pushMany1 = [1, 2, 3]->Array.pushMany([4, 5]) +let pushMany2 = Array.pushMany([1, 2, 3], [4, 5]) + +let sortInPlace1 = + ["c", "a", "b"]->Array.toSorted((a, b) => + %todo("This needs a comparator function. Use `String.compare` for strings, etc.") + ) +let sortInPlace2 = Array.toSorted(["c", "a", "b"], (a, b) => + %todo("This needs a comparator function. Use `String.compare` for strings, etc.") +) + +let unshift1 = [1, 2, 3]->Array.unshift(4) +let unshift2 = Array.unshift([1, 2, 3], 4) + +let unshiftMany1 = [1, 2, 3]->Array.unshiftMany([4, 5]) +let unshiftMany2 = Array.unshiftMany([1, 2, 3], [4, 5]) + +let reduce1 = [1, 2, 3]->Array.reduce(0, (acc, x) => acc + x) +let reduce2 = Array.reduce([1, 2, 3], 0, (acc, x) => acc + x) + +let spliceInPlace1 = [1, 2, 3]->Array.splice(~start=1, ~remove=1, ~insert=[4, 5]) +let spliceInPlace2 = Array.splice([1, 2, 3], ~start=1, ~remove=1, ~insert=[4, 5]) + +let removeFromInPlace1 = [1, 2, 3]->Array.removeInPlace(1) +let removeFromInPlace2 = Array.removeInPlace([1, 2, 3], 1) + +let removeCountInPlace1 = [1, 2, 3]->Array.splice(~start=1, ~remove=1, ~insert=[]) +let removeCountInPlace2 = Array.splice([1, 2, 3], ~start=1, ~remove=1, ~insert=[]) + +let reducei1 = [1, 2, 3]->Array.reduceWithIndex(0, (acc, x, i) => acc + x + i) +let reducei2 = Array.reduceWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) + +let reduceRight1 = [1, 2, 3]->Array.reduceRight(0, (acc, x) => acc + x) +let reduceRight2 = Array.reduceRight([1, 2, 3], 0, (acc, x) => acc + x) + +let reduceRighti1 = [1, 2, 3]->Array.reduceRightWithIndex(0, (acc, x, i) => acc + x + i) +let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected new file mode 100644 index 0000000000..e674d8aee7 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected @@ -0,0 +1,48 @@ +let fromStringExn1 = "123"->BigInt.fromStringOrThrow +let fromStringExn2 = BigInt.fromStringOrThrow("123") + +let land1 = 7n->BigInt.bitwiseAnd(4n) +let land2 = 7n & 4n + +let lor1 = 7n->BigInt.bitwiseOr(4n) +let lor2 = BigInt.bitwiseOr(7n, 4n) + +let lxor1 = 7n->BigInt.bitwiseXor(4n) +let lxor2 = 7n ^ 4n + +let lnot1 = 2n->Js.BigInt.lnot +let lnot2 = Js.BigInt.lnot(2n) + +let lsl1 = 4n->BigInt.shiftLeft(1n) +let lsl2 = 4n << 1n + +let asr1 = 8n->BigInt.shiftRight(1n) +let asr2 = 8n >> 1n + +let toString1 = 123n->BigInt.toString +let toString2 = BigInt.toString(123n) + +let toLocaleString1 = 123n->BigInt.toLocaleString +let toLocaleString2 = BigInt.toLocaleString(123n) + +// From the stdlib module +let stdlib_fromStringExn1 = "123"->BigInt.fromStringOrThrow +let stdlib_fromStringExn2 = BigInt.fromStringOrThrow("123") + +let stdlib_land1 = 7n->BigInt.bitwiseAnd(4n) +let stdlib_land2 = 7n & 4n + +let stdlib_lor1 = BigInt.bitwiseOr(7n, 4n) + +let stdlib_lxor1 = 7n->BigInt.bitwiseXor(4n) +let stdlib_lxor2 = 7n ^ 4n + +let stdlib_lnot1 = 2n->BigInt.bitwiseNot +let stdlib_lnot2 = ~2n + +let stdlib_lsl1 = 4n->BigInt.shiftLeft(1n) +let stdlib_lsl2 = 4n << 1n + +let stdlib_asr1 = 8n->BigInt.shiftRight(1n) +let stdlib_asr2 = 8n >> 1n + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Console.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Console.res.expected new file mode 100644 index 0000000000..472198684f --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Console.res.expected @@ -0,0 +1,29 @@ +let log = Console.log("Hello, World!") +let log2 = Console.log2("Hello", "World") +let log3 = Console.log3("Hello", "World", "!") +let log4 = Console.log4("Hello", "World", "!", "!") +let logMany = Console.logMany(["Hello", "World"]) + +let info = Console.info("Hello, World!") +let info2 = Console.info2("Hello", "World") +let info3 = Console.info3("Hello", "World", "!") +let info4 = Console.info4("Hello", "World", "!", "!") +let infoMany = Console.infoMany(["Hello", "World"]) + +let warn = Console.warn("Hello, World!") +let warn2 = Console.warn2("Hello", "World") +let warn3 = Console.warn3("Hello", "World", "!") +let warn4 = Console.warn4("Hello", "World", "!", "!") +let warnMany = Console.warnMany(["Hello", "World"]) + +let error = Console.error("Hello, World!") +let error2 = Console.error2("Hello", "World") +let error3 = Console.error3("Hello", "World", "!") +let error4 = Console.error4("Hello", "World", "!", "!") +let errorMany = Console.errorMany(["Hello", "World"]) + +let trace = Console.trace() +let timeStart = Console.time("Hello, World!") +let timeEnd = Console.timeEnd("Hello, World!") +let table = Console.table(["Hello", "World"]) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Int.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Int.res.expected new file mode 100644 index 0000000000..49289fa30b --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Int.res.expected @@ -0,0 +1,8 @@ +let result1 = Int.bitwiseAnd(1, 2) +let result2 = Int.bitwiseOr(1, 2) +let result3 = Int.bitwiseXor(1, 2) +let result4 = Int.shiftLeft(1, 2) +let result5 = Int.shiftRightUnsigned(1, 2) +let result6 = Int.shiftRight(1, 2) +let result7 = Int.bitwiseNot(0) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected new file mode 100644 index 0000000000..f5e4af5f9c --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected @@ -0,0 +1,19 @@ +external someJson: Js_json.t = "someJson" +external strToJson: string => Js_json.t = "strToJson" + +let decodeString1 = switch someJson { +| JSON.String(str) => Some(str) +| _ => None +} +let decodeString2 = switch someJson { +| JSON.String(str) => Some(str) +| _ => None +} +let decodeString3 = switch [1, 2, 3] +->Array.map(v => v->Int.toString) +->Array.join(" ") +->strToJson { +| JSON.String(str) => Some(str) +| _ => None +} + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js.res.expected new file mode 100644 index 0000000000..e87cdd9b25 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js.res.expected @@ -0,0 +1,6 @@ +let consoleLog1 = Console.log("Hello") +let consoleLog2 = Console.log2("Hello", "World") +let consoleLog3 = Console.log3("Hello", "World", "!") +let consoleLog4 = Console.log4("Hello", "World", "!", "!") +let consoleLogMany = Console.logMany(["Hello", "World"]) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_String.res.expected b/tests/tools_tests/src/expected/StdlibMigration_String.res.expected new file mode 100644 index 0000000000..031edd3828 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_String.res.expected @@ -0,0 +1,126 @@ +let make1 = 1->String.make +let make2 = String.make(1) + +let fromCharCode1 = 65->String.fromCharCode +let fromCharCode2 = String.fromCharCode(65) + +let fromCharCodeMany1 = [65, 66, 67]->String.fromCharCodeMany +let fromCharCodeMany2 = String.fromCharCodeMany([65, 66, 67]) + +let fromCodePoint1 = 65->String.fromCodePoint +let fromCodePoint2 = String.fromCodePoint(65) + +let fromCodePointMany1 = [65, 66, 67]->String.fromCodePointMany +let fromCodePointMany2 = String.fromCodePointMany([65, 66, 67]) + +let length1 = "abcde"->String.length +let length2 = String.length("abcde") + +let get1 = "abcde"->String.getUnsafe(2) +let get2 = String.getUnsafe("abcde", 2) + +let charAt1 = "abcde"->String.charAt(2) +let charAt2 = String.charAt("abcde", 2) + +let charCodeAt1 = "abcde"->String.charCodeAt(2) +let charCodeAt2 = String.charCodeAt("abcde", 2) + +let codePointAt1 = "abcde"->String.codePointAt(2) +let codePointAt2 = String.codePointAt("abcde", 2) + +let concat1 = "abcde"->String.concat("fghij") +let concat2 = String.concat("abcde", "fghij") + +let concatMany1 = "abcde"->String.concatMany(["fghij", "klmno"]) +let concatMany2 = String.concatMany("abcde", ["fghij", "klmno"]) + +let endsWith1 = "abcde"->String.endsWith("de") +let endsWith2 = String.endsWith("abcde", "de") + +let endsWithFrom1 = "abcde"->String.endsWithFrom("d", 2) +let endsWithFrom2 = String.endsWithFrom("abcde", "d", 2) + +let includes1 = "abcde"->String.includes("de") +let includes2 = String.includes("abcde", "de") + +let includesFrom1 = "abcde"->String.includesFrom("d", 2) +let includesFrom2 = String.includesFrom("abcde", "d", 2) + +let indexOf1 = "abcde"->String.indexOf("de") +let indexOf2 = String.indexOf("abcde", "de") + +let indexOfFrom1 = "abcde"->String.indexOfFrom("d", 2) +let indexOfFrom2 = String.indexOfFrom("abcde", "d", 2) + +let lastIndexOf1 = "abcde"->String.lastIndexOf("de") +let lastIndexOf2 = String.lastIndexOf("abcde", "de") + +let lastIndexOfFrom1 = "abcde"->String.lastIndexOfFrom("d", 2) +let lastIndexOfFrom2 = String.lastIndexOfFrom("abcde", "d", 2) + +let localeCompare1 = "abcde"->String.localeCompare("fghij") +let localeCompare2 = String.localeCompare("abcde", "fghij") + +let match1 = "abcde"->String.match(/d/) +let match2 = String.match("abcde", /d/) + +let normalize1 = "abcde"->String.normalize +let normalize2 = String.normalize("abcde") + +let repeat1 = "abcde"->String.repeat(2) +let repeat2 = String.repeat("abcde", 2) + +let replace1 = "abcde"->String.replace("d", "f") +let replace2 = String.replace("abcde", "d", "f") + +let replaceByRe1 = "abcde"->String.replaceRegExp(/d/, "f") +let replaceByRe2 = String.replaceRegExp("abcde", /d/, "f") + +let search1 = "abcde"->String.search(/d/) +let search2 = String.search("abcde", /d/) + +let slice1 = "abcde"->String.slice(~start=1, ~end=3) +let slice2 = String.slice("abcde", ~start=1, ~end=3) + +let sliceToEnd1 = "abcde"->String.sliceToEnd(~start=1) +let sliceToEnd2 = String.sliceToEnd("abcde", ~start=1) + +let split1 = "abcde"->String.split("d") +let split2 = String.split("abcde", "d") + +let splitAtMost1 = "abcde"->String.splitAtMost("d", ~limit=2) +let splitAtMost2 = String.splitAtMost("abcde", "d", ~limit=2) + +let splitByRe1 = "abcde"->String.splitByRegExp(/d/) +let splitByRe2 = String.splitByRegExp("abcde", /d/) + +let splitByReAtMost1 = "abcde"->String.splitByRegExpAtMost(/d/, ~limit=2) +let splitByReAtMost2 = String.splitByRegExpAtMost("abcde", /d/, ~limit=2) + +let startsWith1 = "abcde"->String.startsWith("ab") +let startsWith2 = String.startsWith("abcde", "ab") + +let startsWithFrom1 = "abcde"->String.startsWithFrom("b", 1) +let startsWithFrom2 = String.startsWithFrom("abcde", "b", 1) + +let substring1 = "abcde"->String.substring(~start=1, ~end=3) +let substring2 = String.substring("abcde", ~start=1, ~end=3) + +let substringToEnd1 = "abcde"->String.substringToEnd(~start=1) +let substringToEnd2 = String.substringToEnd("abcde", ~start=1) + +let toLowerCase1 = "abcde"->String.toLowerCase +let toLowerCase2 = String.toLowerCase("abcde") + +let toLocaleLowerCase1 = "abcde"->String.toLocaleLowerCase +let toLocaleLowerCase2 = String.toLocaleLowerCase("abcde") + +let toUpperCase1 = "abcde"->String.toUpperCase +let toUpperCase2 = String.toUpperCase("abcde") + +let toLocaleUpperCase1 = "abcde"->String.toLocaleUpperCase +let toLocaleUpperCase2 = String.toLocaleUpperCase("abcde") + +let trim1 = "abcde"->String.trim +let trim2 = String.trim("abcde") + diff --git a/tests/tools_tests/src/migrate/DeprecatedStuff.res b/tests/tools_tests/src/migrate/DeprecatedStuff.res new file mode 100644 index 0000000000..ec1494961e --- /dev/null +++ b/tests/tools_tests/src/migrate/DeprecatedStuff.res @@ -0,0 +1,11 @@ +@send +external slice: (string, ~from: int, ~to_: int) => string = "slice" + +@send +external shift: array<'a> => option<'a> = "shift" + +module Constants = { + let otherThing = [2, 3] +} + +let deprecatedThing = [1, 2] diff --git a/tests/tools_tests/src/migrate/DeprecatedStuff.resi b/tests/tools_tests/src/migrate/DeprecatedStuff.resi new file mode 100644 index 0000000000..1c91c3e439 --- /dev/null +++ b/tests/tools_tests/src/migrate/DeprecatedStuff.resi @@ -0,0 +1,26 @@ +@deprecated({ + reason: "Use `String.slice` instead", + migrate: String.slice( + ~start=%insert.labelledArgument("from"), + ~end=%insert.labelledArgument("to_"), + ), +}) +@send +external slice: (string, ~from: int, ~to_: int) => string = "slice" + +@send +@deprecated({ + reason: "Use `Array.shift` instead.", + migrate: Array.shift(), +}) +external shift: array<'a> => option<'a> = "shift" + +module Constants: { + let otherThing: array +} + +@deprecated({ + reason: "Use `otherThing` instead.", + migrate: DeprecatedStuff.Constants.otherThing, +}) +let deprecatedThing: array diff --git a/tests/tools_tests/src/migrate/FileToMigrate.res b/tests/tools_tests/src/migrate/FileToMigrate.res new file mode 100644 index 0000000000..097d2f5c21 --- /dev/null +++ b/tests/tools_tests/src/migrate/FileToMigrate.res @@ -0,0 +1,14 @@ +let someNiceString = DeprecatedStuff.slice("abcdefg", ~from=2, ~to_=5) + +let someNiceString2 = DeprecatedStuff.slice( + DeprecatedStuff.slice("abcdefg", ~from=0, ~to_=1), + ~from=2, + ~to_=5, +) + +let someNiceString3 = "abcdefg"->DeprecatedStuff.slice(~from=2, ~to_=5) + +let shift1 = DeprecatedStuff.shift([1, 2, 3]) +let shift2 = [1, 2, 3]->DeprecatedStuff.shift + +let deprecatedThing1 = DeprecatedStuff.deprecatedThing diff --git a/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Array.res b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Array.res new file mode 100644 index 0000000000..369db964f3 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Array.res @@ -0,0 +1,3 @@ +// Migrations that will not compile after migration (by design) +let sortInPlaceWith1 = [3, 1, 2]->Js.Array2.sortInPlaceWith((a, b) => a - b) +let sortInPlaceWith2 = Js.Array2.sortInPlaceWith([3, 1, 2], (a, b) => a - b) diff --git a/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_String.res b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_String.res new file mode 100644 index 0000000000..d377bf2d05 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_String.res @@ -0,0 +1,11 @@ +let normalizeByForm1 = "abcde"->Js.String2.normalizeByForm("a") +let normalizeByForm2 = Js.String2.normalizeByForm("abcde", "a") + +let unsafeReplaceBy01 = "abcde"->Js.String2.unsafeReplaceBy0(/d/, (_, _, _) => "f") +let unsafeReplaceBy02 = Js.String2.unsafeReplaceBy0("abcde", /d/, (_, _, _) => "f") + +let unsafeReplaceBy11 = "abcde"->Js.String2.unsafeReplaceBy1(/d/, (_, _, _, _) => "f") +let unsafeReplaceBy12 = Js.String2.unsafeReplaceBy1("abcde", /d/, (_, _, _, _) => "f") + +let unsafeReplaceBy21 = "abcde"->Js.String2.unsafeReplaceBy2(/d/, (_, _, _, _, _) => "f") +let unsafeReplaceBy22 = Js.String2.unsafeReplaceBy2("abcde", /d/, (_, _, _, _, _) => "f") diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Array.res b/tests/tools_tests/src/migrate/StdlibMigration_Array.res new file mode 100644 index 0000000000..cf8e65a744 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Array.res @@ -0,0 +1,169 @@ +let shift1 = [1, 2, 3]->Js.Array2.shift +let shift2 = Js.Array2.shift([1, 2, 3]) + +let slice1 = [1, 2, 3]->Js.Array2.slice(~start=1, ~end_=2) +let slice2 = Js.Array2.slice([1, 2, 3], ~start=1, ~end_=2) + +external someArrayLike: Js_array2.array_like = "whatever" + +let from1 = someArrayLike->Js.Array2.from +let from2 = Js.Array2.from(someArrayLike) + +let fromMap1 = someArrayLike->Js.Array2.fromMap(s => s ++ "!") +let fromMap2 = Js.Array2.fromMap(someArrayLike, s => s ++ "!") + +let isArray1 = [1, 2, 3]->Js.Array2.isArray +let isArray2 = Js.Array2.isArray([1, 2, 3]) + +let length1 = [1, 2, 3]->Js.Array2.length +let length2 = Js.Array2.length([1, 2, 3]) + +let fillInPlace1 = [1, 2, 3]->Js.Array2.fillInPlace(0) +let fillInPlace2 = Js.Array2.fillInPlace([1, 2, 3], 0) + +let fillFromInPlace1 = [1, 2, 3, 4]->Js.Array2.fillFromInPlace(0, ~from=2) +let fillFromInPlace2 = Js.Array2.fillFromInPlace([1, 2, 3, 4], 0, ~from=2) + +let fillRangeInPlace1 = [1, 2, 3, 4]->Js.Array2.fillRangeInPlace(0, ~start=1, ~end_=3) +let fillRangeInPlace2 = Js.Array2.fillRangeInPlace([1, 2, 3, 4], 0, ~start=1, ~end_=3) + +let pop1 = [1, 2, 3]->Js.Array2.pop +let pop2 = Js.Array2.pop([1, 2, 3]) + +let reverseInPlace1 = [1, 2, 3]->Js.Array2.reverseInPlace +let reverseInPlace2 = Js.Array2.reverseInPlace([1, 2, 3]) + +let concat1 = [1, 2]->Js.Array2.concat([3, 4]) +let concat2 = Js.Array2.concat([1, 2], [3, 4]) + +let concatMany1 = [1, 2]->Js.Array2.concatMany([[3, 4], [5, 6]]) +let concatMany2 = Js.Array2.concatMany([1, 2], [[3, 4], [5, 6]]) + +let includes1 = [1, 2, 3]->Js.Array2.includes(2) +let includes2 = Js.Array2.includes([1, 2, 3], 2) + +let indexOf1 = [1, 2, 3]->Js.Array2.indexOf(2) +let indexOf2 = Js.Array2.indexOf([1, 2, 3], 2) + +let indexOfFrom1 = [1, 2, 1, 3]->Js.Array2.indexOfFrom(1, ~from=2) +let indexOfFrom2 = Js.Array2.indexOfFrom([1, 2, 1, 3], 1, ~from=2) + +let joinWith1 = [1, 2, 3]->Js.Array2.joinWith(",") +let joinWith2 = Js.Array2.joinWith([1, 2, 3], ",") + +let lastIndexOf1 = [1, 2, 1, 3]->Js.Array2.lastIndexOf(1) +let lastIndexOf2 = Js.Array2.lastIndexOf([1, 2, 1, 3], 1) + +let lastIndexOfFrom1 = [1, 2, 1, 3, 1]->Js.Array2.lastIndexOfFrom(1, ~from=3) +let lastIndexOfFrom2 = Js.Array2.lastIndexOfFrom([1, 2, 1, 3, 1], 1, ~from=3) + +let copy1 = [1, 2, 3]->Js.Array2.copy +let copy2 = Js.Array2.copy([1, 2, 3]) + +let sliceFrom1 = [1, 2, 3, 4]->Js.Array2.sliceFrom(2) +let sliceFrom2 = Js.Array2.sliceFrom([1, 2, 3, 4], 2) + +let toString1 = [1, 2, 3]->Js.Array2.toString +let toString2 = Js.Array2.toString([1, 2, 3]) + +let toLocaleString1 = [1, 2, 3]->Js.Array2.toLocaleString +let toLocaleString2 = Js.Array2.toLocaleString([1, 2, 3]) + +let every1 = [2, 4, 6]->Js.Array2.every(x => mod(x, 2) == 0) +let every2 = Js.Array2.every([2, 4, 6], x => mod(x, 2) == 0) + +let everyi1 = [0, 1, 2]->Js.Array2.everyi((x, i) => x == i) +let everyi2 = Js.Array2.everyi([0, 1, 2], (x, i) => x == i) + +let filter1 = [1, 2, 3, 4]->Js.Array2.filter(x => x > 2) +let filter2 = Js.Array2.filter([1, 2, 3, 4], x => x > 2) + +let filteri1 = [0, 1, 2, 3]->Js.Array2.filteri((_x, i) => i > 1) +let filteri2 = Js.Array2.filteri([0, 1, 2, 3], (_x, i) => i > 1) + +let find1 = [1, 2, 3, 4]->Js.Array2.find(x => x > 2) +let find2 = Js.Array2.find([1, 2, 3, 4], x => x > 2) + +let findi1 = [0, 1, 2, 3]->Js.Array2.findi((_x, i) => i > 1) +let findi2 = Js.Array2.findi([0, 1, 2, 3], (_x, i) => i > 1) + +let findIndex1 = [1, 2, 3, 4]->Js.Array2.findIndex(x => x > 2) +let findIndex2 = Js.Array2.findIndex([1, 2, 3, 4], x => x > 2) + +let findIndexi1 = [0, 1, 2, 3]->Js.Array2.findIndexi((_x, i) => i > 1) +let findIndexi2 = Js.Array2.findIndexi([0, 1, 2, 3], (_x, i) => i > 1) + +let forEach1 = [1, 2, 3]->Js.Array2.forEach(x => ignore(x)) +let forEach2 = Js.Array2.forEach([1, 2, 3], x => ignore(x)) + +let forEachi1 = [1, 2, 3]->Js.Array2.forEachi((x, i) => ignore(x + i)) +let forEachi2 = Js.Array2.forEachi([1, 2, 3], (x, i) => ignore(x + i)) + +let map1 = [1, 2, 3]->Js.Array2.map(x => x * 2) +let map2 = Js.Array2.map([1, 2, 3], x => x * 2) + +let mapi1 = [1, 2, 3]->Js.Array2.mapi((x, i) => x + i) +let mapi2 = Js.Array2.mapi([1, 2, 3], (x, i) => x + i) + +let some1 = [1, 2, 3, 4]->Js.Array2.some(x => x > 3) +let some2 = Js.Array2.some([1, 2, 3, 4], x => x > 3) + +let somei1 = [0, 1, 2, 3]->Js.Array2.somei((_x, i) => i > 2) +let somei2 = Js.Array2.somei([0, 1, 2, 3], (_x, i) => i > 2) + +let unsafeGet1 = [1, 2, 3]->Js.Array2.unsafe_get(1) +let unsafeGet2 = Js.Array2.unsafe_get([1, 2, 3], 1) + +let unsafeSet1 = [1, 2, 3]->Js.Array2.unsafe_set(1, 5) +let unsafeSet2 = Js.Array2.unsafe_set([1, 2, 3], 1, 5) + +let copyWithin1 = [1, 2, 3, 4, 5]->Js.Array2.copyWithin(~to_=2) +let copyWithin2 = Js.Array2.copyWithin([1, 2, 3, 4, 5], ~to_=2) + +let copyWithinFrom1 = [1, 2, 3, 4, 5]->Js.Array2.copyWithinFrom(~to_=0, ~from=2) +let copyWithinFrom2 = Js.Array2.copyWithinFrom([1, 2, 3, 4, 5], ~to_=0, ~from=2) + +let copyWithinFromRange1 = + [1, 2, 3, 4, 5, 6]->Js.Array2.copyWithinFromRange(~to_=1, ~start=2, ~end_=5) +let copyWithinFromRange2 = Js.Array2.copyWithinFromRange( + [1, 2, 3, 4, 5, 6], + ~to_=1, + ~start=2, + ~end_=5, +) + +let push1 = [1, 2, 3]->Js.Array2.push(4) +let push2 = Js.Array2.push([1, 2, 3], 4) + +let pushMany1 = [1, 2, 3]->Js.Array2.pushMany([4, 5]) +let pushMany2 = Js.Array2.pushMany([1, 2, 3], [4, 5]) + +let sortInPlace1 = ["c", "a", "b"]->Js.Array2.sortInPlace +let sortInPlace2 = Js.Array2.sortInPlace(["c", "a", "b"]) + +let unshift1 = [1, 2, 3]->Js.Array2.unshift(4) +let unshift2 = Js.Array2.unshift([1, 2, 3], 4) + +let unshiftMany1 = [1, 2, 3]->Js.Array2.unshiftMany([4, 5]) +let unshiftMany2 = Js.Array2.unshiftMany([1, 2, 3], [4, 5]) + +let reduce1 = [1, 2, 3]->Js.Array2.reduce((acc, x) => acc + x, 0) +let reduce2 = Js.Array2.reduce([1, 2, 3], (acc, x) => acc + x, 0) + +let spliceInPlace1 = [1, 2, 3]->Js.Array2.spliceInPlace(~pos=1, ~remove=1, ~add=[4, 5]) +let spliceInPlace2 = Js.Array2.spliceInPlace([1, 2, 3], ~pos=1, ~remove=1, ~add=[4, 5]) + +let removeFromInPlace1 = [1, 2, 3]->Js.Array2.removeFromInPlace(~pos=1) +let removeFromInPlace2 = Js.Array2.removeFromInPlace([1, 2, 3], ~pos=1) + +let removeCountInPlace1 = [1, 2, 3]->Js.Array2.removeCountInPlace(~pos=1, ~count=1) +let removeCountInPlace2 = Js.Array2.removeCountInPlace([1, 2, 3], ~pos=1, ~count=1) + +let reducei1 = [1, 2, 3]->Js.Array2.reducei((acc, x, i) => acc + x + i, 0) +let reducei2 = Js.Array2.reducei([1, 2, 3], (acc, x, i) => acc + x + i, 0) + +let reduceRight1 = [1, 2, 3]->Js.Array2.reduceRight((acc, x) => acc + x, 0) +let reduceRight2 = Js.Array2.reduceRight([1, 2, 3], (acc, x) => acc + x, 0) + +let reduceRighti1 = [1, 2, 3]->Js.Array2.reduceRighti((acc, x, i) => acc + x + i, 0) +let reduceRighti2 = Js.Array2.reduceRighti([1, 2, 3], (acc, x, i) => acc + x + i, 0) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res b/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res new file mode 100644 index 0000000000..219f3dd56f --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res @@ -0,0 +1,47 @@ +let fromStringExn1 = "123"->Js.BigInt.fromStringExn +let fromStringExn2 = Js.BigInt.fromStringExn("123") + +let land1 = 7n->Js.BigInt.land(4n) +let land2 = Js.BigInt.land(7n, 4n) + +let lor1 = 7n->Js.BigInt.lor(4n) +let lor2 = Js.BigInt.lor(7n, 4n) + +let lxor1 = 7n->Js.BigInt.lxor(4n) +let lxor2 = Js.BigInt.lxor(7n, 4n) + +let lnot1 = 2n->Js.BigInt.lnot +let lnot2 = Js.BigInt.lnot(2n) + +let lsl1 = 4n->Js.BigInt.lsl(1n) +let lsl2 = Js.BigInt.lsl(4n, 1n) + +let asr1 = 8n->Js.BigInt.asr(1n) +let asr2 = Js.BigInt.asr(8n, 1n) + +let toString1 = 123n->Js.BigInt.toString +let toString2 = Js.BigInt.toString(123n) + +let toLocaleString1 = 123n->Js.BigInt.toLocaleString +let toLocaleString2 = Js.BigInt.toLocaleString(123n) + +// From the stdlib module +let stdlib_fromStringExn1 = "123"->BigInt.fromStringExn +let stdlib_fromStringExn2 = BigInt.fromStringExn("123") + +let stdlib_land1 = 7n->BigInt.land(4n) +let stdlib_land2 = BigInt.land(7n, 4n) + +let stdlib_lor1 = BigInt.lor(7n, 4n) + +let stdlib_lxor1 = 7n->BigInt.lxor(4n) +let stdlib_lxor2 = BigInt.lxor(7n, 4n) + +let stdlib_lnot1 = 2n->BigInt.lnot +let stdlib_lnot2 = BigInt.lnot(2n) + +let stdlib_lsl1 = 4n->BigInt.lsl(1n) +let stdlib_lsl2 = BigInt.lsl(4n, 1n) + +let stdlib_asr1 = 8n->BigInt.asr(1n) +let stdlib_asr2 = BigInt.asr(8n, 1n) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Console.res b/tests/tools_tests/src/migrate/StdlibMigration_Console.res new file mode 100644 index 0000000000..0e142a0575 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Console.res @@ -0,0 +1,28 @@ +let log = Js_console.log("Hello, World!") +let log2 = Js_console.log2("Hello", "World") +let log3 = Js_console.log3("Hello", "World", "!") +let log4 = Js_console.log4("Hello", "World", "!", "!") +let logMany = Js_console.logMany(["Hello", "World"]) + +let info = Js_console.info("Hello, World!") +let info2 = Js_console.info2("Hello", "World") +let info3 = Js_console.info3("Hello", "World", "!") +let info4 = Js_console.info4("Hello", "World", "!", "!") +let infoMany = Js_console.infoMany(["Hello", "World"]) + +let warn = Js_console.warn("Hello, World!") +let warn2 = Js_console.warn2("Hello", "World") +let warn3 = Js_console.warn3("Hello", "World", "!") +let warn4 = Js_console.warn4("Hello", "World", "!", "!") +let warnMany = Js_console.warnMany(["Hello", "World"]) + +let error = Js_console.error("Hello, World!") +let error2 = Js_console.error2("Hello", "World") +let error3 = Js_console.error3("Hello", "World", "!") +let error4 = Js_console.error4("Hello", "World", "!", "!") +let errorMany = Js_console.errorMany(["Hello", "World"]) + +let trace = Js_console.trace() +let timeStart = Js_console.timeStart("Hello, World!") +let timeEnd = Js_console.timeEnd("Hello, World!") +let table = Js_console.table(["Hello", "World"]) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Int.res b/tests/tools_tests/src/migrate/StdlibMigration_Int.res new file mode 100644 index 0000000000..b76172c1a1 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Int.res @@ -0,0 +1,7 @@ +let result1 = Int.Bitwise.land(1, 2) +let result2 = Int.Bitwise.lor(1, 2) +let result3 = Int.Bitwise.lxor(1, 2) +let result4 = Int.Bitwise.lsl(1, 2) +let result5 = Int.Bitwise.lsr(1, 2) +let result6 = Int.Bitwise.asr(1, 2) +let result7 = Int.Bitwise.lnot(0) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_JSON.res b/tests/tools_tests/src/migrate/StdlibMigration_JSON.res new file mode 100644 index 0000000000..60e13379a2 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_JSON.res @@ -0,0 +1,11 @@ +external someJson: Js_json.t = "someJson" +external strToJson: string => Js_json.t = "strToJson" + +let decodeString1 = someJson->Js_json.decodeString +let decodeString2 = Js_json.decodeString(someJson) +let decodeString3 = + [1, 2, 3] + ->Array.map(v => v->Int.toString) + ->Array.join(" ") + ->strToJson + ->Js_json.decodeString diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js.res b/tests/tools_tests/src/migrate/StdlibMigration_Js.res new file mode 100644 index 0000000000..39deedf002 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js.res @@ -0,0 +1,5 @@ +let consoleLog1 = Js.log("Hello") +let consoleLog2 = Js.log2("Hello", "World") +let consoleLog3 = Js.log3("Hello", "World", "!") +let consoleLog4 = Js.log4("Hello", "World", "!", "!") +let consoleLogMany = Js.logMany(["Hello", "World"]) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_String.res b/tests/tools_tests/src/migrate/StdlibMigration_String.res new file mode 100644 index 0000000000..a67821e71f --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_String.res @@ -0,0 +1,125 @@ +let make1 = 1->Js.String2.make +let make2 = Js.String2.make(1) + +let fromCharCode1 = 65->Js.String2.fromCharCode +let fromCharCode2 = Js.String2.fromCharCode(65) + +let fromCharCodeMany1 = [65, 66, 67]->Js.String2.fromCharCodeMany +let fromCharCodeMany2 = Js.String2.fromCharCodeMany([65, 66, 67]) + +let fromCodePoint1 = 65->Js.String2.fromCodePoint +let fromCodePoint2 = Js.String2.fromCodePoint(65) + +let fromCodePointMany1 = [65, 66, 67]->Js.String2.fromCodePointMany +let fromCodePointMany2 = Js.String2.fromCodePointMany([65, 66, 67]) + +let length1 = "abcde"->Js.String2.length +let length2 = Js.String2.length("abcde") + +let get1 = "abcde"->Js.String2.get(2) +let get2 = Js.String2.get("abcde", 2) + +let charAt1 = "abcde"->Js.String2.charAt(2) +let charAt2 = Js.String2.charAt("abcde", 2) + +let charCodeAt1 = "abcde"->Js.String2.charCodeAt(2) +let charCodeAt2 = Js.String2.charCodeAt("abcde", 2) + +let codePointAt1 = "abcde"->Js.String2.codePointAt(2) +let codePointAt2 = Js.String2.codePointAt("abcde", 2) + +let concat1 = "abcde"->Js.String2.concat("fghij") +let concat2 = Js.String2.concat("abcde", "fghij") + +let concatMany1 = "abcde"->Js.String2.concatMany(["fghij", "klmno"]) +let concatMany2 = Js.String2.concatMany("abcde", ["fghij", "klmno"]) + +let endsWith1 = "abcde"->Js.String2.endsWith("de") +let endsWith2 = Js.String2.endsWith("abcde", "de") + +let endsWithFrom1 = "abcde"->Js.String2.endsWithFrom("d", 2) +let endsWithFrom2 = Js.String2.endsWithFrom("abcde", "d", 2) + +let includes1 = "abcde"->Js.String2.includes("de") +let includes2 = Js.String2.includes("abcde", "de") + +let includesFrom1 = "abcde"->Js.String2.includesFrom("d", 2) +let includesFrom2 = Js.String2.includesFrom("abcde", "d", 2) + +let indexOf1 = "abcde"->Js.String2.indexOf("de") +let indexOf2 = Js.String2.indexOf("abcde", "de") + +let indexOfFrom1 = "abcde"->Js.String2.indexOfFrom("d", 2) +let indexOfFrom2 = Js.String2.indexOfFrom("abcde", "d", 2) + +let lastIndexOf1 = "abcde"->Js.String2.lastIndexOf("de") +let lastIndexOf2 = Js.String2.lastIndexOf("abcde", "de") + +let lastIndexOfFrom1 = "abcde"->Js.String2.lastIndexOfFrom("d", 2) +let lastIndexOfFrom2 = Js.String2.lastIndexOfFrom("abcde", "d", 2) + +let localeCompare1 = "abcde"->Js.String2.localeCompare("fghij") +let localeCompare2 = Js.String2.localeCompare("abcde", "fghij") + +let match1 = "abcde"->Js.String2.match_(/d/) +let match2 = Js.String2.match_("abcde", /d/) + +let normalize1 = "abcde"->Js.String2.normalize +let normalize2 = Js.String2.normalize("abcde") + +let repeat1 = "abcde"->Js.String2.repeat(2) +let repeat2 = Js.String2.repeat("abcde", 2) + +let replace1 = "abcde"->Js.String2.replace("d", "f") +let replace2 = Js.String2.replace("abcde", "d", "f") + +let replaceByRe1 = "abcde"->Js.String2.replaceByRe(/d/, "f") +let replaceByRe2 = Js.String2.replaceByRe("abcde", /d/, "f") + +let search1 = "abcde"->Js.String2.search(/d/) +let search2 = Js.String2.search("abcde", /d/) + +let slice1 = "abcde"->Js.String2.slice(~from=1, ~to_=3) +let slice2 = Js.String2.slice("abcde", ~from=1, ~to_=3) + +let sliceToEnd1 = "abcde"->Js.String2.sliceToEnd(~from=1) +let sliceToEnd2 = Js.String2.sliceToEnd("abcde", ~from=1) + +let split1 = "abcde"->Js.String2.split("d") +let split2 = Js.String2.split("abcde", "d") + +let splitAtMost1 = "abcde"->Js.String2.splitAtMost("d", ~limit=2) +let splitAtMost2 = Js.String2.splitAtMost("abcde", "d", ~limit=2) + +let splitByRe1 = "abcde"->Js.String2.splitByRe(/d/) +let splitByRe2 = Js.String2.splitByRe("abcde", /d/) + +let splitByReAtMost1 = "abcde"->Js.String2.splitByReAtMost(/d/, ~limit=2) +let splitByReAtMost2 = Js.String2.splitByReAtMost("abcde", /d/, ~limit=2) + +let startsWith1 = "abcde"->Js.String2.startsWith("ab") +let startsWith2 = Js.String2.startsWith("abcde", "ab") + +let startsWithFrom1 = "abcde"->Js.String2.startsWithFrom("b", 1) +let startsWithFrom2 = Js.String2.startsWithFrom("abcde", "b", 1) + +let substring1 = "abcde"->Js.String2.substring(~from=1, ~to_=3) +let substring2 = Js.String2.substring("abcde", ~from=1, ~to_=3) + +let substringToEnd1 = "abcde"->Js.String2.substringToEnd(~from=1) +let substringToEnd2 = Js.String2.substringToEnd("abcde", ~from=1) + +let toLowerCase1 = "abcde"->Js.String2.toLowerCase +let toLowerCase2 = Js.String2.toLowerCase("abcde") + +let toLocaleLowerCase1 = "abcde"->Js.String2.toLocaleLowerCase +let toLocaleLowerCase2 = Js.String2.toLocaleLowerCase("abcde") + +let toUpperCase1 = "abcde"->Js.String2.toUpperCase +let toUpperCase2 = Js.String2.toUpperCase("abcde") + +let toLocaleUpperCase1 = "abcde"->Js.String2.toLocaleUpperCase +let toLocaleUpperCase2 = Js.String2.toLocaleUpperCase("abcde") + +let trim1 = "abcde"->Js.String2.trim +let trim2 = Js.String2.trim("abcde") diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res new file mode 100644 index 0000000000..52a6757808 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res @@ -0,0 +1,170 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Array.res. +let shift1 = [1, 2, 3]->Array.shift +let shift2 = Array.shift([1, 2, 3]) + +let slice1 = [1, 2, 3]->Array.slice(~start=1, ~end=2) +let slice2 = Array.slice([1, 2, 3], ~start=1, ~end=2) + +external someArrayLike: Js_array2.array_like = "whatever" + +let from1 = someArrayLike->Array.fromArrayLike +let from2 = Array.fromArrayLike(someArrayLike) + +let fromMap1 = someArrayLike->Array.fromArrayLikeWithMap(s => s ++ "!") +let fromMap2 = Array.fromArrayLikeWithMap(someArrayLike, s => s ++ "!") + +let isArray1 = [1, 2, 3]->Array.isArray +let isArray2 = Array.isArray([1, 2, 3]) + +let length1 = [1, 2, 3]->Array.length +let length2 = Array.length([1, 2, 3]) + +let fillInPlace1 = [1, 2, 3]->Array.fillAll(0) +let fillInPlace2 = Array.fillAll([1, 2, 3], 0) + +let fillFromInPlace1 = [1, 2, 3, 4]->Array.fillToEnd(0, ~start=2) +let fillFromInPlace2 = Array.fillToEnd([1, 2, 3, 4], 0, ~start=2) + +let fillRangeInPlace1 = [1, 2, 3, 4]->Array.fill(0, ~start=1, ~end=3) +let fillRangeInPlace2 = Array.fill([1, 2, 3, 4], 0, ~start=1, ~end=3) + +let pop1 = [1, 2, 3]->Array.pop +let pop2 = Array.pop([1, 2, 3]) + +let reverseInPlace1 = [1, 2, 3]->Array.reverse +let reverseInPlace2 = Array.reverse([1, 2, 3]) + +let concat1 = [1, 2]->Array.concat([3, 4]) +let concat2 = Array.concat([1, 2], [3, 4]) + +let concatMany1 = [1, 2]->Array.concatMany([[3, 4], [5, 6]]) +let concatMany2 = Array.concatMany([1, 2], [[3, 4], [5, 6]]) + +let includes1 = [1, 2, 3]->Array.includes(2) +let includes2 = Array.includes([1, 2, 3], 2) + +let indexOf1 = [1, 2, 3]->Array.indexOf(2) +let indexOf2 = Array.indexOf([1, 2, 3], 2) + +let indexOfFrom1 = [1, 2, 1, 3]->Array.indexOfFrom(1, 2) +let indexOfFrom2 = Array.indexOfFrom([1, 2, 1, 3], 1, 2) + +let joinWith1 = [1, 2, 3]->Array.joinUnsafe(",") +let joinWith2 = Array.joinUnsafe([1, 2, 3], ",") + +let lastIndexOf1 = [1, 2, 1, 3]->Array.lastIndexOf(1) +let lastIndexOf2 = Array.lastIndexOf([1, 2, 1, 3], 1) + +let lastIndexOfFrom1 = [1, 2, 1, 3, 1]->Array.lastIndexOfFrom(1, 3) +let lastIndexOfFrom2 = Array.lastIndexOfFrom([1, 2, 1, 3, 1], 1, 3) + +let copy1 = [1, 2, 3]->Array.copy +let copy2 = Array.copy([1, 2, 3]) + +let sliceFrom1 = [1, 2, 3, 4]->Array.sliceToEnd(~start=2) +let sliceFrom2 = Array.sliceToEnd([1, 2, 3, 4], ~start=2) + +let toString1 = [1, 2, 3]->Array.toString +let toString2 = Array.toString([1, 2, 3]) + +let toLocaleString1 = [1, 2, 3]->Array.toLocaleString +let toLocaleString2 = Array.toLocaleString([1, 2, 3]) + +let every1 = [2, 4, 6]->Array.every(x => mod(x, 2) == 0) +let every2 = Array.every([2, 4, 6], x => mod(x, 2) == 0) + +let everyi1 = [0, 1, 2]->Array.everyWithIndex((x, i) => x == i) +let everyi2 = Array.everyWithIndex([0, 1, 2], (x, i) => x == i) + +let filter1 = [1, 2, 3, 4]->Array.filter(x => x > 2) +let filter2 = Array.filter([1, 2, 3, 4], x => x > 2) + +let filteri1 = [0, 1, 2, 3]->Array.filterWithIndex((_x, i) => i > 1) +let filteri2 = Array.filterWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let find1 = [1, 2, 3, 4]->Array.find(x => x > 2) +let find2 = Array.find([1, 2, 3, 4], x => x > 2) + +let findi1 = [0, 1, 2, 3]->Array.findWithIndex((_x, i) => i > 1) +let findi2 = Array.findWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let findIndex1 = [1, 2, 3, 4]->Array.findIndex(x => x > 2) +let findIndex2 = Array.findIndex([1, 2, 3, 4], x => x > 2) + +let findIndexi1 = [0, 1, 2, 3]->Array.findIndexWithIndex((_x, i) => i > 1) +let findIndexi2 = Array.findIndexWithIndex([0, 1, 2, 3], (_x, i) => i > 1) + +let forEach1 = [1, 2, 3]->Array.forEach(x => ignore(x)) +let forEach2 = Array.forEach([1, 2, 3], x => ignore(x)) + +let forEachi1 = [1, 2, 3]->Array.forEachWithIndex((x, i) => ignore(x + i)) +let forEachi2 = Array.forEachWithIndex([1, 2, 3], (x, i) => ignore(x + i)) + +let map1 = [1, 2, 3]->Array.map(x => x * 2) +let map2 = Array.map([1, 2, 3], x => x * 2) + +let mapi1 = [1, 2, 3]->Array.mapWithIndex((x, i) => x + i) +let mapi2 = Array.mapWithIndex([1, 2, 3], (x, i) => x + i) + +let some1 = [1, 2, 3, 4]->Array.some(x => x > 3) +let some2 = Array.some([1, 2, 3, 4], x => x > 3) + +let somei1 = [0, 1, 2, 3]->Array.someWithIndex((_x, i) => i > 2) +let somei2 = Array.someWithIndex([0, 1, 2, 3], (_x, i) => i > 2) + +let unsafeGet1 = [1, 2, 3]->Array.getUnsafe(1) +let unsafeGet2 = Array.getUnsafe([1, 2, 3], 1) + +let unsafeSet1 = [1, 2, 3]->Array.setUnsafe(1, 5) +let unsafeSet2 = Array.setUnsafe([1, 2, 3], 1, 5) + +let copyWithin1 = [1, 2, 3, 4, 5]->Array.copyAllWithin(~target=2) +let copyWithin2 = Array.copyAllWithin([1, 2, 3, 4, 5], ~target=2) + +let copyWithinFrom1 = [1, 2, 3, 4, 5]->Array.copyWithinToEnd(~target=0, ~start=2) +let copyWithinFrom2 = Array.copyWithinToEnd([1, 2, 3, 4, 5], ~target=0, ~start=2) + +let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~target=1, ~start=2, ~end=5) +let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~target=1, ~start=2, ~end=5) + +let push1 = [1, 2, 3]->Array.push(4) +let push2 = Array.push([1, 2, 3], 4) + +let pushMany1 = [1, 2, 3]->Array.pushMany([4, 5]) +let pushMany2 = Array.pushMany([1, 2, 3], [4, 5]) + +let sortInPlace1 = + ["c", "a", "b"]->Array.toSorted((a, b) => + %todo("This needs a comparator function. Use `String.compare` for strings, etc.") + ) +let sortInPlace2 = Array.toSorted(["c", "a", "b"], (a, b) => + %todo("This needs a comparator function. Use `String.compare` for strings, etc.") +) + +let unshift1 = [1, 2, 3]->Array.unshift(4) +let unshift2 = Array.unshift([1, 2, 3], 4) + +let unshiftMany1 = [1, 2, 3]->Array.unshiftMany([4, 5]) +let unshiftMany2 = Array.unshiftMany([1, 2, 3], [4, 5]) + +let reduce1 = [1, 2, 3]->Array.reduce(0, (acc, x) => acc + x) +let reduce2 = Array.reduce([1, 2, 3], 0, (acc, x) => acc + x) + +let spliceInPlace1 = [1, 2, 3]->Array.splice(~start=1, ~remove=1, ~insert=[4, 5]) +let spliceInPlace2 = Array.splice([1, 2, 3], ~start=1, ~remove=1, ~insert=[4, 5]) + +let removeFromInPlace1 = [1, 2, 3]->Array.removeInPlace(1) +let removeFromInPlace2 = Array.removeInPlace([1, 2, 3], 1) + +let removeCountInPlace1 = [1, 2, 3]->Array.splice(~start=1, ~remove=1, ~insert=[]) +let removeCountInPlace2 = Array.splice([1, 2, 3], ~start=1, ~remove=1, ~insert=[]) + +let reducei1 = [1, 2, 3]->Array.reduceWithIndex(0, (acc, x, i) => acc + x + i) +let reducei2 = Array.reduceWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) + +let reduceRight1 = [1, 2, 3]->Array.reduceRight(0, (acc, x) => acc + x) +let reduceRight2 = Array.reduceRight([1, 2, 3], 0, (acc, x) => acc + x) + +let reduceRighti1 = [1, 2, 3]->Array.reduceRightWithIndex(0, (acc, x, i) => acc + x + i) +let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res new file mode 100644 index 0000000000..3ea3562f5d --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res @@ -0,0 +1,49 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_BigInt.res. +let fromStringExn1 = "123"->BigInt.fromStringOrThrow +let fromStringExn2 = BigInt.fromStringOrThrow("123") + +let land1 = 7n->BigInt.bitwiseAnd(4n) +let land2 = 7n & 4n + +let lor1 = 7n->BigInt.bitwiseOr(4n) +let lor2 = BigInt.bitwiseOr(7n, 4n) + +let lxor1 = 7n->BigInt.bitwiseXor(4n) +let lxor2 = 7n ^ 4n + +let lnot1 = 2n->Js.BigInt.lnot +let lnot2 = Js.BigInt.lnot(2n) + +let lsl1 = 4n->BigInt.shiftLeft(1n) +let lsl2 = 4n << 1n + +let asr1 = 8n->BigInt.shiftRight(1n) +let asr2 = 8n >> 1n + +let toString1 = 123n->BigInt.toString +let toString2 = BigInt.toString(123n) + +let toLocaleString1 = 123n->BigInt.toLocaleString +let toLocaleString2 = BigInt.toLocaleString(123n) + +// From the stdlib module +let stdlib_fromStringExn1 = "123"->BigInt.fromStringOrThrow +let stdlib_fromStringExn2 = BigInt.fromStringOrThrow("123") + +let stdlib_land1 = 7n->BigInt.bitwiseAnd(4n) +let stdlib_land2 = 7n & 4n + +let stdlib_lor1 = BigInt.bitwiseOr(7n, 4n) + +let stdlib_lxor1 = 7n->BigInt.bitwiseXor(4n) +let stdlib_lxor2 = 7n ^ 4n + +let stdlib_lnot1 = 2n->BigInt.bitwiseNot +let stdlib_lnot2 = ~2n + +let stdlib_lsl1 = 4n->BigInt.shiftLeft(1n) +let stdlib_lsl2 = 4n << 1n + +let stdlib_asr1 = 8n->BigInt.shiftRight(1n) +let stdlib_asr2 = 8n >> 1n diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Console.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Console.res new file mode 100644 index 0000000000..d539a85560 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Console.res @@ -0,0 +1,30 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Console.res. +let log = Console.log("Hello, World!") +let log2 = Console.log2("Hello", "World") +let log3 = Console.log3("Hello", "World", "!") +let log4 = Console.log4("Hello", "World", "!", "!") +let logMany = Console.logMany(["Hello", "World"]) + +let info = Console.info("Hello, World!") +let info2 = Console.info2("Hello", "World") +let info3 = Console.info3("Hello", "World", "!") +let info4 = Console.info4("Hello", "World", "!", "!") +let infoMany = Console.infoMany(["Hello", "World"]) + +let warn = Console.warn("Hello, World!") +let warn2 = Console.warn2("Hello", "World") +let warn3 = Console.warn3("Hello", "World", "!") +let warn4 = Console.warn4("Hello", "World", "!", "!") +let warnMany = Console.warnMany(["Hello", "World"]) + +let error = Console.error("Hello, World!") +let error2 = Console.error2("Hello", "World") +let error3 = Console.error3("Hello", "World", "!") +let error4 = Console.error4("Hello", "World", "!", "!") +let errorMany = Console.errorMany(["Hello", "World"]) + +let trace = Console.trace() +let timeStart = Console.time("Hello, World!") +let timeEnd = Console.timeEnd("Hello, World!") +let table = Console.table(["Hello", "World"]) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Int.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Int.res new file mode 100644 index 0000000000..43b70137c8 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Int.res @@ -0,0 +1,9 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Int.res. +let result1 = Int.bitwiseAnd(1, 2) +let result2 = Int.bitwiseOr(1, 2) +let result3 = Int.bitwiseXor(1, 2) +let result4 = Int.shiftLeft(1, 2) +let result5 = Int.shiftRightUnsigned(1, 2) +let result6 = Int.shiftRight(1, 2) +let result7 = Int.bitwiseNot(0) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res new file mode 100644 index 0000000000..103bd0109c --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res @@ -0,0 +1,20 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_JSON.res. +external someJson: Js_json.t = "someJson" +external strToJson: string => Js_json.t = "strToJson" + +let decodeString1 = switch someJson { +| JSON.String(str) => Some(str) +| _ => None +} +let decodeString2 = switch someJson { +| JSON.String(str) => Some(str) +| _ => None +} +let decodeString3 = switch [1, 2, 3] +->Array.map(v => v->Int.toString) +->Array.join(" ") +->strToJson { +| JSON.String(str) => Some(str) +| _ => None +} diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js.res new file mode 100644 index 0000000000..87922b7521 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js.res @@ -0,0 +1,7 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js.res. +let consoleLog1 = Console.log("Hello") +let consoleLog2 = Console.log2("Hello", "World") +let consoleLog3 = Console.log3("Hello", "World", "!") +let consoleLog4 = Console.log4("Hello", "World", "!", "!") +let consoleLogMany = Console.logMany(["Hello", "World"]) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res new file mode 100644 index 0000000000..9e67e14937 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res @@ -0,0 +1,127 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_String.res. +let make1 = 1->String.make +let make2 = String.make(1) + +let fromCharCode1 = 65->String.fromCharCode +let fromCharCode2 = String.fromCharCode(65) + +let fromCharCodeMany1 = [65, 66, 67]->String.fromCharCodeMany +let fromCharCodeMany2 = String.fromCharCodeMany([65, 66, 67]) + +let fromCodePoint1 = 65->String.fromCodePoint +let fromCodePoint2 = String.fromCodePoint(65) + +let fromCodePointMany1 = [65, 66, 67]->String.fromCodePointMany +let fromCodePointMany2 = String.fromCodePointMany([65, 66, 67]) + +let length1 = "abcde"->String.length +let length2 = String.length("abcde") + +let get1 = "abcde"->String.getUnsafe(2) +let get2 = String.getUnsafe("abcde", 2) + +let charAt1 = "abcde"->String.charAt(2) +let charAt2 = String.charAt("abcde", 2) + +let charCodeAt1 = "abcde"->String.charCodeAt(2) +let charCodeAt2 = String.charCodeAt("abcde", 2) + +let codePointAt1 = "abcde"->String.codePointAt(2) +let codePointAt2 = String.codePointAt("abcde", 2) + +let concat1 = "abcde"->String.concat("fghij") +let concat2 = String.concat("abcde", "fghij") + +let concatMany1 = "abcde"->String.concatMany(["fghij", "klmno"]) +let concatMany2 = String.concatMany("abcde", ["fghij", "klmno"]) + +let endsWith1 = "abcde"->String.endsWith("de") +let endsWith2 = String.endsWith("abcde", "de") + +let endsWithFrom1 = "abcde"->String.endsWithFrom("d", 2) +let endsWithFrom2 = String.endsWithFrom("abcde", "d", 2) + +let includes1 = "abcde"->String.includes("de") +let includes2 = String.includes("abcde", "de") + +let includesFrom1 = "abcde"->String.includesFrom("d", 2) +let includesFrom2 = String.includesFrom("abcde", "d", 2) + +let indexOf1 = "abcde"->String.indexOf("de") +let indexOf2 = String.indexOf("abcde", "de") + +let indexOfFrom1 = "abcde"->String.indexOfFrom("d", 2) +let indexOfFrom2 = String.indexOfFrom("abcde", "d", 2) + +let lastIndexOf1 = "abcde"->String.lastIndexOf("de") +let lastIndexOf2 = String.lastIndexOf("abcde", "de") + +let lastIndexOfFrom1 = "abcde"->String.lastIndexOfFrom("d", 2) +let lastIndexOfFrom2 = String.lastIndexOfFrom("abcde", "d", 2) + +let localeCompare1 = "abcde"->String.localeCompare("fghij") +let localeCompare2 = String.localeCompare("abcde", "fghij") + +let match1 = "abcde"->String.match(/d/) +let match2 = String.match("abcde", /d/) + +let normalize1 = "abcde"->String.normalize +let normalize2 = String.normalize("abcde") + +let repeat1 = "abcde"->String.repeat(2) +let repeat2 = String.repeat("abcde", 2) + +let replace1 = "abcde"->String.replace("d", "f") +let replace2 = String.replace("abcde", "d", "f") + +let replaceByRe1 = "abcde"->String.replaceRegExp(/d/, "f") +let replaceByRe2 = String.replaceRegExp("abcde", /d/, "f") + +let search1 = "abcde"->String.search(/d/) +let search2 = String.search("abcde", /d/) + +let slice1 = "abcde"->String.slice(~start=1, ~end=3) +let slice2 = String.slice("abcde", ~start=1, ~end=3) + +let sliceToEnd1 = "abcde"->String.sliceToEnd(~start=1) +let sliceToEnd2 = String.sliceToEnd("abcde", ~start=1) + +let split1 = "abcde"->String.split("d") +let split2 = String.split("abcde", "d") + +let splitAtMost1 = "abcde"->String.splitAtMost("d", ~limit=2) +let splitAtMost2 = String.splitAtMost("abcde", "d", ~limit=2) + +let splitByRe1 = "abcde"->String.splitByRegExp(/d/) +let splitByRe2 = String.splitByRegExp("abcde", /d/) + +let splitByReAtMost1 = "abcde"->String.splitByRegExpAtMost(/d/, ~limit=2) +let splitByReAtMost2 = String.splitByRegExpAtMost("abcde", /d/, ~limit=2) + +let startsWith1 = "abcde"->String.startsWith("ab") +let startsWith2 = String.startsWith("abcde", "ab") + +let startsWithFrom1 = "abcde"->String.startsWithFrom("b", 1) +let startsWithFrom2 = String.startsWithFrom("abcde", "b", 1) + +let substring1 = "abcde"->String.substring(~start=1, ~end=3) +let substring2 = String.substring("abcde", ~start=1, ~end=3) + +let substringToEnd1 = "abcde"->String.substringToEnd(~start=1) +let substringToEnd2 = String.substringToEnd("abcde", ~start=1) + +let toLowerCase1 = "abcde"->String.toLowerCase +let toLowerCase2 = String.toLowerCase("abcde") + +let toLocaleLowerCase1 = "abcde"->String.toLocaleLowerCase +let toLocaleLowerCase2 = String.toLocaleLowerCase("abcde") + +let toUpperCase1 = "abcde"->String.toUpperCase +let toUpperCase2 = String.toUpperCase("abcde") + +let toLocaleUpperCase1 = "abcde"->String.toLocaleUpperCase +let toLocaleUpperCase2 = String.toLocaleUpperCase("abcde") + +let trim1 = "abcde"->String.trim +let trim2 = String.trim("abcde") diff --git a/tests/tools_tests/test.sh b/tests/tools_tests/test.sh index 73e42acfd6..4e44f42170 100755 --- a/tests/tools_tests/test.sh +++ b/tests/tools_tests/test.sh @@ -33,6 +33,24 @@ for file in src/docstrings-format/*.{res,resi,md}; do fi done +# Test migrate command +for file in src/migrate/*.{res,resi}; do + output="src/expected/$(basename $file).expected" + ../../_build/install/default/bin/rescript-tools migrate "$file" --stdout > $output + if [ "$RUNNER_OS" == "Windows" ]; then + perl -pi -e 's/\r\n/\n/g' -- $output + fi +done + +# Move migrated files to expected directory so they can be compiled in the project +for file in src/migrate/StdlibMigration_*.res; do + expected_file="src/expected/$(basename $file).expected" + output="src/migrate/migrated/Migrated_$(basename $file)" + echo "// This file is autogenerated so it can be type checked. +// It's the migrated version of $file." > "$output" && cat "$expected_file" >> "$output" + ../../cli/rescript.js format "$output" +done + warningYellow='\033[0;33m' successGreen='\033[0;32m' reset='\033[0m' diff --git a/tools/bin/main.ml b/tools/bin/main.ml index 88f7ffa575..6f1a76ff45 100644 --- a/tools/bin/main.ml +++ b/tools/bin/main.ml @@ -32,6 +32,7 @@ Usage: rescript-tools [command] Commands: +migrate [--stdout] Runs the migration tool on the given file doc Generate documentation format-codeblocks Format ReScript code blocks [--stdout] Output to stdout @@ -66,6 +67,15 @@ let main () = in logAndExit (Tools.extractDocs ~entryPointFile:path ~debug:false) | _ -> logAndExit (Error docHelp)) + | "migrate" :: file :: opts -> ( + let isStdout = List.mem "--stdout" opts in + let outputMode = if isStdout then `Stdout else `File in + match + (Tools.Migrate.migrate ~entryPointFile:file ~outputMode, outputMode) + with + | Ok content, `Stdout -> print_endline content + | result, `File -> logAndExit result + | Error e, _ -> logAndExit (Error e)) | "format-codeblocks" :: rest -> ( match rest with | ["-h"] | ["--help"] -> logAndExit (Ok formatCodeblocksHelp) diff --git a/tools/src/tools.ml b/tools/src/tools.ml index 1722fdda07..aafdaba331 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -1292,3 +1292,591 @@ module ExtractCodeblocks = struct ]) |> Protocol.array) end + +module StringMap = Map.Make (String) + +module Migrate = struct + (* + Currently, the migrate command can handle: + - Function calls, including mapping labelled/optional arguments between calls. Piped and not piped. + + It _cannot_ (among much else) handle: + - Changing position of unlabelled arguments (would be problematic with pipes etc) + *) + + (* + TODO: + - Migrate type usage (Js.Array2.t -> array, etc) + - Add "migratePipe" for specific migrations of pipe calls, like `BigInt.land` that can be `&` when not piped, but needs to be `BigInt.bitwiseAnd` when piped. + *) + + module MapperUtils = struct + let get_template_args_to_insert ?(is_pipe = false) mapper template_args + source_args = + let labelled_args_that_will_be_mapped = ref [] in + let unlabelled_positions_that_will_be_mapped = ref [] in + let mapped_template_args = + template_args + |> List.filter_map (fun (label, arg) -> + match (label, arg) with + | ( Asttypes.Nolabel, + { + Parsetree.pexp_desc = + Pexp_extension + ( {txt = "insert.labelledArgument"}, + PStr + [ + { + pstr_desc = + Pstr_eval + ( { + pexp_desc = + Pexp_constant + (Pconst_string (arg_name, _)); + }, + _ ); + }; + ] ); + } ) -> ( + (* Map labelled args *) + let arg_in_source_args = + source_args + |> List.find_map (fun (label, arg) -> + match label with + | Asttypes.Labelled {txt = label} + | Optional {txt = label} -> + if label = arg_name then Some arg else None + | _ -> None) + in + match arg_in_source_args with + | None -> None + | Some arg -> + labelled_args_that_will_be_mapped := + arg_name :: !labelled_args_that_will_be_mapped; + Some (Asttypes.Nolabel, arg)) + | ( template_label, + { + Parsetree.pexp_desc = + Pexp_extension + ( {txt = "insert.unlabelledArgument"}, + PStr + [ + { + pstr_desc = + Pstr_eval + ( { + pexp_desc = + Pexp_constant + (Pconst_integer (count_str, _)); + }, + _ ); + }; + ] ); + } ) -> ( + (* Map unlabelled args *) + let count = int_of_string count_str in + if count <= 0 then None + else + (* Count unlabelled arguments properly: + - For regular calls: count=1 refers to 2nd unlabelled arg (since 1st can't be remapped due to pipes) + - For pipe calls: count=1 refers to 1st unlabelled arg in pipe_args *) + let target_count = if is_pipe then count else count + 1 in + let unlabelled_count = ref 0 in + let found_arg = ref None in + source_args + |> List.iter (fun (label, arg) -> + match label with + | Asttypes.Nolabel -> + incr unlabelled_count; + if !unlabelled_count = target_count then + found_arg := Some arg + | _ -> ()); + match !found_arg with + | None -> None + | Some arg -> + unlabelled_positions_that_will_be_mapped := + target_count :: !unlabelled_positions_that_will_be_mapped; + Some (template_label, arg)) + | ( _, + { + pexp_desc = + Pexp_extension + ( { + txt = + ( "insert.labelledArgument" + | "insert.unlabelledArgument" ); + }, + _ ); + } ) -> + (* Do not add any other instance of insert.* *) + None + | _, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)} -> + None + | _ -> Some (label, mapper.Ast_mapper.expr mapper arg)) + in + ( mapped_template_args, + !labelled_args_that_will_be_mapped, + !unlabelled_positions_that_will_be_mapped ) + + let filter_and_transform_args source_args ~unlabelled_positions_to_insert + ~will_be_mapped ~labelled_args_map = + let unlabelled_consumed = ref 0 in + source_args + |> List.filter_map (fun (label, arg) -> + match label with + | Asttypes.Nolabel -> + incr unlabelled_consumed; + if List.mem !unlabelled_consumed unlabelled_positions_to_insert + then + (* This unlabelled arg has been mapped already, do not add. *) + None + else Some (label, arg) + | Asttypes.Labelled {loc; txt = label} + | Optional {loc; txt = label} + when StringMap.mem label labelled_args_map -> + (* Map labelled args that has just changed name. *) + let mapped_label_name = StringMap.find label labelled_args_map in + Some (Asttypes.Labelled {loc; txt = mapped_label_name}, arg) + | (Labelled {txt} | Optional {txt}) + when List.mem txt will_be_mapped -> + (* These have been mapped already, do not add. *) + None + | label -> Some (label, arg)) + + let build_labelled_args_map template_args = + template_args + |> List.filter_map (fun (label, arg) -> + match (label, arg) with + | ( (Asttypes.Labelled {txt = label} | Optional {txt = label}), + { + Parsetree.pexp_desc = + Pexp_extension + ( {txt = "insert.labelledArgument"}, + PStr + [ + { + pstr_desc = + Pstr_eval + ( { + pexp_desc = + Pexp_constant + (Pconst_string (arg_name, _)); + }, + _ ); + }; + ] ); + } ) -> + Some (arg_name, label) + | _ -> None) + |> List.fold_left + (fun map (k, v) -> StringMap.add k v map) + StringMap.empty + + let apply_migration_template ?(is_pipe = false) mapper template_args + source_args = + let labelled_args_map = build_labelled_args_map template_args in + let ( template_args_to_insert, + will_be_mapped, + unlabelled_positions_to_insert ) = + get_template_args_to_insert ~is_pipe mapper template_args source_args + in + let filtered_args = + filter_and_transform_args source_args ~unlabelled_positions_to_insert + ~will_be_mapped ~labelled_args_map + in + filtered_args @ template_args_to_insert + end + + (* Finds a specific argument in a list of arguments. *) + let find_arg args (find_this_arg : [`Labelled of string | `Unlabelled of int]) + = + let unlabelled_count = ref 0 in + args + |> List.find_map (fun (lbl, arg) -> + match (find_this_arg, lbl) with + | ( `Labelled arg_name, + (Asttypes.Labelled {txt = label} | Optional {txt = label}) ) + when label = arg_name -> + Some (lbl, arg) + | `Unlabelled count, Nolabel -> + let current_count = !unlabelled_count in + incr unlabelled_count; + if current_count = count then Some (lbl, arg) else None + | _, Nolabel -> + incr unlabelled_count; + None + | _ -> None) + + let replace_from_args_in_expr expr source_args = + let mapper = + { + Ast_mapper.default_mapper with + expr = + (fun mapper exp -> + match exp with + | { + pexp_desc = + Pexp_extension + ( {txt = "insert.labelledArgument"}, + PStr + [ + { + pstr_desc = + Pstr_eval + ( { + pexp_desc = + Pexp_constant (Pconst_string (arg_name, _)); + }, + _ ); + }; + ] ); + } -> ( + match find_arg source_args (`Labelled arg_name) with + | Some (_, arg) -> arg + | None -> exp) + | { + pexp_desc = + Pexp_extension + ( {txt = "insert.unlabelledArgument"}, + PStr + [ + { + pstr_desc = + Pstr_eval + ( { + pexp_desc = + Pexp_constant (Pconst_integer (count_str, _)); + }, + _ ); + }; + ] ); + } -> ( + match + find_arg source_args (`Unlabelled (int_of_string count_str)) + with + | Some (_, arg) -> arg + | None -> exp) + | _ -> Ast_mapper.default_mapper.expr mapper exp); + } + in + mapper.expr mapper expr + + let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = + (* Function calls *) + let deprecated_function_calls = + deprecated_used + |> List.filter (fun (d : Cmt_utils.deprecated_used) -> + match d.context with + | Some FunctionCall -> true + | _ -> false) + in + let loc_to_deprecated_fn_call = + Hashtbl.create (List.length deprecated_function_calls) + in + deprecated_function_calls + |> List.iter (fun ({Cmt_utils.source_loc} as d) -> + Hashtbl.replace loc_to_deprecated_fn_call source_loc d); + + (* References *) + let deprecated_references = + deprecated_used + |> List.filter (fun (d : Cmt_utils.deprecated_used) -> + match d.context with + | Some Reference -> true + | _ -> false) + in + let loc_to_deprecated_reference = + Hashtbl.create (List.length deprecated_references) + in + deprecated_references + |> List.iter (fun ({Cmt_utils.source_loc} as d) -> + Hashtbl.replace loc_to_deprecated_reference source_loc d); + + let mapper = + { + Ast_mapper.default_mapper with + extension = + (fun mapper ext -> + (* Map back %todo_ to %todo, since using %todo directly would result in errors where we don't want them. *) + match ext with + | ({txt = "todo_"} as e), payload -> + Ast_mapper.default_mapper.extension mapper + ({e with txt = "todo"}, payload) + | e -> Ast_mapper.default_mapper.extension mapper e); + expr = + (fun mapper exp -> + match exp with + | {pexp_desc = Pexp_ident {loc}} + when Hashtbl.mem loc_to_deprecated_reference loc -> ( + (* Map references to their migration template. *) + let deprecated_info = + Hashtbl.find loc_to_deprecated_reference loc + in + Hashtbl.remove loc_to_deprecated_reference loc; + match deprecated_info.migration_template with + | None -> exp + | Some e -> e) + | { + pexp_desc = + Pexp_apply {funct = {pexp_loc = fn_loc}; args = source_args}; + } + when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( + let deprecated_info = + Hashtbl.find loc_to_deprecated_fn_call fn_loc + in + Hashtbl.remove loc_to_deprecated_fn_call fn_loc; + + let source_args = + source_args + |> List.map (fun (label, arg) -> + (label, mapper.expr mapper arg)) + in + + (* TODO: Here we could add strict and partial mode, to control if args are merged or not. *) + match deprecated_info.migration_template with + | Some {pexp_desc = Pexp_match (e, cases)} -> + { + exp with + pexp_desc = + Pexp_match (replace_from_args_in_expr e source_args, cases); + } + | Some + { + pexp_desc = + Pexp_apply + { + funct = template_funct; + args = template_args; + partial; + transformed_jsx; + }; + } -> + let migrated_args = + MapperUtils.apply_migration_template mapper template_args + source_args + in + { + exp with + pexp_desc = + Pexp_apply + { + funct = template_funct; + args = migrated_args; + partial; + transformed_jsx; + }; + } + | _ -> + (* TODO: More elaborate warnings etc *) + (* Invalid config. *) + exp) + | { + pexp_desc = + Pexp_apply + { + funct = {pexp_desc = Pexp_ident {txt = Lident "->"}} as funct; + args = + (_ as lhs) + :: (Nolabel, {pexp_loc = fn_loc; pexp_desc = Pexp_ident _}) + :: _; + }; + } + when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( + (* Pipe with no arguments, [1, 2, 3]->someDeprecated + This is the only pipe we need to handle, because the argument one is handled by the transform above. *) + let deprecated_info = + Hashtbl.find loc_to_deprecated_fn_call fn_loc + in + Hashtbl.remove loc_to_deprecated_fn_call fn_loc; + + let migration_template_to_use = + match deprecated_info.migration_piped_template with + | Some template -> Some template + | None -> deprecated_info.migration_template + in + match migration_template_to_use with + | Some {pexp_desc = Pexp_match (e, cases)} -> + { + exp with + pexp_desc = + Pexp_match (replace_from_args_in_expr e [lhs], cases); + } + | Some + { + pexp_desc = + Pexp_apply + { + funct = template_funct; + args = template_args; + partial; + transformed_jsx; + }; + } -> + let template_args_to_insert, _, _ = + MapperUtils.get_template_args_to_insert mapper template_args + [] + in + if Ext_list.is_empty template_args_to_insert then + { + exp with + pexp_desc = + Pexp_apply + { + funct; + args = [lhs; (Nolabel, template_funct)]; + partial; + transformed_jsx; + }; + } + else + { + exp with + pexp_desc = + Pexp_apply + { + funct; + args = + [ + lhs; + ( Nolabel, + Ast_helper.Exp.apply template_funct + template_args_to_insert ); + ]; + partial; + transformed_jsx; + }; + } + | _ -> + (* TODO: More elaborate warnings etc *) + (* Invalid config. *) + exp) + | { + pexp_desc = + Pexp_apply + { + funct = {pexp_desc = Pexp_ident {txt = Lident "->"}} as funct; + args = + (_ as lhs) + :: ( Nolabel, + { + pexp_desc = + Pexp_apply + {funct = {pexp_loc = fn_loc}; args = pipe_args}; + } ) + :: _; + }; + } + when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( + (* Pipe with arguments, [1, 2, 3, 4]->someDeprecated(arg1, arg2) *) + let deprecated_info = + Hashtbl.find loc_to_deprecated_fn_call fn_loc + in + Hashtbl.remove loc_to_deprecated_fn_call fn_loc; + + let migration_template_to_use = + match deprecated_info.migration_piped_template with + | Some template -> Some template + | None -> deprecated_info.migration_template + in + match migration_template_to_use with + | Some + { + pexp_desc = + Pexp_apply + { + funct = template_funct; + args = template_args; + partial; + transformed_jsx; + }; + } -> + let migrated_args = + MapperUtils.apply_migration_template ~is_pipe:true mapper + template_args pipe_args + in + { + exp with + pexp_desc = + Pexp_apply + { + funct; + args = + [ + lhs; + ( Nolabel, + Ast_helper.Exp.apply template_funct migrated_args + ); + ]; + partial; + transformed_jsx; + }; + } + | _ -> + (* TODO: More elaborate warnings etc *) + (* Invalid config. *) + exp) + | _ -> Ast_mapper.default_mapper.expr mapper exp); + } + in + mapper + + let migrate ~entryPointFile ~outputMode = + let path = + match Filename.is_relative entryPointFile with + | true -> Unix.realpath entryPointFile + | false -> entryPointFile + in + let result = + if Filename.check_suffix path ".res" then + let parser = + Res_driver.parsing_engine.parse_implementation ~for_printer:true + in + let {Res_driver.parsetree; comments; source} = parser ~filename:path in + match Cmt.loadCmtInfosFromPath ~path with + | None -> + Error + (Printf.sprintf + "error: failed to run migration for %s because build artifacts \ + could not be found. try to build the project" + path) + | Some {cmt_extra_info = {deprecated_used}} -> + let mapper = makeMapper deprecated_used in + let astMapped = mapper.structure mapper parsetree in + Ok + ( Res_printer.print_implementation + ~width:Res_printer.default_print_width astMapped ~comments, + source ) + else if Filename.check_suffix path ".resi" then + let parser = + Res_driver.parsing_engine.parse_interface ~for_printer:true + in + let {Res_driver.parsetree = signature; comments; source} = + parser ~filename:path + in + let mapper = makeMapper [] in + let astMapped = mapper.signature mapper signature in + Ok + ( Res_printer.print_interface ~width:Res_printer.default_print_width + astMapped ~comments, + source ) + else + Error + (Printf.sprintf + "File extension not supported. This command accepts .res, .resi \ + files") + in + match result with + | Error e -> Error e + | Ok (contents, source) when contents <> source -> ( + match outputMode with + | `Stdout -> Ok contents + | `File -> + let oc = open_out path in + Printf.fprintf oc "%s" contents; + close_out oc; + Ok (Filename.basename path ^ ": File migrated successfully")) + | Ok (contents, _) -> ( + match outputMode with + | `Stdout -> Ok contents + | `File -> Ok (Filename.basename path ^ ": File did not need migration")) +end From 663ef1ad1646af77c533b1901bfa1d9bcb0444a3 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 25 Aug 2025 10:13:54 +0200 Subject: [PATCH 02/41] wip migrate --- packages/@rescript/runtime/Stdlib_Array.resi | 9 +- .../expected/OptionalArgRename.res.expected | 8 + .../expected/OptionalArgRename.resi.expected | 6 + .../expected/PipeAndRecursive.res.expected | 40 ++ .../StdlibMigration_BigInt.res.expected | 18 +- .../src/migrate/OptionalArgRename.res | 7 + .../src/migrate/OptionalArgRename.resi | 5 + .../src/migrate/PipeAndRecursive.res | 25 + .../Migrated_StdlibMigration_BigInt.res | 18 +- tools/src/migrate.ml | 613 ++++++++++++++++++ tools/src/migrate.mli | 4 + tools/src/tools.ml | 588 +---------------- 12 files changed, 732 insertions(+), 609 deletions(-) create mode 100644 tests/tools_tests/src/expected/OptionalArgRename.res.expected create mode 100644 tests/tools_tests/src/expected/OptionalArgRename.resi.expected create mode 100644 tests/tools_tests/src/expected/PipeAndRecursive.res.expected create mode 100644 tests/tools_tests/src/migrate/OptionalArgRename.res create mode 100644 tests/tools_tests/src/migrate/OptionalArgRename.resi create mode 100644 tests/tools_tests/src/migrate/PipeAndRecursive.res create mode 100644 tools/src/migrate.ml create mode 100644 tools/src/migrate.mli diff --git a/packages/@rescript/runtime/Stdlib_Array.resi b/packages/@rescript/runtime/Stdlib_Array.resi index 1cd985ea86..c3d913bc60 100644 --- a/packages/@rescript/runtime/Stdlib_Array.resi +++ b/packages/@rescript/runtime/Stdlib_Array.resi @@ -102,8 +102,10 @@ arr->Array.copyAllWithin(~target=2) == [100, 101, 100, 101, 102] arr == [100, 101, 100, 101, 102] ``` */ -@deprecated("Use `copyWithin` instead") -@send external copyAllWithin: (array<'a>, ~target: int) => array<'a> = "copyWithin" +@deprecated("Use `copyWithin` instead") @send external copyAllWithin: ( + array<'a>, + ~target: int, +) => array<'a> = "copyWithin" /** `copyWithinToEnd(array, ~target, ~start)` copies starting at element `start` in the given array to the designated `target` position, returning the resulting array. @@ -120,8 +122,7 @@ arr->Array.copyWithinToEnd(~target=0, ~start=2) == [102, 103, 104, 103, 104] arr == [102, 103, 104, 103, 104] ``` */ -@deprecated("Use `copyWithin` instead") -@send +@deprecated("Use `copyWithin` instead") @send external copyWithinToEnd: (array<'a>, ~target: int, ~start: int) => array<'a> = "copyWithin" /** diff --git a/tests/tools_tests/src/expected/OptionalArgRename.res.expected b/tests/tools_tests/src/expected/OptionalArgRename.res.expected new file mode 100644 index 0000000000..2a7450467d --- /dev/null +++ b/tests/tools_tests/src/expected/OptionalArgRename.res.expected @@ -0,0 +1,8 @@ +module Target = { + let doStuff = (~newName: option=?) => () +} + +external doStuff: (~oldName: option=?) => unit = "doStuff" + +/* Intentionally no usage here; this test exercises migration config parsing and ensures optional label rename is preserved and doesn’t crash. */ + diff --git a/tests/tools_tests/src/expected/OptionalArgRename.resi.expected b/tests/tools_tests/src/expected/OptionalArgRename.resi.expected new file mode 100644 index 0000000000..3c8aa0a5ed --- /dev/null +++ b/tests/tools_tests/src/expected/OptionalArgRename.resi.expected @@ -0,0 +1,6 @@ +@deprecated({ + reason: "Use new label name", + migrate: OptionalArgRename.Target.doStuff(~newName=%insert.labelledArgument("oldName")), +}) +external doStuff: (~oldName: option=?) => unit = "doStuff" + diff --git a/tests/tools_tests/src/expected/PipeAndRecursive.res.expected b/tests/tools_tests/src/expected/PipeAndRecursive.res.expected new file mode 100644 index 0000000000..2820be6c3d --- /dev/null +++ b/tests/tools_tests/src/expected/PipeAndRecursive.res.expected @@ -0,0 +1,40 @@ +module Target = { + let a = x => x + 1 + let b = x => x + 2 +} + +@deprecated({ + reason: "test piped vs non-piped", + migrate: PipeAndRecursive.Target.a(), + migratePiped: PipeAndRecursive.Target.b(), +}) +external dep: int => int = "dep" + +let id = x => x + +/* Should use migrate (Target.a), since lhs has 0 pipes */ +let onePipe = PipeAndRecursive.Target.a(1) + +/* Still migrate (Target.a), since lhs has 1 pipe (< 2) */ +let twoPipes = 1->id->PipeAndRecursive.Target.b + +/* Should use migratePiped (Target.b), since lhs has 2 pipes */ +let threePipes = 1->id->id->PipeAndRecursive.Target.b + +/* Recursion: all dep steps should migrate */ +let many = PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a( + PipeAndRecursive.Target.a(PipeAndRecursive.Target.a(PipeAndRecursive.Target.a(1))), + ), + ), + ), + ), + ), + ), +) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected index e674d8aee7..727a58ab09 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected @@ -1,22 +1,22 @@ let fromStringExn1 = "123"->BigInt.fromStringOrThrow let fromStringExn2 = BigInt.fromStringOrThrow("123") -let land1 = 7n->BigInt.bitwiseAnd(4n) +let land1 = 7n & 4n let land2 = 7n & 4n let lor1 = 7n->BigInt.bitwiseOr(4n) let lor2 = BigInt.bitwiseOr(7n, 4n) -let lxor1 = 7n->BigInt.bitwiseXor(4n) +let lxor1 = 7n ^ 4n let lxor2 = 7n ^ 4n let lnot1 = 2n->Js.BigInt.lnot let lnot2 = Js.BigInt.lnot(2n) -let lsl1 = 4n->BigInt.shiftLeft(1n) +let lsl1 = 4n << 1n let lsl2 = 4n << 1n -let asr1 = 8n->BigInt.shiftRight(1n) +let asr1 = 8n >> 1n let asr2 = 8n >> 1n let toString1 = 123n->BigInt.toString @@ -29,20 +29,20 @@ let toLocaleString2 = BigInt.toLocaleString(123n) let stdlib_fromStringExn1 = "123"->BigInt.fromStringOrThrow let stdlib_fromStringExn2 = BigInt.fromStringOrThrow("123") -let stdlib_land1 = 7n->BigInt.bitwiseAnd(4n) +let stdlib_land1 = 7n & 4n let stdlib_land2 = 7n & 4n let stdlib_lor1 = BigInt.bitwiseOr(7n, 4n) -let stdlib_lxor1 = 7n->BigInt.bitwiseXor(4n) +let stdlib_lxor1 = 7n ^ 4n let stdlib_lxor2 = 7n ^ 4n -let stdlib_lnot1 = 2n->BigInt.bitwiseNot +let stdlib_lnot1 = ~2n let stdlib_lnot2 = ~2n -let stdlib_lsl1 = 4n->BigInt.shiftLeft(1n) +let stdlib_lsl1 = 4n << 1n let stdlib_lsl2 = 4n << 1n -let stdlib_asr1 = 8n->BigInt.shiftRight(1n) +let stdlib_asr1 = 8n >> 1n let stdlib_asr2 = 8n >> 1n diff --git a/tests/tools_tests/src/migrate/OptionalArgRename.res b/tests/tools_tests/src/migrate/OptionalArgRename.res new file mode 100644 index 0000000000..e58fb0fd1c --- /dev/null +++ b/tests/tools_tests/src/migrate/OptionalArgRename.res @@ -0,0 +1,7 @@ +module Target = { + let doStuff = (~newName: option=?) => () +} + +external doStuff: (~oldName: option=?) => unit = "doStuff" + +/* Intentionally no usage here; this test exercises migration config parsing and ensures optional label rename is preserved and doesn’t crash. */ diff --git a/tests/tools_tests/src/migrate/OptionalArgRename.resi b/tests/tools_tests/src/migrate/OptionalArgRename.resi new file mode 100644 index 0000000000..cc6995c020 --- /dev/null +++ b/tests/tools_tests/src/migrate/OptionalArgRename.resi @@ -0,0 +1,5 @@ +@deprecated({ + reason: "Use new label name", + migrate: OptionalArgRename.Target.doStuff(~newName=%insert.labelledArgument("oldName")), +}) +external doStuff: (~oldName: option=?) => unit = "doStuff" diff --git a/tests/tools_tests/src/migrate/PipeAndRecursive.res b/tests/tools_tests/src/migrate/PipeAndRecursive.res new file mode 100644 index 0000000000..a2da460513 --- /dev/null +++ b/tests/tools_tests/src/migrate/PipeAndRecursive.res @@ -0,0 +1,25 @@ +module Target = { + let a = x => x + 1 + let b = x => x + 2 +} + +@deprecated({ + reason: "test piped vs non-piped", + migrate: PipeAndRecursive.Target.a(), + migratePiped: PipeAndRecursive.Target.b(), +}) +external dep: int => int = "dep" + +let id = x => x + +/* Should use migrate (Target.a), since lhs has 0 pipes */ +let onePipe = 1->dep + +/* Still migrate (Target.a), since lhs has 1 pipe (< 2) */ +let twoPipes = 1->id->dep + +/* Should use migratePiped (Target.b), since lhs has 2 pipes */ +let threePipes = 1->id->id->dep + +/* Recursion: all dep steps should migrate */ +let many = 1->dep->dep->dep->dep->dep->dep->dep->dep->dep->dep diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res index 3ea3562f5d..846cb3d7ae 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res @@ -3,22 +3,22 @@ let fromStringExn1 = "123"->BigInt.fromStringOrThrow let fromStringExn2 = BigInt.fromStringOrThrow("123") -let land1 = 7n->BigInt.bitwiseAnd(4n) +let land1 = 7n & 4n let land2 = 7n & 4n let lor1 = 7n->BigInt.bitwiseOr(4n) let lor2 = BigInt.bitwiseOr(7n, 4n) -let lxor1 = 7n->BigInt.bitwiseXor(4n) +let lxor1 = 7n ^ 4n let lxor2 = 7n ^ 4n let lnot1 = 2n->Js.BigInt.lnot let lnot2 = Js.BigInt.lnot(2n) -let lsl1 = 4n->BigInt.shiftLeft(1n) +let lsl1 = 4n << 1n let lsl2 = 4n << 1n -let asr1 = 8n->BigInt.shiftRight(1n) +let asr1 = 8n >> 1n let asr2 = 8n >> 1n let toString1 = 123n->BigInt.toString @@ -31,19 +31,19 @@ let toLocaleString2 = BigInt.toLocaleString(123n) let stdlib_fromStringExn1 = "123"->BigInt.fromStringOrThrow let stdlib_fromStringExn2 = BigInt.fromStringOrThrow("123") -let stdlib_land1 = 7n->BigInt.bitwiseAnd(4n) +let stdlib_land1 = 7n & 4n let stdlib_land2 = 7n & 4n let stdlib_lor1 = BigInt.bitwiseOr(7n, 4n) -let stdlib_lxor1 = 7n->BigInt.bitwiseXor(4n) +let stdlib_lxor1 = 7n ^ 4n let stdlib_lxor2 = 7n ^ 4n -let stdlib_lnot1 = 2n->BigInt.bitwiseNot +let stdlib_lnot1 = ~2n let stdlib_lnot2 = ~2n -let stdlib_lsl1 = 4n->BigInt.shiftLeft(1n) +let stdlib_lsl1 = 4n << 1n let stdlib_lsl2 = 4n << 1n -let stdlib_asr1 = 8n->BigInt.shiftRight(1n) +let stdlib_asr1 = 8n >> 1n let stdlib_asr2 = 8n >> 1n diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml new file mode 100644 index 0000000000..fd515fda27 --- /dev/null +++ b/tools/src/migrate.ml @@ -0,0 +1,613 @@ +open Analysis + +module StringMap = Map.Make (String) +module StringSet = Set.Make (String) +module IntSet = Set.Make (Int) + +(* Public API: migrate ~entryPointFile ~outputMode *) + +module InsertExt = struct + type placeholder = Labelled of string | Unlabelled of int + + let ext_labelled = "insert.labelledArgument" + let ext_unlabelled = "insert.unlabelledArgument" + + (* + Unlabelled argument placeholders use 0-based indexing. + Pipe semantics: the pipe LHS occupies index 0 when resolving placeholders + in piped templates. For inner calls that exclude the LHS (e.g. `lhs->f(x)`), + we adjust drop positions at the call site to keep the generated call correct. + *) + let placeholder_of_expr = function + | { + Parsetree.pexp_desc = + Pexp_extension + ( {txt}, + PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_constant c}, _)}] + ); + } -> + if txt = ext_labelled then + match c with + | Pconst_string (name, _) -> Some (Labelled name) + | _ -> None + else if txt = ext_unlabelled then + match c with + | Pconst_integer (s, _) -> ( + match int_of_string_opt s with + | Some i -> Some (Unlabelled i) + | None -> None) + | _ -> None + else None + | _ -> None +end + +module ArgUtils = struct + let map_expr_args mapper args = + args + |> List.map (fun (label, arg) -> (label, mapper.Ast_mapper.expr mapper arg)) +end + +module ExprUtils = struct + let rec is_pipe_apply (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_apply {funct = {pexp_desc = Pexp_ident {txt = Lident "->"}}; _} -> + true + | Pexp_construct (_, Some e) + | Pexp_constraint (e, _) + | Pexp_coerce (e, _, _) + | Pexp_let (_, _, e) + | Pexp_sequence (e, _) + | Pexp_letmodule (_, _, e) + | Pexp_open (_, _, e) -> + is_pipe_apply e + | _ -> false +end + +module MapperUtils = struct + let build_labelled_args_map template_args = + template_args + |> List.filter_map (fun (label, arg) -> + match (label, InsertExt.placeholder_of_expr arg) with + | ( (Asttypes.Labelled {txt = label} | Optional {txt = label}), + Some (InsertExt.Labelled arg_name) ) -> + Some (arg_name, label) + | _ -> None) + |> List.fold_left (fun map (k, v) -> StringMap.add k v map) StringMap.empty + + (* + Pure computation of which template args to insert and which source args + are consumed by placeholders. + + Indexing is 0-based everywhere. + For piped application, the pipe LHS occupies index 0 in the source list + used for placeholder resolution. If the inner call excludes the LHS + (e.g. `lhs -> f(args)`), adjust drop positions accordingly at the call site. + + Returns: + - template_args_to_insert: args to append to the final call + - labelled_will_be_mapped: names of labelled source args that are consumed + - unlabelled_positions_to_insert: 0-based indices of unlabelled source args to drop + *) + let get_template_args_to_insert mapper template_args source_args = + let find_source_labelled name = + source_args + |> List.find_map (fun (label, arg) -> + match label with + | Asttypes.Labelled {txt = l} | Optional {txt = l} -> + if l = name then Some arg else None + | _ -> None) + in + let find_source_unlabelled target = + let rec loop i = function + | [] -> None + | (Asttypes.Nolabel, arg) :: rest -> + if i = target then Some arg else loop (i + 1) rest + | _ :: rest -> loop i rest + in + loop 0 source_args + in + let is_unit_expr (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_construct ({txt = Lident "()"}, None) -> true + | _ -> false + in + + (* For each template argument, decide whether it is a placeholder that + should be substituted from the source call, or a concrete argument which + should be preserved (after mapping through the mapper). + Accumulator: + - rev_args: arguments to append to the final call (in reverse order) + - used_labelled: names of labelled args consumed from the source call + - used_unlabelled: 0-based positions of unlabelled args consumed. *) + let accumulate_template_arg (rev_args, used_labelled, used_unlabelled) + (label, arg) = + match InsertExt.placeholder_of_expr arg with + | Some (InsertExt.Labelled name) -> ( + match label with + | Asttypes.Nolabel -> ( + match find_source_labelled name with + | Some arg' -> + ( (Asttypes.Nolabel, arg') :: rev_args, + StringSet.add name used_labelled, + used_unlabelled ) + | None -> (rev_args, used_labelled, used_unlabelled)) + | _ -> (rev_args, used_labelled, used_unlabelled)) + | Some (InsertExt.Unlabelled target) when target >= 0 -> ( + match find_source_unlabelled target with + | Some arg' -> + ( (label, arg') :: rev_args, + used_labelled, + IntSet.add target used_unlabelled ) + | None -> (rev_args, used_labelled, used_unlabelled)) + | Some _ -> (rev_args, used_labelled, used_unlabelled) + | None -> + if is_unit_expr arg then (rev_args, used_labelled, used_unlabelled) + else + ( (label, mapper.Ast_mapper.expr mapper arg) :: rev_args, + used_labelled, + used_unlabelled ) + in + let rev_args, labelled_set, unlabelled_set = + List.fold_left accumulate_template_arg + ([], StringSet.empty, IntSet.empty) + template_args + in + (List.rev rev_args, labelled_set, unlabelled_set) + + let drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped = + let _, rev = + List.fold_left + (fun (idx, acc) (label, arg) -> + match label with + | Asttypes.Nolabel -> + let drop = IntSet.mem idx unlabelled_positions_to_insert in + let idx' = idx + 1 in + if drop then (idx', acc) else (idx', (label, arg) :: acc) + | Asttypes.Labelled {txt} | Optional {txt} -> + if StringSet.mem txt will_be_mapped then (idx, acc) + else (idx, (label, arg) :: acc)) + (0, []) source_args + in + List.rev rev + + let rename_labels source_args ~labelled_args_map = + source_args + |> List.map (fun (label, arg) -> + match label with + | Asttypes.Labelled ({loc; txt} as l) -> + if StringMap.mem txt labelled_args_map then + let mapped = StringMap.find txt labelled_args_map in + (Asttypes.Labelled {loc; txt = mapped}, arg) + else (Asttypes.Labelled l, arg) + | Optional ({loc; txt} as l) -> + if StringMap.mem txt labelled_args_map then + let mapped = StringMap.find txt labelled_args_map in + (Optional {loc; txt = mapped}, arg) + else (Optional l, arg) + | _ -> (label, arg)) + + let apply_migration_template mapper template_args source_args = + let labelled_args_map = build_labelled_args_map template_args in + let template_args_to_insert, will_be_mapped, unlabelled_positions_to_insert + = + get_template_args_to_insert mapper template_args source_args + in + let dropped = + drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped + in + let renamed = rename_labels dropped ~labelled_args_map in + renamed @ template_args_to_insert + + let migrate_piped_args mapper ~template_args ~lhs ~pipe_args = + let full_source_args = lhs :: pipe_args in + let template_args_to_insert, will_be_mapped, unlabelled_positions_to_insert + = + get_template_args_to_insert mapper template_args full_source_args + in + let labelled_args_map = build_labelled_args_map template_args in + let adjusted_unlabelled_to_drop = + IntSet.fold + (fun i acc -> if i > 0 then IntSet.add (i - 1) acc else acc) + unlabelled_positions_to_insert IntSet.empty + in + let dropped = + drop_args pipe_args + ~unlabelled_positions_to_insert:adjusted_unlabelled_to_drop + ~will_be_mapped + in + let renamed = rename_labels dropped ~labelled_args_map in + renamed @ template_args_to_insert +end + +type args_ctx = { + labelled: (string, Parsetree.expression) Hashtbl.t; + unlabelled: (int, Parsetree.expression) Hashtbl.t; +} + +let build_args_ctx args : args_ctx = + let labelled = Hashtbl.create 8 in + let unlabelled = Hashtbl.create 8 in + let idx = ref 0 in + args + |> List.iter (fun (lbl, arg) -> + match lbl with + | Asttypes.Nolabel -> + Hashtbl.replace unlabelled !idx arg; + incr idx + | Asttypes.Labelled {txt} | Optional {txt} -> + Hashtbl.replace labelled txt arg); + {labelled; unlabelled} + +let find_in_args_ctx args_ctx + (find_this : [`Labelled of string | `Unlabelled of int]) = + match find_this with + | `Labelled name -> Hashtbl.find_opt args_ctx.labelled name + | `Unlabelled i -> Hashtbl.find_opt args_ctx.unlabelled i + +let replace_from_args_ctx_in_expr expr args_ctx = + let mapper = + { + Ast_mapper.default_mapper with + expr = + (fun mapper exp -> + match InsertExt.placeholder_of_expr exp with + | Some (InsertExt.Labelled name) -> ( + match find_in_args_ctx args_ctx (`Labelled name) with + | Some arg -> arg + | None -> exp) + | Some (InsertExt.Unlabelled i) -> ( + match find_in_args_ctx args_ctx (`Unlabelled i) with + | Some arg -> arg + | None -> exp) + | None -> Ast_mapper.default_mapper.expr mapper exp); + } + in + mapper.expr mapper expr + +let replace_from_args_in_expr expr source_args = + replace_from_args_ctx_in_expr expr (build_args_ctx source_args) + +let remap_needed_extensions (mapper : Ast_mapper.mapper) + (ext : Parsetree.extension) : Parsetree.extension = + match ext with + | ({txt = "todo_"} as e), payload -> + Ast_mapper.default_mapper.extension mapper ({e with txt = "todo"}, payload) + | e -> Ast_mapper.default_mapper.extension mapper e + +let migrate_reference_from_info (deprecated_info : Cmt_utils.deprecated_used) + exp = + match deprecated_info.migration_template with + | Some e -> e + | None -> exp + +module Template = struct + type t = + | Apply of { + funct: Parsetree.expression; + args: (Asttypes.arg_label * Parsetree.expression) list; + partial: bool; + transformed_jsx: bool; + } + | Match of {expr: Parsetree.expression; cases: Parsetree.case list} + + let of_expr = function + | {Parsetree.pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} + -> + Some (Apply {funct; args; partial; transformed_jsx}) + | {Parsetree.pexp_desc = Pexp_match (expr, cases)} -> + Some (Match {expr; cases}) + | _ -> None + + let mk_apply (exp : Parsetree.expression) ~funct ~args ~partial + ~transformed_jsx = + {exp with pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} + + (* Apply a non-piped migration template to a direct call. *) + let apply_direct ~mapper ~template ~call_args (exp : Parsetree.expression) = + match template with + | Match {expr; cases} -> + { + exp with + pexp_desc = Pexp_match (replace_from_args_in_expr expr call_args, cases); + } + | Apply + {funct = template_funct; args = template_args; partial; transformed_jsx} + -> + let migrated_args = + MapperUtils.apply_migration_template mapper template_args call_args + in + mk_apply exp ~funct:template_funct ~args:migrated_args ~partial + ~transformed_jsx + + (* Apply a piped migration template. The `lhs` is the value being piped and + `pipe_args` are the arguments in the right-hand call (if any). *) + let apply_piped ~mapper ~template ~lhs ~pipe_args ~funct + (exp : Parsetree.expression) = + match template with + | Match {expr; cases} -> + { + exp with + pexp_desc = Pexp_match (replace_from_args_in_expr expr [lhs], cases); + } + | Apply + {funct = template_funct; args = template_args; partial; transformed_jsx} + -> + let pipe_args_mapped = ArgUtils.map_expr_args mapper pipe_args in + let migrated_args = + MapperUtils.migrate_piped_args mapper ~template_args ~lhs + ~pipe_args:pipe_args_mapped + in + mk_apply exp ~funct + ~args: + [ + lhs; + (Asttypes.Nolabel, Ast_helper.Exp.apply template_funct migrated_args); + ] + ~partial ~transformed_jsx + + (* Like apply_piped, but when there are no pipe args and the template has no + arguments to insert, collapse to `funct lhs template_funct`. *) + let apply_piped_maybe_empty ~mapper ~template ~lhs ~pipe_args ~funct + (exp : Parsetree.expression) = + match template with + | Match _ -> apply_piped ~mapper ~template ~lhs ~pipe_args ~funct exp + | Apply + {funct = template_funct; args = template_args; partial; transformed_jsx} + -> + if Ext_list.is_empty pipe_args then + let template_args_to_insert, _, _ = + MapperUtils.get_template_args_to_insert mapper template_args [] + in + if Ext_list.is_empty template_args_to_insert then + mk_apply exp ~funct + ~args:[lhs; (Asttypes.Nolabel, template_funct)] + ~partial ~transformed_jsx + else + mk_apply exp ~funct + ~args: + [ + lhs; + ( Asttypes.Nolabel, + Ast_helper.Exp.apply template_funct template_args_to_insert ); + ] + ~partial ~transformed_jsx + else apply_piped ~mapper ~template ~lhs ~pipe_args ~funct exp + + (* Handle the special case of a single-step pipe where we are allowed to + collapse the pipe into a direct call. *) + let apply_single_pipe_collapse ~mapper ~template ~lhs_exp ~pipe_args + (exp : Parsetree.expression) = + match template with + | Match {expr; cases} -> + Ast_helper.Exp.match_ + (replace_from_args_in_expr expr + ((Asttypes.Nolabel, lhs_exp) + :: ArgUtils.map_expr_args mapper pipe_args)) + cases + | Apply + { + funct = templ_f; + args = templ_args; + partial = tpartial; + transformed_jsx = tjsx; + } -> + let pipe_args_mapped = ArgUtils.map_expr_args mapper pipe_args in + let migrated_args = + MapperUtils.apply_migration_template mapper templ_args + ((Asttypes.Nolabel, lhs_exp) :: pipe_args_mapped) + in + mk_apply exp ~funct:templ_f ~args:migrated_args ~partial:tpartial + ~transformed_jsx:tjsx +end + +(* Apply a direct-call migration template to a call site. *) +let apply_template_direct mapper template_expr call_args exp = + match Template.of_expr template_expr with + | Some template -> Template.apply_direct ~mapper ~template ~call_args exp + | None -> exp + +(* Choose a template to use for piped forms, preferring a specific piped + template when available and valid; otherwise fall back to the direct + template. *) +let choose_template_for_piped (deprecated_info : Cmt_utils.deprecated_used) = + match deprecated_info.migration_piped_template with + | Some e -> ( + match Template.of_expr e with + | Some t -> Some t + | None -> None) + | None -> ( + match deprecated_info.migration_template with + | Some e2 -> ( + match Template.of_expr e2 with + | Some t -> Some t + | None -> None) + | None -> None) + +(* Apply migration for a single-step pipe if possible, else use the piped + template. Mirrors the previous inline logic from the mapper. *) +let apply_single_step_or_piped ~mapper + ~(deprecated_info : Cmt_utils.deprecated_used) ~lhs ~lhs_exp ~pipe_args + ~funct exp = + let is_single_pipe_step = not (ExprUtils.is_pipe_apply lhs_exp) in + if + is_single_pipe_step + && Option.is_some deprecated_info.migration_piped_template + then + match deprecated_info.migration_template with + | Some e -> ( + match Template.of_expr e with + | Some t -> + Template.apply_single_pipe_collapse ~mapper ~template:t ~lhs_exp + ~pipe_args exp + | None -> ( + match deprecated_info.migration_piped_template with + | Some e2 -> ( + match Template.of_expr e2 with + | Some t -> + Template.apply_piped ~mapper ~template:t ~lhs ~pipe_args ~funct exp + | None -> exp) + | None -> exp)) + | None -> ( + match deprecated_info.migration_piped_template with + | Some e2 -> ( + match Template.of_expr e2 with + | Some t -> + Template.apply_piped ~mapper ~template:t ~lhs ~pipe_args ~funct exp + | None -> exp) + | None -> exp) + else + match choose_template_for_piped deprecated_info with + | Some t -> + Template.apply_piped_maybe_empty ~mapper ~template:t ~lhs ~pipe_args + ~funct exp + | None -> exp + +let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = + let deprecated_function_calls = + deprecated_used + |> List.filter (fun (d : Cmt_utils.deprecated_used) -> + match d.context with + | Some FunctionCall -> true + | _ -> false) + in + let loc_to_deprecated_fn_call = + Hashtbl.create (List.length deprecated_function_calls) + in + deprecated_function_calls + |> List.iter (fun ({Cmt_utils.source_loc} as d) -> + Hashtbl.replace loc_to_deprecated_fn_call source_loc d); + + let deprecated_references = + deprecated_used + |> List.filter (fun (d : Cmt_utils.deprecated_used) -> + match d.context with + | Some Reference -> true + | _ -> false) + in + let loc_to_deprecated_reference = + Hashtbl.create (List.length deprecated_references) + in + deprecated_references + |> List.iter (fun ({Cmt_utils.source_loc} as d) -> + Hashtbl.replace loc_to_deprecated_reference source_loc d); + + let mapper = + { + Ast_mapper.default_mapper with + extension = remap_needed_extensions; + expr = + (fun mapper exp -> + match exp with + | {pexp_desc = Pexp_ident {loc}} + when Hashtbl.mem loc_to_deprecated_reference loc -> + let deprecated_info = + Hashtbl.find loc_to_deprecated_reference loc + in + migrate_reference_from_info deprecated_info exp + | { + pexp_desc = + Pexp_apply {funct = {pexp_loc = fn_loc}; args = call_args}; + } + when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( + let deprecated_info = + Hashtbl.find loc_to_deprecated_fn_call fn_loc + in + let call_args = ArgUtils.map_expr_args mapper call_args in + match deprecated_info.migration_template with + | Some e -> apply_template_direct mapper e call_args exp + | None -> exp) + | { + pexp_desc = + Pexp_apply + { + funct = {pexp_desc = Pexp_ident {txt = Lident "->"}} as funct; + args = (lhs_label, lhs_exp) :: (Nolabel, rhs) :: _; + }; + } -> ( + let lhs_exp = mapper.expr mapper lhs_exp in + let lhs = (lhs_label, lhs_exp) in + let fn_loc_opt, pipe_args = + match rhs with + | {pexp_loc = fn_loc; pexp_desc = Pexp_ident _} -> + (Some fn_loc, []) + | { + pexp_desc = + Pexp_apply + { + funct = {pexp_loc = fn_loc; pexp_desc = Pexp_ident _}; + args = pipe_args; + }; + } -> + (Some fn_loc, pipe_args) + | _ -> (None, []) + in + match fn_loc_opt with + | None -> Ast_mapper.default_mapper.expr mapper exp + | Some fn_loc when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> + let deprecated_info = + Hashtbl.find loc_to_deprecated_fn_call fn_loc + in + apply_single_step_or_piped ~mapper ~deprecated_info ~lhs ~lhs_exp + ~pipe_args ~funct exp + | Some _ -> Ast_mapper.default_mapper.expr mapper exp) + | _ -> Ast_mapper.default_mapper.expr mapper exp); + } + in + mapper + +let migrate ~entryPointFile ~outputMode = + let path = + match Filename.is_relative entryPointFile with + | true -> Unix.realpath entryPointFile + | false -> entryPointFile + in + let result = + if Filename.check_suffix path ".res" then + let parser = + Res_driver.parsing_engine.parse_implementation ~for_printer:true + in + let {Res_driver.parsetree; comments; source} = parser ~filename:path in + match Cmt.loadCmtInfosFromPath ~path with + | None -> + Error + (Printf.sprintf + "error: failed to run migration for %s because build artifacts \ + could not be found. try to build the project" + path) + | Some {cmt_extra_info = {deprecated_used}} -> + let mapper = makeMapper deprecated_used in + let astMapped = mapper.structure mapper parsetree in + Ok + ( Res_printer.print_implementation + ~width:Res_printer.default_print_width astMapped ~comments, + source ) + else if Filename.check_suffix path ".resi" then + let parser = + Res_driver.parsing_engine.parse_interface ~for_printer:true + in + let {Res_driver.parsetree = signature; comments; source} = + parser ~filename:path + in + let mapper = makeMapper [] in + let astMapped = mapper.signature mapper signature in + Ok (Res_printer.print_interface astMapped ~comments, source) + else + Error + (Printf.sprintf + "File extension not supported. This command accepts .res and .resi \ + files") + in + match result with + | Error e -> Error e + | Ok (contents, source) when contents <> source -> ( + match outputMode with + | `Stdout -> Ok contents + | `File -> + let oc = open_out path in + Printf.fprintf oc "%s" contents; + close_out oc; + Ok (Filename.basename path ^ ": File migrated successfully")) + | Ok (contents, _) -> ( + match outputMode with + | `Stdout -> Ok contents + | `File -> Ok (Filename.basename path ^ ": File did not need migration")) diff --git a/tools/src/migrate.mli b/tools/src/migrate.mli new file mode 100644 index 0000000000..1831a90b30 --- /dev/null +++ b/tools/src/migrate.mli @@ -0,0 +1,4 @@ +val migrate : + entryPointFile:string -> + outputMode:[`File | `Stdout] -> + (string, string) result diff --git a/tools/src/tools.ml b/tools/src/tools.ml index aafdaba331..eb591aa912 100644 --- a/tools/src/tools.ml +++ b/tools/src/tools.ml @@ -1293,590 +1293,4 @@ module ExtractCodeblocks = struct |> Protocol.array) end -module StringMap = Map.Make (String) - -module Migrate = struct - (* - Currently, the migrate command can handle: - - Function calls, including mapping labelled/optional arguments between calls. Piped and not piped. - - It _cannot_ (among much else) handle: - - Changing position of unlabelled arguments (would be problematic with pipes etc) - *) - - (* - TODO: - - Migrate type usage (Js.Array2.t -> array, etc) - - Add "migratePipe" for specific migrations of pipe calls, like `BigInt.land` that can be `&` when not piped, but needs to be `BigInt.bitwiseAnd` when piped. - *) - - module MapperUtils = struct - let get_template_args_to_insert ?(is_pipe = false) mapper template_args - source_args = - let labelled_args_that_will_be_mapped = ref [] in - let unlabelled_positions_that_will_be_mapped = ref [] in - let mapped_template_args = - template_args - |> List.filter_map (fun (label, arg) -> - match (label, arg) with - | ( Asttypes.Nolabel, - { - Parsetree.pexp_desc = - Pexp_extension - ( {txt = "insert.labelledArgument"}, - PStr - [ - { - pstr_desc = - Pstr_eval - ( { - pexp_desc = - Pexp_constant - (Pconst_string (arg_name, _)); - }, - _ ); - }; - ] ); - } ) -> ( - (* Map labelled args *) - let arg_in_source_args = - source_args - |> List.find_map (fun (label, arg) -> - match label with - | Asttypes.Labelled {txt = label} - | Optional {txt = label} -> - if label = arg_name then Some arg else None - | _ -> None) - in - match arg_in_source_args with - | None -> None - | Some arg -> - labelled_args_that_will_be_mapped := - arg_name :: !labelled_args_that_will_be_mapped; - Some (Asttypes.Nolabel, arg)) - | ( template_label, - { - Parsetree.pexp_desc = - Pexp_extension - ( {txt = "insert.unlabelledArgument"}, - PStr - [ - { - pstr_desc = - Pstr_eval - ( { - pexp_desc = - Pexp_constant - (Pconst_integer (count_str, _)); - }, - _ ); - }; - ] ); - } ) -> ( - (* Map unlabelled args *) - let count = int_of_string count_str in - if count <= 0 then None - else - (* Count unlabelled arguments properly: - - For regular calls: count=1 refers to 2nd unlabelled arg (since 1st can't be remapped due to pipes) - - For pipe calls: count=1 refers to 1st unlabelled arg in pipe_args *) - let target_count = if is_pipe then count else count + 1 in - let unlabelled_count = ref 0 in - let found_arg = ref None in - source_args - |> List.iter (fun (label, arg) -> - match label with - | Asttypes.Nolabel -> - incr unlabelled_count; - if !unlabelled_count = target_count then - found_arg := Some arg - | _ -> ()); - match !found_arg with - | None -> None - | Some arg -> - unlabelled_positions_that_will_be_mapped := - target_count :: !unlabelled_positions_that_will_be_mapped; - Some (template_label, arg)) - | ( _, - { - pexp_desc = - Pexp_extension - ( { - txt = - ( "insert.labelledArgument" - | "insert.unlabelledArgument" ); - }, - _ ); - } ) -> - (* Do not add any other instance of insert.* *) - None - | _, {pexp_desc = Pexp_construct ({txt = Lident "()"}, None)} -> - None - | _ -> Some (label, mapper.Ast_mapper.expr mapper arg)) - in - ( mapped_template_args, - !labelled_args_that_will_be_mapped, - !unlabelled_positions_that_will_be_mapped ) - - let filter_and_transform_args source_args ~unlabelled_positions_to_insert - ~will_be_mapped ~labelled_args_map = - let unlabelled_consumed = ref 0 in - source_args - |> List.filter_map (fun (label, arg) -> - match label with - | Asttypes.Nolabel -> - incr unlabelled_consumed; - if List.mem !unlabelled_consumed unlabelled_positions_to_insert - then - (* This unlabelled arg has been mapped already, do not add. *) - None - else Some (label, arg) - | Asttypes.Labelled {loc; txt = label} - | Optional {loc; txt = label} - when StringMap.mem label labelled_args_map -> - (* Map labelled args that has just changed name. *) - let mapped_label_name = StringMap.find label labelled_args_map in - Some (Asttypes.Labelled {loc; txt = mapped_label_name}, arg) - | (Labelled {txt} | Optional {txt}) - when List.mem txt will_be_mapped -> - (* These have been mapped already, do not add. *) - None - | label -> Some (label, arg)) - - let build_labelled_args_map template_args = - template_args - |> List.filter_map (fun (label, arg) -> - match (label, arg) with - | ( (Asttypes.Labelled {txt = label} | Optional {txt = label}), - { - Parsetree.pexp_desc = - Pexp_extension - ( {txt = "insert.labelledArgument"}, - PStr - [ - { - pstr_desc = - Pstr_eval - ( { - pexp_desc = - Pexp_constant - (Pconst_string (arg_name, _)); - }, - _ ); - }; - ] ); - } ) -> - Some (arg_name, label) - | _ -> None) - |> List.fold_left - (fun map (k, v) -> StringMap.add k v map) - StringMap.empty - - let apply_migration_template ?(is_pipe = false) mapper template_args - source_args = - let labelled_args_map = build_labelled_args_map template_args in - let ( template_args_to_insert, - will_be_mapped, - unlabelled_positions_to_insert ) = - get_template_args_to_insert ~is_pipe mapper template_args source_args - in - let filtered_args = - filter_and_transform_args source_args ~unlabelled_positions_to_insert - ~will_be_mapped ~labelled_args_map - in - filtered_args @ template_args_to_insert - end - - (* Finds a specific argument in a list of arguments. *) - let find_arg args (find_this_arg : [`Labelled of string | `Unlabelled of int]) - = - let unlabelled_count = ref 0 in - args - |> List.find_map (fun (lbl, arg) -> - match (find_this_arg, lbl) with - | ( `Labelled arg_name, - (Asttypes.Labelled {txt = label} | Optional {txt = label}) ) - when label = arg_name -> - Some (lbl, arg) - | `Unlabelled count, Nolabel -> - let current_count = !unlabelled_count in - incr unlabelled_count; - if current_count = count then Some (lbl, arg) else None - | _, Nolabel -> - incr unlabelled_count; - None - | _ -> None) - - let replace_from_args_in_expr expr source_args = - let mapper = - { - Ast_mapper.default_mapper with - expr = - (fun mapper exp -> - match exp with - | { - pexp_desc = - Pexp_extension - ( {txt = "insert.labelledArgument"}, - PStr - [ - { - pstr_desc = - Pstr_eval - ( { - pexp_desc = - Pexp_constant (Pconst_string (arg_name, _)); - }, - _ ); - }; - ] ); - } -> ( - match find_arg source_args (`Labelled arg_name) with - | Some (_, arg) -> arg - | None -> exp) - | { - pexp_desc = - Pexp_extension - ( {txt = "insert.unlabelledArgument"}, - PStr - [ - { - pstr_desc = - Pstr_eval - ( { - pexp_desc = - Pexp_constant (Pconst_integer (count_str, _)); - }, - _ ); - }; - ] ); - } -> ( - match - find_arg source_args (`Unlabelled (int_of_string count_str)) - with - | Some (_, arg) -> arg - | None -> exp) - | _ -> Ast_mapper.default_mapper.expr mapper exp); - } - in - mapper.expr mapper expr - - let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = - (* Function calls *) - let deprecated_function_calls = - deprecated_used - |> List.filter (fun (d : Cmt_utils.deprecated_used) -> - match d.context with - | Some FunctionCall -> true - | _ -> false) - in - let loc_to_deprecated_fn_call = - Hashtbl.create (List.length deprecated_function_calls) - in - deprecated_function_calls - |> List.iter (fun ({Cmt_utils.source_loc} as d) -> - Hashtbl.replace loc_to_deprecated_fn_call source_loc d); - - (* References *) - let deprecated_references = - deprecated_used - |> List.filter (fun (d : Cmt_utils.deprecated_used) -> - match d.context with - | Some Reference -> true - | _ -> false) - in - let loc_to_deprecated_reference = - Hashtbl.create (List.length deprecated_references) - in - deprecated_references - |> List.iter (fun ({Cmt_utils.source_loc} as d) -> - Hashtbl.replace loc_to_deprecated_reference source_loc d); - - let mapper = - { - Ast_mapper.default_mapper with - extension = - (fun mapper ext -> - (* Map back %todo_ to %todo, since using %todo directly would result in errors where we don't want them. *) - match ext with - | ({txt = "todo_"} as e), payload -> - Ast_mapper.default_mapper.extension mapper - ({e with txt = "todo"}, payload) - | e -> Ast_mapper.default_mapper.extension mapper e); - expr = - (fun mapper exp -> - match exp with - | {pexp_desc = Pexp_ident {loc}} - when Hashtbl.mem loc_to_deprecated_reference loc -> ( - (* Map references to their migration template. *) - let deprecated_info = - Hashtbl.find loc_to_deprecated_reference loc - in - Hashtbl.remove loc_to_deprecated_reference loc; - match deprecated_info.migration_template with - | None -> exp - | Some e -> e) - | { - pexp_desc = - Pexp_apply {funct = {pexp_loc = fn_loc}; args = source_args}; - } - when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( - let deprecated_info = - Hashtbl.find loc_to_deprecated_fn_call fn_loc - in - Hashtbl.remove loc_to_deprecated_fn_call fn_loc; - - let source_args = - source_args - |> List.map (fun (label, arg) -> - (label, mapper.expr mapper arg)) - in - - (* TODO: Here we could add strict and partial mode, to control if args are merged or not. *) - match deprecated_info.migration_template with - | Some {pexp_desc = Pexp_match (e, cases)} -> - { - exp with - pexp_desc = - Pexp_match (replace_from_args_in_expr e source_args, cases); - } - | Some - { - pexp_desc = - Pexp_apply - { - funct = template_funct; - args = template_args; - partial; - transformed_jsx; - }; - } -> - let migrated_args = - MapperUtils.apply_migration_template mapper template_args - source_args - in - { - exp with - pexp_desc = - Pexp_apply - { - funct = template_funct; - args = migrated_args; - partial; - transformed_jsx; - }; - } - | _ -> - (* TODO: More elaborate warnings etc *) - (* Invalid config. *) - exp) - | { - pexp_desc = - Pexp_apply - { - funct = {pexp_desc = Pexp_ident {txt = Lident "->"}} as funct; - args = - (_ as lhs) - :: (Nolabel, {pexp_loc = fn_loc; pexp_desc = Pexp_ident _}) - :: _; - }; - } - when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( - (* Pipe with no arguments, [1, 2, 3]->someDeprecated - This is the only pipe we need to handle, because the argument one is handled by the transform above. *) - let deprecated_info = - Hashtbl.find loc_to_deprecated_fn_call fn_loc - in - Hashtbl.remove loc_to_deprecated_fn_call fn_loc; - - let migration_template_to_use = - match deprecated_info.migration_piped_template with - | Some template -> Some template - | None -> deprecated_info.migration_template - in - match migration_template_to_use with - | Some {pexp_desc = Pexp_match (e, cases)} -> - { - exp with - pexp_desc = - Pexp_match (replace_from_args_in_expr e [lhs], cases); - } - | Some - { - pexp_desc = - Pexp_apply - { - funct = template_funct; - args = template_args; - partial; - transformed_jsx; - }; - } -> - let template_args_to_insert, _, _ = - MapperUtils.get_template_args_to_insert mapper template_args - [] - in - if Ext_list.is_empty template_args_to_insert then - { - exp with - pexp_desc = - Pexp_apply - { - funct; - args = [lhs; (Nolabel, template_funct)]; - partial; - transformed_jsx; - }; - } - else - { - exp with - pexp_desc = - Pexp_apply - { - funct; - args = - [ - lhs; - ( Nolabel, - Ast_helper.Exp.apply template_funct - template_args_to_insert ); - ]; - partial; - transformed_jsx; - }; - } - | _ -> - (* TODO: More elaborate warnings etc *) - (* Invalid config. *) - exp) - | { - pexp_desc = - Pexp_apply - { - funct = {pexp_desc = Pexp_ident {txt = Lident "->"}} as funct; - args = - (_ as lhs) - :: ( Nolabel, - { - pexp_desc = - Pexp_apply - {funct = {pexp_loc = fn_loc}; args = pipe_args}; - } ) - :: _; - }; - } - when Hashtbl.mem loc_to_deprecated_fn_call fn_loc -> ( - (* Pipe with arguments, [1, 2, 3, 4]->someDeprecated(arg1, arg2) *) - let deprecated_info = - Hashtbl.find loc_to_deprecated_fn_call fn_loc - in - Hashtbl.remove loc_to_deprecated_fn_call fn_loc; - - let migration_template_to_use = - match deprecated_info.migration_piped_template with - | Some template -> Some template - | None -> deprecated_info.migration_template - in - match migration_template_to_use with - | Some - { - pexp_desc = - Pexp_apply - { - funct = template_funct; - args = template_args; - partial; - transformed_jsx; - }; - } -> - let migrated_args = - MapperUtils.apply_migration_template ~is_pipe:true mapper - template_args pipe_args - in - { - exp with - pexp_desc = - Pexp_apply - { - funct; - args = - [ - lhs; - ( Nolabel, - Ast_helper.Exp.apply template_funct migrated_args - ); - ]; - partial; - transformed_jsx; - }; - } - | _ -> - (* TODO: More elaborate warnings etc *) - (* Invalid config. *) - exp) - | _ -> Ast_mapper.default_mapper.expr mapper exp); - } - in - mapper - - let migrate ~entryPointFile ~outputMode = - let path = - match Filename.is_relative entryPointFile with - | true -> Unix.realpath entryPointFile - | false -> entryPointFile - in - let result = - if Filename.check_suffix path ".res" then - let parser = - Res_driver.parsing_engine.parse_implementation ~for_printer:true - in - let {Res_driver.parsetree; comments; source} = parser ~filename:path in - match Cmt.loadCmtInfosFromPath ~path with - | None -> - Error - (Printf.sprintf - "error: failed to run migration for %s because build artifacts \ - could not be found. try to build the project" - path) - | Some {cmt_extra_info = {deprecated_used}} -> - let mapper = makeMapper deprecated_used in - let astMapped = mapper.structure mapper parsetree in - Ok - ( Res_printer.print_implementation - ~width:Res_printer.default_print_width astMapped ~comments, - source ) - else if Filename.check_suffix path ".resi" then - let parser = - Res_driver.parsing_engine.parse_interface ~for_printer:true - in - let {Res_driver.parsetree = signature; comments; source} = - parser ~filename:path - in - let mapper = makeMapper [] in - let astMapped = mapper.signature mapper signature in - Ok - ( Res_printer.print_interface ~width:Res_printer.default_print_width - astMapped ~comments, - source ) - else - Error - (Printf.sprintf - "File extension not supported. This command accepts .res, .resi \ - files") - in - match result with - | Error e -> Error e - | Ok (contents, source) when contents <> source -> ( - match outputMode with - | `Stdout -> Ok contents - | `File -> - let oc = open_out path in - Printf.fprintf oc "%s" contents; - close_out oc; - Ok (Filename.basename path ^ ": File migrated successfully")) - | Ok (contents, _) -> ( - match outputMode with - | `Stdout -> Ok contents - | `File -> Ok (Filename.basename path ^ ": File did not need migration")) -end +module Migrate = Migrate From c994f7bd9d40853394fba2c558836c238c1fc8b5 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 25 Aug 2025 13:45:17 +0200 Subject: [PATCH 03/41] pipe chain example --- .../src/expected/StdlibMigration_Array.res.expected | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Array.res | 6 ++++++ .../src/migrate/migrated/Migrated_StdlibMigration_Array.res | 3 +++ 3 files changed, 12 insertions(+) diff --git a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected index 4f18613d4e..1f28e32781 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected @@ -167,3 +167,6 @@ let reduceRight2 = Array.reduceRight([1, 2, 3], 0, (acc, x) => acc + x) let reduceRighti1 = [1, 2, 3]->Array.reduceRightWithIndex(0, (acc, x, i) => acc + x + i) let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) +let pipeChain = + [1, 2, 3]->Array.map(x => x * 2)->Array.filter(x => x > 2)->Array.reduce(0, (acc, x) => acc + x) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Array.res b/tests/tools_tests/src/migrate/StdlibMigration_Array.res index cf8e65a744..f2ce25c807 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Array.res @@ -167,3 +167,9 @@ let reduceRight2 = Js.Array2.reduceRight([1, 2, 3], (acc, x) => acc + x, 0) let reduceRighti1 = [1, 2, 3]->Js.Array2.reduceRighti((acc, x, i) => acc + x + i, 0) let reduceRighti2 = Js.Array2.reduceRighti([1, 2, 3], (acc, x, i) => acc + x + i, 0) + +let pipeChain = + [1, 2, 3] + ->Js.Array2.map(x => x * 2) + ->Js.Array2.filter(x => x > 2) + ->Js.Array2.reduce((acc, x) => acc + x, 0) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res index 52a6757808..4b6ce8e861 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res @@ -168,3 +168,6 @@ let reduceRight2 = Array.reduceRight([1, 2, 3], 0, (acc, x) => acc + x) let reduceRighti1 = [1, 2, 3]->Array.reduceRightWithIndex(0, (acc, x, i) => acc + x + i) let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc + x + i) + +let pipeChain = + [1, 2, 3]->Array.map(x => x * 2)->Array.filter(x => x > 2)->Array.reduce(0, (acc, x) => acc + x) From a6e3af7e7cde6033e20fecd1f6ae5a01b16ef76d Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 13:27:37 +0200 Subject: [PATCH 04/41] migrations for Js_option --- packages/@rescript/runtime/Js_option.resi | 74 ++++++++++++++++++- .../StdlibMigration_Option.res.expected | 31 ++++++++ .../src/migrate/StdlibMigration_Option.res | 30 ++++++++ .../Migrated_StdlibMigration_Option.res | 32 ++++++++ 4 files changed, 166 insertions(+), 1 deletion(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Option.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Option.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res diff --git a/packages/@rescript/runtime/Js_option.resi b/packages/@rescript/runtime/Js_option.resi index 8a5f6f01e3..3aebd75c00 100644 --- a/packages/@rescript/runtime/Js_option.resi +++ b/packages/@rescript/runtime/Js_option.resi @@ -24,27 +24,99 @@ type t<'a> = option<'a> +@deprecated({ + reason: "Use `Some()` directly instead.", + migrate: Some(), +}) let some: 'a => option<'a> +@deprecated({ + reason: "Use `Option.isSome` instead.", + migrate: Option.isSome(), +}) let isSome: option<'a> => bool +// Skipping automatic migration because this is a rather weird function that is probably not that much used. +@deprecated("Use `Option.equal` instead.") let isSomeValue: (('a, 'a) => bool, 'a, option<'a>) => bool +@deprecated({ + reason: "Use `Option.isNone` instead.", + migrate: Option.isNone(), +}) let isNone: option<'a> => bool +@deprecated({ + reason: "Use `Option.getOrThrow` instead.", + migrate: Option.getOrThrow(), +}) let getExn: option<'a> => 'a +@deprecated({ + reason: "Use `Option.equal` instead.", + migrate: Option.equal( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(2), + %insert.unlabelledArgument(0), + ), + +}) let equal: (('a, 'b) => bool, option<'a>, option<'b>) => bool +@deprecated({ + reason: "Use `Option.flatMap` instead.", + migrate: Option.flatMap( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(0), + ), + migratePiped: Option.flatMap(%insert.unlabelledArgument(0)), +}) let andThen: ('a => option<'b>, option<'a>) => option<'b> +@deprecated({ + reason: "Use `Option.map` instead.", + migrate: Option.map( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(0), + ), + migratePiped: Option.map(%insert.unlabelledArgument(0)), +}) let map: ('a => 'b, option<'a>) => option<'b> +@deprecated({ + reason: "Use `Option.getOr` instead.", + migrate: Option.getOr( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(0), + ), + migratePiped: Option.getOr(%insert.unlabelledArgument(0)), +}) let getWithDefault: ('a, option<'a>) => 'a -@deprecated("Use `getWithDefault` instead since default has special meaning in ES module") +@deprecated({ + reason: + "Use `Option.getOr` instead. Note: `default` has special meaning in ES modules.", + migrate: Option.getOr( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(0), + ), + migratePiped: Option.getOr(%insert.unlabelledArgument(0)), +}) let default: ('a, option<'a>) => 'a +@deprecated({ + reason: "Use `Option.filter` instead.", + migrate: Option.filter( + %insert.unlabelledArgument(1), + %insert.unlabelledArgument(0), + ), + migratePiped: Option.filter(%insert.unlabelledArgument(0)), +}) let filter: ('a => bool, option<'a>) => option<'a> +@deprecated({ + reason: "Use `Option.orElse` instead.", + migrate: Option.orElse(), + migratePiped: Option.orElse(%insert.unlabelledArgument(0)), +}) let firstSome: (option<'a>, option<'a>) => option<'a> diff --git a/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected new file mode 100644 index 0000000000..91f561a0c7 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected @@ -0,0 +1,31 @@ +let someCall = Js.Option.some(3) +let somePiped = 3->Js.Option.some + +let isSome1 = Some(1)->Option.isSome +let isSome2 = Option.isSome(None) + +let isNone1 = None->Option.isNone +let isNone2 = Option.isNone(Some(2)) + +let eq = (a: int, b: int) => a == b +// let isSomeValue1 = Js.Option.isSomeValue(eq, 2, Some(2)) + +let getExn1 = Option.getOrThrow(Some(3)) +let getExn2 = Some(3)->Option.getOrThrow + +let equal1 = Option.equal(Some(2), Some(2), eq) + +let f = (x: int) => x > 0 ? Some(x + 1) : None +let andThen1 = Option.flatMap(Some(2), f) + +let map1 = Option.map(Some(2), x => x * 2) + +let getWithDefault1 = Option.getOr(Some(2), 0) + +let default1 = Option.getOr(Some(2), 0) + +let filter1 = Option.filter(Some(1), x => x > 0) + +let firstSome1 = Option.orElse(Some(1), None) +let firstSome2 = Option.orElse(Some(1), None) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Option.res b/tests/tools_tests/src/migrate/StdlibMigration_Option.res new file mode 100644 index 0000000000..4c60e251dd --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Option.res @@ -0,0 +1,30 @@ +let someCall = Js.Option.some(3) +let somePiped = 3->Js.Option.some + +let isSome1 = Some(1)->Js.Option.isSome +let isSome2 = Js.Option.isSome(None) + +let isNone1 = None->Js.Option.isNone +let isNone2 = Js.Option.isNone(Some(2)) + +let eq = (a: int, b: int) => a == b +// let isSomeValue1 = Js.Option.isSomeValue(eq, 2, Some(2)) + +let getExn1 = Js.Option.getExn(Some(3)) +let getExn2 = Some(3)->Js.Option.getExn + +let equal1 = Js.Option.equal(eq, Some(2), Some(2)) + +let f = (x: int) => x > 0 ? Some(x + 1) : None +let andThen1 = Js.Option.andThen(f, Some(2)) + +let map1 = Js.Option.map(x => x * 2, Some(2)) + +let getWithDefault1 = Js.Option.getWithDefault(0, Some(2)) + +let default1 = Js.Option.default(0, Some(2)) + +let filter1 = Js.Option.filter(x => x > 0, Some(1)) + +let firstSome1 = Js.Option.firstSome(Some(1), None) +let firstSome2 = Some(1)->Js.Option.firstSome(None) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res new file mode 100644 index 0000000000..bacd4299b1 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res @@ -0,0 +1,32 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Option.res. +let someCall = Js.Option.some(3) +let somePiped = 3->Js.Option.some + +let isSome1 = Some(1)->Option.isSome +let isSome2 = Option.isSome(None) + +let isNone1 = None->Option.isNone +let isNone2 = Option.isNone(Some(2)) + +let eq = (a: int, b: int) => a == b +// let isSomeValue1 = Js.Option.isSomeValue(eq, 2, Some(2)) + +let getExn1 = Option.getOrThrow(Some(3)) +let getExn2 = Some(3)->Option.getOrThrow + +let equal1 = Option.equal(Some(2), Some(2), eq) + +let f = (x: int) => x > 0 ? Some(x + 1) : None +let andThen1 = Option.flatMap(Some(2), f) + +let map1 = Option.map(Some(2), x => x * 2) + +let getWithDefault1 = Option.getOr(Some(2), 0) + +let default1 = Option.getOr(Some(2), 0) + +let filter1 = Option.filter(Some(1), x => x > 0) + +let firstSome1 = Option.orElse(Some(1), None) +let firstSome2 = Option.orElse(Some(1), None) From 89d301564f7bee71c6d37ae36c8e533c1cb58c9c Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 13:55:47 +0200 Subject: [PATCH 05/41] migrations for Js_null --- packages/@rescript/runtime/Js_null.resi | 51 +++++++++++++++++-- .../StdlibMigration_Null.res.expected | 33 ++++++++++++ .../src/migrate/StdlibMigration_Null.res | 32 ++++++++++++ .../Migrated_StdlibMigration_Null.res | 34 +++++++++++++ 4 files changed, 147 insertions(+), 3 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Null.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Null.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res diff --git a/packages/@rescript/runtime/Js_null.resi b/packages/@rescript/runtime/Js_null.resi index 7d97c19237..57eef83d6b 100644 --- a/packages/@rescript/runtime/Js_null.resi +++ b/packages/@rescript/runtime/Js_null.resi @@ -28,16 +28,37 @@ type t<+'a> = Primitive_js_extern.null<'a> = Value('a) | @as(null) Null /** Constructs a value of `Js.null<'a>` containing a value of `'a`. */ +@deprecated({ + reason: "Use `Null.make` instead.", + migrate: Null.make(), +}) external return: 'a => t<'a> = "%identity" /** Returns `true` if the given value is empty (`null`), `false` otherwise. */ -@deprecated("Use = Js.null directly ") +@deprecated({ + reason: "Use `== Js.null` directly.", + migrate: %insert.unlabelledArgument(0) === Null.null, + migratePiped: Null.equal(Null, (a, b) => a === b), +}) let test: t<'a> => bool /** The empty value, `null` */ +@deprecated({ + reason: "Use `Null.null` instead.", + migrate: Null.null, +}) external empty: t<'a> = "%null" +@deprecated({ + reason: "Use `Null.getUnsafe` instead.", + migrate: Null.getUnsafe(), +}) external getUnsafe: t<'a> => 'a = "%identity" + +@deprecated({ + reason: "Use `Null.getOrThrow` instead.", + migrate: Null.getOrThrow(), +}) let getExn: t<'a> => 'a /** @@ -54,6 +75,10 @@ let maybeGreetWorld = (maybeGreeting: Js.null) => Js.Null.bind(maybeGreeting, greeting => greeting ++ " world!") ``` */ +@deprecated({ + reason: "Use `Null.map` instead.", + migrate: Null.map(), +}) let bind: (t<'a>, 'a => 'b) => t<'b> /** @@ -67,6 +92,10 @@ let maybeSay = (maybeMessage: Js.null) => Js.Null.iter(maybeMessage, message => Js.log(message)) ``` */ +@deprecated({ + reason: "Use `Null.forEach` instead.", + migrate: Null.forEach(), +}) let iter: (t<'a>, 'a => unit) => unit /** @@ -74,15 +103,31 @@ Maps `option<'a>` to `Js.null<'a>`. `Some(a)` => `a` `None` => `empty` */ +@deprecated({ + reason: "Use `Null.fromOption` instead.", + migrate: Null.fromOption(), +}) let fromOption: option<'a> => t<'a> -@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> +@deprecated({ + reason: "Use `Null.fromOption` instead.", + migrate: Null.fromOption(), +}) +let from_opt: option<'a> => t<'a> /** Maps `Js.null<'a>` to `option<'a>`. `a` => `Some(a)` `empty` => `None` */ +@deprecated({ + reason: "Use `Null.toOption` instead.", + migrate: Null.toOption(), +}) external toOption: t<'a> => option<'a> = "%null_to_opt" -@deprecated("Use toOption instead") external to_opt: t<'a> => option<'a> = "%null_to_opt" +@deprecated({ + reason: "Use `Null.toOption` instead.", + migrate: Null.toOption(), +}) +external to_opt: t<'a> => option<'a> = "%null_to_opt" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected new file mode 100644 index 0000000000..14a42abc06 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected @@ -0,0 +1,33 @@ +let make1 = "hello"->Null.make +let make2 = Null.make("hello") + +let empty1 = Null.null + +let getUnsafe1 = Null.make(1)->Null.getUnsafe +let getUnsafe2 = Null.getUnsafe(Null.make(1)) + +let getExn1 = Null.make(1)->Null.getOrThrow +let getExn2 = Null.getOrThrow(Null.make(1)) + +let map1 = Null.make(2)->Null.map(x => x + 1) +let map2 = Null.map(Null.make(2), x => x + 1) + +let forEach1 = Null.make(2)->Null.forEach(x => ignore(x)) +let forEach2 = Null.forEach(Null.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Null.fromOption +let fromOption2 = Null.fromOption(None) + +let from_opt1 = Some("y")->Null.fromOption +let from_opt2 = Null.fromOption(None) + +let toOption1 = Null.make(3)->Null.toOption +let toOption2 = Null.toOption(Null.make(3)) + +let to_opt1 = Null.make(4)->Null.toOption +let to_opt2 = Null.toOption(Null.make(4)) + +let test1 = Null.null === Null.null +let test2 = Null.null === Null.null +let test3 = Null.make(5)->Null.map(v => v)->Null.equal(Null, (a, b) => a === b) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Null.res b/tests/tools_tests/src/migrate/StdlibMigration_Null.res new file mode 100644 index 0000000000..e0081a11be --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Null.res @@ -0,0 +1,32 @@ +let make1 = "hello"->Js.Null.return +let make2 = Js.Null.return("hello") + +let empty1 = Js.Null.empty + +let getUnsafe1 = Js.Null.return(1)->Js.Null.getUnsafe +let getUnsafe2 = Js.Null.getUnsafe(Js.Null.return(1)) + +let getExn1 = Js.Null.return(1)->Js.Null.getExn +let getExn2 = Js.Null.getExn(Js.Null.return(1)) + +let map1 = Js.Null.return(2)->Js.Null.bind(x => x + 1) +let map2 = Js.Null.bind(Js.Null.return(2), x => x + 1) + +let forEach1 = Js.Null.return(2)->Js.Null.iter(x => ignore(x)) +let forEach2 = Js.Null.iter(Js.Null.return(2), x => ignore(x)) + +let fromOption1 = Some("x")->Js.Null.fromOption +let fromOption2 = Js.Null.fromOption(None) + +let from_opt1 = Some("y")->Js.Null.from_opt +let from_opt2 = Js.Null.from_opt(None) + +let toOption1 = Js.Null.return(3)->Js.Null.toOption +let toOption2 = Js.Null.toOption(Js.Null.return(3)) + +let to_opt1 = Js.Null.return(4)->Js.Null.to_opt +let to_opt2 = Js.Null.to_opt(Js.Null.return(4)) + +let test1 = Js.Null.empty->Js.Null.test +let test2 = Js.Null.test(Js.Null.empty) +let test3 = Js.Null.return(5)->Js.Null.bind(v => v)->Js.Null.test diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res new file mode 100644 index 0000000000..d418565f7b --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res @@ -0,0 +1,34 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Null.res. +let make1 = "hello"->Null.make +let make2 = Null.make("hello") + +let empty1 = Null.null + +let getUnsafe1 = Null.make(1)->Null.getUnsafe +let getUnsafe2 = Null.getUnsafe(Null.make(1)) + +let getExn1 = Null.make(1)->Null.getOrThrow +let getExn2 = Null.getOrThrow(Null.make(1)) + +let map1 = Null.make(2)->Null.map(x => x + 1) +let map2 = Null.map(Null.make(2), x => x + 1) + +let forEach1 = Null.make(2)->Null.forEach(x => ignore(x)) +let forEach2 = Null.forEach(Null.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Null.fromOption +let fromOption2 = Null.fromOption(None) + +let from_opt1 = Some("y")->Null.fromOption +let from_opt2 = Null.fromOption(None) + +let toOption1 = Null.make(3)->Null.toOption +let toOption2 = Null.toOption(Null.make(3)) + +let to_opt1 = Null.make(4)->Null.toOption +let to_opt2 = Null.toOption(Null.make(4)) + +let test1 = Null.null === Null.null +let test2 = Null.null === Null.null +let test3 = Null.make(5)->Null.map(v => v)->Null.equal(Null, (a, b) => a === b) From abfbdc70e6f0576107a45115c7b3ecd2e2e901f8 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 13:59:46 +0200 Subject: [PATCH 06/41] rename migration template for pipe chains --- compiler/ml/builtin_attributes.ml | 16 +++++++++------- compiler/ml/cmt_format.ml | 4 ++-- compiler/ml/cmt_format.mli | 2 +- compiler/ml/cmt_utils.ml | 13 +++++++++---- packages/@rescript/runtime/Js_bigint.res | 10 +++++----- packages/@rescript/runtime/Js_null.resi | 2 +- packages/@rescript/runtime/Js_option.resi | 12 ++++++------ packages/@rescript/runtime/Stdlib_BigInt.resi | 10 +++++----- .../src/expected/PipeAndRecursive.res.expected | 4 ++-- .../tools_tests/src/migrate/PipeAndRecursive.res | 4 ++-- tools/src/migrate.ml | 8 ++++---- 11 files changed, 46 insertions(+), 39 deletions(-) diff --git a/compiler/ml/builtin_attributes.ml b/compiler/ml/builtin_attributes.ml index 8dea16c662..4243659e63 100644 --- a/compiler/ml/builtin_attributes.ml +++ b/compiler/ml/builtin_attributes.ml @@ -104,21 +104,22 @@ let rec deprecated_of_attrs_with_migrate = function Some migration_template | _ -> None) in - let migration_piped_template = + let migration_in_pipe_chain_template = fields |> List.find_map (fun field -> match field with | { - lid = {txt = Lident "migratePiped"}; - x = migration_piped_template; + lid = {txt = Lident "migrateInPipeChain"}; + x = migration_in_pipe_chain_template; } -> - Some migration_piped_template + Some migration_in_pipe_chain_template | _ -> None) in (* TODO: Validate and error if expected shape mismatches *) match reason with - | Some reason -> Some (reason, migration_template, migration_piped_template) + | Some reason -> + Some (reason, migration_template, migration_in_pipe_chain_template) | None -> None) | ({txt = "ocaml.deprecated" | "deprecated"; _}, p) :: _ -> Some (string_of_opt_payload p, None, None) @@ -127,9 +128,10 @@ let rec deprecated_of_attrs_with_migrate = function let check_deprecated ?deprecated_context loc attrs s = match deprecated_of_attrs_with_migrate attrs with | None -> () - | Some (txt, migration_template, migration_piped_template) -> + | Some (txt, migration_template, migration_in_pipe_chain_template) -> !Cmt_utils.record_deprecated_used - ?deprecated_context ?migration_template ?migration_piped_template loc txt; + ?deprecated_context ?migration_template ?migration_in_pipe_chain_template + loc txt; Location.deprecated loc (cat s txt) let check_deprecated_inclusion ~def ~use loc attrs1 attrs2 s = diff --git a/compiler/ml/cmt_format.ml b/compiler/ml/cmt_format.ml index 4b9fb2b054..864aba2016 100644 --- a/compiler/ml/cmt_format.ml +++ b/compiler/ml/cmt_format.ml @@ -166,8 +166,8 @@ let add_saved_type b = saved_types := b :: !saved_types let get_saved_types () = !saved_types let set_saved_types l = saved_types := l -let record_deprecated_used ?deprecated_context ?migration_template ?migration_piped_template source_loc deprecated_text = - deprecated_used := {Cmt_utils.source_loc; deprecated_text; migration_template; migration_piped_template; context = deprecated_context} :: !deprecated_used +let record_deprecated_used ?deprecated_context ?migration_template ?migration_in_pipe_chain_template source_loc deprecated_text = + deprecated_used := {Cmt_utils.source_loc; deprecated_text; migration_template; migration_in_pipe_chain_template; context = deprecated_context} :: !deprecated_used let _ = Cmt_utils.record_deprecated_used := record_deprecated_used diff --git a/compiler/ml/cmt_format.mli b/compiler/ml/cmt_format.mli index 620be12e50..66589f088d 100644 --- a/compiler/ml/cmt_format.mli +++ b/compiler/ml/cmt_format.mli @@ -115,7 +115,7 @@ val record_value_dependency : val record_deprecated_used : ?deprecated_context:Cmt_utils.deprecated_used_context -> ?migration_template:Parsetree.expression -> - ?migration_piped_template:Parsetree.expression -> + ?migration_in_pipe_chain_template:Parsetree.expression -> Location.t -> string -> unit diff --git a/compiler/ml/cmt_utils.ml b/compiler/ml/cmt_utils.ml index f06a268427..3e08cd93b4 100644 --- a/compiler/ml/cmt_utils.ml +++ b/compiler/ml/cmt_utils.ml @@ -4,7 +4,7 @@ type deprecated_used = { source_loc: Location.t; deprecated_text: string; migration_template: Parsetree.expression option; - migration_piped_template: Parsetree.expression option; + migration_in_pipe_chain_template: Parsetree.expression option; context: deprecated_used_context option; } @@ -13,14 +13,19 @@ type cmt_extra_info = {deprecated_used: deprecated_used list} let record_deprecated_used : (?deprecated_context:deprecated_used_context -> ?migration_template:Parsetree.expression -> - ?migration_piped_template:Parsetree.expression -> + ?migration_in_pipe_chain_template:Parsetree.expression -> Location.t -> string -> unit) ref = ref (fun - ?deprecated_context ?migration_template ?migration_piped_template _ _ -> + ?deprecated_context + ?migration_template + ?migration_in_pipe_chain_template + _ + _ + -> ignore deprecated_context; ignore migration_template; - ignore migration_piped_template) + ignore migration_in_pipe_chain_template) diff --git a/packages/@rescript/runtime/Js_bigint.res b/packages/@rescript/runtime/Js_bigint.res index 4695f8128b..0a28b8307f 100644 --- a/packages/@rescript/runtime/Js_bigint.res +++ b/packages/@rescript/runtime/Js_bigint.res @@ -51,7 +51,7 @@ external \"**": (bigint, bigint) => bigint = "%powbigint" @deprecated({ reason: "Use `&` operator or `BigInt.bitwiseAnd` instead.", migrate: %insert.unlabelledArgument(0) & %insert.unlabelledArgument(1), - migratePiped: BigInt.bitwiseAnd(), + migrateInPipeChain: BigInt.bitwiseAnd(), }) external land: (bigint, bigint) => bigint = "%andbigint" @@ -64,28 +64,28 @@ external lor: (bigint, bigint) => bigint = "%orbigint" @deprecated({ reason: "Use `^` operator or `BigInt.bitwiseXor` instead.", migrate: %insert.unlabelledArgument(0) ^ %insert.unlabelledArgument(1), - migratePiped: BigInt.bitwiseXor(), + migrateInPipeChain: BigInt.bitwiseXor(), }) external lxor: (bigint, bigint) => bigint = "%xorbigint" @deprecated({ reason: "Use `~` operator or `BigInt.bitwiseNot` instead.", migrate: ~(%insert.unlabelledArgument(0)), - migratePiped: BigInt.bitwiseNot(), + migrateInPipeChain: BigInt.bitwiseNot(), }) let lnot = x => lxor(x, -1n) @deprecated({ reason: "Use `<<` operator or `BigInt.shiftLeft` instead.", migrate: %insert.unlabelledArgument(0) << %insert.unlabelledArgument(1), - migratePiped: BigInt.shiftLeft(), + migrateInPipeChain: BigInt.shiftLeft(), }) external lsl: (bigint, bigint) => bigint = "%lslbigint" @deprecated({ reason: "Use `>>` operator or `BigInt.shiftRight` instead.", migrate: %insert.unlabelledArgument(0) >> %insert.unlabelledArgument(1), - migratePiped: BigInt.shiftRight(), + migrateInPipeChain: BigInt.shiftRight(), }) external asr: (bigint, bigint) => bigint = "%asrbigint" diff --git a/packages/@rescript/runtime/Js_null.resi b/packages/@rescript/runtime/Js_null.resi index 57eef83d6b..a61a216174 100644 --- a/packages/@rescript/runtime/Js_null.resi +++ b/packages/@rescript/runtime/Js_null.resi @@ -38,7 +38,7 @@ external return: 'a => t<'a> = "%identity" @deprecated({ reason: "Use `== Js.null` directly.", migrate: %insert.unlabelledArgument(0) === Null.null, - migratePiped: Null.equal(Null, (a, b) => a === b), + migrateInPipeChain: Null.equal(Null, (a, b) => a === b), }) let test: t<'a> => bool diff --git a/packages/@rescript/runtime/Js_option.resi b/packages/@rescript/runtime/Js_option.resi index 3aebd75c00..16a607e9f2 100644 --- a/packages/@rescript/runtime/Js_option.resi +++ b/packages/@rescript/runtime/Js_option.resi @@ -69,7 +69,7 @@ let equal: (('a, 'b) => bool, option<'a>, option<'b>) => bool %insert.unlabelledArgument(1), %insert.unlabelledArgument(0), ), - migratePiped: Option.flatMap(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.flatMap(%insert.unlabelledArgument(0)), }) let andThen: ('a => option<'b>, option<'a>) => option<'b> @@ -79,7 +79,7 @@ let andThen: ('a => option<'b>, option<'a>) => option<'b> %insert.unlabelledArgument(1), %insert.unlabelledArgument(0), ), - migratePiped: Option.map(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.map(%insert.unlabelledArgument(0)), }) let map: ('a => 'b, option<'a>) => option<'b> @@ -89,7 +89,7 @@ let map: ('a => 'b, option<'a>) => option<'b> %insert.unlabelledArgument(1), %insert.unlabelledArgument(0), ), - migratePiped: Option.getOr(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.getOr(%insert.unlabelledArgument(0)), }) let getWithDefault: ('a, option<'a>) => 'a @@ -100,7 +100,7 @@ let getWithDefault: ('a, option<'a>) => 'a %insert.unlabelledArgument(1), %insert.unlabelledArgument(0), ), - migratePiped: Option.getOr(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.getOr(%insert.unlabelledArgument(0)), }) let default: ('a, option<'a>) => 'a @@ -110,13 +110,13 @@ let default: ('a, option<'a>) => 'a %insert.unlabelledArgument(1), %insert.unlabelledArgument(0), ), - migratePiped: Option.filter(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.filter(%insert.unlabelledArgument(0)), }) let filter: ('a => bool, option<'a>) => option<'a> @deprecated({ reason: "Use `Option.orElse` instead.", migrate: Option.orElse(), - migratePiped: Option.orElse(%insert.unlabelledArgument(0)), + migrateInPipeChain: Option.orElse(%insert.unlabelledArgument(0)), }) let firstSome: (option<'a>, option<'a>) => option<'a> diff --git a/packages/@rescript/runtime/Stdlib_BigInt.resi b/packages/@rescript/runtime/Stdlib_BigInt.resi index 690307f96b..86c1ea9203 100644 --- a/packages/@rescript/runtime/Stdlib_BigInt.resi +++ b/packages/@rescript/runtime/Stdlib_BigInt.resi @@ -350,7 +350,7 @@ BigInt.land(7n, 4n) == 4n @deprecated({ reason: "Use `&` operator or `bitwiseAnd` instead.", migrate: %insert.unlabelledArgument(0) & %insert.unlabelledArgument(1), - migratePiped: BigInt.bitwiseAnd(), + migrateInPipeChain: BigInt.bitwiseAnd(), }) external land: (bigint, bigint) => bigint = "%andbigint" @@ -385,7 +385,7 @@ BigInt.lxor(7n, 4n) == 3n @deprecated({ reason: "Use `^` operator or `bitwiseXor` instead.", migrate: %insert.unlabelledArgument(0) ^ %insert.unlabelledArgument(1), - migratePiped: BigInt.bitwiseXor(), + migrateInPipeChain: BigInt.bitwiseXor(), }) external lxor: (bigint, bigint) => bigint = "%xorbigint" @@ -403,7 +403,7 @@ BigInt.lnot(2n) == -3n @deprecated({ reason: "Use `~` operator or `bitwiseNot` instead.", migrate: ~(%insert.unlabelledArgument(0)), - migratePiped: BigInt.bitwiseNot(), + migrateInPipeChain: BigInt.bitwiseNot(), }) external lnot: bigint => bigint = "%bitnot_bigint" @@ -421,7 +421,7 @@ BigInt.lsl(4n, 1n) == 8n @deprecated({ reason: "Use `<<` operator or `shiftLeft` instead.", migrate: %insert.unlabelledArgument(0) << %insert.unlabelledArgument(1), - migratePiped: BigInt.shiftLeft(), + migrateInPipeChain: BigInt.shiftLeft(), }) external lsl: (bigint, bigint) => bigint = "%lslbigint" @@ -439,6 +439,6 @@ BigInt.asr(8n, 1n) == 4n @deprecated({ reason: "Use `>>` operator or `shiftRight` instead.", migrate: %insert.unlabelledArgument(0) >> %insert.unlabelledArgument(1), - migratePiped: BigInt.shiftRight(), + migrateInPipeChain: BigInt.shiftRight(), }) external asr: (bigint, bigint) => bigint = "%asrbigint" diff --git a/tests/tools_tests/src/expected/PipeAndRecursive.res.expected b/tests/tools_tests/src/expected/PipeAndRecursive.res.expected index 2820be6c3d..b4c3f023c9 100644 --- a/tests/tools_tests/src/expected/PipeAndRecursive.res.expected +++ b/tests/tools_tests/src/expected/PipeAndRecursive.res.expected @@ -6,7 +6,7 @@ module Target = { @deprecated({ reason: "test piped vs non-piped", migrate: PipeAndRecursive.Target.a(), - migratePiped: PipeAndRecursive.Target.b(), + migrateInPipeChain: PipeAndRecursive.Target.b(), }) external dep: int => int = "dep" @@ -18,7 +18,7 @@ let onePipe = PipeAndRecursive.Target.a(1) /* Still migrate (Target.a), since lhs has 1 pipe (< 2) */ let twoPipes = 1->id->PipeAndRecursive.Target.b -/* Should use migratePiped (Target.b), since lhs has 2 pipes */ +/* Should use migrateInPipeChain (Target.b), since lhs has 2 pipes */ let threePipes = 1->id->id->PipeAndRecursive.Target.b /* Recursion: all dep steps should migrate */ diff --git a/tests/tools_tests/src/migrate/PipeAndRecursive.res b/tests/tools_tests/src/migrate/PipeAndRecursive.res index a2da460513..cae67949b7 100644 --- a/tests/tools_tests/src/migrate/PipeAndRecursive.res +++ b/tests/tools_tests/src/migrate/PipeAndRecursive.res @@ -6,7 +6,7 @@ module Target = { @deprecated({ reason: "test piped vs non-piped", migrate: PipeAndRecursive.Target.a(), - migratePiped: PipeAndRecursive.Target.b(), + migrateInPipeChain: PipeAndRecursive.Target.b(), }) external dep: int => int = "dep" @@ -18,7 +18,7 @@ let onePipe = 1->dep /* Still migrate (Target.a), since lhs has 1 pipe (< 2) */ let twoPipes = 1->id->dep -/* Should use migratePiped (Target.b), since lhs has 2 pipes */ +/* Should use migrateInPipeChain (Target.b), since lhs has 2 pipes */ let threePipes = 1->id->id->dep /* Recursion: all dep steps should migrate */ diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index fd515fda27..ffba914258 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -410,7 +410,7 @@ let apply_template_direct mapper template_expr call_args exp = template when available and valid; otherwise fall back to the direct template. *) let choose_template_for_piped (deprecated_info : Cmt_utils.deprecated_used) = - match deprecated_info.migration_piped_template with + match deprecated_info.migration_in_pipe_chain_template with | Some e -> ( match Template.of_expr e with | Some t -> Some t @@ -431,7 +431,7 @@ let apply_single_step_or_piped ~mapper let is_single_pipe_step = not (ExprUtils.is_pipe_apply lhs_exp) in if is_single_pipe_step - && Option.is_some deprecated_info.migration_piped_template + && Option.is_some deprecated_info.migration_in_pipe_chain_template then match deprecated_info.migration_template with | Some e -> ( @@ -440,7 +440,7 @@ let apply_single_step_or_piped ~mapper Template.apply_single_pipe_collapse ~mapper ~template:t ~lhs_exp ~pipe_args exp | None -> ( - match deprecated_info.migration_piped_template with + match deprecated_info.migration_in_pipe_chain_template with | Some e2 -> ( match Template.of_expr e2 with | Some t -> @@ -448,7 +448,7 @@ let apply_single_step_or_piped ~mapper | None -> exp) | None -> exp)) | None -> ( - match deprecated_info.migration_piped_template with + match deprecated_info.migration_in_pipe_chain_template with | Some e2 -> ( match Template.of_expr e2 with | Some t -> From 9e76d0f74093f92c532e85a792b507223bb8103f Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 14:08:12 +0200 Subject: [PATCH 07/41] migrations for Js_null_undefined --- .../@rescript/runtime/Js_null_undefined.resi | 43 ++++++++++++++++++- .../StdlibMigration_Nullable.res.expected | 27 ++++++++++++ .../src/migrate/StdlibMigration_Nullable.res | 27 ++++++++++++ .../Migrated_StdlibMigration_Nullable.res | 28 ++++++++++++ 4 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Nullable.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Nullable.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Nullable.res diff --git a/packages/@rescript/runtime/Js_null_undefined.resi b/packages/@rescript/runtime/Js_null_undefined.resi index 6dbbff513e..713d7115c9 100644 --- a/packages/@rescript/runtime/Js_null_undefined.resi +++ b/packages/@rescript/runtime/Js_null_undefined.resi @@ -31,15 +31,31 @@ type t<+'a> = Primitive_js_extern.nullable<'a> = Value('a) | @as(null) Null | @as(undefined) Undefined /** Constructs a value of `Js.null_undefined<'a>` containing a value of `'a`. */ +@deprecated({ + reason: "Use `Nullable.make` instead.", + migrate: Nullable.make(), +}) external return: 'a => t<'a> = "%identity" /** Returns `true` if the given value is null or undefined, `false` otherwise. */ +@deprecated({ + reason: "Use `Nullable.isNullable` instead.", + migrate: Nullable.isNullable(), +}) external isNullable: t<'a> => bool = "%is_nullable" /** The null value of type `Js.null_undefined<'a>`. */ +@deprecated({ + reason: "Use `Nullable.null` instead.", + migrate: Nullable.null, +}) external null: t<'a> = "%null" /** The undefined value of type `Js.null_undefined<'a>`. */ +@deprecated({ + reason: "Use `Nullable.undefined` instead.", + migrate: Nullable.undefined, +}) external undefined: t<'a> = "%undefined" /** @@ -56,6 +72,10 @@ let maybeGreetWorld = (maybeGreeting: Js.null_undefined) => Js.Null_undefined.bind(maybeGreeting, greeting => greeting ++ " world!") ``` */ +@deprecated({ + reason: "Use `Nullable.map` instead.", + migrate: Nullable.map(), +}) let bind: (t<'a>, 'a => 'b) => t<'b> /** @@ -69,6 +89,10 @@ let maybeSay = (maybeMessage: Js.null_undefined) => Js.Null_undefined.iter(maybeMessage, message => Js.log(message)) ``` */ +@deprecated({ + reason: "Use `Nullable.forEach` instead.", + migrate: Nullable.forEach(), +}) let iter: (t<'a>, 'a => unit) => unit /** @@ -76,9 +100,16 @@ Maps `option<'a>` to `Js.null_undefined<'a>`. `Some(a)` => `a` `None` => `undefined` */ +@deprecated({ + reason: "Use `Nullable.fromOption` instead.", + migrate: Nullable.fromOption(), +}) let fromOption: option<'a> => t<'a> -@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> +@deprecated({ + reason: "Use `Nullable.fromOption` instead.", + migrate: Nullable.fromOption(), +}) let from_opt: option<'a> => t<'a> /** Maps `Js.null_undefined<'a>` to `option<'a>`. @@ -86,6 +117,14 @@ Maps `Js.null_undefined<'a>` to `option<'a>`. `undefined` => `None` `null` => `None` */ +@deprecated({ + reason: "Use `Nullable.toOption` instead.", + migrate: Nullable.toOption(), +}) external toOption: t<'a> => option<'a> = "%nullable_to_opt" -@deprecated("Use toOption instead") external to_opt: t<'a> => option<'a> = "%nullable_to_opt" +@deprecated({ + reason: "Use `Nullable.toOption` instead.", + migrate: Nullable.toOption(), +}) +external to_opt: t<'a> => option<'a> = "%nullable_to_opt" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Nullable.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Nullable.res.expected new file mode 100644 index 0000000000..77c35f71db --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Nullable.res.expected @@ -0,0 +1,27 @@ +let make1 = "hello"->Nullable.make +let make2 = Nullable.make("hello") + +let null1 = Nullable.null +let undefined1 = Nullable.undefined + +let isNullable1 = Nullable.null->Nullable.isNullable +let isNullable2 = Nullable.isNullable(Nullable.null) + +let map1 = Nullable.make(2)->Nullable.map(x => x + 1) +let map2 = Nullable.map(Nullable.make(2), x => x + 1) + +let forEach1 = Nullable.make(2)->Nullable.forEach(x => ignore(x)) +let forEach2 = Nullable.forEach(Nullable.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Nullable.fromOption +let fromOption2 = Nullable.fromOption(None) + +let from_opt1 = Some("y")->Nullable.fromOption +let from_opt2 = Nullable.fromOption(None) + +let toOption1 = Nullable.make(3)->Nullable.toOption +let toOption2 = Nullable.toOption(Nullable.make(3)) + +let to_opt1 = Nullable.make(4)->Nullable.toOption +let to_opt2 = Nullable.toOption(Nullable.make(4)) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res b/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res new file mode 100644 index 0000000000..6b54a332f4 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res @@ -0,0 +1,27 @@ +let make1 = "hello"->Js.Null_undefined.return +let make2 = Js.Null_undefined.return("hello") + +let null1 = Js.Null_undefined.null +let undefined1 = Js.Null_undefined.undefined + +let isNullable1 = Js.Null_undefined.null->Js.Null_undefined.isNullable +let isNullable2 = Js.Null_undefined.isNullable(Js.Null_undefined.null) + +let map1 = Js.Null_undefined.return(2)->Js.Null_undefined.bind(x => x + 1) +let map2 = Js.Null_undefined.bind(Js.Null_undefined.return(2), x => x + 1) + +let forEach1 = Js.Null_undefined.return(2)->Js.Null_undefined.iter(x => ignore(x)) +let forEach2 = Js.Null_undefined.iter(Js.Null_undefined.return(2), x => ignore(x)) + +let fromOption1 = Some("x")->Js.Null_undefined.fromOption +let fromOption2 = Js.Null_undefined.fromOption(None) + +let from_opt1 = Some("y")->Js.Null_undefined.from_opt +let from_opt2 = Js.Null_undefined.from_opt(None) + +let toOption1 = Js.Null_undefined.return(3)->Js.Null_undefined.toOption +let toOption2 = Js.Null_undefined.toOption(Js.Null_undefined.return(3)) + +let to_opt1 = Js.Null_undefined.return(4)->Js.Null_undefined.to_opt +let to_opt2 = Js.Null_undefined.to_opt(Js.Null_undefined.return(4)) + diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Nullable.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Nullable.res new file mode 100644 index 0000000000..3dde672d28 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Nullable.res @@ -0,0 +1,28 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Nullable.res. +let make1 = "hello"->Nullable.make +let make2 = Nullable.make("hello") + +let null1 = Nullable.null +let undefined1 = Nullable.undefined + +let isNullable1 = Nullable.null->Nullable.isNullable +let isNullable2 = Nullable.isNullable(Nullable.null) + +let map1 = Nullable.make(2)->Nullable.map(x => x + 1) +let map2 = Nullable.map(Nullable.make(2), x => x + 1) + +let forEach1 = Nullable.make(2)->Nullable.forEach(x => ignore(x)) +let forEach2 = Nullable.forEach(Nullable.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Nullable.fromOption +let fromOption2 = Nullable.fromOption(None) + +let from_opt1 = Some("y")->Nullable.fromOption +let from_opt2 = Nullable.fromOption(None) + +let toOption1 = Nullable.make(3)->Nullable.toOption +let toOption2 = Nullable.toOption(Nullable.make(3)) + +let to_opt1 = Nullable.make(4)->Nullable.toOption +let to_opt2 = Nullable.toOption(Nullable.make(4)) From 4e27a2081140925e87d28ba46ce3bd78fc9be398 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 20:39:39 +0200 Subject: [PATCH 08/41] js_float migrations --- packages/@rescript/runtime/Js_float.res | 48 +++++++++++++++++++ .../StdlibMigration_Float.res.expected | 35 ++++++++++++++ .../src/migrate/StdlibMigration_Float.res | 35 ++++++++++++++ .../Migrated_StdlibMigration_Float.res | 36 ++++++++++++++ 4 files changed, 154 insertions(+) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Float.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Float.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Float.res diff --git a/packages/@rescript/runtime/Js_float.res b/packages/@rescript/runtime/Js_float.res index dd72791c0b..ff5f604085 100644 --- a/packages/@rescript/runtime/Js_float.res +++ b/packages/@rescript/runtime/Js_float.res @@ -29,6 +29,10 @@ Provide utilities for JS float. /** The special value "Not a Number". See [`NaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN) on MDN. */ +@deprecated({ + reason: "Use `Float.Constants.nan` instead.", + migrate: Float.Constants.nan, +}) @val external _NaN: float = "NaN" @@ -39,6 +43,10 @@ Note that both `_NaN = _NaN` and `_NaN == _NaN` will return `false`. `isNaN` is therefore necessary to test for `_NaN`. Return `true` if the given value is `_NaN`, `false` otherwise. See [`isNaN`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN) on MDN. */ +@deprecated({ + reason: "Use `Float.isNaN` instead.", + migrate: Float.isNaN(), +}) @val @scope("Number") external isNaN: float => bool = "isNaN" @@ -62,6 +70,10 @@ Js.Float.isFinite(Js.Float._NaN) Js.Float.isFinite(1234.) ``` */ +@deprecated({ + reason: "Use `Float.isFinite` instead.", + migrate: Float.isFinite(), +}) @val @scope("Number") external isFinite: float => bool = "isFinite" @@ -80,6 +92,10 @@ Js.Float.toExponential(77.1234)->Js.log Js.Float.toExponential(77.)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toExponential` instead.", + migrate: Float.toExponential(), +}) @send external toExponential: float => string = "toExponential" @@ -98,6 +114,10 @@ See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Re Js.Float.toExponentialWithPrecision(77.1234, ~digits=2)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toExponential` instead.", + migrate: Float.toExponential(~digits=%insert.labelledArgument("digits")), +}) @send external toExponentialWithPrecision: (float, ~digits: int) => string = "toExponential" @@ -116,6 +136,10 @@ Js.Float.toFixed(12345.6789)->Js.log Js.Float.toFixed(1.2e21)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toFixed` instead.", + migrate: Float.toFixed(), +}) @send external toFixed: float => string = "toFixed" @@ -139,6 +163,10 @@ Js.Float.toFixedWithPrecision(12345.6789, ~digits=1)->Js.log Js.Float.toFixedWithPrecision(0., ~digits=2)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toFixed` instead.", + migrate: Float.toFixed(~digits=%insert.labelledArgument("digits")), +}) @send external toFixedWithPrecision: (float, ~digits: int) => string = "toFixed" @@ -161,6 +189,10 @@ Js.Float.toPrecision(12345.6789)->Js.log Js.Float.toPrecision(1.2e21)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toPrecision` instead.", + migrate: Float.toPrecision(), +}) @send external toPrecision: float => string = "toPrecision" @@ -193,6 +225,10 @@ Js.Float.toPrecisionWithPrecision(12345.6789, ~digits=1)->Js.log Js.Float.toPrecisionWithPrecision(0., ~digits=2)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toPrecision` instead.", + migrate: Float.toPrecision(~digits=%insert.labelledArgument("digits")), +}) @send external toPrecisionWithPrecision: (float, ~digits: int) => string = "toPrecision" @@ -207,6 +243,10 @@ fixed-point (usually). See [`toString`](https://developer.mozilla.org/en-US/docs Js.Float.toString(12345.6789)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toString` instead.", + migrate: Float.toString(), +}) @send external toString: float => string = "toString" @@ -233,6 +273,10 @@ Js.Float.toStringWithRadix(3735928559., ~radix=16)->Js.log Js.Float.toStringWithRadix(123.456, ~radix=36)->Js.log ``` */ +@deprecated({ + reason: "Use `Float.toString` instead.", + migrate: Float.toString(~radix=%insert.labelledArgument("radix")), +}) @send external toStringWithRadix: (float, ~radix: int) => string = "toString" @@ -268,5 +312,9 @@ Js.Float.fromString("hello") Js.Float.fromString("100a") ``` */ +@deprecated({ + reason: "Use `Float.parseFloat` instead.", + migrate: Float.parseFloat(), +}) @val external fromString: string => float = "Number" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Float.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Float.res.expected new file mode 100644 index 0000000000..1e70760134 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Float.res.expected @@ -0,0 +1,35 @@ +let nan1 = Float.Constants.nan + +let isNaN1 = Float.Constants.nan->Float.isNaN +let isNaN2 = Float.isNaN(Float.Constants.nan) + +let isFinite1 = 1234.0->Float.isFinite +let isFinite2 = Float.isFinite(1234.0) + +let toExponential1 = 77.1234->Float.toExponential +let toExponential2 = Float.toExponential(77.1234) + +let toExponentialWithPrecision1 = 77.1234->Float.toExponential(~digits=2) +let toExponentialWithPrecision2 = Float.toExponential(77.1234, ~digits=2) + +let toFixed1 = 12345.6789->Float.toFixed +let toFixed2 = Float.toFixed(12345.6789) + +let toFixedWithPrecision1 = 12345.6789->Float.toFixed(~digits=1) +let toFixedWithPrecision2 = Float.toFixed(12345.6789, ~digits=1) + +let toPrecision1 = 12345.6789->Float.toPrecision +let toPrecision2 = Float.toPrecision(12345.6789) + +let toPrecisionWithPrecision1 = 12345.6789->Float.toPrecision(~digits=2) +let toPrecisionWithPrecision2 = Float.toPrecision(12345.6789, ~digits=2) + +let toString1 = 12345.6789->Float.toString +let toString2 = Float.toString(12345.6789) + +let toStringWithRadix1 = 6.0->Float.toString(~radix=2) +let toStringWithRadix2 = Float.toString(6.0, ~radix=2) + +let parse1 = "123"->Float.parseFloat +let parse2 = Float.parseFloat("123") + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Float.res b/tests/tools_tests/src/migrate/StdlibMigration_Float.res new file mode 100644 index 0000000000..d7fa18efe2 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Float.res @@ -0,0 +1,35 @@ +let nan1 = Js.Float._NaN + +let isNaN1 = Js.Float._NaN->Js.Float.isNaN +let isNaN2 = Js.Float.isNaN(Js.Float._NaN) + +let isFinite1 = 1234.0->Js.Float.isFinite +let isFinite2 = Js.Float.isFinite(1234.0) + +let toExponential1 = 77.1234->Js.Float.toExponential +let toExponential2 = Js.Float.toExponential(77.1234) + +let toExponentialWithPrecision1 = 77.1234->Js.Float.toExponentialWithPrecision(~digits=2) +let toExponentialWithPrecision2 = Js.Float.toExponentialWithPrecision(77.1234, ~digits=2) + +let toFixed1 = 12345.6789->Js.Float.toFixed +let toFixed2 = Js.Float.toFixed(12345.6789) + +let toFixedWithPrecision1 = 12345.6789->Js.Float.toFixedWithPrecision(~digits=1) +let toFixedWithPrecision2 = Js.Float.toFixedWithPrecision(12345.6789, ~digits=1) + +let toPrecision1 = 12345.6789->Js.Float.toPrecision +let toPrecision2 = Js.Float.toPrecision(12345.6789) + +let toPrecisionWithPrecision1 = 12345.6789->Js.Float.toPrecisionWithPrecision(~digits=2) +let toPrecisionWithPrecision2 = Js.Float.toPrecisionWithPrecision(12345.6789, ~digits=2) + +let toString1 = 12345.6789->Js.Float.toString +let toString2 = Js.Float.toString(12345.6789) + +let toStringWithRadix1 = 6.0->Js.Float.toStringWithRadix(~radix=2) +let toStringWithRadix2 = Js.Float.toStringWithRadix(6.0, ~radix=2) + +let parse1 = "123"->Js.Float.fromString +let parse2 = Js.Float.fromString("123") + diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Float.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Float.res new file mode 100644 index 0000000000..d4bdcc1a15 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Float.res @@ -0,0 +1,36 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Float.res. +let nan1 = Float.Constants.nan + +let isNaN1 = Float.Constants.nan->Float.isNaN +let isNaN2 = Float.isNaN(Float.Constants.nan) + +let isFinite1 = 1234.0->Float.isFinite +let isFinite2 = Float.isFinite(1234.0) + +let toExponential1 = 77.1234->Float.toExponential +let toExponential2 = Float.toExponential(77.1234) + +let toExponentialWithPrecision1 = 77.1234->Float.toExponential(~digits=2) +let toExponentialWithPrecision2 = Float.toExponential(77.1234, ~digits=2) + +let toFixed1 = 12345.6789->Float.toFixed +let toFixed2 = Float.toFixed(12345.6789) + +let toFixedWithPrecision1 = 12345.6789->Float.toFixed(~digits=1) +let toFixedWithPrecision2 = Float.toFixed(12345.6789, ~digits=1) + +let toPrecision1 = 12345.6789->Float.toPrecision +let toPrecision2 = Float.toPrecision(12345.6789) + +let toPrecisionWithPrecision1 = 12345.6789->Float.toPrecision(~digits=2) +let toPrecisionWithPrecision2 = Float.toPrecision(12345.6789, ~digits=2) + +let toString1 = 12345.6789->Float.toString +let toString2 = Float.toString(12345.6789) + +let toStringWithRadix1 = 6.0->Float.toString(~radix=2) +let toStringWithRadix2 = Float.toString(6.0, ~radix=2) + +let parse1 = "123"->Float.parseFloat +let parse2 = Float.parseFloat("123") From aaa668df2ef00d3b3d178512f315d1b46f69f522 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 21:14:29 +0200 Subject: [PATCH 09/41] Js_int migrations --- packages/@rescript/runtime/Js_int.res | 32 +++++ .../StdlibMigration_Js_Int.res.expected | 24 ++++ .../src/migrate/StdlibMigration_Js_Int.res | 23 ++++ .../Migrated_StdlibMigration_Array.res | 4 +- .../Migrated_StdlibMigration_Js_Int.res | 25 ++++ tools/src/migrate.ml | 113 +++++++++++------- 6 files changed, 177 insertions(+), 44 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js_Int.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js_Int.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Int.res diff --git a/packages/@rescript/runtime/Js_int.res b/packages/@rescript/runtime/Js_int.res index cf6cc7cf46..d75bd4a999 100644 --- a/packages/@rescript/runtime/Js_int.res +++ b/packages/@rescript/runtime/Js_int.res @@ -49,6 +49,10 @@ See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Re Js.log(Js.Int.toExponential(77)) ``` */ +@deprecated({ + reason: "Use `Int.toExponential` instead.", + migrate: Int.toExponential(), +}) @send external toExponential: int => string = "toExponential" @@ -73,6 +77,10 @@ Js.log(Js.Int.toExponentialWithPrecision(77, ~digits=2)) Js.log(Js.Int.toExponentialWithPrecision(5678, ~digits=2)) ``` */ +@deprecated({ + reason: "Use `Int.toExponential` instead.", + migrate: Int.toExponential(~digits=%insert.labelledArgument("digits")), +}) @send external toExponentialWithPrecision: (int, ~digits: int) => string = "toExponential" @@ -92,6 +100,10 @@ See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe Js.log(Js.Int.toPrecision(123456789)) ``` */ +@deprecated({ + reason: "Use `Int.toPrecision` instead.", + migrate: Int.toPrecision(), +}) @send external toPrecision: int => string = "toPrecision" @@ -120,6 +132,10 @@ Js.log(Js.Int.toPrecisionWithPrecision(123456789, ~digits=2)) Js.log(Js.Int.toPrecisionWithPrecision(0, ~digits=2)) ``` */ +@deprecated({ + reason: "Use `Int.toPrecision` instead.", + migrate: Int.toPrecision(~digits=%insert.labelledArgument("digits")), +}) @send external toPrecisionWithPrecision: (int, ~digits: int) => string = "toPrecision" @@ -136,6 +152,10 @@ See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen Js.log(Js.Int.toString(123456789)) ``` */ +@deprecated({ + reason: "Use `Int.toString` instead.", + migrate: Int.toString(), +}) @send external toString: int => string = "toString" @@ -161,11 +181,23 @@ Js.log(Js.Int.toStringWithRadix(3735928559, ~radix=16)) Js.log(Js.Int.toStringWithRadix(123456, ~radix=36)) ``` */ +@deprecated({ + reason: "Use `Int.toString` instead.", + migrate: Int.toString(~radix=%insert.labelledArgument("radix")), +}) @send external toStringWithRadix: (int, ~radix: int) => string = "toString" +@deprecated({ + reason: "Use `Int.toFloat` instead.", + migrate: Int.toFloat(), +}) external toFloat: int => float = "%floatofint" +@deprecated({ + reason: "Use `Int.equal` instead.", + migrate: Int.equal(), +}) let equal = (x: int, y) => x == y let max: int = 2147483647 let min: int = -2147483648 diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_Int.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_Int.res.expected new file mode 100644 index 0000000000..2852afd3ba --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_Int.res.expected @@ -0,0 +1,24 @@ +let toExponential1 = 77->Int.toExponential +let toExponential2 = Int.toExponential(77) + +let toExponentialWithPrecision1 = 77->Int.toExponential(~digits=2) +let toExponentialWithPrecision2 = Int.toExponential(77, ~digits=2) + +let toPrecision1 = 123456789->Int.toPrecision +let toPrecision2 = Int.toPrecision(123456789) + +let toPrecisionWithPrecision1 = 123456789->Int.toPrecision(~digits=2) +let toPrecisionWithPrecision2 = Int.toPrecision(123456789, ~digits=2) + +let toString1 = 123456789->Int.toString +let toString2 = Int.toString(123456789) + +let toStringWithRadix1 = 373592855->Int.toString(~radix=16) +let toStringWithRadix2 = Int.toString(373592855, ~radix=16) + +let toFloat1 = 42->Int.toFloat +let toFloat2 = Int.toFloat(42) + +let equal1 = Js.Int.equal(1, 1) +let equal2 = 1->Js.Int.equal(2) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_Int.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_Int.res new file mode 100644 index 0000000000..b120c23691 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_Int.res @@ -0,0 +1,23 @@ +let toExponential1 = 77->Js.Int.toExponential +let toExponential2 = Js.Int.toExponential(77) + +let toExponentialWithPrecision1 = 77->Js.Int.toExponentialWithPrecision(~digits=2) +let toExponentialWithPrecision2 = Js.Int.toExponentialWithPrecision(77, ~digits=2) + +let toPrecision1 = 123456789->Js.Int.toPrecision +let toPrecision2 = Js.Int.toPrecision(123456789) + +let toPrecisionWithPrecision1 = 123456789->Js.Int.toPrecisionWithPrecision(~digits=2) +let toPrecisionWithPrecision2 = Js.Int.toPrecisionWithPrecision(123456789, ~digits=2) + +let toString1 = 123456789->Js.Int.toString +let toString2 = Js.Int.toString(123456789) + +let toStringWithRadix1 = 373592855->Js.Int.toStringWithRadix(~radix=16) +let toStringWithRadix2 = Js.Int.toStringWithRadix(373592855, ~radix=16) + +let toFloat1 = 42->Js.Int.toFloat +let toFloat2 = Js.Int.toFloat(42) + +let equal1 = Js.Int.equal(1, 1) +let equal2 = 1->Js.Int.equal(2) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res index 4b6ce8e861..d94e7340c6 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res @@ -125,8 +125,8 @@ let copyWithin2 = Array.copyAllWithin([1, 2, 3, 4, 5], ~target=2) let copyWithinFrom1 = [1, 2, 3, 4, 5]->Array.copyWithinToEnd(~target=0, ~start=2) let copyWithinFrom2 = Array.copyWithinToEnd([1, 2, 3, 4, 5], ~target=0, ~start=2) -let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~target=1, ~start=2, ~end=5) -let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~target=1, ~start=2, ~end=5) +let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~start=2, ~target=1, ~end=5) +let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~start=2, ~target=1, ~end=5) let push1 = [1, 2, 3]->Array.push(4) let push2 = Array.push([1, 2, 3], 4) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Int.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Int.res new file mode 100644 index 0000000000..379b142ce9 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Int.res @@ -0,0 +1,25 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js_Int.res. +let toExponential1 = 77->Int.toExponential +let toExponential2 = Int.toExponential(77) + +let toExponentialWithPrecision1 = 77->Int.toExponential(~digits=2) +let toExponentialWithPrecision2 = Int.toExponential(77, ~digits=2) + +let toPrecision1 = 123456789->Int.toPrecision +let toPrecision2 = Int.toPrecision(123456789) + +let toPrecisionWithPrecision1 = 123456789->Int.toPrecision(~digits=2) +let toPrecisionWithPrecision2 = Int.toPrecision(123456789, ~digits=2) + +let toString1 = 123456789->Int.toString +let toString2 = Int.toString(123456789) + +let toStringWithRadix1 = 373592855->Int.toString(~radix=16) +let toStringWithRadix2 = Int.toString(373592855, ~radix=16) + +let toFloat1 = 42->Int.toFloat +let toFloat2 = Int.toFloat(42) + +let equal1 = Js.Int.equal(1, 1) +let equal2 = 1->Js.Int.equal(2) diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index ffba914258..4a4cd4cf0e 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -64,6 +64,66 @@ module ExprUtils = struct end module MapperUtils = struct + (* Collect placeholder usages anywhere inside an expression. *) + let collect_placeholders (expr : Parsetree.expression) = + let labelled = ref StringSet.empty in + let unlabelled = ref IntSet.empty in + let open Ast_iterator in + let iter = + { + default_iterator with + expr = + (fun self e -> + (match InsertExt.placeholder_of_expr e with + | Some (InsertExt.Labelled name) -> + labelled := StringSet.add name !labelled + | Some (InsertExt.Unlabelled i) when i >= 0 -> + unlabelled := IntSet.add i !unlabelled + | _ -> ()); + default_iterator.expr self e); + } + in + iter.expr iter expr; + (!labelled, !unlabelled) + + (* Replace placeholders anywhere inside an expression using the given + source arguments. *) + let replace_placeholders_in_expr (expr : Parsetree.expression) + (source_args : (Asttypes.arg_label * Parsetree.expression) list) = + let labelled = Hashtbl.create 8 in + let unlabelled = Hashtbl.create 8 in + let idx = ref 0 in + source_args + |> List.iter (fun (lbl, arg) -> + match lbl with + | Asttypes.Nolabel -> + Hashtbl.replace unlabelled !idx arg; + incr idx + | Asttypes.Labelled {txt} | Optional {txt} -> + Hashtbl.replace labelled txt arg); + let find = function + | `Labelled name -> Hashtbl.find_opt labelled name + | `Unlabelled i -> Hashtbl.find_opt unlabelled i + in + let mapper = + { + Ast_mapper.default_mapper with + expr = + (fun mapper exp -> + match InsertExt.placeholder_of_expr exp with + | Some (InsertExt.Labelled name) -> ( + match find (`Labelled name) with + | Some arg -> arg + | None -> exp) + | Some (InsertExt.Unlabelled i) -> ( + match find (`Unlabelled i) with + | Some arg -> arg + | None -> exp) + | None -> Ast_mapper.default_mapper.expr mapper exp); + } + in + mapper.expr mapper expr + let build_labelled_args_map template_args = template_args |> List.filter_map (fun (label, arg) -> @@ -89,23 +149,6 @@ module MapperUtils = struct - unlabelled_positions_to_insert: 0-based indices of unlabelled source args to drop *) let get_template_args_to_insert mapper template_args source_args = - let find_source_labelled name = - source_args - |> List.find_map (fun (label, arg) -> - match label with - | Asttypes.Labelled {txt = l} | Optional {txt = l} -> - if l = name then Some arg else None - | _ -> None) - in - let find_source_unlabelled target = - let rec loop i = function - | [] -> None - | (Asttypes.Nolabel, arg) :: rest -> - if i = target then Some arg else loop (i + 1) rest - | _ :: rest -> loop i rest - in - loop 0 source_args - in let is_unit_expr (e : Parsetree.expression) = match e.pexp_desc with | Pexp_construct ({txt = Lident "()"}, None) -> true @@ -121,31 +164,17 @@ module MapperUtils = struct - used_unlabelled: 0-based positions of unlabelled args consumed. *) let accumulate_template_arg (rev_args, used_labelled, used_unlabelled) (label, arg) = - match InsertExt.placeholder_of_expr arg with - | Some (InsertExt.Labelled name) -> ( - match label with - | Asttypes.Nolabel -> ( - match find_source_labelled name with - | Some arg' -> - ( (Asttypes.Nolabel, arg') :: rev_args, - StringSet.add name used_labelled, - used_unlabelled ) - | None -> (rev_args, used_labelled, used_unlabelled)) - | _ -> (rev_args, used_labelled, used_unlabelled)) - | Some (InsertExt.Unlabelled target) when target >= 0 -> ( - match find_source_unlabelled target with - | Some arg' -> - ( (label, arg') :: rev_args, - used_labelled, - IntSet.add target used_unlabelled ) - | None -> (rev_args, used_labelled, used_unlabelled)) - | Some _ -> (rev_args, used_labelled, used_unlabelled) - | None -> - if is_unit_expr arg then (rev_args, used_labelled, used_unlabelled) - else - ( (label, mapper.Ast_mapper.expr mapper arg) :: rev_args, - used_labelled, - used_unlabelled ) + (* Always perform nested replacement inside the argument expression, + and collect which placeholders were used so we can drop them from the + original call's arguments. *) + let labelled_used_here, unlabelled_used_here = collect_placeholders arg in + let arg_replaced = replace_placeholders_in_expr arg source_args in + if is_unit_expr arg_replaced then + (rev_args, used_labelled, used_unlabelled) + else + ( (label, mapper.Ast_mapper.expr mapper arg_replaced) :: rev_args, + StringSet.union used_labelled labelled_used_here, + IntSet.union used_unlabelled unlabelled_used_here ) in let rev_args, labelled_set, unlabelled_set = List.fold_left accumulate_template_arg From ffc960ab4f6a71a5144e661b27106baba94fde41 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 21:16:39 +0200 Subject: [PATCH 10/41] format --- packages/@rescript/runtime/Js_float.res | 6 ++-- .../@rescript/runtime/Js_null_undefined.resi | 3 +- packages/@rescript/runtime/Js_option.resi | 29 ++++--------------- .../StdlibMigration_Array.res.expected | 4 +-- .../src/migrate/StdlibMigration_Float.res | 1 - .../src/migrate/StdlibMigration_Nullable.res | 1 - 6 files changed, 14 insertions(+), 30 deletions(-) diff --git a/packages/@rescript/runtime/Js_float.res b/packages/@rescript/runtime/Js_float.res index ff5f604085..2bc9ab50cf 100644 --- a/packages/@rescript/runtime/Js_float.res +++ b/packages/@rescript/runtime/Js_float.res @@ -47,7 +47,8 @@ therefore necessary to test for `_NaN`. Return `true` if the given value is reason: "Use `Float.isNaN` instead.", migrate: Float.isNaN(), }) -@val @scope("Number") +@val +@scope("Number") external isNaN: float => bool = "isNaN" /** @@ -74,7 +75,8 @@ Js.Float.isFinite(1234.) reason: "Use `Float.isFinite` instead.", migrate: Float.isFinite(), }) -@val @scope("Number") +@val +@scope("Number") external isFinite: float => bool = "isFinite" /** diff --git a/packages/@rescript/runtime/Js_null_undefined.resi b/packages/@rescript/runtime/Js_null_undefined.resi index 713d7115c9..4bd9305ada 100644 --- a/packages/@rescript/runtime/Js_null_undefined.resi +++ b/packages/@rescript/runtime/Js_null_undefined.resi @@ -109,7 +109,8 @@ let fromOption: option<'a> => t<'a> @deprecated({ reason: "Use `Nullable.fromOption` instead.", migrate: Nullable.fromOption(), -}) let from_opt: option<'a> => t<'a> +}) +let from_opt: option<'a> => t<'a> /** Maps `Js.null_undefined<'a>` to `option<'a>`. diff --git a/packages/@rescript/runtime/Js_option.resi b/packages/@rescript/runtime/Js_option.resi index 16a607e9f2..1275dfc8cb 100644 --- a/packages/@rescript/runtime/Js_option.resi +++ b/packages/@rescript/runtime/Js_option.resi @@ -59,57 +59,40 @@ let getExn: option<'a> => 'a %insert.unlabelledArgument(2), %insert.unlabelledArgument(0), ), - }) let equal: (('a, 'b) => bool, option<'a>, option<'b>) => bool @deprecated({ reason: "Use `Option.flatMap` instead.", - migrate: Option.flatMap( - %insert.unlabelledArgument(1), - %insert.unlabelledArgument(0), - ), + migrate: Option.flatMap(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), migrateInPipeChain: Option.flatMap(%insert.unlabelledArgument(0)), }) let andThen: ('a => option<'b>, option<'a>) => option<'b> @deprecated({ reason: "Use `Option.map` instead.", - migrate: Option.map( - %insert.unlabelledArgument(1), - %insert.unlabelledArgument(0), - ), + migrate: Option.map(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), migrateInPipeChain: Option.map(%insert.unlabelledArgument(0)), }) let map: ('a => 'b, option<'a>) => option<'b> @deprecated({ reason: "Use `Option.getOr` instead.", - migrate: Option.getOr( - %insert.unlabelledArgument(1), - %insert.unlabelledArgument(0), - ), + migrate: Option.getOr(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), migrateInPipeChain: Option.getOr(%insert.unlabelledArgument(0)), }) let getWithDefault: ('a, option<'a>) => 'a @deprecated({ - reason: - "Use `Option.getOr` instead. Note: `default` has special meaning in ES modules.", - migrate: Option.getOr( - %insert.unlabelledArgument(1), - %insert.unlabelledArgument(0), - ), + reason: "Use `Option.getOr` instead. Note: `default` has special meaning in ES modules.", + migrate: Option.getOr(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), migrateInPipeChain: Option.getOr(%insert.unlabelledArgument(0)), }) let default: ('a, option<'a>) => 'a @deprecated({ reason: "Use `Option.filter` instead.", - migrate: Option.filter( - %insert.unlabelledArgument(1), - %insert.unlabelledArgument(0), - ), + migrate: Option.filter(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), migrateInPipeChain: Option.filter(%insert.unlabelledArgument(0)), }) let filter: ('a => bool, option<'a>) => option<'a> diff --git a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected index 1f28e32781..32235a9f50 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected @@ -123,8 +123,8 @@ let copyWithin2 = Array.copyAllWithin([1, 2, 3, 4, 5], ~target=2) let copyWithinFrom1 = [1, 2, 3, 4, 5]->Array.copyWithinToEnd(~target=0, ~start=2) let copyWithinFrom2 = Array.copyWithinToEnd([1, 2, 3, 4, 5], ~target=0, ~start=2) -let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~target=1, ~start=2, ~end=5) -let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~target=1, ~start=2, ~end=5) +let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~start=2, ~target=1, ~end=5) +let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~start=2, ~target=1, ~end=5) let push1 = [1, 2, 3]->Array.push(4) let push2 = Array.push([1, 2, 3], 4) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Float.res b/tests/tools_tests/src/migrate/StdlibMigration_Float.res index d7fa18efe2..e87cfb0e5c 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Float.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Float.res @@ -32,4 +32,3 @@ let toStringWithRadix2 = Js.Float.toStringWithRadix(6.0, ~radix=2) let parse1 = "123"->Js.Float.fromString let parse2 = Js.Float.fromString("123") - diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res b/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res index 6b54a332f4..8ee7644118 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Nullable.res @@ -24,4 +24,3 @@ let toOption2 = Js.Null_undefined.toOption(Js.Null_undefined.return(3)) let to_opt1 = Js.Null_undefined.return(4)->Js.Null_undefined.to_opt let to_opt2 = Js.Null_undefined.to_opt(Js.Null_undefined.return(4)) - From 8523d2240d40ea2b3b65c307009a09cbd4b013bd Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 28 Aug 2025 21:21:15 +0200 Subject: [PATCH 11/41] dict migrations --- packages/@rescript/runtime/Js_dict.resi | 42 +++++++++++++++++++ .../StdlibMigration_Dict.res.expected | 34 +++++++++++++++ .../src/migrate/StdlibMigration_Dict.res | 33 +++++++++++++++ .../Migrated_StdlibMigration_Dict.res | 35 ++++++++++++++++ 4 files changed, 144 insertions(+) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Dict.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res diff --git a/packages/@rescript/runtime/Js_dict.resi b/packages/@rescript/runtime/Js_dict.resi index eb293554c8..5f7a841b15 100644 --- a/packages/@rescript/runtime/Js_dict.resi +++ b/packages/@rescript/runtime/Js_dict.resi @@ -57,6 +57,10 @@ Js.Dict.get(ages, "Vinh") == Some(22) Js.Dict.get(ages, "Paul") == None ``` */ +@deprecated({ + reason: "Use `Dict.get` instead.", + migrate: Dict.get(), +}) let get: (t<'a>, key) => option<'a> /** @@ -69,6 +73,10 @@ Js.Dict.unsafeGet(ages, "Fred") == 49 Js.Dict.unsafeGet(ages, "Paul") // returns undefined ``` */ +@deprecated({ + reason: "Use `Dict.getUnsafe` instead.", + migrate: Dict.getUnsafe(), +}) @get_index external unsafeGet: (t<'a>, key) => 'a = "" @@ -88,6 +96,10 @@ Js.Dict.set(ages, "David", 66) Js.log(ages == Js.Dict.fromList(list{("Maria", 31), ("Vinh", 22), ("Fred", 49), ("David", 66)})) ``` */ +@deprecated({ + reason: "Use `Dict.set` instead.", + migrate: Dict.set(), +}) @set_index external set: (t<'a>, key, 'a) => unit = "" @@ -100,14 +112,26 @@ Returns all the keys in the dictionary `dict`. Js.Dict.keys(ages) == ["Maria", "Vinh", "Fred"] ``` */ +@deprecated({ + reason: "Use `Dict.keysToArray` instead.", + migrate: Dict.keysToArray(), +}) @val external keys: t<'a> => array = "Object.keys" /** Returns an empty dictionary. */ +@deprecated({ + reason: "Use `Dict.make` instead.", + migrate: Dict.make(), +}) @obj external empty: unit => t<'a> = "" /** Experimental internal function */ +@deprecated({ + reason: "Use `Dict.delete` instead.", + migrate: Dict.delete(), +}) let unsafeDeleteKey: (t, string) => unit /** @@ -119,6 +143,10 @@ Returns an array of key/value pairs in the given dictionary (ES2017). Js.Dict.entries(ages) == [("Maria", 30), ("Vinh", 22), ("Fred", 49)] ``` */ +@deprecated({ + reason: "Use `Dict.toArray` instead.", + migrate: Dict.toArray(), +}) let entries: t<'a> => array<(key, 'a)> /** @@ -130,6 +158,10 @@ Returns the values in the given dictionary (ES2017). Js.Dict.values(ages) == [30, 22, 49] ``` */ +@deprecated({ + reason: "Use `Dict.valuesToArray` instead.", + migrate: Dict.valuesToArray(), +}) let values: t<'a> => array<'a> /** @@ -142,6 +174,7 @@ argument. let capitals = Js.Dict.fromList(list{("Japan", "Tokyo"), ("France", "Paris"), ("Egypt", "Cairo")}) ``` */ +@deprecated("Use `Dict.fromArray(List.toArray(...))` instead.") let fromList: list<(key, 'a)> => t<'a> /** @@ -154,6 +187,10 @@ argument. let capitals2 = Js.Dict.fromArray([("Germany", "Berlin"), ("Burkina Faso", "Ouagadougou")]) ``` */ +@deprecated({ + reason: "Use `Dict.fromArray` instead.", + migrate: Dict.fromArray(), +}) let fromArray: array<(key, 'a)> => t<'a> /** @@ -171,4 +208,9 @@ let salePrices = Js.Dict.map(discount, prices) salePrices == Js.Dict.fromList(list{("pen", 0.90), ("book", 4.50), ("stapler", 6.30)}) ``` */ +@deprecated({ + reason: "Use `Dict.mapValues` instead.", + migrate: Dict.mapValues(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), + migrateInPipeChain: Dict.mapValues(), +}) let map: ('a => 'b, t<'a>) => t<'b> diff --git a/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected new file mode 100644 index 0000000000..af24b116db --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected @@ -0,0 +1,34 @@ +let d = Dict.make() + +let get1 = d->Dict.get("k") +let get2 = Dict.get(d, "k") + +let unsafeGet1 = d->Dict.getUnsafe("k") +let unsafeGet2 = Dict.getUnsafe(d, "k") + +let set1 = d->Dict.set("k", 1) +let set2 = Dict.set(d, "k", 1) + +let keys1 = d->Dict.keysToArray +let keys2 = Dict.keysToArray(d) + +let values1 = d->Dict.valuesToArray +let values2 = Dict.valuesToArray(d) + +let entries1 = d->Dict.toArray +let entries2 = Dict.toArray(d) + +let dStr: Js.Dict.t = Dict.make() +let del1 = dStr->Dict.delete("k") +let del2 = Dict.delete(dStr, "k") + +let empty1: Js.Dict.t = Dict.make() + +let fromArray1 = [("a", 1), ("b", 2)]->Dict.fromArray +let fromArray2 = Dict.fromArray([("a", 1), ("b", 2)]) + +let fromList1 = list{("a", 1), ("b", 2)}->Js.Dict.fromList +let fromList2 = Js.Dict.fromList(list{("a", 1), ("b", 2)}) + +let map2 = Dict.mapValues(d, x => x + 1) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Dict.res b/tests/tools_tests/src/migrate/StdlibMigration_Dict.res new file mode 100644 index 0000000000..b0f00cd7cb --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Dict.res @@ -0,0 +1,33 @@ +let d = Js.Dict.empty() + +let get1 = d->Js.Dict.get("k") +let get2 = Js.Dict.get(d, "k") + +let unsafeGet1 = d->Js.Dict.unsafeGet("k") +let unsafeGet2 = Js.Dict.unsafeGet(d, "k") + +let set1 = d->Js.Dict.set("k", 1) +let set2 = Js.Dict.set(d, "k", 1) + +let keys1 = d->Js.Dict.keys +let keys2 = Js.Dict.keys(d) + +let values1 = d->Js.Dict.values +let values2 = Js.Dict.values(d) + +let entries1 = d->Js.Dict.entries +let entries2 = Js.Dict.entries(d) + +let dStr: Js.Dict.t = Js.Dict.empty() +let del1 = dStr->Js.Dict.unsafeDeleteKey("k") +let del2 = Js.Dict.unsafeDeleteKey(dStr, "k") + +let empty1: Js.Dict.t = Js.Dict.empty() + +let fromArray1 = [("a", 1), ("b", 2)]->Js.Dict.fromArray +let fromArray2 = Js.Dict.fromArray([("a", 1), ("b", 2)]) + +let fromList1 = list{("a", 1), ("b", 2)}->Js.Dict.fromList +let fromList2 = Js.Dict.fromList(list{("a", 1), ("b", 2)}) + +let map2 = Js.Dict.map(x => x + 1, d) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res new file mode 100644 index 0000000000..4391c59509 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res @@ -0,0 +1,35 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Dict.res. +let d = Dict.make() + +let get1 = d->Dict.get("k") +let get2 = Dict.get(d, "k") + +let unsafeGet1 = d->Dict.getUnsafe("k") +let unsafeGet2 = Dict.getUnsafe(d, "k") + +let set1 = d->Dict.set("k", 1) +let set2 = Dict.set(d, "k", 1) + +let keys1 = d->Dict.keysToArray +let keys2 = Dict.keysToArray(d) + +let values1 = d->Dict.valuesToArray +let values2 = Dict.valuesToArray(d) + +let entries1 = d->Dict.toArray +let entries2 = Dict.toArray(d) + +let dStr: Js.Dict.t = Dict.make() +let del1 = dStr->Dict.delete("k") +let del2 = Dict.delete(dStr, "k") + +let empty1: Js.Dict.t = Dict.make() + +let fromArray1 = [("a", 1), ("b", 2)]->Dict.fromArray +let fromArray2 = Dict.fromArray([("a", 1), ("b", 2)]) + +let fromList1 = list{("a", 1), ("b", 2)}->Js.Dict.fromList +let fromList2 = Js.Dict.fromList(list{("a", 1), ("b", 2)}) + +let map2 = Dict.mapValues(d, x => x + 1) From 7a25a6468d73eb1617e281d333e0cdc732d86f56 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 29 Aug 2025 22:27:26 +0200 Subject: [PATCH 12/41] migrations for Js_date --- packages/@rescript/runtime/Js_date.res | 435 +++++++++++++++++- .../StdlibMigration_Date.res.expected | 188 ++++++++ .../src/migrate/StdlibMigration_Date.res | 136 ++++++ .../Migrated_StdlibMigration_Date.res | 189 ++++++++ tools/src/migrate.ml | 28 ++ 5 files changed, 965 insertions(+), 11 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Date.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Date.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res diff --git a/packages/@rescript/runtime/Js_date.res b/packages/@rescript/runtime/Js_date.res index 73eb494d38..be002df106 100644 --- a/packages/@rescript/runtime/Js_date.res +++ b/packages/@rescript/runtime/Js_date.res @@ -42,6 +42,10 @@ on MDN.) Js.Date.valueOf(exampleDate) == 123456654321.0 ``` */ +@deprecated({ + reason: "Use `Date.getTime` instead.", + migrate: Date.getTime(), +}) @send external valueOf: t => float = "valueOf" @@ -56,6 +60,10 @@ on MDN. let now = Js.Date.make() ``` */ +@deprecated({ + reason: "Use `Date.make` instead.", + migrate: Date.make(), +}) @new external make: unit => t = "Date" @@ -71,6 +79,10 @@ on MDN. Js.Date.fromFloat(123456654321.0) == exampleDate ``` */ +@deprecated({ + reason: "Use `Date.fromTime` instead.", + migrate: Date.fromTime(), +}) @new external fromFloat: float => t = "Date" @@ -89,6 +101,10 @@ Js.Date.fromString("1973-11-29T21:30:54.321Z00:00") == exampleDate Js.Date.fromString("Thor, 32 Lok -19 60:70:80 XYZ") // returns NaN ``` */ +@deprecated({ + reason: "Use `Date.fromString` instead.", + migrate: Date.fromString(), +}) @new external fromString: string => t = "Date" @@ -105,6 +121,13 @@ on MDN. let november1 = Js.Date.makeWithYM(~year=2020.0, ~month=10.0, ()) ``` */ +@deprecated({ + reason: "Use `Date.makeWithYM` instead.", + migrate: Date.makeWithYM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ), +}) @new external makeWithYM: (~year: float, ~month: float, unit) => t = "Date" @@ -115,6 +138,14 @@ year in the current time zone. Fractional parts of arguments are ignored. See Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) on MDN. */ +@deprecated({ + reason: "Use `Date.makeWithYMD` instead.", + migrate: Date.makeWithYMD( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ), +}) @new external makeWithYMD: (~year: float, ~month: float, ~date: float, unit) => t = "Date" @@ -125,6 +156,15 @@ Fractional parts of arguments are ignored. See [`Date()` Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) on MDN. Fractional parts of the arguments are ignored. */ +@deprecated({ + reason: "Use `Date.makeWithYMDH` instead.", + migrate: Date.makeWithYMDH( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ), +}) @new external makeWithYMDH: (~year: float, ~month: float, ~date: float, ~hours: float, unit) => t = "Date" @@ -136,6 +176,16 @@ Fractional parts of arguments are ignored. See [`Date()` Constructor](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date) on MDN. */ +@deprecated({ + reason: "Use `Date.makeWithYMDHM` instead.", + migrate: Date.makeWithYMDHM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ), +}) @new external makeWithYMDHM: ( ~year: float, @@ -167,6 +217,17 @@ Js.Date.makeWithYMDHMS( ) == exampleDate ``` */ +@deprecated({ + reason: "Use `Date.makeWithYMDHMS` instead.", + migrate: Date.makeWithYMDHMS( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) @new external makeWithYMDHMS: ( ~year: float, @@ -191,6 +252,13 @@ on MDN. let november1 = Js.Date.utcWithYM(~year=2020.0, ~month=10.0, ()) ``` */ +@deprecated({ + reason: "Use `Date.UTC.makeWithYM` instead.", + migrate: Date.UTC.makeWithYM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ), +}) @val("Date.UTC") external utcWithYM: (~year: float, ~month: float, unit) => float = "" @@ -201,6 +269,14 @@ of arguments are ignored. See [`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) on MDN. */ +@deprecated({ + reason: "Use `Date.UTC.makeWithYMD` instead.", + migrate: Date.UTC.makeWithYMD( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ), +}) @val("Date.UTC") external utcWithYMD: (~year: float, ~month: float, ~date: float, unit) => float = "" @@ -212,6 +288,15 @@ See [`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) on MDN. */ +@deprecated({ + reason: "Use `Date.UTC.makeWithYMDH` instead.", + migrate: Date.UTC.makeWithYMDH( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ), +}) @val("Date.UTC") external utcWithYMDH: (~year: float, ~month: float, ~date: float, ~hours: float, unit) => float = "" @@ -223,6 +308,16 @@ arguments are ignored. See [`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) on MDN. */ +@deprecated({ + reason: "Use `Date.UTC.makeWithYMDHM` instead.", + migrate: Date.UTC.makeWithYMDHM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ), +}) @val("Date.UTC") external utcWithYMDHM: ( ~year: float, @@ -242,6 +337,17 @@ See [`Date.UTC`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC) on MDN. */ +@deprecated({ + reason: "Use `Date.UTC.makeWithYMDHMS` instead.", + migrate: Date.UTC.makeWithYMDHMS( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) @val("Date.UTC") external utcWithYMDHMS: ( ~year: float, @@ -254,10 +360,19 @@ external utcWithYMDHMS: ( ) => float = "" /** Returns the current time as number of milliseconds since Unix epoch. */ +@deprecated({ + reason: "Use `Date.now` instead.", + migrate: Date.now(), +}) @val("Date.now") external now: unit => float = "" -@new @deprecated("Please use `fromString` instead") external parse: string => t = "Date" +@new +@deprecated({ + reason: "Use `Date.fromString` instead.", + migrate: Date.fromString(), +}) +external parse: string => t = "Date" /** Returns a float with the number of milliseconds past the epoch represented by @@ -268,7 +383,12 @@ string. According to the documentation on MDN, its use is discouraged. Returns `NaN` if passed invalid date string. */ -@val("parse") @scope("Date") +@deprecated({ + reason: "Use `Date.fromString` + `Date.getTime` instead.", + migrate: Date.getTime(Date.fromString(%insert.unlabelledArgument(0))), +}) +@val("parse") +@scope("Date") external parseAsFloat: string => float = "" /** @@ -283,6 +403,10 @@ on MDN. Js.Date.getDate(exampleDate) == 29.0 ``` */ +@deprecated({ + reason: "Use `Date.getDate` instead.", + migrate: Date.getDate(), +}) @send external getDate: t => float = "getDate" @@ -298,6 +422,10 @@ on MDN. Js.Date.getDay(exampleDate) == 4.0 ``` */ +@deprecated({ + reason: "Use `Date.getDay` instead.", + migrate: Date.getDay(), +}) @send external getDay: t => float = "getDay" @@ -313,6 +441,10 @@ on MDN. Js.Date.getFullYear(exampleDate) == 1973.0 ``` */ +@deprecated({ + reason: "Use `Date.getFullYear` instead.", + migrate: Date.getFullYear(), +}) @send external getFullYear: t => float = "getFullYear" @@ -327,6 +459,10 @@ on MDN. Js.Date.getHours(exampleDate) == 22.0 // Vienna is in GMT+01:00 ``` */ +@deprecated({ + reason: "Use `Date.getHours` instead.", + migrate: Date.getHours(), +}) @send external getHours: t => float = "getHours" @@ -342,6 +478,10 @@ on MDN. Js.Date.getMilliseconds(exampleDate) == 321.0 ``` */ +@deprecated({ + reason: "Use `Date.getMilliseconds` instead.", + migrate: Date.getMilliseconds(), +}) @send external getMilliseconds: t => float = "getMilliseconds" @@ -357,6 +497,10 @@ on MDN. Js.Date.getMinutes(exampleDate) == 30.0 ``` */ +@deprecated({ + reason: "Use `Date.getMinutes` instead.", + migrate: Date.getMinutes(), +}) @send external getMinutes: t => float = "getMinutes" @@ -372,6 +516,10 @@ on MDN. Js.Date.getMonth(exampleDate) == 10.0 ``` */ +@deprecated({ + reason: "Use `Date.getMonth` instead.", + migrate: Date.getMonth(), +}) @send external getMonth: t => float = "getMonth" @@ -386,6 +534,10 @@ on MDN. Js.Date.getSeconds(exampleDate) == 54.0 ``` */ +@deprecated({ + reason: "Use `Date.getSeconds` instead.", + migrate: Date.getSeconds(), +}) @send external getSeconds: t => float = "getSeconds" @@ -400,6 +552,10 @@ on MDN. Js.Date.getTime(exampleDate) == 123456654321.0 ``` */ +@deprecated({ + reason: "Use `Date.getTime` instead.", + migrate: Date.getTime(), +}) @send external getTime: t => float = "getTime" @@ -414,6 +570,10 @@ on MDN. Js.Date.getTimezoneOffset(exampleDate) == -60.0 ``` */ +@deprecated({ + reason: "Use `Date.getTimezoneOffset` instead.", + migrate: Date.getTimezoneOffset(), +}) @send external getTimezoneOffset: t => float = "getTimezoneOffset" @@ -428,6 +588,10 @@ on MDN. Js.Date.getUTCDate(exampleDate) == 29.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCDate` instead.", + migrate: Date.getUTCDate(), +}) @send external getUTCDate: t => float = "getUTCDate" @@ -443,6 +607,10 @@ on MDN. Js.Date.getUTCDay(exampleDate) == 4.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCDay` instead.", + migrate: Date.getUTCDay(), +}) @send external getUTCDay: t => float = "getUTCDay" @@ -458,6 +626,10 @@ on MDN. Js.Date.getUTCFullYear(exampleDate) == 1973.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCFullYear` instead.", + migrate: Date.getUTCFullYear(), +}) @send external getUTCFullYear: t => float = "getUTCFullYear" @@ -472,6 +644,10 @@ on MDN. Js.Date.getUTCHours(exampleDate) == 21.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCHours` instead.", + migrate: Date.getUTCHours(), +}) @send external getUTCHours: t => float = "getUTCHours" @@ -486,6 +662,10 @@ on MDN. Js.Date.getUTCMilliseconds(exampleDate) == 321.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCMilliseconds` instead.", + migrate: Date.getUTCMilliseconds(), +}) @send external getUTCMilliseconds: t => float = "getUTCMilliseconds" @@ -500,6 +680,10 @@ on MDN. Js.Date.getUTCMinutes(exampleDate) == 30.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCMinutes` instead.", + migrate: Date.getUTCMinutes(), +}) @send external getUTCMinutes: t => float = "getUTCMinutes" @@ -515,6 +699,10 @@ on MDN. Js.Date.getUTCMonth(exampleDate) == 10.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCMonth` instead.", + migrate: Date.getUTCMonth(), +}) @send external getUTCMonth: t => float = "getUTCMonth" @@ -529,10 +717,15 @@ on MDN. Js.Date.getUTCSeconds(exampleDate) == 54.0 ``` */ +@deprecated({ + reason: "Use `Date.getUTCSeconds` instead.", + migrate: Date.getUTCSeconds(), +}) @send external getUTCSeconds: t => float = "getUTCSeconds" -@send @deprecated("Use `getFullYear` instead.") external getYear: t => float = "getYear" +@send @deprecated({reason: "Use `getFullYear` instead.", migrate: Date.getFullYear()}) +external getYear: t => float = "getYear" /** Sets the given `Date`’s day of month to the value in the second argument @@ -551,6 +744,10 @@ date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") twoWeeksBefore == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setDate` instead.", + migrate: Date.setDate(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setDate: (t, float) => float = "setDate" @@ -570,6 +767,10 @@ date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") nextYear == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setFullYear` instead.", + migrate: Date.setFullYear(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setFullYear: (t, float) => float = "setFullYear" @@ -590,6 +791,13 @@ date1 == Js.Date.fromString("1974-01-22T21:30:54.321Z00:00") future == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setFullYearM` instead.", + migrate: Date.setFullYearM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ), +}) @send external setFullYearM: (t, ~year: float, ~month: float, unit) => float = "setFullYear" @@ -611,6 +819,14 @@ future == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setFullYearMD` instead.", + migrate: Date.setFullYearMD( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ), +}) external setFullYearMD: (t, ~year: float, ~month: float, ~date: float, unit) => float = "setFullYear" @@ -630,6 +846,10 @@ date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") nextHour == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setHours` instead.", + migrate: Date.setHours(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setHours: (t, float) => float = "setHours" @@ -650,6 +870,13 @@ date1 == Js.Date.fromString("1973-11-29T22:46:54.321Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setHoursM` instead.", + migrate: Date.setHoursM( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ), +}) @send external setHoursM: (t, ~hours: float, ~minutes: float, unit) => float = "setHours" @@ -671,6 +898,14 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setHoursMS` instead.", + migrate: Date.setHoursMS( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) external setHoursMS: (t, ~hours: float, ~minutes: float, ~seconds: float, unit) => float = "setHours" @@ -699,6 +934,15 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setHoursMSMs` instead.", + migrate: Date.setHoursMSMs( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setHoursMSMs: ( t, ~hours: float, @@ -725,6 +969,10 @@ date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setMilliseconds` instead.", + migrate: Date.setMilliseconds(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setMilliseconds: (t, float) => float = "setMilliseconds" @@ -744,6 +992,10 @@ date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setMinutes` instead.", + migrate: Date.setMinutes(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setMinutes: (t, float) => float = "setMinutes" @@ -765,6 +1017,13 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setMinutesS` instead.", + migrate: Date.setMinutesS( + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) external setMinutesS: (t, ~minutes: float, ~seconds: float, unit) => float = "setMinutes" /** @@ -785,6 +1044,14 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setMinutesSMs` instead.", + migrate: Date.setMinutesSMs( + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setMinutesSMs: (t, ~minutes: float, ~seconds: float, ~milliseconds: float, unit) => float = "setMinutes" @@ -804,6 +1071,10 @@ date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setMonth` instead.", + migrate: Date.setMonth(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setMonth: (t, float) => float = "setMonth" @@ -824,7 +1095,7 @@ date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") futureTime == Js.Date.getTime(date1) ``` */ -@send +@deprecated("Use `Date.setMonth` then `Date.setDate`. No direct 1:1 migration available.") @send external setMonthD: (t, ~month: float, ~date: float, unit) => float = "setMonth" /** @@ -843,6 +1114,10 @@ date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setSeconds` instead.", + migrate: Date.setSeconds(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setSeconds: (t, float) => float = "setSeconds" @@ -864,6 +1139,13 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setSecondsMs` instead.", + migrate: Date.setSecondsMs( + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setSecondsMs: (t, ~seconds: float, ~milliseconds: float, unit) => float = "setSeconds" /** @@ -883,7 +1165,7 @@ date1 == Js.Date.fromString("1976-04-19T12:37:12.101Z00:00") futureTime == Js.Date.getTime(date1) ``` */ -@send +@send @deprecated external setTime: (t, float) => float = "setTime" /** @@ -902,6 +1184,10 @@ date1 == Js.Date.fromString("1973-11-15T21:30:54.321Z00:00") twoWeeksBefore == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCDate` instead.", + migrate: Date.setUTCDate(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCDate: (t, float) => float = "setUTCDate" @@ -921,6 +1207,10 @@ date1 == Js.Date.fromString("1974-11-15T21:30:54.321Z00:00") nextYear == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCFullYear` instead.", + migrate: Date.setUTCFullYear(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCFullYear: (t, float) => float = "setUTCFullYear" @@ -941,6 +1231,13 @@ future == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCFullYearM` instead.", + migrate: Date.setUTCFullYearM( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ), +}) external setUTCFullYearM: (t, ~year: float, ~month: float, unit) => float = "setUTCFullYear" /** @@ -961,6 +1258,14 @@ future == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCFullYearMD` instead.", + migrate: Date.setUTCFullYearMD( + ~year=Float.toInt(%insert.labelledArgument("year")), + ~month=Float.toInt(%insert.labelledArgument("month")), + ~day=Float.toInt(%insert.labelledArgument("date")), + ), +}) external setUTCFullYearMD: (t, ~year: float, ~month: float, ~date: float, unit) => float = "setUTCFullYear" @@ -980,6 +1285,10 @@ date1 == Js.Date.fromString("1973-11-29T22:30:54.321Z00:00") nextHour == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCHours` instead.", + migrate: Date.setUTCHours(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCHours: (t, float) => float = "setUTCHours" @@ -1000,6 +1309,13 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCHoursM` instead.", + migrate: Date.setUTCHoursM( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ), +}) external setUTCHoursM: (t, ~hours: float, ~minutes: float, unit) => float = "setUTCHours" /** @@ -1021,6 +1337,14 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCHoursMS` instead.", + migrate: Date.setUTCHoursMS( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) external setUTCHoursMS: (t, ~hours: float, ~minutes: float, ~seconds: float, unit) => float = "setUTCHours" @@ -1049,6 +1373,15 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCHoursMSMs` instead.", + migrate: Date.setUTCHoursMSMs( + ~hours=Float.toInt(%insert.labelledArgument("hours")), + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setUTCHoursMSMs: ( t, ~hours: float, @@ -1074,6 +1407,10 @@ date1 == Js.Date.fromString("1973-11-29T21:30:54.494Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCMilliseconds` instead.", + migrate: Date.setUTCMilliseconds(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCMilliseconds: (t, float) => float = "setUTCMilliseconds" @@ -1093,6 +1430,10 @@ date1 == Js.Date.fromString("1973-11-29T21:34:54.494Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCMinutes` instead.", + migrate: Date.setUTCMinutes(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCMinutes: (t, float) => float = "setUTCMinutes" @@ -1113,6 +1454,13 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCMinutesS` instead.", + migrate: Date.setUTCMinutesS( + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ), +}) external setUTCMinutesS: (t, ~minutes: float, ~seconds: float, unit) => float = "setUTCMinutes" /** @@ -1139,6 +1487,14 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCMinutesSMs` instead.", + migrate: Date.setUTCMinutesSMs( + ~minutes=Float.toInt(%insert.labelledArgument("minutes")), + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setUTCMinutesSMs: ( t, ~minutes: float, @@ -1163,6 +1519,10 @@ date1 == Js.Date.fromString("1973-12-29T21:34:56.789Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCMonth` instead.", + migrate: Date.setUTCMonth(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCMonth: (t, float) => float = "setUTCMonth" @@ -1182,6 +1542,7 @@ date1 == Js.Date.fromString("1973-12-08T21:34:56.789Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated("Use `Date.setUTCMonth` then `Date.setUTCDate`. No direct 1:1 migration available.") @send external setUTCMonthD: (t, ~month: float, ~date: float, unit) => float = "setUTCMonth" @@ -1201,6 +1562,10 @@ date1 == Js.Date.fromString("1973-12-29T21:30:56.321Z00:00") futureTime == Js.Date.getTime(date1) ``` */ +@deprecated({ + reason: "Use `Date.setUTCSeconds` instead.", + migrate: Date.setUTCSeconds(Float.toInt(%insert.unlabelledArgument(1))), +}) @send external setUTCSeconds: (t, float) => float = "setUTCSeconds" @@ -1221,11 +1586,18 @@ futureTime == Js.Date.getTime(date1) ``` */ @send +@deprecated({ + reason: "Use `Date.setUTCSecondsMs` instead.", + migrate: Date.setUTCSecondsMs( + ~seconds=Float.toInt(%insert.labelledArgument("seconds")), + ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), + ), +}) external setUTCSecondsMs: (t, ~seconds: float, ~milliseconds: float, unit) => float = "setUTCSeconds" /** Same as [`setTime()`](#settime). */ -@send +@deprecated @send external setUTCTime: (t, float) => float = "setTime" @send @deprecated("Use `setFullYear` instead") external setYear: (t, float) => float = "setYear" @@ -1242,10 +1614,19 @@ on MDN. Js.Date.toDateString(exampleDate) == "Thu Nov 29 1973" ``` */ +@deprecated({ + reason: "Use `Date.toDateString` instead.", + migrate: Date.toDateString(), +}) @send external toDateString: t => string = "toDateString" -@send @deprecated("Use `toUTCString` instead") external toGMTString: t => string = "toGMTString" +@send +@deprecated({ + reason: "Use `Date.toUTCString` instead.", + migrate: Date.toUTCString(), +}) +external toGMTString: t => string = "toGMTString" /** Returns a simplified version of the ISO 8601 format for the date. See @@ -1258,14 +1639,18 @@ on MDN. Js.Date.toISOString(exampleDate) == "1973-11-29T21:30:54.321Z" ``` */ +@deprecated({ + reason: "Use `Date.toISOString` instead.", + migrate: Date.toISOString(), +}) @send external toISOString: t => string = "toISOString" +@deprecated({ + reason: "This method is unsafe. It will be changed to return option in a future release. Please use toJSONUnsafe instead.", + migrate: Date.toJSON(), +}) @send -@deprecated( - "This method is unsafe. It will be changed to return option in a future \ - release. Please use toJSONUnsafe instead." -) external toJSON: t => string = "toJSON" /** @@ -1273,6 +1658,10 @@ Returns a string representation of the given date. See [`Date.toJSON`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON) on MDN. */ +@deprecated({ + reason: "Use `Date.toJSON` instead.", + migrate: Date.toJSON(), +}) @send external toJSONUnsafe: t => string = "toJSON" @@ -1289,6 +1678,10 @@ Js.Date.toLocaleDateString(exampleDate) == "11/29/1973" // for en_US.utf8 Js.Date.toLocaleDateString(exampleDate) == "29.11.73" // for de_DE.utf8 ``` */ +@deprecated({ + reason: "Use `Date.toLocaleDateString` instead.", + migrate: Date.toLocaleDateString(), +}) @send external toLocaleDateString: t => string = "toLocaleDateString" @@ -1307,6 +1700,10 @@ Js.Date.toLocaleString(exampleDate) == "11/29/1973, 10:30:54 PM" // for en_US.ut Js.Date.toLocaleString(exampleDate) == "29.11.1973, 22:30:54" // for de_DE.utf8 ``` */ +@deprecated({ + reason: "Use `Date.toLocaleString` instead.", + migrate: Date.toLocaleString(), +}) @send external toLocaleString: t => string = "toLocaleString" @@ -1324,6 +1721,10 @@ Js.Date.toLocaleString(exampleDate) == "10:30:54 PM" // for en_US.utf8 Js.Date.toLocaleString(exampleDate) == "22:30:54" // for de_DE.utf8 ``` */ +@deprecated({ + reason: "Use `Date.toLocaleTimeString` instead.", + migrate: Date.toLocaleTimeString(), +}) @send external toLocaleTimeString: t => string = "toLocaleTimeString" @@ -1343,6 +1744,10 @@ Js.Date.toString( ) == "Thu Nov 29 1973 22:30:54 GMT+0100 (Central European Standard Time)" ``` */ +@deprecated({ + reason: "Use `Date.toString` instead.", + migrate: Date.toString(), +}) @send external toString: t => string = "toString" @@ -1358,6 +1763,10 @@ on MDN. Js.Date.toTimeString(exampleDate) == "22:30:54 GMT+0100 (Central European Standard Time)" ``` */ +@deprecated({ + reason: "Use `Date.toTimeString` instead.", + migrate: Date.toTimeString(), +}) @send external toTimeString: t => string = "toTimeString" @@ -1373,5 +1782,9 @@ on MDN. Js.Date.toUTCString(exampleDate) == "Thu, 29 Nov 1973 21:30:54 GMT" ``` */ +@deprecated({ + reason: "Use `Date.toUTCString` instead.", + migrate: Date.toUTCString(), +}) @send external toUTCString: t => string = "toUTCString" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected new file mode 100644 index 0000000000..fa0108faf1 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected @@ -0,0 +1,188 @@ +let d1 = Date.make() +let d2 = Date.fromString("1973-11-29T21:30:54.321Z") +let d3 = Date.fromTime(123456789.0) + +let msNow = Date.now() + +let v1 = d2->Date.getTime +let v2 = Date.getTime(d2) + +let y = d2->Date.getFullYear +let mo = d2->Date.getMonth +let dayOfMonth = d2->Date.getDate +let dayOfWeek = d2->Date.getDay +let h = d2->Date.getHours +let mi = d2->Date.getMinutes +let s = d2->Date.getSeconds +let ms = d2->Date.getMilliseconds +let tz = d2->Date.getTimezoneOffset + +let uy = d2->Date.getUTCFullYear +let um = d2->Date.getUTCMonth +let ud = d2->Date.getUTCDate +let uday = d2->Date.getUTCDay +let uh = d2->Date.getUTCHours +let umi = d2->Date.getUTCMinutes +let us = d2->Date.getUTCSeconds +let ums = d2->Date.getUTCMilliseconds + +let s1 = d2->Date.toISOString +let s2 = d2->Date.toUTCString +let s3 = d2->Date.toString +let s4 = d2->Date.toTimeString +let s5 = d2->Date.toDateString +let s6 = d2->Date.toLocaleString +let s7 = d2->Date.toLocaleDateString +let s8 = d2->Date.toLocaleTimeString + +/* Additional deprecated APIs to exercise migration */ + +/* getters and legacy variants */ +let t = d2->Date.getTime +let y2 = d2->Date.getFullYear + +/* constructors with components */ +let mym = Date.makeWithYM(~year=Float.toInt(2020.0), ~month=Float.toInt(10.0)) +let mymd = Date.makeWithYMD( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), +) +let mymdh = Date.makeWithYMDH( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), +) +let mymdhm = Date.makeWithYMDHM( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), +) +let mymdhms = Date.makeWithYMDHMS( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), + ~seconds=Float.toInt(54.0), +) + +/* Date.UTC variants */ +let uym = Date.UTC.makeWithYM(~year=Float.toInt(2020.0), ~month=Float.toInt(10.0)) +let uymd = Date.UTC.makeWithYMD( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), +) +let uymdh = Date.UTC.makeWithYMDH( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), +) +let uymdhm = Date.UTC.makeWithYMDHM( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), +) +let uymdhms = Date.UTC.makeWithYMDHMS( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), + ~seconds=Float.toInt(54.0), +) + +/* parse APIs */ +let p = Date.fromString("1973-11-29T21:30:54.321Z") +let pf = Date.getTime(Date.fromString("1973-11-29T21:30:54.321Z")) + +/* setters (local time) */ +let setD = d2->Date.setDate(Float.toInt(15.0)) +let setFY = d2->Date.setFullYear(Float.toInt(1974.0)) + +let setFYM = d2->Date.setFullYearM(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0)) +let setFYMD = + d2->Date.setFullYearMD(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0), ~day=Float.toInt(7.0)) +let setH = d2->Date.setHours(Float.toInt(22.0)) +let setHM = d2->Date.setHoursM(~hours=Float.toInt(22.0), ~minutes=Float.toInt(46.0)) +let setHMS = + d2->Date.setHoursMS( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ) +let setHMSMs = + d2->Date.setHoursMSMs( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ~milliseconds=Float.toInt(494.0), + ) +let setMs = d2->Date.setMilliseconds(Float.toInt(494.0)) +let setMin = d2->Date.setMinutes(Float.toInt(34.0)) +let setMinS = d2->Date.setMinutesS(~minutes=Float.toInt(34.0), ~seconds=Float.toInt(56.0)) +let setMinSMs = + d2->Date.setMinutesSMs( + ~minutes=Float.toInt(34.0), + ~seconds=Float.toInt(56.0), + ~milliseconds=Float.toInt(789.0), + ) +let setMon = d2->Date.setMonth(Float.toInt(11.0)) +let setMonD = d2->Js.Date.setMonthD(~month=11.0, ~date=8.0, ()) +let setSec = d2->Date.setSeconds(Float.toInt(56.0)) +let setSecMs = d2->Date.setSecondsMs(~seconds=Float.toInt(56.0), ~milliseconds=Float.toInt(789.0)) + +/* setters (UTC) */ +let setUD = d2->Date.setUTCDate(Float.toInt(15.0)) +let setUFY = d2->Date.setUTCFullYear(Float.toInt(1974.0)) +let setUFYM = d2->Date.setUTCFullYearM(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0)) +let setUFYMD = + d2->Date.setUTCFullYearMD( + ~year=Float.toInt(1974.0), + ~month=Float.toInt(0.0), + ~day=Float.toInt(7.0), + ) +let setUH = d2->Date.setUTCHours(Float.toInt(22.0)) +let setUHM = d2->Date.setUTCHoursM(~hours=Float.toInt(22.0), ~minutes=Float.toInt(46.0)) +let setUHMS = + d2->Date.setUTCHoursMS( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ) +let setUHMSMs = + d2->Date.setUTCHoursMSMs( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ~milliseconds=Float.toInt(494.0), + ) +let setUMs = d2->Date.setUTCMilliseconds(Float.toInt(494.0)) +let setUMin = d2->Date.setUTCMinutes(Float.toInt(34.0)) +let setUMinS = d2->Date.setUTCMinutesS(~minutes=Float.toInt(34.0), ~seconds=Float.toInt(56.0)) +let setUMinSMs = + d2->Date.setUTCMinutesSMs( + ~minutes=Float.toInt(34.0), + ~seconds=Float.toInt(56.0), + ~milliseconds=Float.toInt(789.0), + ) +let setUMon = d2->Date.setUTCMonth(Float.toInt(11.0)) +let setUMonD = d2->Js.Date.setUTCMonthD(~month=11.0, ~date=8.0, ()) +let setUSec = d2->Date.setUTCSeconds(Float.toInt(56.0)) +let setUSecMs = + d2->Date.setUTCSecondsMs(~seconds=Float.toInt(56.0), ~milliseconds=Float.toInt(789.0)) +let setUT = d2->Js.Date.setUTCTime(198765432101.0) +let setYr = d2->Js.Date.setYear(1999.0) + +/* other string conversions */ +let s9 = d2->Date.toUTCString +let j1 = d2->Date.toJSON +let j2 = d2->Date.toJSON + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Date.res b/tests/tools_tests/src/migrate/StdlibMigration_Date.res new file mode 100644 index 0000000000..09ad744b65 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Date.res @@ -0,0 +1,136 @@ +let d1 = Js.Date.make() +let d2 = Js.Date.fromString("1973-11-29T21:30:54.321Z") +let d3 = Js.Date.fromFloat(123456789.0) + +let msNow = Js.Date.now() + +let v1 = d2->Js.Date.valueOf +let v2 = Js.Date.valueOf(d2) + +let y = d2->Js.Date.getFullYear +let mo = d2->Js.Date.getMonth +let dayOfMonth = d2->Js.Date.getDate +let dayOfWeek = d2->Js.Date.getDay +let h = d2->Js.Date.getHours +let mi = d2->Js.Date.getMinutes +let s = d2->Js.Date.getSeconds +let ms = d2->Js.Date.getMilliseconds +let tz = d2->Js.Date.getTimezoneOffset + +let uy = d2->Js.Date.getUTCFullYear +let um = d2->Js.Date.getUTCMonth +let ud = d2->Js.Date.getUTCDate +let uday = d2->Js.Date.getUTCDay +let uh = d2->Js.Date.getUTCHours +let umi = d2->Js.Date.getUTCMinutes +let us = d2->Js.Date.getUTCSeconds +let ums = d2->Js.Date.getUTCMilliseconds + +let s1 = d2->Js.Date.toISOString +let s2 = d2->Js.Date.toUTCString +let s3 = d2->Js.Date.toString +let s4 = d2->Js.Date.toTimeString +let s5 = d2->Js.Date.toDateString +let s6 = d2->Js.Date.toLocaleString +let s7 = d2->Js.Date.toLocaleDateString +let s8 = d2->Js.Date.toLocaleTimeString + +/* Additional deprecated APIs to exercise migration */ + +/* getters and legacy variants */ +let t = d2->Js.Date.getTime +let y2 = d2->Js.Date.getYear + +/* constructors with components */ +let mym = Js.Date.makeWithYM(~year=2020.0, ~month=10.0, ()) +let mymd = Js.Date.makeWithYMD(~year=1973.0, ~month=10.0, ~date=29.0, ()) +let mymdh = Js.Date.makeWithYMDH(~year=1973.0, ~month=10.0, ~date=29.0, ~hours=21.0, ()) +let mymdhm = Js.Date.makeWithYMDHM( + ~year=1973.0, + ~month=10.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + (), +) +let mymdhms = Js.Date.makeWithYMDHMS( + ~year=1973.0, + ~month=10.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + ~seconds=54.0, + (), +) + +/* Date.UTC variants */ +let uym = Js.Date.utcWithYM(~year=2020.0, ~month=10.0, ()) +let uymd = Js.Date.utcWithYMD(~year=1973.0, ~month=10.0, ~date=29.0, ()) +let uymdh = Js.Date.utcWithYMDH(~year=1973.0, ~month=10.0, ~date=29.0, ~hours=21.0, ()) +let uymdhm = Js.Date.utcWithYMDHM( + ~year=1973.0, + ~month=10.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + (), +) +let uymdhms = Js.Date.utcWithYMDHMS( + ~year=1973.0, + ~month=10.0, + ~date=29.0, + ~hours=21.0, + ~minutes=30.0, + ~seconds=54.0, + (), +) + +/* parse APIs */ +let p = Js.Date.parse("1973-11-29T21:30:54.321Z") +let pf = Js.Date.parseAsFloat("1973-11-29T21:30:54.321Z") + +/* setters (local time) */ +let setD = d2->Js.Date.setDate(15.0) +let setFY = d2->Js.Date.setFullYear(1974.0) + +let setFYM = d2->Js.Date.setFullYearM(~year=1974.0, ~month=0.0, ()) +let setFYMD = d2->Js.Date.setFullYearMD(~year=1974.0, ~month=0.0, ~date=7.0, ()) +let setH = d2->Js.Date.setHours(22.0) +let setHM = d2->Js.Date.setHoursM(~hours=22.0, ~minutes=46.0, ()) +let setHMS = d2->Js.Date.setHoursMS(~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +let setHMSMs = + d2->Js.Date.setHoursMSMs(~hours=22.0, ~minutes=46.0, ~seconds=37.0, ~milliseconds=494.0, ()) +let setMs = d2->Js.Date.setMilliseconds(494.0) +let setMin = d2->Js.Date.setMinutes(34.0) +let setMinS = d2->Js.Date.setMinutesS(~minutes=34.0, ~seconds=56.0, ()) +let setMinSMs = d2->Js.Date.setMinutesSMs(~minutes=34.0, ~seconds=56.0, ~milliseconds=789.0, ()) +let setMon = d2->Js.Date.setMonth(11.0) +let setMonD = d2->Js.Date.setMonthD(~month=11.0, ~date=8.0, ()) +let setSec = d2->Js.Date.setSeconds(56.0) +let setSecMs = d2->Js.Date.setSecondsMs(~seconds=56.0, ~milliseconds=789.0, ()) + +/* setters (UTC) */ +let setUD = d2->Js.Date.setUTCDate(15.0) +let setUFY = d2->Js.Date.setUTCFullYear(1974.0) +let setUFYM = d2->Js.Date.setUTCFullYearM(~year=1974.0, ~month=0.0, ()) +let setUFYMD = d2->Js.Date.setUTCFullYearMD(~year=1974.0, ~month=0.0, ~date=7.0, ()) +let setUH = d2->Js.Date.setUTCHours(22.0) +let setUHM = d2->Js.Date.setUTCHoursM(~hours=22.0, ~minutes=46.0, ()) +let setUHMS = d2->Js.Date.setUTCHoursMS(~hours=22.0, ~minutes=46.0, ~seconds=37.0, ()) +let setUHMSMs = + d2->Js.Date.setUTCHoursMSMs(~hours=22.0, ~minutes=46.0, ~seconds=37.0, ~milliseconds=494.0, ()) +let setUMs = d2->Js.Date.setUTCMilliseconds(494.0) +let setUMin = d2->Js.Date.setUTCMinutes(34.0) +let setUMinS = d2->Js.Date.setUTCMinutesS(~minutes=34.0, ~seconds=56.0, ()) +let setUMinSMs = d2->Js.Date.setUTCMinutesSMs(~minutes=34.0, ~seconds=56.0, ~milliseconds=789.0, ()) +let setUMon = d2->Js.Date.setUTCMonth(11.0) +let setUMonD = d2->Js.Date.setUTCMonthD(~month=11.0, ~date=8.0, ()) +let setUSec = d2->Js.Date.setUTCSeconds(56.0) +let setUSecMs = d2->Js.Date.setUTCSecondsMs(~seconds=56.0, ~milliseconds=789.0, ()) +let setUT = d2->Js.Date.setUTCTime(198765432101.0) +let setYr = d2->Js.Date.setYear(1999.0) + +/* other string conversions */ +let s9 = d2->Js.Date.toGMTString +let j1 = d2->Js.Date.toJSON +let j2 = d2->Js.Date.toJSONUnsafe diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res new file mode 100644 index 0000000000..ba866356f3 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res @@ -0,0 +1,189 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Date.res. +let d1 = Date.make() +let d2 = Date.fromString("1973-11-29T21:30:54.321Z") +let d3 = Date.fromTime(123456789.0) + +let msNow = Date.now() + +let v1 = d2->Date.getTime +let v2 = Date.getTime(d2) + +let y = d2->Date.getFullYear +let mo = d2->Date.getMonth +let dayOfMonth = d2->Date.getDate +let dayOfWeek = d2->Date.getDay +let h = d2->Date.getHours +let mi = d2->Date.getMinutes +let s = d2->Date.getSeconds +let ms = d2->Date.getMilliseconds +let tz = d2->Date.getTimezoneOffset + +let uy = d2->Date.getUTCFullYear +let um = d2->Date.getUTCMonth +let ud = d2->Date.getUTCDate +let uday = d2->Date.getUTCDay +let uh = d2->Date.getUTCHours +let umi = d2->Date.getUTCMinutes +let us = d2->Date.getUTCSeconds +let ums = d2->Date.getUTCMilliseconds + +let s1 = d2->Date.toISOString +let s2 = d2->Date.toUTCString +let s3 = d2->Date.toString +let s4 = d2->Date.toTimeString +let s5 = d2->Date.toDateString +let s6 = d2->Date.toLocaleString +let s7 = d2->Date.toLocaleDateString +let s8 = d2->Date.toLocaleTimeString + +/* Additional deprecated APIs to exercise migration */ + +/* getters and legacy variants */ +let t = d2->Date.getTime +let y2 = d2->Date.getFullYear + +/* constructors with components */ +let mym = Date.makeWithYM(~year=Float.toInt(2020.0), ~month=Float.toInt(10.0)) +let mymd = Date.makeWithYMD( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), +) +let mymdh = Date.makeWithYMDH( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), +) +let mymdhm = Date.makeWithYMDHM( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), +) +let mymdhms = Date.makeWithYMDHMS( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), + ~seconds=Float.toInt(54.0), +) + +/* Date.UTC variants */ +let uym = Date.UTC.makeWithYM(~year=Float.toInt(2020.0), ~month=Float.toInt(10.0)) +let uymd = Date.UTC.makeWithYMD( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), +) +let uymdh = Date.UTC.makeWithYMDH( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), +) +let uymdhm = Date.UTC.makeWithYMDHM( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), +) +let uymdhms = Date.UTC.makeWithYMDHMS( + ~year=Float.toInt(1973.0), + ~month=Float.toInt(10.0), + ~day=Float.toInt(29.0), + ~hours=Float.toInt(21.0), + ~minutes=Float.toInt(30.0), + ~seconds=Float.toInt(54.0), +) + +/* parse APIs */ +let p = Date.fromString("1973-11-29T21:30:54.321Z") +let pf = Date.getTime(Date.fromString("1973-11-29T21:30:54.321Z")) + +/* setters (local time) */ +let setD = d2->Date.setDate(Float.toInt(15.0)) +let setFY = d2->Date.setFullYear(Float.toInt(1974.0)) + +let setFYM = d2->Date.setFullYearM(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0)) +let setFYMD = + d2->Date.setFullYearMD(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0), ~day=Float.toInt(7.0)) +let setH = d2->Date.setHours(Float.toInt(22.0)) +let setHM = d2->Date.setHoursM(~hours=Float.toInt(22.0), ~minutes=Float.toInt(46.0)) +let setHMS = + d2->Date.setHoursMS( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ) +let setHMSMs = + d2->Date.setHoursMSMs( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ~milliseconds=Float.toInt(494.0), + ) +let setMs = d2->Date.setMilliseconds(Float.toInt(494.0)) +let setMin = d2->Date.setMinutes(Float.toInt(34.0)) +let setMinS = d2->Date.setMinutesS(~minutes=Float.toInt(34.0), ~seconds=Float.toInt(56.0)) +let setMinSMs = + d2->Date.setMinutesSMs( + ~minutes=Float.toInt(34.0), + ~seconds=Float.toInt(56.0), + ~milliseconds=Float.toInt(789.0), + ) +let setMon = d2->Date.setMonth(Float.toInt(11.0)) +let setMonD = d2->Js.Date.setMonthD(~month=11.0, ~date=8.0, ()) +let setSec = d2->Date.setSeconds(Float.toInt(56.0)) +let setSecMs = d2->Date.setSecondsMs(~seconds=Float.toInt(56.0), ~milliseconds=Float.toInt(789.0)) + +/* setters (UTC) */ +let setUD = d2->Date.setUTCDate(Float.toInt(15.0)) +let setUFY = d2->Date.setUTCFullYear(Float.toInt(1974.0)) +let setUFYM = d2->Date.setUTCFullYearM(~year=Float.toInt(1974.0), ~month=Float.toInt(0.0)) +let setUFYMD = + d2->Date.setUTCFullYearMD( + ~year=Float.toInt(1974.0), + ~month=Float.toInt(0.0), + ~day=Float.toInt(7.0), + ) +let setUH = d2->Date.setUTCHours(Float.toInt(22.0)) +let setUHM = d2->Date.setUTCHoursM(~hours=Float.toInt(22.0), ~minutes=Float.toInt(46.0)) +let setUHMS = + d2->Date.setUTCHoursMS( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ) +let setUHMSMs = + d2->Date.setUTCHoursMSMs( + ~hours=Float.toInt(22.0), + ~minutes=Float.toInt(46.0), + ~seconds=Float.toInt(37.0), + ~milliseconds=Float.toInt(494.0), + ) +let setUMs = d2->Date.setUTCMilliseconds(Float.toInt(494.0)) +let setUMin = d2->Date.setUTCMinutes(Float.toInt(34.0)) +let setUMinS = d2->Date.setUTCMinutesS(~minutes=Float.toInt(34.0), ~seconds=Float.toInt(56.0)) +let setUMinSMs = + d2->Date.setUTCMinutesSMs( + ~minutes=Float.toInt(34.0), + ~seconds=Float.toInt(56.0), + ~milliseconds=Float.toInt(789.0), + ) +let setUMon = d2->Date.setUTCMonth(Float.toInt(11.0)) +let setUMonD = d2->Js.Date.setUTCMonthD(~month=11.0, ~date=8.0, ()) +let setUSec = d2->Date.setUTCSeconds(Float.toInt(56.0)) +let setUSecMs = + d2->Date.setUTCSecondsMs(~seconds=Float.toInt(56.0), ~milliseconds=Float.toInt(789.0)) +let setUT = d2->Js.Date.setUTCTime(198765432101.0) +let setYr = d2->Js.Date.setYear(1999.0) + +/* other string conversions */ +let s9 = d2->Date.toUTCString +let j1 = d2->Date.toJSON +let j2 = d2->Date.toJSON diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index 4a4cd4cf0e..e1f0c5db28 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -224,6 +224,20 @@ module MapperUtils = struct let dropped = drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped in + (* Also drop any unit arguments that remain from the source call. *) + let is_unit_expr (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_construct ({txt = Lident "()"}, None) -> true + | _ -> false + in + let dropped = + List.filter + (fun (label, arg) -> + match label with + | Asttypes.Nolabel -> not (is_unit_expr arg) + | _ -> true) + dropped + in let renamed = rename_labels dropped ~labelled_args_map in renamed @ template_args_to_insert @@ -244,6 +258,20 @@ module MapperUtils = struct ~unlabelled_positions_to_insert:adjusted_unlabelled_to_drop ~will_be_mapped in + (* Drop any unit arguments that remain from the source call. *) + let is_unit_expr (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_construct ({txt = Lident "()"}, None) -> true + | _ -> false + in + let dropped = + List.filter + (fun (label, arg) -> + match label with + | Asttypes.Nolabel -> not (is_unit_expr arg) + | _ -> true) + dropped + in let renamed = rename_labels dropped ~labelled_args_map in renamed @ template_args_to_insert end From 9116fcdfbf00caec451e6a7fe552ddb5bb4ae70e Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 29 Aug 2025 22:44:35 +0200 Subject: [PATCH 13/41] migrations for Js_re --- packages/@rescript/runtime/Js_re.res | 72 ++++++++++++++++++- ...tdlibMigrationNoCompile_Js_Re.res.expected | 11 +++ .../StdlibMigration_Js_Re.res.expected | 43 +++++++++++ .../StdlibMigrationNoCompile_Js_Re.res | 10 +++ .../src/migrate/StdlibMigration_Js_Re.res | 42 +++++++++++ .../Migrated_StdlibMigration_Js_Re.res | 44 ++++++++++++ 6 files changed, 220 insertions(+), 2 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigrationNoCompile_Js_Re.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Js_Re.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res diff --git a/packages/@rescript/runtime/Js_re.res b/packages/@rescript/runtime/Js_re.res index 41d57f0070..0a66e52b3a 100644 --- a/packages/@rescript/runtime/Js_re.res +++ b/packages/@rescript/runtime/Js_re.res @@ -40,16 +40,31 @@ type result An `array` of the match and captures, the first is the full match and the remaining are the substring captures. */ +@deprecated({ + reason: "Use `RegExp.Result.matches` instead.", + migrate: RegExp.Result.matches(), +}) external captures: result => array> = "%identity" -@deprecated("Use Js.Re.captures instead") +@deprecated({ + reason: "Use `RegExp.Result.matches` instead.", + migrate: RegExp.Result.matches(), +}) external matches: result => array = "%identity" /** 0-based index of the match in the input string. */ +@deprecated({ + reason: "Use `RegExp.Result.index` instead.", + migrate: RegExp.Result.index(), +}) @get external index: result => int = "index" /** The original input string. */ +@deprecated({ + reason: "Use `RegExp.Result.input` instead.", + migrate: RegExp.Result.input(), +}) @get external input: result => string = "input" @@ -74,6 +89,10 @@ let firstReScriptFileExtension = (filename, content) => { firstReScriptFileExtension("School", "School.res School.resi Main.js School.bs.js") ``` */ +@deprecated({ + reason: "Use `RegExp.fromString` instead.", + migrate: RegExp.fromString(), +}) @new external fromString: string => t = "RegExp" @@ -89,18 +108,34 @@ Valid flags: - **u** unicode (es2015) - **y** sticky (es2015) */ +@deprecated({ + reason: "Use `RegExp.fromString` instead.", + migrate: RegExp.fromString(), +}) @new external fromStringWithFlags: (string, ~flags: string) => t = "RegExp" /** Returns the enabled flags as a string. */ +@deprecated({ + reason: "Use `RegExp.flags` instead.", + migrate: RegExp.flags(), +}) @get external flags: t => string = "flags" /** Returns a `bool` indicating whether the global flag is set. */ +@deprecated({ + reason: "Use `RegExp.global` instead.", + migrate: RegExp.global(), +}) @get external global: t => bool = "global" /** Returns a `bool` indicating whether the ignoreCase flag is set. */ +@deprecated({ + reason: "Use `RegExp.ignoreCase` instead.", + migrate: RegExp.ignoreCase(), +}) @get external ignoreCase: t => bool = "ignoreCase" @@ -132,26 +167,50 @@ See [`RegExp: lastIndex`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex) on MDN. */ +@deprecated({ + reason: "Use `RegExp.lastIndex` instead.", + migrate: RegExp.lastIndex(), +}) @get external lastIndex: t => int = "lastIndex" /** Sets the index at which the next match will start its search from. */ +@deprecated({ + reason: "Use `RegExp.setLastIndex` instead.", + migrate: RegExp.setLastIndex(), +}) @set external setLastIndex: (t, int) => unit = "lastIndex" /** Returns a `bool` indicating whether the multiline flag is set. */ +@deprecated({ + reason: "Use `RegExp.multiline` instead.", + migrate: RegExp.multiline(), +}) @get external multiline: t => bool = "multiline" /** Returns the pattern as a `string`. */ +@deprecated({ + reason: "Use `RegExp.source` instead.", + migrate: RegExp.source(), +}) @get external source: t => string = "source" /** Returns a `bool` indicating whether the sticky flag is set. */ +@deprecated({ + reason: "Use `RegExp.sticky` instead.", + migrate: RegExp.sticky(), +}) @get external sticky: t => bool = "sticky" /** Returns a `bool` indicating whether the unicode flag is set. */ +@deprecated({ + reason: "Use `RegExp.unicode` instead.", + migrate: RegExp.unicode(), +}) @get external unicode: t => bool = "unicode" @@ -174,7 +233,12 @@ let result = Js.Re.exec_(re, "The Quick Brown Fox Jumps Over The Lazy Dog") See [`RegExp.prototype.exec()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec) on MDN. */ -@send @return(null_to_opt) +@deprecated({ + reason: "Use `RegExp.exec` instead.", + migrate: RegExp.exec(), +}) +@send +@return(null_to_opt) external exec_: (t, string) => option = "exec" /** @@ -196,5 +260,9 @@ Js.log(str->startsWith("hello")) /* prints "true" */ See [`RegExp.prototype.test()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/test) on MDN. */ +@deprecated({ + reason: "Use `RegExp.test` instead.", + migrate: RegExp.test(), +}) @send external test_: (t, string) => bool = "test" diff --git a/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Js_Re.res.expected b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Js_Re.res.expected new file mode 100644 index 0000000000..1d6923dd1e --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigrationNoCompile_Js_Re.res.expected @@ -0,0 +1,11 @@ +let re2 = RegExp.fromString("foo", ~flags="gi") + +let capture_access = switch re2->RegExp.exec("Foo") { +| None => 0 +| Some(r) => + switch RegExp.Result.matches(r) { + | [Value(full), _] => String.length(full) + | _ => 0 + } +} + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected new file mode 100644 index 0000000000..05d1c01c59 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected @@ -0,0 +1,43 @@ +let re1 = RegExp.fromString("foo") +let re2 = RegExp.fromString("foo", ~flags="gi") + +let flags1 = re2->RegExp.flags +let flags2 = RegExp.flags(re2) + +let g1 = re2->RegExp.global +let g2 = RegExp.global(re2) + +let ic1 = re2->RegExp.ignoreCase +let ic2 = RegExp.ignoreCase(re2) + +let m1 = re2->RegExp.multiline +let m2 = RegExp.multiline(re2) + +let u1 = re2->RegExp.unicode +let u2 = RegExp.unicode(re2) + +let y1 = re2->RegExp.sticky +let y2 = RegExp.sticky(re2) + +let src1 = re2->RegExp.source +let src2 = RegExp.source(re2) + +let li1 = re2->RegExp.lastIndex +let () = re2->RegExp.setLastIndex(0) + +let exec1 = re2->RegExp.exec("Foo bar") +let exec2 = RegExp.exec(re2, "Foo bar") + +let test1 = re2->RegExp.test("Foo bar") +let test2 = RegExp.test(re2, "Foo bar") + +let result_index = switch re2->RegExp.exec("Foo bar") { +| None => 0 +| Some(r) => RegExp.Result.index(r) +} + +let result_input = switch re2->RegExp.exec("Foo bar") { +| None => "" +| Some(r) => RegExp.Result.input(r) +} + diff --git a/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Js_Re.res b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Js_Re.res new file mode 100644 index 0000000000..a820035008 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigrationNoCompile_Js_Re.res @@ -0,0 +1,10 @@ +let re2 = Js.Re.fromStringWithFlags("foo", ~flags="gi") + +let capture_access = switch re2->Js.Re.exec_("Foo") { +| None => 0 +| Some(r) => + switch Js.Re.captures(r) { + | [Value(full), _] => String.length(full) + | _ => 0 + } +} diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res new file mode 100644 index 0000000000..c46d50ea0f --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res @@ -0,0 +1,42 @@ +let re1 = Js.Re.fromString("foo") +let re2 = Js.Re.fromStringWithFlags("foo", ~flags="gi") + +let flags1 = re2->Js.Re.flags +let flags2 = Js.Re.flags(re2) + +let g1 = re2->Js.Re.global +let g2 = Js.Re.global(re2) + +let ic1 = re2->Js.Re.ignoreCase +let ic2 = Js.Re.ignoreCase(re2) + +let m1 = re2->Js.Re.multiline +let m2 = Js.Re.multiline(re2) + +let u1 = re2->Js.Re.unicode +let u2 = Js.Re.unicode(re2) + +let y1 = re2->Js.Re.sticky +let y2 = Js.Re.sticky(re2) + +let src1 = re2->Js.Re.source +let src2 = Js.Re.source(re2) + +let li1 = re2->Js.Re.lastIndex +let () = re2->Js.Re.setLastIndex(0) + +let exec1 = re2->Js.Re.exec_("Foo bar") +let exec2 = Js.Re.exec_(re2, "Foo bar") + +let test1 = re2->Js.Re.test_("Foo bar") +let test2 = Js.Re.test_(re2, "Foo bar") + +let result_index = switch re2->Js.Re.exec_("Foo bar") { +| None => 0 +| Some(r) => Js.Re.index(r) +} + +let result_input = switch re2->Js.Re.exec_("Foo bar") { +| None => "" +| Some(r) => Js.Re.input(r) +} diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res new file mode 100644 index 0000000000..4659a35ddf --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res @@ -0,0 +1,44 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js_Re.res. +let re1 = RegExp.fromString("foo") +let re2 = RegExp.fromString("foo", ~flags="gi") + +let flags1 = re2->RegExp.flags +let flags2 = RegExp.flags(re2) + +let g1 = re2->RegExp.global +let g2 = RegExp.global(re2) + +let ic1 = re2->RegExp.ignoreCase +let ic2 = RegExp.ignoreCase(re2) + +let m1 = re2->RegExp.multiline +let m2 = RegExp.multiline(re2) + +let u1 = re2->RegExp.unicode +let u2 = RegExp.unicode(re2) + +let y1 = re2->RegExp.sticky +let y2 = RegExp.sticky(re2) + +let src1 = re2->RegExp.source +let src2 = RegExp.source(re2) + +let li1 = re2->RegExp.lastIndex +let () = re2->RegExp.setLastIndex(0) + +let exec1 = re2->RegExp.exec("Foo bar") +let exec2 = RegExp.exec(re2, "Foo bar") + +let test1 = re2->RegExp.test("Foo bar") +let test2 = RegExp.test(re2, "Foo bar") + +let result_index = switch re2->RegExp.exec("Foo bar") { +| None => 0 +| Some(r) => RegExp.Result.index(r) +} + +let result_input = switch re2->RegExp.exec("Foo bar") { +| None => "" +| Some(r) => RegExp.Result.input(r) +} From 990d89fe55c93703b0d0a08d75523d9dec285a28 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 29 Aug 2025 22:47:29 +0200 Subject: [PATCH 14/41] migrations for Js_math --- packages/@rescript/runtime/Js_math.res | 440 +++++++++++++++--- .../StdlibMigration_Math.res.expected | 82 ++++ .../src/migrate/StdlibMigration_Math.res | 81 ++++ .../Migrated_StdlibMigration_Math.res | 83 ++++ 4 files changed, 625 insertions(+), 61 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Math.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Math.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Math.res diff --git a/packages/@rescript/runtime/Js_math.res b/packages/@rescript/runtime/Js_math.res index dfda4e187c..29dda7b623 100644 --- a/packages/@rescript/runtime/Js_math.res +++ b/packages/@rescript/runtime/Js_math.res @@ -34,7 +34,12 @@ Euler's number; ≈ 2.718281828459045. See [`Math.E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/E) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.e` instead.", + migrate: Math.Constants.e, +}) +@val +@scope("Math") external _E: float = "E" /** @@ -42,7 +47,12 @@ Natural logarithm of 2; ≈ 0.6931471805599453. See [`Math.LN2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN2) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.ln2` instead.", + migrate: Math.Constants.ln2, +}) +@val +@scope("Math") external _LN2: float = "LN2" /** @@ -50,7 +60,12 @@ Natural logarithm of 10; ≈ 2.302585092994046. See [`Math.LN10`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LN10) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.ln10` instead.", + migrate: Math.Constants.ln10, +}) +@val +@scope("Math") external _LN10: float = "LN10" /** @@ -58,7 +73,12 @@ Base 2 logarithm of E; ≈ 1.4426950408889634. See [`Math.LOG2E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG2E) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.log2e` instead.", + migrate: Math.Constants.log2e, +}) +@val +@scope("Math") external _LOG2E: float = "LOG2E" /** @@ -66,7 +86,12 @@ Base 10 logarithm of E; ≈ 0.4342944819032518. See [`Math.LOG10E`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/LOG10E) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.log10e` instead.", + migrate: Math.Constants.log10e, +}) +@val +@scope("Math") external _LOG10E: float = "LOG10E" /** @@ -74,7 +99,12 @@ Pi - ratio of the circumference to the diameter of a circle; ≈ 3.1415926535897 [`Math.PI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.pi` instead.", + migrate: Math.Constants.pi, +}) +@val +@scope("Math") external _PI: float = "PI" /** @@ -82,7 +112,12 @@ Square root of 1/2; ≈ 0.7071067811865476. See [`Math.SQRT1_2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT1_2) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.sqrt1_2` instead.", + migrate: Math.Constants.sqrt1_2, +}) +@val +@scope("Math") external _SQRT1_2: float = "SQRT1_2" /** @@ -90,7 +125,12 @@ Square root of 2; ≈ 1.4142135623730951. See [`Math.SQRT2`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/SQRT2) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Constants.sqrt2` instead.", + migrate: Math.Constants.sqrt2, +}) +@val +@scope("Math") external _SQRT2: float = "SQRT2" /** @@ -98,7 +138,12 @@ Absolute value for integer argument. See [`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.abs` instead.", + migrate: Math.Int.abs(), +}) +@val +@scope("Math") external abs_int: int => int = "abs" /** @@ -106,7 +151,12 @@ Absolute value for float argument. See [`Math.abs`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/abs) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.abs` instead.", + migrate: Math.abs(), +}) +@val +@scope("Math") external abs_float: float => float = "abs" /** @@ -115,7 +165,12 @@ the range [-1.0, 1.0]. See [`Math.acos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acos) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.acos` instead.", + migrate: Math.acos(), +}) +@val +@scope("Math") external acos: float => float = "acos" /** @@ -124,7 +179,12 @@ is less than 1.0. See [`Math.acosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/acosh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.acosh` instead.", + migrate: Math.acosh(), +}) +@val +@scope("Math") external acosh: float => float = "acosh" /** @@ -133,7 +193,12 @@ the range [-1.0, 1.0]. See [`Math.asin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asin) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.asin` instead.", + migrate: Math.asin(), +}) +@val +@scope("Math") external asin: float => float = "asin" /** @@ -141,7 +206,12 @@ Hyperbolic arcsine (in radians) of argument. See [`Math.asinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/asinh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.asinh` instead.", + migrate: Math.asinh(), +}) +@val +@scope("Math") external asinh: float => float = "asinh" /** @@ -149,7 +219,12 @@ Arctangent (in radians) of argument. See [`Math.atan`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atan) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.atan` instead.", + migrate: Math.atan(), +}) +@val +@scope("Math") external atan: float => float = "atan" /** @@ -159,7 +234,12 @@ arguments -1.0 and 1.0. See [`Math.atanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/atanh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.atanh` instead.", + migrate: Math.atanh(), +}) +@val +@scope("Math") external atanh: float => float = "atanh" /** @@ -178,7 +258,12 @@ Js.Math.atan2(~x=-5.0, ~y=5.0, ()) == 3.0 *. Js.Math._PI /. 4.0 Js.Math.atan2(~x=-0.0, ~y=-5.0, ()) == -.Js.Math._PI /. 2.0 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.atan2` instead.", + migrate: Math.atan2(~y=%insert.labelledArgument("y"), ~x=%insert.labelledArgument("x")), +}) +@val +@scope("Math") external atan2: (~y: float, ~x: float, unit) => float = "atan2" /** @@ -186,7 +271,12 @@ Cube root. See [`Math.cbrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cbrt) on MDN */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.cbrt` instead.", + migrate: Math.cbrt(), +}) +@val +@scope("Math") external cbrt: float => float = "cbrt" /** @@ -207,10 +297,19 @@ Js.Math.unsafe_ceil_int(-3.1) == -3 Js.Math.unsafe_ceil_int(1.0e15) // result is outside range of int datatype ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.ceil` instead.", + migrate: Math.Int.ceil(), +}) +@val +@scope("Math") external unsafe_ceil_int: float => int = "ceil" -@deprecated("Please use `unsafe_ceil_int` instead") let unsafe_ceil = unsafe_ceil_int +@deprecated({ + reason: "Use `Math.Int.ceil` instead.", + migrate: Math.Int.ceil(), +}) +let unsafe_ceil = unsafe_ceil_int /** Returns the smallest `int` greater than or equal to the argument; the result @@ -228,6 +327,10 @@ Js.Math.ceil_int(-1.0e15) == -2147483648 Js.Math.ceil_int(1.0e15) == 2147483647 ``` */ +@deprecated({ + reason: "Use `Math.Int.ceil` instead.", + migrate: Math.Int.ceil(), +}) let ceil_int = (f: float): int => if f > Js_int.toFloat(Js_int.max) { Js_int.max @@ -237,7 +340,11 @@ let ceil_int = (f: float): int => unsafe_ceil_int(f) } -@deprecated("Please use `ceil_int` instead") let ceil = ceil_int +@deprecated({ + reason: "Use `Math.Int.ceil` instead.", + migrate: Math.Int.ceil(), +}) +let ceil = ceil_int /** Returns the smallest integral value greater than or equal to the argument. @@ -255,7 +362,12 @@ Js.Math.ceil_float(-3.1) == -3.0 Js.Math.ceil_float(2_150_000_000.3) == 2_150_000_001.0 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.ceil` instead.", + migrate: Math.ceil(), +}) +@val +@scope("Math") external ceil_float: float => float = "ceil" /** @@ -271,7 +383,12 @@ Js.Math.clz32(-1) == 0 Js.Math.clz32(255) == 24 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.clz32` instead.", + migrate: Math.Int.clz32(), +}) +@val +@scope("Math") external clz32: int => int = "clz32" /** @@ -279,7 +396,12 @@ Cosine of argument, which must be specified in radians. See [`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.cos` instead.", + migrate: Math.cos(), +}) +@val +@scope("Math") external cos: float => float = "cos" /** @@ -287,7 +409,12 @@ Hyperbolic cosine of argument, which must be specified in radians. See [`Math.cosh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cosh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.cosh` instead.", + migrate: Math.cosh(), +}) +@val +@scope("Math") external cosh: float => float = "cosh" /** @@ -296,7 +423,12 @@ power of the given argument. See [`Math.exp`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/exp) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.exp` instead.", + migrate: Math.exp(), +}) +@val +@scope("Math") external exp: float => float = "exp" /** @@ -305,7 +437,12 @@ argument minus 1. See [`Math.expm1`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/expm1) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.expm1` instead.", + migrate: Math.expm1(), +}) +@val +@scope("Math") external expm1: float => float = "expm1" /** @@ -326,10 +463,19 @@ Js.Math.unsafe_floor_int(-3.7) == -4 Js.Math.unsafe_floor_int(1.0e15) // result is outside range of int datatype ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.floor` instead.", + migrate: Math.Int.floor(), +}) +@val +@scope("Math") external unsafe_floor_int: float => int = "floor" -@deprecated("Please use `unsafe_floor_int` instead") let unsafe_floor = unsafe_floor_int +@deprecated({ + reason: "Use `Math.Int.floor` instead.", + migrate: Math.Int.floor(), +}) +let unsafe_floor = unsafe_floor_int /** Returns the largest `int` less than or equal to the argument; the result is @@ -347,6 +493,10 @@ Js.Math.floor_int(-1.0e15) == -2147483648 Js.Math.floor_int(1.0e15) == 2147483647 ``` */ +@deprecated({ + reason: "Use `Math.Int.floor` instead.", + migrate: Math.Int.floor(), +}) let floor_int = f => if f > Js_int.toFloat(Js_int.max) { Js_int.max @@ -356,7 +506,11 @@ let floor_int = f => unsafe_floor(f) } -@deprecated("Please use `floor_int` instead") let floor = floor_int +@deprecated({ + reason: "Use `Math.Int.floor` instead.", + migrate: Math.Int.floor(), +}) +let floor = floor_int /** Returns the largest integral value less than or equal to the argument. The @@ -373,7 +527,12 @@ Js.Math.floor_float(-3.1) == -4.0 Js.Math.floor_float(2_150_000_000.3) == 2_150_000_000.0 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.floor` instead.", + migrate: Math.floor(), +}) +@val +@scope("Math") external floor_float: float => float = "floor" /** @@ -388,7 +547,12 @@ Js.Math.fround(5.5) == 5.5 Js.Math.fround(5.05) == 5.050000190734863 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.fround` instead.", + migrate: Math.fround(), +}) +@val +@scope("Math") external fround: float => float = "fround" /** @@ -397,7 +561,12 @@ Pythagorean formula). See [`Math.hypot`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.hypot` instead.", + migrate: Math.hypot(), +}) +@val +@scope("Math") external hypot: (float, float) => float = "hypot" /** @@ -413,7 +582,13 @@ on MDN. Js.Math.hypotMany([3.0, 4.0, 12.0]) == 13.0 ``` */ -@val @variadic @scope("Math") +@deprecated({ + reason: "Use `Math.hypotMany` instead.", + migrate: Math.hypotMany(), +}) +@val +@variadic +@scope("Math") external hypotMany: array => float = "hypot" /** @@ -422,7 +597,12 @@ performance of multiplication of numbers stored as 32-bit integers. See [`Math.imul`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.imul` instead.", + migrate: Math.Int.imul(), +}) +@val +@scope("Math") external imul: (int, int) => int = "imul" /** @@ -439,7 +619,12 @@ Js.Math.log(Js.Math._E) == 1.0 Js.Math.log(100.0) == 4.605170185988092 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.log` instead.", + migrate: Math.log(), +}) +@val +@scope("Math") external log: float => float = "log" /** @@ -455,7 +640,12 @@ Js.Math.log1p(Js.Math._E -. 1.0) == 1.0 Js.Math.log1p(99.0) == 4.605170185988092 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.log1p` instead.", + migrate: Math.log1p(), +}) +@val +@scope("Math") external log1p: float => float = "log1p" /** @@ -472,7 +662,12 @@ Js.Math.log10(0.01) == -2.0 Js.Math.log10(Js.Math.sqrt(10.0)) == 0.5 ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.log10` instead.", + migrate: Math.log10(), +}) +@val +@scope("Math") external log10: float => float = "log10" /** @@ -489,7 +684,12 @@ Js.Math.log2(0.125) == -3.0 Js.Math.log2(Js.Math._SQRT2) == 0.5000000000000001 // due to precision ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.log2` instead.", + migrate: Math.log2(), +}) +@val +@scope("Math") external log2: float => float = "log2" /** @@ -497,7 +697,12 @@ Returns the maximum of its two integer arguments. See [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.max` instead.", + migrate: Math.Int.max(), +}) +@val +@scope("Math") external max_int: (int, int) => int = "max" /** @@ -505,7 +710,13 @@ Returns the maximum of the integers in the given array. See [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) on MDN. */ -@val @variadic @scope("Math") +@deprecated({ + reason: "Use `Math.Int.maxMany` instead.", + migrate: Math.Int.maxMany(), +}) +@val +@variadic +@scope("Math") external maxMany_int: array => int = "max" /** @@ -513,7 +724,12 @@ Returns the maximum of its two floating point arguments. See [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.max` instead.", + migrate: Math.max(), +}) +@val +@scope("Math") external max_float: (float, float) => float = "max" /** @@ -521,7 +737,13 @@ Returns the maximum of the floating point values in the given array. See [`Math.max`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/max) on MDN. */ -@val @variadic @scope("Math") +@deprecated({ + reason: "Use `Math.maxMany` instead.", + migrate: Math.maxMany(), +}) +@val +@variadic +@scope("Math") external maxMany_float: array => float = "max" /** @@ -529,7 +751,12 @@ Returns the minimum of its two integer arguments. See [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.min` instead.", + migrate: Math.Int.min(), +}) +@val +@scope("Math") external min_int: (int, int) => int = "min" /** @@ -537,7 +764,13 @@ Returns the minimum of the integers in the given array. See [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) on MDN. */ -@val @variadic @scope("Math") +@deprecated({ + reason: "Use `Math.Int.minMany` instead.", + migrate: Math.Int.minMany(), +}) +@val +@variadic +@scope("Math") external minMany_int: array => int = "min" /** @@ -545,7 +778,12 @@ Returns the minimum of its two floating point arguments. See [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.min` instead.", + migrate: Math.min(), +}) +@val +@scope("Math") external min_float: (float, float) => float = "min" /** @@ -553,7 +791,13 @@ Returns the minimum of the floating point values in the given array. See [`Math.min`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/min) on MDN. */ -@val @variadic @scope("Math") +@deprecated({ + reason: "Use `Math.minMany` instead.", + migrate: Math.minMany(), +}) +@val +@variadic +@scope("Math") external minMany_float: array => float = "min" /** @@ -568,7 +812,12 @@ on MDN. Js.Math.pow_int(~base=3, ~exp=4) == 81 ``` */ -@val @scope("Math") @deprecated("use `pow_float` instead, the return type may be not int") +@deprecated({ + reason: "Use `Math.Int.pow` instead.", + migrate: Math.Int.pow(%insert.labelledArgument("base"), ~exp=%insert.labelledArgument("exp")), +}) +@val +@scope("Math") external pow_int: (~base: int, ~exp: int) => int = "pow" /** @@ -587,7 +836,12 @@ Js.Math.pow_float(~base=625.0, ~exp=-0.5) == 0.04 Js.Float.isNaN(Js.Math.pow_float(~base=-2.0, ~exp=0.5)) == true ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.pow` instead.", + migrate: Math.pow(%insert.labelledArgument("base"), ~exp=%insert.labelledArgument("exp")), +}) +@val +@scope("Math") external pow_float: (~base: float, ~exp: float) => float = "pow" /** @@ -595,7 +849,12 @@ Returns a random number in the half-closed interval [0,1). See [`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.random` instead.", + migrate: Math.random(), +}) +@val +@scope("Math") external random: unit => float = "random" /** @@ -604,6 +863,10 @@ half-closed interval [minVal, maxVal). See [`Math.random`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random) on MDN. */ +@deprecated({ + reason: "Use `Math.Int.random` instead.", + migrate: Math.Int.random(), +}) let random_int = (min, max) => floor(random() *. Js_int.toFloat(max - min)) + min /** @@ -624,7 +887,12 @@ Js.Math.unsafe_round(-3.5) == -3 Js.Math.unsafe_round(2_150_000_000_000.3) // out of range for int ``` */ -@val @scope("Math") +@deprecated({ + reason: "Use `Float.toInt(Math.round(_))` instead.", + migrate: Float.toInt(Math.round(%insert.unlabelledArgument(0))), +}) +@val +@scope("Math") external unsafe_round: float => int = "round" /** @@ -632,7 +900,12 @@ Rounds to nearest integral value (expressed as a float). See [`Math.round`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.round` instead.", + migrate: Math.round(), +}) +@val +@scope("Math") external round: float => float = "round" /** @@ -641,7 +914,12 @@ positive. See [`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.Int.sign` instead.", + migrate: Math.Int.sign(), +}) +@val +@scope("Math") external sign_int: int => int = "sign" /** @@ -650,7 +928,12 @@ positive. See [`Math.sign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.sign` instead.", + migrate: Math.sign(), +}) +@val +@scope("Math") external sign_float: float => float = "sign" /** @@ -658,7 +941,12 @@ Sine of argument, which must be specified in radians. See [`Math.sin`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sin) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.sin` instead.", + migrate: Math.sin(), +}) +@val +@scope("Math") external sin: float => float = "sin" /** @@ -666,7 +954,12 @@ Hyperbolic sine of argument, which must be specified in radians. See [`Math.sinh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sinh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.sinh` instead.", + migrate: Math.sinh(), +}) +@val +@scope("Math") external sinh: float => float = "sinh" /** @@ -674,7 +967,12 @@ Square root. If the argument is negative, this function returns `NaN`. See [`Math.sqrt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sqrt) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.sqrt` instead.", + migrate: Math.sqrt(), +}) +@val +@scope("Math") external sqrt: float => float = "sqrt" /** @@ -683,7 +981,12 @@ argument is positive infinity or negative infinity. See [`Math.cos`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/cos) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.tan` instead.", + migrate: Math.tan(), +}) +@val +@scope("Math") external tan: float => float = "tan" /** @@ -691,7 +994,12 @@ Hyperbolic tangent of argument, which must be specified in radians. See [`Math.tanh`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/tanh) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.tanh` instead.", + migrate: Math.tanh(), +}) +@val +@scope("Math") external tanh: float => float = "tanh" /** @@ -703,7 +1011,12 @@ exactly. See [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Float.toInt(Math.trunc(_))` instead.", + migrate: Float.toInt(Math.trunc(%insert.unlabelledArgument(0))), +}) +@val +@scope("Math") external unsafe_trunc: float => int = "trunc" /** @@ -711,5 +1024,10 @@ Truncates its argument; i.e., removes fractional digits. See [`Math.trunc`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc) on MDN. */ -@val @scope("Math") +@deprecated({ + reason: "Use `Math.trunc` instead.", + migrate: Math.trunc(), +}) +@val +@scope("Math") external trunc: float => float = "trunc" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Math.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Math.res.expected new file mode 100644 index 0000000000..ccce8ab209 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Math.res.expected @@ -0,0 +1,82 @@ +// Exercise migrations from Js.Math to Math + +let e = Math.Constants.e +let pi = Math.Constants.pi +let ln2 = Math.Constants.ln2 +let ln10 = Math.Constants.ln10 +let log2e = Math.Constants.log2e +let log10e = Math.Constants.log10e +let sqrt_half = Math.Constants.sqrt1_2 +let sqrt2c = Math.Constants.sqrt2 + +let absInt1 = Math.Int.abs(-5) +let absFloat1 = Math.abs(-3.5) + +let acos1 = Math.acos(1.0) +let acosh1 = Math.acosh(1.5) +let asinh1 = Math.asinh(1.0) +let asin1 = Math.asin(0.5) +let atan1 = Math.atan(1.0) +let atanh1 = Math.atanh(0.5) + +let atan21 = Math.atan2(~y=0.0, ~x=10.0) + +let cbrt1 = Math.cbrt(27.0) + +let ceilInt1 = Math.Int.ceil(3.2) +let ceilInt2 = Math.Int.ceil(3.2) +let ceilFloat1 = Math.ceil(3.2) + +let clz1 = Math.Int.clz32(255) + +let cos1 = Math.cos(0.0) +let cosh1 = Math.cosh(0.0) +let exp1 = Math.exp(1.0) +let expm11 = Math.expm1(1.0) +let log1p1 = Math.log1p(1.0) + +let floorInt1 = Math.Int.floor(3.7) +let floorInt2 = Math.Int.floor(3.7) +let floorFloat1 = Math.floor(3.7) + +let fround1 = Math.fround(5.05) + +let hypot1 = Math.hypot(3.0, 4.0) +let hypotMany1 = Math.hypotMany([3.0, 4.0, 12.0]) + +let imul1 = Math.Int.imul(3, 4) + +let log1 = Math.log(Math.Constants.e) +let log10_1 = Math.log10(1000.0) +let log2_1 = Math.log2(512.0) + +let maxInt1 = Math.Int.max(1, 2) +let maxIntMany1 = Math.Int.maxMany([1, 10, 3]) +let maxFloat1 = Math.max(1.5, 2.5) +let maxFloatMany1 = Math.maxMany([1.5, 2.5, 0.5]) + +let minInt1 = Math.Int.min(1, 2) +let minIntMany1 = Math.Int.minMany([1, 10, 3]) +let minFloat1 = Math.min(1.5, 2.5) +let minFloatMany1 = Math.minMany([1.5, 2.5, 0.5]) + +let powInt1 = Math.Int.pow(3, ~exp=4) +let powFloat1 = Math.pow(3.0, ~exp=4.0) + +let rand1 = Math.random() + +let roundUnsafe1 = Float.toInt(Math.round(3.7)) +let round1 = Math.round(3.7) + +let signInt1 = Math.Int.sign(-5) +let signFloat1 = Math.sign(-5.0) + +let sin1 = Math.sin(0.0) +let sinh1 = Math.sinh(0.0) +let sqrt1 = Math.sqrt(9.0) +let tan1 = Math.tan(0.5) +let tanh1 = Math.tanh(0.0) + +let truncUnsafe1 = Float.toInt(Math.trunc(3.7)) +let trunc1 = Math.trunc(3.7) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Math.res b/tests/tools_tests/src/migrate/StdlibMigration_Math.res new file mode 100644 index 0000000000..4d9e9427bc --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Math.res @@ -0,0 +1,81 @@ +// Exercise migrations from Js.Math to Math + +let e = Js.Math._E +let pi = Js.Math._PI +let ln2 = Js.Math._LN2 +let ln10 = Js.Math._LN10 +let log2e = Js.Math._LOG2E +let log10e = Js.Math._LOG10E +let sqrt_half = Js.Math._SQRT1_2 +let sqrt2c = Js.Math._SQRT2 + +let absInt1 = Js.Math.abs_int(-5) +let absFloat1 = Js.Math.abs_float(-3.5) + +let acos1 = Js.Math.acos(1.0) +let acosh1 = Js.Math.acosh(1.5) +let asinh1 = Js.Math.asinh(1.0) +let asin1 = Js.Math.asin(0.5) +let atan1 = Js.Math.atan(1.0) +let atanh1 = Js.Math.atanh(0.5) + +let atan21 = Js.Math.atan2(~y=0.0, ~x=10.0, ()) + +let cbrt1 = Js.Math.cbrt(27.0) + +let ceilInt1 = Js.Math.unsafe_ceil_int(3.2) +let ceilInt2 = Js.Math.unsafe_ceil_int(3.2) +let ceilFloat1 = Js.Math.ceil_float(3.2) + +let clz1 = Js.Math.clz32(255) + +let cos1 = Js.Math.cos(0.0) +let cosh1 = Js.Math.cosh(0.0) +let exp1 = Js.Math.exp(1.0) +let expm11 = Js.Math.expm1(1.0) +let log1p1 = Js.Math.log1p(1.0) + +let floorInt1 = Js.Math.unsafe_floor_int(3.7) +let floorInt2 = Js.Math.unsafe_floor_int(3.7) +let floorFloat1 = Js.Math.floor_float(3.7) + +let fround1 = Js.Math.fround(5.05) + +let hypot1 = Js.Math.hypot(3.0, 4.0) +let hypotMany1 = Js.Math.hypotMany([3.0, 4.0, 12.0]) + +let imul1 = Js.Math.imul(3, 4) + +let log1 = Js.Math.log(Js.Math._E) +let log10_1 = Js.Math.log10(1000.0) +let log2_1 = Js.Math.log2(512.0) + +let maxInt1 = Js.Math.max_int(1, 2) +let maxIntMany1 = Js.Math.maxMany_int([1, 10, 3]) +let maxFloat1 = Js.Math.max_float(1.5, 2.5) +let maxFloatMany1 = Js.Math.maxMany_float([1.5, 2.5, 0.5]) + +let minInt1 = Js.Math.min_int(1, 2) +let minIntMany1 = Js.Math.minMany_int([1, 10, 3]) +let minFloat1 = Js.Math.min_float(1.5, 2.5) +let minFloatMany1 = Js.Math.minMany_float([1.5, 2.5, 0.5]) + +let powInt1 = Js.Math.pow_int(~base=3, ~exp=4) +let powFloat1 = Js.Math.pow_float(~base=3.0, ~exp=4.0) + +let rand1 = Js.Math.random() + +let roundUnsafe1 = Js.Math.unsafe_round(3.7) +let round1 = Js.Math.round(3.7) + +let signInt1 = Js.Math.sign_int(-5) +let signFloat1 = Js.Math.sign_float(-5.0) + +let sin1 = Js.Math.sin(0.0) +let sinh1 = Js.Math.sinh(0.0) +let sqrt1 = Js.Math.sqrt(9.0) +let tan1 = Js.Math.tan(0.5) +let tanh1 = Js.Math.tanh(0.0) + +let truncUnsafe1 = Js.Math.unsafe_trunc(3.7) +let trunc1 = Js.Math.trunc(3.7) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Math.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Math.res new file mode 100644 index 0000000000..e6cda4a09a --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Math.res @@ -0,0 +1,83 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Math.res. +// Exercise migrations from Js.Math to Math + +let e = Math.Constants.e +let pi = Math.Constants.pi +let ln2 = Math.Constants.ln2 +let ln10 = Math.Constants.ln10 +let log2e = Math.Constants.log2e +let log10e = Math.Constants.log10e +let sqrt_half = Math.Constants.sqrt1_2 +let sqrt2c = Math.Constants.sqrt2 + +let absInt1 = Math.Int.abs(-5) +let absFloat1 = Math.abs(-3.5) + +let acos1 = Math.acos(1.0) +let acosh1 = Math.acosh(1.5) +let asinh1 = Math.asinh(1.0) +let asin1 = Math.asin(0.5) +let atan1 = Math.atan(1.0) +let atanh1 = Math.atanh(0.5) + +let atan21 = Math.atan2(~y=0.0, ~x=10.0) + +let cbrt1 = Math.cbrt(27.0) + +let ceilInt1 = Math.Int.ceil(3.2) +let ceilInt2 = Math.Int.ceil(3.2) +let ceilFloat1 = Math.ceil(3.2) + +let clz1 = Math.Int.clz32(255) + +let cos1 = Math.cos(0.0) +let cosh1 = Math.cosh(0.0) +let exp1 = Math.exp(1.0) +let expm11 = Math.expm1(1.0) +let log1p1 = Math.log1p(1.0) + +let floorInt1 = Math.Int.floor(3.7) +let floorInt2 = Math.Int.floor(3.7) +let floorFloat1 = Math.floor(3.7) + +let fround1 = Math.fround(5.05) + +let hypot1 = Math.hypot(3.0, 4.0) +let hypotMany1 = Math.hypotMany([3.0, 4.0, 12.0]) + +let imul1 = Math.Int.imul(3, 4) + +let log1 = Math.log(Math.Constants.e) +let log10_1 = Math.log10(1000.0) +let log2_1 = Math.log2(512.0) + +let maxInt1 = Math.Int.max(1, 2) +let maxIntMany1 = Math.Int.maxMany([1, 10, 3]) +let maxFloat1 = Math.max(1.5, 2.5) +let maxFloatMany1 = Math.maxMany([1.5, 2.5, 0.5]) + +let minInt1 = Math.Int.min(1, 2) +let minIntMany1 = Math.Int.minMany([1, 10, 3]) +let minFloat1 = Math.min(1.5, 2.5) +let minFloatMany1 = Math.minMany([1.5, 2.5, 0.5]) + +let powInt1 = Math.Int.pow(3, ~exp=4) +let powFloat1 = Math.pow(3.0, ~exp=4.0) + +let rand1 = Math.random() + +let roundUnsafe1 = Float.toInt(Math.round(3.7)) +let round1 = Math.round(3.7) + +let signInt1 = Math.Int.sign(-5) +let signFloat1 = Math.sign(-5.0) + +let sin1 = Math.sin(0.0) +let sinh1 = Math.sinh(0.0) +let sqrt1 = Math.sqrt(9.0) +let tan1 = Math.tan(0.5) +let tanh1 = Math.tanh(0.0) + +let truncUnsafe1 = Float.toInt(Math.trunc(3.7)) +let trunc1 = Math.trunc(3.7) From 9b83514acb1ee695f2baba55b122b77da342a82e Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Fri, 29 Aug 2025 22:59:13 +0200 Subject: [PATCH 15/41] one more test --- .../src/expected/StdlibMigration_Js_Re.res.expected | 5 +++++ tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res | 5 +++++ .../src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res | 5 +++++ 3 files changed, 15 insertions(+) diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected index 05d1c01c59..5788ed39cf 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected @@ -31,6 +31,11 @@ let exec2 = RegExp.exec(re2, "Foo bar") let test1 = re2->RegExp.test("Foo bar") let test2 = RegExp.test(re2, "Foo bar") +let matches_access = switch re2->RegExp.exec("Foo bar") { +| None => 0 +| Some(r) => RegExp.Result.matches(r)->Array.length +} + let result_index = switch re2->RegExp.exec("Foo bar") { | None => 0 | Some(r) => RegExp.Result.index(r) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res index c46d50ea0f..bec13cff93 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res @@ -31,6 +31,11 @@ let exec2 = Js.Re.exec_(re2, "Foo bar") let test1 = re2->Js.Re.test_("Foo bar") let test2 = Js.Re.test_(re2, "Foo bar") +let matches_access = switch re2->Js.Re.exec_("Foo bar") { +| None => 0 +| Some(r) => Js.Re.matches(r)->Array.length +} + let result_index = switch re2->Js.Re.exec_("Foo bar") { | None => 0 | Some(r) => Js.Re.index(r) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res index 4659a35ddf..b952f005d9 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res @@ -33,6 +33,11 @@ let exec2 = RegExp.exec(re2, "Foo bar") let test1 = re2->RegExp.test("Foo bar") let test2 = RegExp.test(re2, "Foo bar") +let matches_access = switch re2->RegExp.exec("Foo bar") { +| None => 0 +| Some(r) => RegExp.Result.matches(r)->Array.length +} + let result_index = switch re2->RegExp.exec("Foo bar") { | None => 0 | Some(r) => RegExp.Result.index(r) From 08555bf72268420370852d71be16aec3c7af1ea5 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:09:57 +0200 Subject: [PATCH 16/41] migrations for js_undefined --- packages/@rescript/runtime/Js_undefined.resi | 48 +++++++++++++++++-- .../StdlibMigration_Js_Undefined.res.expected | 36 ++++++++++++++ .../migrate/StdlibMigration_Js_Undefined.res | 35 ++++++++++++++ .../Migrated_StdlibMigration_Js_Undefined.res | 37 ++++++++++++++ 4 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js_Undefined.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js_Undefined.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Undefined.res diff --git a/packages/@rescript/runtime/Js_undefined.resi b/packages/@rescript/runtime/Js_undefined.resi index f33ffa39d4..c900832f25 100644 --- a/packages/@rescript/runtime/Js_undefined.resi +++ b/packages/@rescript/runtime/Js_undefined.resi @@ -28,10 +28,14 @@ type t<+'a> = Primitive_js_extern.undefined<'a> /** Constructs a value of `Js.undefined<'a>` containing a value of `'a`. */ +@deprecated({ + reason: "Use `Nullable.make` or `option` directly instead.", + migrate: Nullable.make(), +}) external return: 'a => t<'a> = "%identity" /** Returns `true` if the given value is empty (undefined), `false` otherwise. */ -@deprecated("Use = Js.undefined directly") +@deprecated let test: t<'a> => bool /** @@ -39,12 +43,26 @@ Returns `true` if the given value is empty (undefined). **since 1.6.1** */ +@deprecated let testAny: 'a => bool /** The empty value, `undefined` */ +@deprecated({ + reason: "Use `Nullable.undefined` instead.", + migrate: Nullable.undefined, +}) external empty: t<'a> = "%undefined" +@deprecated({ + reason: "Use `Nullable.getUnsafe` instead.", + migrate: Nullable.getUnsafe(), +}) external getUnsafe: t<'a> => 'a = "%identity" + +@deprecated({ + reason: "Use `Nullable.getOrThrow` instead.", + migrate: Nullable.getOrThrow(), +}) let getExn: t<'a> => 'a /** @@ -60,6 +78,10 @@ let maybeGreetWorld = (maybeGreeting: Js.undefined) => Js.Undefined.bind(maybeGreeting, greeting => greeting ++ " world!") ``` */ +@deprecated({ + reason: "Use `Nullable.map` instead.", + migrate: Nullable.map(), +}) let bind: (t<'a>, 'a => 'b) => t<'b> /** @@ -74,6 +96,10 @@ let maybeSay = (maybeMessage: Js.undefined) => Js.Undefined.iter(maybeMessage, message => Js.log(message)) ``` */ +@deprecated({ + reason: "Use `Nullable.forEach` instead.", + migrate: Nullable.forEach(), +}) let iter: (t<'a>, 'a => unit) => unit /** @@ -81,15 +107,31 @@ Maps `option<'a>` to `Js.undefined<'a>`. `Some(a)` => `a` `None` => `empty` */ +@deprecated({ + reason: "Use `Nullable.fromOption` instead.", + migrate: Nullable.fromOption(), +}) let fromOption: option<'a> => t<'a> -@deprecated("Use fromOption instead") let from_opt: option<'a> => t<'a> +@deprecated({ + reason: "Use `Nullable.fromOption` instead.", + migrate: Nullable.fromOption(), +}) +let from_opt: option<'a> => t<'a> /** Maps `Js.undefined<'a>` to `option<'a>` `a` => `Some(a)` `empty` => `None` */ +@deprecated({ + reason: "Use `Nullable.toOption` instead.", + migrate: Nullable.toOption(), +}) let toOption: t<'a> => option<'a> -@deprecated("use toOption instead") let to_opt: t<'a> => option<'a> +@deprecated({ + reason: "Use `Nullable.toOption` instead.", + migrate: Nullable.toOption(), +}) +let to_opt: t<'a> => option<'a> diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_Undefined.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_Undefined.res.expected new file mode 100644 index 0000000000..19289cbc74 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_Undefined.res.expected @@ -0,0 +1,36 @@ +let make1 = "hello"->Nullable.make +let make2 = Nullable.make("hello") + +let empty1 = Nullable.undefined + +let getUnsafe1 = Nullable.make(1)->Nullable.getUnsafe +let getUnsafe2 = Nullable.getUnsafe(Nullable.make(1)) + +let getExn1 = Nullable.make(1)->Nullable.getOrThrow +let getExn2 = Nullable.getOrThrow(Nullable.make(1)) + +let map1 = Nullable.make(2)->Nullable.map(x => x + 1) +let map2 = Nullable.map(Nullable.make(2), x => x + 1) + +let forEach1 = Nullable.make(2)->Nullable.forEach(x => ignore(x)) +let forEach2 = Nullable.forEach(Nullable.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Nullable.fromOption +let fromOption2 = Nullable.fromOption(None) + +let from_opt1 = Some("y")->Nullable.fromOption +let from_opt2 = Nullable.fromOption(None) + +let toOption1 = Nullable.make(3)->Nullable.toOption +let toOption2 = Nullable.toOption(Nullable.make(3)) + +let to_opt1 = Nullable.make(4)->Nullable.toOption +let to_opt2 = Nullable.toOption(Nullable.make(4)) + +let test1 = Js.Undefined.empty->Js.Undefined.test +let test2 = Js.Undefined.test(Js.Undefined.empty) +let test3 = Js.Undefined.return(5)->Js.Undefined.bind(v => v)->Js.Undefined.test + +let testAny1 = Js.Undefined.testAny(Js.Undefined.empty) +let testAny2 = Js.Undefined.empty->Js.Undefined.testAny + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_Undefined.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_Undefined.res new file mode 100644 index 0000000000..66cc08ae7c --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_Undefined.res @@ -0,0 +1,35 @@ +let make1 = "hello"->Js.Undefined.return +let make2 = Js.Undefined.return("hello") + +let empty1 = Js.Undefined.empty + +let getUnsafe1 = Js.Undefined.return(1)->Js.Undefined.getUnsafe +let getUnsafe2 = Js.Undefined.getUnsafe(Js.Undefined.return(1)) + +let getExn1 = Js.Undefined.return(1)->Js.Undefined.getExn +let getExn2 = Js.Undefined.getExn(Js.Undefined.return(1)) + +let map1 = Js.Undefined.return(2)->Js.Undefined.bind(x => x + 1) +let map2 = Js.Undefined.bind(Js.Undefined.return(2), x => x + 1) + +let forEach1 = Js.Undefined.return(2)->Js.Undefined.iter(x => ignore(x)) +let forEach2 = Js.Undefined.iter(Js.Undefined.return(2), x => ignore(x)) + +let fromOption1 = Some("x")->Js.Undefined.fromOption +let fromOption2 = Js.Undefined.fromOption(None) + +let from_opt1 = Some("y")->Js.Undefined.from_opt +let from_opt2 = Js.Undefined.from_opt(None) + +let toOption1 = Js.Undefined.return(3)->Js.Undefined.toOption +let toOption2 = Js.Undefined.toOption(Js.Undefined.return(3)) + +let to_opt1 = Js.Undefined.return(4)->Js.Undefined.to_opt +let to_opt2 = Js.Undefined.to_opt(Js.Undefined.return(4)) + +let test1 = Js.Undefined.empty->Js.Undefined.test +let test2 = Js.Undefined.test(Js.Undefined.empty) +let test3 = Js.Undefined.return(5)->Js.Undefined.bind(v => v)->Js.Undefined.test + +let testAny1 = Js.Undefined.testAny(Js.Undefined.empty) +let testAny2 = Js.Undefined.empty->Js.Undefined.testAny diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Undefined.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Undefined.res new file mode 100644 index 0000000000..47a7a23687 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Undefined.res @@ -0,0 +1,37 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js_Undefined.res. +let make1 = "hello"->Nullable.make +let make2 = Nullable.make("hello") + +let empty1 = Nullable.undefined + +let getUnsafe1 = Nullable.make(1)->Nullable.getUnsafe +let getUnsafe2 = Nullable.getUnsafe(Nullable.make(1)) + +let getExn1 = Nullable.make(1)->Nullable.getOrThrow +let getExn2 = Nullable.getOrThrow(Nullable.make(1)) + +let map1 = Nullable.make(2)->Nullable.map(x => x + 1) +let map2 = Nullable.map(Nullable.make(2), x => x + 1) + +let forEach1 = Nullable.make(2)->Nullable.forEach(x => ignore(x)) +let forEach2 = Nullable.forEach(Nullable.make(2), x => ignore(x)) + +let fromOption1 = Some("x")->Nullable.fromOption +let fromOption2 = Nullable.fromOption(None) + +let from_opt1 = Some("y")->Nullable.fromOption +let from_opt2 = Nullable.fromOption(None) + +let toOption1 = Nullable.make(3)->Nullable.toOption +let toOption2 = Nullable.toOption(Nullable.make(3)) + +let to_opt1 = Nullable.make(4)->Nullable.toOption +let to_opt2 = Nullable.toOption(Nullable.make(4)) + +let test1 = Js.Undefined.empty->Js.Undefined.test +let test2 = Js.Undefined.test(Js.Undefined.empty) +let test3 = Js.Undefined.return(5)->Js.Undefined.bind(v => v)->Js.Undefined.test + +let testAny1 = Js.Undefined.testAny(Js.Undefined.empty) +let testAny2 = Js.Undefined.empty->Js.Undefined.testAny From d04aba655b3b346a3c17266e7f71ea1605b617f4 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:10:12 +0200 Subject: [PATCH 17/41] deprecate Js_OO --- packages/@rescript/runtime/Js_OO.res | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/packages/@rescript/runtime/Js_OO.res b/packages/@rescript/runtime/Js_OO.res index aba40deefa..fcf6664496 100644 --- a/packages/@rescript/runtime/Js_OO.res +++ b/packages/@rescript/runtime/Js_OO.res @@ -24,29 +24,52 @@ @@config({flags: ["-unboxed-types"]}) +@deprecated external unsafe_to_method: 'a => 'a = "%unsafe_to_method" module Callback = { + @deprecated type arity1<'a> = {@internal i1: 'a} + @deprecated type arity2<'a> = {@internal i2: 'a} + @deprecated type arity3<'a> = {@internal i3: 'a} + @deprecated type arity4<'a> = {@internal i4: 'a} + @deprecated type arity5<'a> = {@internal i5: 'a} + @deprecated type arity6<'a> = {@internal i6: 'a} + @deprecated type arity7<'a> = {@internal i7: 'a} + @deprecated type arity8<'a> = {@internal i8: 'a} + @deprecated type arity9<'a> = {@internal i9: 'a} + @deprecated type arity10<'a> = {@internal i10: 'a} + @deprecated type arity11<'a> = {@internal i11: 'a} + @deprecated type arity12<'a> = {@internal i12: 'a} + @deprecated type arity13<'a> = {@internal i13: 'a} + @deprecated type arity14<'a> = {@internal i14: 'a} + @deprecated type arity15<'a> = {@internal i15: 'a} + @deprecated type arity16<'a> = {@internal i16: 'a} + @deprecated type arity17<'a> = {@internal i17: 'a} + @deprecated type arity18<'a> = {@internal i18: 'a} + @deprecated type arity19<'a> = {@internal i19: 'a} + @deprecated type arity20<'a> = {@internal i20: 'a} + @deprecated type arity21<'a> = {@internal i21: 'a} + @deprecated type arity22<'a> = {@internal i22: 'a} } From b0bfe1f56dd30ee7a7c7790befb5dd369c98b29d Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:11:46 +0200 Subject: [PATCH 18/41] migrations for Js_extern --- packages/@rescript/runtime/Js_extern.res | 16 ++++++++++++++++ .../expected/StdlibMigration_Extern.res.expected | 7 +++++++ .../src/migrate/StdlibMigration_Extern.res | 6 ++++++ .../migrated/Migrated_StdlibMigration_Extern.res | 8 ++++++++ 4 files changed, 37 insertions(+) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Extern.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Extern.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Extern.res diff --git a/packages/@rescript/runtime/Js_extern.res b/packages/@rescript/runtime/Js_extern.res index f1e49974e4..baced59fa3 100644 --- a/packages/@rescript/runtime/Js_extern.res +++ b/packages/@rescript/runtime/Js_extern.res @@ -1,7 +1,23 @@ +@deprecated({ + reason: "Use `Nullable.isNullable` instead.", + migrate: Nullable.isNullable(), +}) external testAny: 'a => bool = "%is_nullable" +@deprecated({ + reason: "Use `Nullable.null` instead.", + migrate: Nullable.null, +}) external null: Primitive_js_extern.null<'a> = "%null" +@deprecated({ + reason: "Use `Nullable.undefined` instead.", + migrate: Nullable.undefined, +}) external undefined: Primitive_js_extern.null<'a> = "%undefined" +@deprecated({ + reason: "Use `Type.typeof` instead.", + migrate: Type.typeof(), +}) external typeof: 'a => string = "%typeof" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Extern.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Extern.res.expected new file mode 100644 index 0000000000..c28d1259e1 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Extern.res.expected @@ -0,0 +1,7 @@ +// Exercise migrations from Js_extern to new Stdlib APIs + +let isNullish = Nullable.isNullable(%raw("null")) +let n = Nullable.null +let u = Nullable.undefined +let ty = Type.typeof("hello") + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Extern.res b/tests/tools_tests/src/migrate/StdlibMigration_Extern.res new file mode 100644 index 0000000000..3ff65d4bba --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Extern.res @@ -0,0 +1,6 @@ +// Exercise migrations from Js_extern to new Stdlib APIs + +let isNullish = Js_extern.testAny(%raw("null")) +let n = Js_extern.null +let u = Js_extern.undefined +let ty = Js_extern.typeof("hello") diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Extern.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Extern.res new file mode 100644 index 0000000000..fc60d7b0c0 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Extern.res @@ -0,0 +1,8 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Extern.res. +// Exercise migrations from Js_extern to new Stdlib APIs + +let isNullish = Nullable.isNullable(%raw("null")) +let n = Nullable.null +let u = Nullable.undefined +let ty = Type.typeof("hello") From 80cbefe1d0047a9ab1c8cbc1d99e1cac9fff26eb Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:12:55 +0200 Subject: [PATCH 19/41] migrations for Js_global --- packages/@rescript/runtime/Js_global.res | 40 +++++++++++++++++++ .../StdlibMigration_Global.res.expected | 16 ++++++++ .../src/migrate/StdlibMigration_Global.res | 15 +++++++ .../Migrated_StdlibMigration_Global.res | 17 ++++++++ 4 files changed, 88 insertions(+) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Global.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Global.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res diff --git a/packages/@rescript/runtime/Js_global.res b/packages/@rescript/runtime/Js_global.res index 153779b198..f7abba205b 100644 --- a/packages/@rescript/runtime/Js_global.res +++ b/packages/@rescript/runtime/Js_global.res @@ -55,6 +55,10 @@ let cancel = () => Js.Nullable.iter(interval.contents, intervalId => Js.Global.clearInterval(intervalId)) ``` */ +@deprecated({ + reason: "Use `clearInterval` instead.", + migrate: clearInterval(), +}) @val external clearInterval: intervalId => unit = "clearInterval" @@ -78,6 +82,10 @@ let procrastinate = mins => { } ``` */ +@deprecated({ + reason: "Use `clearTimeout` instead.", + migrate: clearTimeout(), +}) @val external clearTimeout: timeoutId => unit = "clearTimeout" @@ -101,6 +109,10 @@ let tick = () => { Js.Global.setInterval(tick, 1000) ``` */ +@deprecated({ + reason: "Use `setInterval` instead.", + migrate: setInterval(), +}) @val external setInterval: (unit => unit, int) => intervalId = "setInterval" @@ -124,6 +136,10 @@ let tick = () => { Js.Global.setIntervalFloat(tick, 1000.0) ``` */ +@deprecated({ + reason: "Use `setIntervalFloat` instead.", + migrate: setIntervalFloat(), +}) @val external setIntervalFloat: (unit => unit, float) => intervalId = "setInterval" @@ -142,6 +158,10 @@ let message = "Timed out!" Js.Global.setTimeout(() => Js.log(message), 1000) ``` */ +@deprecated({ + reason: "Use `setTimeout` instead.", + migrate: setTimeout(), +}) @val external setTimeout: (unit => unit, int) => timeoutId = "setTimeout" @@ -160,6 +180,10 @@ let message = "Timed out!" Js.Global.setTimeoutFloat(() => Js.log(message), 1000.0) ``` */ +@deprecated({ + reason: "Use `setTimeoutFloat` instead.", + migrate: setTimeoutFloat(), +}) @val external setTimeoutFloat: (unit => unit, float) => timeoutId = "setTimeout" @@ -168,6 +192,10 @@ URL-encodes a string. See [`encodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) on MDN. */ +@deprecated({ + reason: "Use `encodeURI` instead.", + migrate: encodeURI(), +}) @val external encodeURI: string => string = "encodeURI" @@ -176,6 +204,10 @@ Decodes a URL-enmcoded string produced by `encodeURI` See [`decodeURI`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) on MDN. */ +@deprecated({ + reason: "Use `decodeURI` instead.", + migrate: decodeURI(), +}) @val external decodeURI: string => string = "decodeURI" @@ -184,6 +216,10 @@ URL-encodes a string, including characters with special meaning in a URI. See [`encodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent) on MDN. */ +@deprecated({ + reason: "Use `encodeURIComponent` instead.", + migrate: encodeURIComponent(), +}) @val external encodeURIComponent: string => string = "encodeURIComponent" @@ -192,5 +228,9 @@ Decodes a URL-enmcoded string produced by `encodeURIComponent` See [`decodeURIComponent`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/decodeURIComponent) on MDN. */ +@deprecated({ + reason: "Use `decodeURIComponent` instead.", + migrate: decodeURIComponent(), +}) @val external decodeURIComponent: string => string = "decodeURIComponent" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected new file mode 100644 index 0000000000..f0ff03a9eb --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected @@ -0,0 +1,16 @@ +let t1: Js.Global.timeoutId = setTimeout(() => (), 1000) +let t2: Js.Global.timeoutId = setTimeoutFloat(() => (), 1000.0) + +clearTimeout(t1) + +let i1: Js.Global.intervalId = setInterval(() => (), 2000) +let i2: Js.Global.intervalId = setIntervalFloat(() => (), 2000.0) + +clearInterval(i1) + +let e1 = encodeURI("https://rescript-lang.org?array=[someValue]") +let d1 = decodeURI("https://rescript-lang.org?array=%5BsomeValue%5D") + +let e2 = encodeURIComponent("array=[someValue]") +let d2 = decodeURIComponent("array%3D%5BsomeValue%5D") + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Global.res b/tests/tools_tests/src/migrate/StdlibMigration_Global.res new file mode 100644 index 0000000000..e15828838b --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Global.res @@ -0,0 +1,15 @@ +let t1: Js.Global.timeoutId = Js.Global.setTimeout(() => (), 1000) +let t2: Js.Global.timeoutId = Js.Global.setTimeoutFloat(() => (), 1000.0) + +Js.Global.clearTimeout(t1) + +let i1: Js.Global.intervalId = Js.Global.setInterval(() => (), 2000) +let i2: Js.Global.intervalId = Js.Global.setIntervalFloat(() => (), 2000.0) + +Js.Global.clearInterval(i1) + +let e1 = Js.Global.encodeURI("https://rescript-lang.org?array=[someValue]") +let d1 = Js.Global.decodeURI("https://rescript-lang.org?array=%5BsomeValue%5D") + +let e2 = Js.Global.encodeURIComponent("array=[someValue]") +let d2 = Js.Global.decodeURIComponent("array%3D%5BsomeValue%5D") diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res new file mode 100644 index 0000000000..a079afd25f --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res @@ -0,0 +1,17 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Global.res. +let t1: Js.Global.timeoutId = setTimeout(() => (), 1000) +let t2: Js.Global.timeoutId = setTimeoutFloat(() => (), 1000.0) + +clearTimeout(t1) + +let i1: Js.Global.intervalId = setInterval(() => (), 2000) +let i2: Js.Global.intervalId = setIntervalFloat(() => (), 2000.0) + +clearInterval(i1) + +let e1 = encodeURI("https://rescript-lang.org?array=[someValue]") +let d1 = decodeURI("https://rescript-lang.org?array=%5BsomeValue%5D") + +let e2 = encodeURIComponent("array=[someValue]") +let d2 = decodeURIComponent("array%3D%5BsomeValue%5D") From 81ea2872f7e4ceed4b68d14f0f6ad56fca012c59 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:13:26 +0200 Subject: [PATCH 20/41] migrations for Js_obj --- packages/@rescript/runtime/Js_obj.res | 12 ++++++++++++ .../src/expected/StdlibMigration_Obj.res.expected | 8 ++++++++ .../tools_tests/src/migrate/StdlibMigration_Obj.res | 7 +++++++ .../migrated/Migrated_StdlibMigration_Obj.res | 9 +++++++++ 4 files changed, 36 insertions(+) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Obj.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Obj.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Obj.res diff --git a/packages/@rescript/runtime/Js_obj.res b/packages/@rescript/runtime/Js_obj.res index 5b8896068d..e42c663d6e 100644 --- a/packages/@rescript/runtime/Js_obj.res +++ b/packages/@rescript/runtime/Js_obj.res @@ -27,6 +27,10 @@ Provides functions for inspecting and manipulating native JavaScript objects */ /** `empty()` returns the empty object `{}` */ +@deprecated({ + reason: "Use `Object.make` instead.", + migrate: Object.make(), +}) @obj external empty: unit => {..} = "" @@ -63,6 +67,10 @@ Js.log(obj) Js.log(target) ``` */ +@deprecated({ + reason: "Use `Object.assign` instead.", + migrate: Object.assign(), +}) @val external assign: ({..}, {..}) => {..} = "Object.assign" @@ -100,5 +108,9 @@ external assign: ({..}, {..}) => {..} = "Object.assign" */ /** `keys(obj)` returns an `array` of the keys of `obj`'s own enumerable properties. */ +@deprecated({ + reason: "Use `Object.keysToArray` instead.", + migrate: Object.keysToArray(), +}) @val external keys: {..} => array = "Object.keys" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Obj.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Obj.res.expected new file mode 100644 index 0000000000..ad86db6537 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Obj.res.expected @@ -0,0 +1,8 @@ +let empty1 = Object.make() + +let assign1 = Object.make()->Object.assign({"a": 1}) +let assign2 = Object.assign(Object.make(), {"a": 1}) + +let keys1 = {"a": 1, "b": 2}->Object.keysToArray +let keys2 = Object.keysToArray({"a": 1, "b": 2}) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Obj.res b/tests/tools_tests/src/migrate/StdlibMigration_Obj.res new file mode 100644 index 0000000000..b7ecb2e6cb --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Obj.res @@ -0,0 +1,7 @@ +let empty1 = Js.Obj.empty() + +let assign1 = Js.Obj.empty()->Js.Obj.assign({"a": 1}) +let assign2 = Js.Obj.assign(Js.Obj.empty(), {"a": 1}) + +let keys1 = {"a": 1, "b": 2}->Js.Obj.keys +let keys2 = Js.Obj.keys({"a": 1, "b": 2}) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Obj.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Obj.res new file mode 100644 index 0000000000..8a9f1f5ad1 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Obj.res @@ -0,0 +1,9 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Obj.res. +let empty1 = Object.make() + +let assign1 = Object.make()->Object.assign({"a": 1}) +let assign2 = Object.assign(Object.make(), {"a": 1}) + +let keys1 = {"a": 1, "b": 2}->Object.keysToArray +let keys2 = Object.keysToArray({"a": 1, "b": 2}) From b6e35703d2fb57194e79b8ec8609d2c7e292313a Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sat, 30 Aug 2025 18:36:28 +0200 Subject: [PATCH 21/41] make parsing of @deprecated with migration info an experimental feature --- compiler/ml/builtin_attributes.ml | 25 ++- compiler/ml/experimental_features.ml | 4 +- compiler/ml/experimental_features.mli | 2 +- docs/docson/build-schema.json | 4 + rewatch/CompilerConfigurationSpec.md | 1 + rewatch/src/config.rs | 5 +- ...-dev-dependency-used-by-non-dev-source.txt | 69 +------- rewatch/tests/snapshots/dependency-cycle.txt | 69 +------- rewatch/tests/snapshots/remove-file.txt | 119 +++----------- .../rename-file-internal-dep-namespace.txt | 147 +++--------------- .../snapshots/rename-file-internal-dep.txt | 129 +-------------- .../snapshots/rename-file-with-interface.txt | 129 +-------------- rewatch/tests/snapshots/rename-file.txt | 129 +-------------- .../tests/snapshots/rename-interface-file.txt | 129 +-------------- 14 files changed, 89 insertions(+), 872 deletions(-) diff --git a/compiler/ml/builtin_attributes.ml b/compiler/ml/builtin_attributes.ml index 4243659e63..dee344df5b 100644 --- a/compiler/ml/builtin_attributes.ml +++ b/compiler/ml/builtin_attributes.ml @@ -75,6 +75,12 @@ let cat s1 s2 = let rec deprecated_of_attrs = function | [] -> None + | ( {txt = "deprecated"; _}, + PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_record _}, _)}] ) + :: _ -> + (* Skip record payloads here. `deprecated_of_attrs_with_migrate` should be used if we want to + parse record payloads. *) + None | ({txt = "ocaml.deprecated" | "deprecated"; _}, p) :: _ -> Some (string_of_opt_payload p) | _ :: tl -> deprecated_of_attrs tl @@ -126,13 +132,18 @@ let rec deprecated_of_attrs_with_migrate = function | _ :: tl -> deprecated_of_attrs_with_migrate tl let check_deprecated ?deprecated_context loc attrs s = - match deprecated_of_attrs_with_migrate attrs with - | None -> () - | Some (txt, migration_template, migration_in_pipe_chain_template) -> - !Cmt_utils.record_deprecated_used - ?deprecated_context ?migration_template ?migration_in_pipe_chain_template - loc txt; - Location.deprecated loc (cat s txt) + if Experimental_features.is_enabled DeprecatedMigrations then ( + match deprecated_of_attrs_with_migrate attrs with + | None -> () + | Some (txt, migration_template, migration_in_pipe_chain_template) -> + !Cmt_utils.record_deprecated_used + ?deprecated_context ?migration_template + ?migration_in_pipe_chain_template loc txt; + Location.deprecated loc (cat s txt)) + else + match deprecated_of_attrs attrs with + | None -> () + | Some txt -> Location.deprecated loc (cat s txt) let check_deprecated_inclusion ~def ~use loc attrs1 attrs2 s = match (deprecated_of_attrs attrs1, deprecated_of_attrs attrs2) with diff --git a/compiler/ml/experimental_features.ml b/compiler/ml/experimental_features.ml index 179f43735b..1dcc2076b2 100644 --- a/compiler/ml/experimental_features.ml +++ b/compiler/ml/experimental_features.ml @@ -1,12 +1,14 @@ -type feature = LetUnwrap +type feature = LetUnwrap | DeprecatedMigrations let to_string (f : feature) : string = match f with | LetUnwrap -> "LetUnwrap" + | DeprecatedMigrations -> "DeprecatedMigrations" let from_string (s : string) : feature option = match s with | "LetUnwrap" -> Some LetUnwrap + | "DeprecatedMigrations" -> Some DeprecatedMigrations | _ -> None module FeatureSet = Set.Make (struct diff --git a/compiler/ml/experimental_features.mli b/compiler/ml/experimental_features.mli index bc58c931c2..e6c15561b3 100644 --- a/compiler/ml/experimental_features.mli +++ b/compiler/ml/experimental_features.mli @@ -1,4 +1,4 @@ -type feature = LetUnwrap +type feature = LetUnwrap | DeprecatedMigrations val enable_from_string : string -> unit val is_enabled : feature -> bool diff --git a/docs/docson/build-schema.json b/docs/docson/build-schema.json index a770247c6c..19b8edac10 100644 --- a/docs/docson/build-schema.json +++ b/docs/docson/build-schema.json @@ -492,6 +492,10 @@ "LetUnwrap": { "type": "boolean", "description": "Enable `let?` syntax." + }, + "DeprecatedMigrations": { + "type": "boolean", + "description": "Enable parsing of the `@deprecated` attribute with migration information." } }, "additionalProperties": false diff --git a/rewatch/CompilerConfigurationSpec.md b/rewatch/CompilerConfigurationSpec.md index ac93033f6a..c3a5658d8b 100644 --- a/rewatch/CompilerConfigurationSpec.md +++ b/rewatch/CompilerConfigurationSpec.md @@ -122,6 +122,7 @@ An object of feature flags to enable experimental compiler behavior. Only suppor Currently supported features: - LetUnwrap: Enable `let?` syntax. +- DeprecatedMigrations: Enable parsing of the `@deprecated` attribute with migration information. ### Warnings diff --git a/rewatch/src/config.rs b/rewatch/src/config.rs index 67130325f9..2ff09680a9 100644 --- a/rewatch/src/config.rs +++ b/rewatch/src/config.rs @@ -229,6 +229,7 @@ pub enum DeprecationWarning { #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum ExperimentalFeature { LetUnwrap, + DeprecatedMigrations, } impl<'de> serde::Deserialize<'de> for ExperimentalFeature { @@ -248,8 +249,9 @@ impl<'de> serde::Deserialize<'de> for ExperimentalFeature { { match v { "LetUnwrap" => Ok(ExperimentalFeature::LetUnwrap), + "DeprecatedMigrations" => Ok(ExperimentalFeature::DeprecatedMigrations), other => { - let available = ["LetUnwrap"].join(", "); + let available = ["LetUnwrap", "DeprecatedMigrations"].join(", "); Err(DeError::custom(format!( "Unknown experimental feature '{other}'. Available features: {available}", ))) @@ -548,6 +550,7 @@ impl Config { "-enable-experimental".to_string(), match feature { ExperimentalFeature::LetUnwrap => "LetUnwrap", + ExperimentalFeature::DeprecatedMigrations => "DeprecatedMigrations", } .to_string(), ] diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index e919bf8438..fcf2118183 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -1,69 +1,6 @@ -Cleaned 0/113 -Parsed 4 source files -Compiled 3 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - +Cleaned 0/115 +Parsed 2 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 2e2412a38f..2b90a0c8e2 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,69 +1,6 @@ -Cleaned 0/110 -Parsed 6 source files -Compiled 2 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - +Cleaned 0/115 +Parsed 1 source files +Compiled 0 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index d1ed672e27..10f05cb95e 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,111 +1,30 @@ -Cleaned 0/110 -Parsed 4 source files -Compiled 5 modules +Cleaned 1/115 +Parsed 0 source files +Compiled 1 modules - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ +The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dependencies' instead. - deprecated: Js.log - Use `Console.log` instead. +The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dev-dependencies' instead. +The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'compiler-flags' instead. - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 + We've found a bug for you! + /packages/dep01/src/Dep01.res:3:9-17 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() + 2 │ Js.log("02") + 3 │ Dep02.log() 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - + The module or file Dep02 can't be found. + - If it's a third-party dependency: + - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? + -The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dependencies' instead. - -The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dev-dependencies' instead. -The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'compiler-flags' instead. +Incremental build failed. Error:  Failed to Compile. See Errors Above diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt index c54b428e24..17dcaaf94c 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt @@ -1,129 +1,6 @@ -Cleaned 1/111 -Parsed 5 source files -Compiled 7 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/new-namespace/src/Other_module2.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 2/115 +Parsed 2 source files +Compiled 3 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -133,3 +10,21 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. + + We've found a bug for you! + /packages/new-namespace/src/NS_alias.res:2:1-16 + + 1 │ let hello_world = () => "Hello world" + 2 │ Other_module.bla() + 3 │ + + The module or file Other_module can't be found. + - If it's a third-party dependency: + - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? + + + Hint: Did you mean Other_module2? + + +Incremental build failed. Error:  Failed to Compile. See Errors Above diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index 06ab229ea1..bebcb52cfd 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,105 +1,6 @@ -Cleaned 1/110 -Parsed 6 source files -Compiled 8 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 2/115 +Parsed 2 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -110,30 +11,6 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - We've found a bug for you! /packages/main/src/Main.res:4:8-24 diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index a4e563ccaa..3202fc9a0c 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,130 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/110 -Parsed 6 source files -Compiled 7 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 2/115 +Parsed 1 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index b4c542aab9..760b9fda3b 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,129 +1,6 @@ -Cleaned 0/110 -Parsed 5 source files -Compiled 5 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main2.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main2.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 1/115 +Parsed 1 source files +Compiled 1 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index ef2ff1a174..621f151afb 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,130 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/110 -Parsed 6 source files -Compiled 7 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 1/115 +Parsed 1 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. From b2e0bdc757e56683f46a1eafd3d58be50187cfd7 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 13:48:24 +0200 Subject: [PATCH 22/41] Revert "make parsing of @deprecated with migration info an experimental feature" This reverts commit 59c902c27f5ffba17eb21e4c7db3edb94c711b27. --- compiler/ml/builtin_attributes.ml | 25 +-- compiler/ml/experimental_features.ml | 4 +- compiler/ml/experimental_features.mli | 2 +- docs/docson/build-schema.json | 4 - rewatch/CompilerConfigurationSpec.md | 1 - rewatch/src/config.rs | 5 +- ...-dev-dependency-used-by-non-dev-source.txt | 69 +++++++- rewatch/tests/snapshots/dependency-cycle.txt | 69 +++++++- rewatch/tests/snapshots/remove-file.txt | 119 +++++++++++--- .../rename-file-internal-dep-namespace.txt | 147 +++++++++++++++--- .../snapshots/rename-file-internal-dep.txt | 129 ++++++++++++++- .../snapshots/rename-file-with-interface.txt | 129 ++++++++++++++- rewatch/tests/snapshots/rename-file.txt | 129 ++++++++++++++- .../tests/snapshots/rename-interface-file.txt | 129 ++++++++++++++- 14 files changed, 872 insertions(+), 89 deletions(-) diff --git a/compiler/ml/builtin_attributes.ml b/compiler/ml/builtin_attributes.ml index dee344df5b..4243659e63 100644 --- a/compiler/ml/builtin_attributes.ml +++ b/compiler/ml/builtin_attributes.ml @@ -75,12 +75,6 @@ let cat s1 s2 = let rec deprecated_of_attrs = function | [] -> None - | ( {txt = "deprecated"; _}, - PStr [{pstr_desc = Pstr_eval ({pexp_desc = Pexp_record _}, _)}] ) - :: _ -> - (* Skip record payloads here. `deprecated_of_attrs_with_migrate` should be used if we want to - parse record payloads. *) - None | ({txt = "ocaml.deprecated" | "deprecated"; _}, p) :: _ -> Some (string_of_opt_payload p) | _ :: tl -> deprecated_of_attrs tl @@ -132,18 +126,13 @@ let rec deprecated_of_attrs_with_migrate = function | _ :: tl -> deprecated_of_attrs_with_migrate tl let check_deprecated ?deprecated_context loc attrs s = - if Experimental_features.is_enabled DeprecatedMigrations then ( - match deprecated_of_attrs_with_migrate attrs with - | None -> () - | Some (txt, migration_template, migration_in_pipe_chain_template) -> - !Cmt_utils.record_deprecated_used - ?deprecated_context ?migration_template - ?migration_in_pipe_chain_template loc txt; - Location.deprecated loc (cat s txt)) - else - match deprecated_of_attrs attrs with - | None -> () - | Some txt -> Location.deprecated loc (cat s txt) + match deprecated_of_attrs_with_migrate attrs with + | None -> () + | Some (txt, migration_template, migration_in_pipe_chain_template) -> + !Cmt_utils.record_deprecated_used + ?deprecated_context ?migration_template ?migration_in_pipe_chain_template + loc txt; + Location.deprecated loc (cat s txt) let check_deprecated_inclusion ~def ~use loc attrs1 attrs2 s = match (deprecated_of_attrs attrs1, deprecated_of_attrs attrs2) with diff --git a/compiler/ml/experimental_features.ml b/compiler/ml/experimental_features.ml index 1dcc2076b2..179f43735b 100644 --- a/compiler/ml/experimental_features.ml +++ b/compiler/ml/experimental_features.ml @@ -1,14 +1,12 @@ -type feature = LetUnwrap | DeprecatedMigrations +type feature = LetUnwrap let to_string (f : feature) : string = match f with | LetUnwrap -> "LetUnwrap" - | DeprecatedMigrations -> "DeprecatedMigrations" let from_string (s : string) : feature option = match s with | "LetUnwrap" -> Some LetUnwrap - | "DeprecatedMigrations" -> Some DeprecatedMigrations | _ -> None module FeatureSet = Set.Make (struct diff --git a/compiler/ml/experimental_features.mli b/compiler/ml/experimental_features.mli index e6c15561b3..bc58c931c2 100644 --- a/compiler/ml/experimental_features.mli +++ b/compiler/ml/experimental_features.mli @@ -1,4 +1,4 @@ -type feature = LetUnwrap | DeprecatedMigrations +type feature = LetUnwrap val enable_from_string : string -> unit val is_enabled : feature -> bool diff --git a/docs/docson/build-schema.json b/docs/docson/build-schema.json index 19b8edac10..a770247c6c 100644 --- a/docs/docson/build-schema.json +++ b/docs/docson/build-schema.json @@ -492,10 +492,6 @@ "LetUnwrap": { "type": "boolean", "description": "Enable `let?` syntax." - }, - "DeprecatedMigrations": { - "type": "boolean", - "description": "Enable parsing of the `@deprecated` attribute with migration information." } }, "additionalProperties": false diff --git a/rewatch/CompilerConfigurationSpec.md b/rewatch/CompilerConfigurationSpec.md index c3a5658d8b..ac93033f6a 100644 --- a/rewatch/CompilerConfigurationSpec.md +++ b/rewatch/CompilerConfigurationSpec.md @@ -122,7 +122,6 @@ An object of feature flags to enable experimental compiler behavior. Only suppor Currently supported features: - LetUnwrap: Enable `let?` syntax. -- DeprecatedMigrations: Enable parsing of the `@deprecated` attribute with migration information. ### Warnings diff --git a/rewatch/src/config.rs b/rewatch/src/config.rs index 2ff09680a9..67130325f9 100644 --- a/rewatch/src/config.rs +++ b/rewatch/src/config.rs @@ -229,7 +229,6 @@ pub enum DeprecationWarning { #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum ExperimentalFeature { LetUnwrap, - DeprecatedMigrations, } impl<'de> serde::Deserialize<'de> for ExperimentalFeature { @@ -249,9 +248,8 @@ impl<'de> serde::Deserialize<'de> for ExperimentalFeature { { match v { "LetUnwrap" => Ok(ExperimentalFeature::LetUnwrap), - "DeprecatedMigrations" => Ok(ExperimentalFeature::DeprecatedMigrations), other => { - let available = ["LetUnwrap", "DeprecatedMigrations"].join(", "); + let available = ["LetUnwrap"].join(", "); Err(DeError::custom(format!( "Unknown experimental feature '{other}'. Available features: {available}", ))) @@ -550,7 +548,6 @@ impl Config { "-enable-experimental".to_string(), match feature { ExperimentalFeature::LetUnwrap => "LetUnwrap", - ExperimentalFeature::DeprecatedMigrations => "DeprecatedMigrations", } .to_string(), ] diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index fcf2118183..e919bf8438 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -1,6 +1,69 @@ -Cleaned 0/115 -Parsed 2 source files -Compiled 2 modules +Cleaned 0/113 +Parsed 4 source files +Compiled 3 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 2b90a0c8e2..2e2412a38f 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,6 +1,69 @@ -Cleaned 0/115 -Parsed 1 source files -Compiled 0 modules +Cleaned 0/110 +Parsed 6 source files +Compiled 2 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index 10f05cb95e..d1ed672e27 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,30 +1,111 @@ -Cleaned 1/115 -Parsed 0 source files -Compiled 1 modules +Cleaned 0/110 +Parsed 4 source files +Compiled 5 modules -The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dependencies' instead. + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 -The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dev-dependencies' instead. + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) -The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'compiler-flags' instead. + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 - We've found a bug for you! - /packages/dep01/src/Dep01.res:3:9-17 + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() + 2 │ Js.log("02") + 3 │ Dep02.log() 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + - The module or file Dep02 can't be found. - - If it's a third-party dependency: - - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? - - Did you include the file's directory to the "sources" in rescript.json? - +The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dependencies' instead. + +The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dev-dependencies' instead. -Incremental build failed. Error:  Failed to Compile. See Errors Above +The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'compiler-flags' instead. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt index 17dcaaf94c..c54b428e24 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt @@ -1,30 +1,135 @@ -Cleaned 2/115 -Parsed 2 source files -Compiled 3 modules +Cleaned 1/111 +Parsed 5 source files +Compiled 7 modules -The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dependencies' instead. + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 -The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'dev-dependencies' instead. + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) -The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. -Use 'compiler-flags' instead. + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module2.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ - We've found a bug for you! - /packages/new-namespace/src/NS_alias.res:2:1-16 + deprecated: Js.log + Use `Console.log` instead. - 1 │ let hello_world = () => "Hello world" - 2 │ Other_module.bla() + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + - The module or file Other_module can't be found. - - If it's a third-party dependency: - - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? - - Did you include the file's directory to the "sources" in rescript.json? - - - Hint: Did you mean Other_module2? +The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dependencies' instead. +The field 'bs-dev-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'dev-dependencies' instead. -Incremental build failed. Error:  Failed to Compile. See Errors Above +The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. +Use 'compiler-flags' instead. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index bebcb52cfd..06ab229ea1 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,6 +1,105 @@ -Cleaned 2/115 -Parsed 2 source files -Compiled 2 modules +Cleaned 1/110 +Parsed 6 source files +Compiled 8 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -11,6 +110,30 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + We've found a bug for you! /packages/main/src/Main.res:4:8-24 diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index 3202fc9a0c..a4e563ccaa 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,7 +1,130 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/115 -Parsed 1 source files -Compiled 2 modules +Cleaned 2/110 +Parsed 6 source files +Compiled 7 modules + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index 760b9fda3b..b4c542aab9 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,6 +1,129 @@ -Cleaned 1/115 -Parsed 1 source files -Compiled 1 modules +Cleaned 0/110 +Parsed 5 source files +Compiled 5 modules + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main2.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main2.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index 621f151afb..ef2ff1a174 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,7 +1,130 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/115 -Parsed 1 source files -Compiled 2 modules +Cleaned 1/110 +Parsed 6 source files +Compiled 7 modules + + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:6:16-33 + + 4 │ let at = get + 5 │ + 6 │ let includes = Js.Array2.includes + 7 │ + 8 │ let head = t => t->get(0) + + deprecated: Js.Array2.includes + Use `Array.includes` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:24:12-25 + + 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany + 23 │ + 24 │ let mapi = Js.Array2.mapi + 25 │ + 26 │ let flatten = t => t->flatMap(x => x) + + deprecated: Js.Array2.mapi + Use `Array.mapWithIndex` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:32:14-29 + + 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) + 31 │ + 32 │ let filter = Js.Array2.filter + 33 │ + 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) + + deprecated: Js.Array2.filter + Use `Array.filter` instead. + + + Warning number 3 + /packages/dep02/src/Array.res:48:18-35 + + 46 │ + 47 │ module String = { + 48 │ let joinWith = Js.Array2.joinWith + 49 │ let join = joinWith(_, "") + 50 │ } + + deprecated: Js.Array2.joinWith + Use `Array.joinUnsafe` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:2:37-42 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep02/src/Dep02.res:3:1-6 + + 1 │ open Array + 2 │ let log = () => ["a", "b"]->forEach(Js.log) + 3 │ Js.log(NS.Alias.hello_world()) + 4 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:1:1-6 + + 1 │ Js.log("01") + 2 │ Dep01.log() + 3 │ + + deprecated: Js.log + Use `Console.log` instead. + + + Warning number 3 + /packages/main/src/Main.res:4:1-6 + + 2 │ Dep01.log() + 3 │ + 4 │ Js.log(InternalDep.value) + 5 │ + 6 │ module Array = Belt.Array + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. From a5834dbc67f386779bed576a58e3d504a181e67f Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 14:12:22 +0200 Subject: [PATCH 23/41] typed array migrations --- packages/@rescript/runtime/Js_typed_array.res | 615 +++- .../@rescript/runtime/Js_typed_array2.res | 2584 ++++++++++++++--- ...tdlibMigration_Js_typed_array.res.expected | 8 + ...dlibMigration_Js_typed_array2.res.expected | 19 + .../StdlibMigration_Js_typed_array.res | 7 + .../StdlibMigration_Js_typed_array2.res | 22 + ...igrated_StdlibMigration_Js_typed_array.res | 9 + ...grated_StdlibMigration_Js_typed_array2.res | 20 + 8 files changed, 2761 insertions(+), 523 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js_typed_array.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Js_typed_array2.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array2.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array2.res diff --git a/packages/@rescript/runtime/Js_typed_array.res b/packages/@rescript/runtime/Js_typed_array.res index 753c14fa72..08aefe61c7 100644 --- a/packages/@rescript/runtime/Js_typed_array.res +++ b/packages/@rescript/runtime/Js_typed_array.res @@ -102,6 +102,10 @@ module type S = { /* Accessor functions */ // @bs.send.pipe(: t) /** ES2016 */ + @deprecated({ + reason: "Use `TypedArray.includes` instead.", + migrate: TypedArray.includes(), + }) external includes: elt => bool = "includes" // @bs.send.pipe(: t) external indexOf: elt => int = "indexOf" @@ -189,12 +193,25 @@ module Int8Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -218,14 +235,16 @@ module Int8Array = { // @bs.send.pipe(: t) external lastIndexOf: elt => int = "lastIndexOf" // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" - // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ - external slice: (~start: int, ~end_: int) => t = "slice" + @deprecated("Use `TypedArray.slice` instead.") + external // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" - // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" + @deprecated("Use `TypedArray.sliceToEnd` instead.") + external // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ - external subarray: (~start: int, ~end_: int) => t = "subarray" + subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -267,9 +286,19 @@ module Int8Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Int8Array" + @deprecated({ + reason: "Use `Int8Array.Constants.bytesPerElement` instead.", + migrate: Int8Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Int8Array.fromArray` instead.", + migrate: Int8Array.fromArray(), + }) + @new + external make: array => t = "Int8Array" /** can throw */ @new external fromBuffer: array_buffer => t = "Int8Array" @@ -279,19 +308,39 @@ module Int8Array = { param offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Int8Array" + @deprecated({ + reason: "Use `Int8Array.fromBufferToEnd` instead.", + migrate: Int8Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Int8Array" /** raise Js.Exn.Error raises Js exception param offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Int8Array.fromBufferWithRange` instead.", + migrate: Int8Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int8Array" - @new external fromLength: int => t = "Int8Array" - @val external from: array_like => t = "Int8Array.from" + @deprecated({ + reason: "Use `Int8Array.fromLength` instead.", + migrate: Int8Array.fromLength(), + }) + @new + external fromLength: int => t = "Int8Array" + @deprecated({ + reason: "Use `Int8Array.fromArrayLikeOrIterable` instead.", + migrate: Int8Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Int8Array.from" /* *Array.of is redundant, use make */ } @@ -313,12 +362,25 @@ module Uint8Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -343,12 +405,28 @@ module Uint8Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -391,9 +469,19 @@ module Uint8Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Uint8Array" + @deprecated({ + reason: "Use `Uint8Array.Constants.bytesPerElement` instead.", + migrate: Uint8Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint8Array.fromArray` instead.", + migrate: Uint8Array.fromArray(), + }) + @new + external make: array => t = "Uint8Array" /** can throw */ @new external fromBuffer: array_buffer => t = "Uint8Array" @@ -403,19 +491,39 @@ module Uint8Array = { **param** offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" + @deprecated({ + reason: "Use `Uint8Array.fromBufferToEnd` instead.", + migrate: Uint8Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" /** **raise** Js.Exn.Error raises Js exception **param** offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Uint8Array.fromBufferWithRange` instead.", + migrate: Uint8Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8Array" - @new external fromLength: int => t = "Uint8Array" - @val external from: array_like => t = "Uint8Array.from" + @deprecated({ + reason: "Use `Uint8Array.fromLength` instead.", + migrate: Uint8Array.fromLength(), + }) + @new + external fromLength: int => t = "Uint8Array" + @deprecated({ + reason: "Use `Uint8Array.fromArrayLikeOrIterable` instead.", + migrate: Uint8Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint8Array.from" /* *Array.of is redundant, use make */ } @@ -437,12 +545,25 @@ module Uint8ClampedArray = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -467,12 +588,20 @@ module Uint8ClampedArray = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -515,9 +644,19 @@ module Uint8ClampedArray = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" - - @new external make: array => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `Uint8ClampedArray.Constants.bytesPerElement` instead.", + migrate: Uint8ClampedArray.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint8ClampedArray.fromArray` instead.", + migrate: Uint8ClampedArray.fromArray(), + }) + @new + external make: array => t = "Uint8ClampedArray" /** can throw */ @new external fromBuffer: array_buffer => t = "Uint8ClampedArray" @@ -527,19 +666,39 @@ module Uint8ClampedArray = { **param** offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromBufferToEnd` instead.", + migrate: Uint8ClampedArray.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" /** **raise** Js.Exn.Error raises Js exception **param** offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Uint8ClampedArray.fromBufferWithRange` instead.", + migrate: Uint8ClampedArray.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8ClampedArray" - @new external fromLength: int => t = "Uint8ClampedArray" - @val external from: array_like => t = "Uint8ClampedArray.from" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromLength` instead.", + migrate: Uint8ClampedArray.fromLength(), + }) + @new + external fromLength: int => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromArrayLikeOrIterable` instead.", + migrate: Uint8ClampedArray.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint8ClampedArray.from" /* *Array.of is redundant, use make */ } @@ -561,12 +720,25 @@ module Int16Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -591,12 +763,20 @@ module Int16Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -639,11 +819,25 @@ module Int16Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Int16Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Int16Array" + @deprecated({ + reason: "Use `Int16Array.Constants.bytesPerElement` instead.", + migrate: Int16Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Int16Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Int16Array.fromArray` instead.", + migrate: Int16Array.fromArray(), + }) + @new + external make: array => t = "Int16Array" /** can throw */ @new + @deprecated({ + reason: "Use `Int16Array.fromBuffer` instead.", + migrate: Int16Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Int16Array" /** @@ -652,6 +846,10 @@ module Int16Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Int16Array.fromBufferToEnd` instead.", + migrate: Int16Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Int16Array" /** @@ -660,10 +858,27 @@ module Int16Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Int16Array.fromBufferWithRange` instead.", + migrate: Int16Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int16Array" - @new external fromLength: int => t = "Int16Array" - @val external from: array_like => t = "Int16Array.from" + @deprecated({ + reason: "Use `Int16Array.fromLength` instead.", + migrate: Int16Array.fromLength(), + }) + @new + external fromLength: int => t = "Int16Array" + @deprecated({ + reason: "Use `Int16Array.fromArrayLikeOrIterable` instead.", + migrate: Int16Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Int16Array.from" /* *Array.of is redundant, use make */ } @@ -685,12 +900,25 @@ module Uint16Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -715,12 +943,20 @@ module Uint16Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -763,11 +999,25 @@ module Uint16Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Uint16Array" + @deprecated({ + reason: "Use `Uint16Array.Constants.bytesPerElement` instead.", + migrate: Uint16Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint16Array.fromArray` instead.", + migrate: Uint16Array.fromArray(), + }) + @new + external make: array => t = "Uint16Array" /** can throw */ @new + @deprecated({ + reason: "Use `Uint16Array.fromBuffer` instead.", + migrate: Uint16Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Uint16Array" /** @@ -776,6 +1026,10 @@ module Uint16Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Uint16Array.fromBufferToEnd` instead.", + migrate: Uint16Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Uint16Array" /** @@ -784,10 +1038,27 @@ module Uint16Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Uint16Array.fromBufferWithRange` instead.", + migrate: Uint16Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint16Array" - @new external fromLength: int => t = "Uint16Array" - @val external from: array_like => t = "Uint16Array.from" + @deprecated({ + reason: "Use `Uint16Array.fromLength` instead.", + migrate: Uint16Array.fromLength(), + }) + @new + external fromLength: int => t = "Uint16Array" + @deprecated({ + reason: "Use `Uint16Array.fromArrayLikeOrIterable` instead.", + migrate: Uint16Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint16Array.from" /* *Array.of is redundant, use make */ } @@ -809,12 +1080,25 @@ module Int32Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -839,12 +1123,20 @@ module Int32Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -887,11 +1179,25 @@ module Int32Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Int32Array" + @deprecated({ + reason: "Use `Int32Array.Constants.bytesPerElement` instead.", + migrate: Int32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Int32Array.fromArray` instead.", + migrate: Int32Array.fromArray(), + }) + @new + external make: array => t = "Int32Array" /** can throw */ @new + @deprecated({ + reason: "Use `Int32Array.fromBuffer` instead.", + migrate: Int32Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Int32Array" /** @@ -900,6 +1206,10 @@ module Int32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Int32Array.fromBufferToEnd", + migrate: Int32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Int32Array" /** @@ -908,10 +1218,27 @@ module Int32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Int32Array.fromBufferWithRange` instead.", + migrate: Int32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int32Array" - @new external fromLength: int => t = "Int32Array" - @val external from: array_like => t = "Int32Array.from" + @deprecated({ + reason: "Use `Int32Array.fromLength` instead.", + migrate: Int32Array.fromLength(), + }) + @new + external fromLength: int => t = "Int32Array" + @deprecated({ + reason: "Use `Int32Array.fromArrayLikeOrIterable` instead.", + migrate: Int32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Int32Array.from" /* *Array.of is redundant, use make */ @new @deprecated("use `make` instead") external create: array => t = "Int32Array" @new @deprecated("use `fromBuffer` instead") external of_buffer: array_buffer => t = "Int32Array" @@ -936,12 +1263,25 @@ module Uint32Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -966,12 +1306,20 @@ module Uint32Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -1014,11 +1362,25 @@ module Uint32Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Uint32Array" + @deprecated({ + reason: "Use `Uint32Array.Constants.bytesPerElement` instead.", + migrate: Uint32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint32Array.fromArray` instead.", + migrate: Uint32Array.fromArray(), + }) + @new + external make: array => t = "Uint32Array" /** can throw */ @new + @deprecated({ + reason: "Use `Uint32Array.fromBuffer` instead.", + migrate: Uint32Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Uint32Array" /** @@ -1027,6 +1389,10 @@ module Uint32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Uint32Array.fromBufferToEnd` instead.", + migrate: Uint32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Uint32Array" /** @@ -1035,10 +1401,27 @@ module Uint32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Uint32Array.fromBufferWithRange` instead.", + migrate: Uint32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint32Array" - @new external fromLength: int => t = "Uint32Array" - @val external from: array_like => t = "Uint32Array.from" + @deprecated({ + reason: "Use `Uint32Array.fromLength` instead.", + migrate: Uint32Array.fromLength(), + }) + @new + external fromLength: int => t = "Uint32Array" + @deprecated({ + reason: "Use `Uint32Array.fromArrayLikeOrIterable` instead.", + migrate: Uint32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint32Array.from" /* *Array.of is redundant, use make */ } @@ -1063,12 +1446,25 @@ module Float32Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -1141,11 +1537,25 @@ module Float32Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Float32Array" + @deprecated({ + reason: "Use `Float32Array.Constants.bytesPerElement` instead.", + migrate: Float32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Float32Array.fromArray` instead.", + migrate: Float32Array.fromArray(), + }) + @new + external make: array => t = "Float32Array" /** can throw */ @new + @deprecated({ + reason: "Use `Float32Array.fromBuffer` instead.", + migrate: Float32Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Float32Array" /** @@ -1154,6 +1564,10 @@ module Float32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Float32Array.fromBufferToEnd` instead.", + migrate: Float32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Float32Array" /** @@ -1162,10 +1576,27 @@ module Float32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Float32Array.fromBufferWithRange` instead.", + migrate: Float32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float32Array" - @new external fromLength: int => t = "Float32Array" - @val external from: array_like => t = "Float32Array.from" + @deprecated({ + reason: "Use `Float32Array.fromLength` instead.", + migrate: Float32Array.fromLength(), + }) + @new + external fromLength: int => t = "Float32Array" + @deprecated({ + reason: "Use `Float32Array.fromArrayLikeOrIterable` instead.", + migrate: Float32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Float32Array.from" /* *Array.of is redundant, use make */ @new @deprecated("use `make` instead") external create: array => t = "Float32Array" @new @deprecated("use `fromBuffer` instead") @@ -1191,12 +1622,25 @@ module Float64Array = { /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ // @bs.send.pipe(: t) external copyWithin: (~to_: int) => t = "copyWithin" // @bs.send.pipe(: t) external copyWithinFrom: (~to_: int, ~from: int) => t = "copyWithin" // @bs.send.pipe(: t) + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) external copyWithinFromRange: (~to_: int, ~start: int, ~end_: int) => t = "copyWithin" // @bs.send.pipe(: t) external fillInPlace: elt => t = "fill" @@ -1221,12 +1665,20 @@ module Float64Array = { // @bs.send.pipe(: t) external lastIndexOfFrom: (elt, ~from: int) => int = "lastIndexOf" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) external slice: (~start: int, ~end_: int) => t = "slice" // @bs.send.pipe(: t) external copy: t = "slice" // @bs.send.pipe(: t) external sliceFrom: int => t = "slice" // @bs.send.pipe(: t) /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) external subarray: (~start: int, ~end_: int) => t = "subarray" // @bs.send.pipe(: t) external subarrayFrom: int => t = "subarray" @@ -1269,11 +1721,25 @@ module Float64Array = { // @bs.send.pipe(: t) external some: ((. elt) => bool) => bool = "some" // @bs.send.pipe(: t) external somei: ((. elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" - - @new external make: array => t = "Float64Array" + @deprecated({ + reason: "Use `Float64Array.Constants.bytesPerElement` instead.", + migrate: Float64Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Float64Array.fromArray` instead.", + migrate: Float64Array.fromArray(), + }) + @new + external make: array => t = "Float64Array" /** can throw */ @new + @deprecated({ + reason: "Use `Float64Array.fromBuffer` instead.", + migrate: Float64Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Float64Array" /** @@ -1282,6 +1748,10 @@ module Float64Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Float64Array.fromBufferToEnd` instead.", + migrate: Float64Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Float64Array" /** @@ -1290,10 +1760,27 @@ module Float64Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Float64Array.fromBufferWithRange` instead.", + migrate: Float64Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float64Array" - @new external fromLength: int => t = "Float64Array" - @val external from: array_like => t = "Float64Array.from" + @deprecated({ + reason: "Use `Float64Array.fromLength` instead.", + migrate: Float64Array.fromLength(), + }) + @new + external fromLength: int => t = "Float64Array" + @deprecated({ + reason: "Use `Float64Array.fromArrayLikeOrIterable` instead.", + migrate: Float64Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Float64Array.from" /* *Array.of is redundant, use make */ @new @deprecated("use `make` instead") external create: array => t = "Float64Array" @new @deprecated("use `fromBuffer` instead") diff --git a/packages/@rescript/runtime/Js_typed_array2.res b/packages/@rescript/runtime/Js_typed_array2.res index 873517c72f..a0412233cb 100644 --- a/packages/@rescript/runtime/Js_typed_array2.res +++ b/packages/@rescript/runtime/Js_typed_array2.res @@ -52,8 +52,18 @@ module ArrayBuffer = { @get external byteLength: t => int = "byteLength" - @send external slice: (t, ~start: int, ~end_: int) => array_buffer = "slice" - @send external sliceFrom: (t, int) => array_buffer = "slice" + @deprecated({ + reason: "Use `ArrayBuffer.slice` instead.", + migrate: ArrayBuffer.slice(~end=%insert.labelledArgument("end_")), + }) + @send + external slice: (t, ~start: int, ~end_: int) => array_buffer = "slice" + @deprecated({ + reason: "Use `ArrayBuffer.sliceToEnd` instead.", + migrate: ArrayBuffer.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) + @send + external sliceFrom: (t, int) => array_buffer = "slice" } /* commented out until bs has a plan for iterators @@ -73,93 +83,337 @@ module Int8Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArray` instead.", + migrate: TypedArray.setArray(), + }) + @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - @send external reverseInPlace: t => t = "reverse" + @deprecated({ + reason: "Use `TypedArray.fillAll` instead.", + migrate: TypedArray.fillAll(), + }) + @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({ + reason: "Use `TypedArray.reverse` instead.", + migrate: TypedArray.reverse(), + }) + @send + external reverseInPlace: t => t = "reverse" + + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use `Int.compare` for ints, etc.") + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({ + reason: "Use `TypedArray.sort` instead.", + migrate: TypedArray.sort(), + }) + @deprecated({ + reason: "Use `TypedArray.sort` instead.", + migrate: TypedArray.sort(), + }) + @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + @deprecated({ + reason: "Use `TypedArray.includes` instead.", + migrate: TypedArray.includes(), + }) + @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOf` instead.", + migrate: TypedArray.indexOf(), + }) + @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(","), + }) + @send + external join: t => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(), + }) + @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOf` instead.", + migrate: TypedArray.lastIndexOf(), + }) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) @send external slice: (t, ~start: int, ~end_: int) => t = "slice" - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + @deprecated({ + reason: "Use `TypedArray.copy` instead.", + migrate: TypedArray.copy(), + }) + @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) + @send + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - @send external subarrayFrom: (t, int) => t = "subarray" + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) + @send + external subarrayFrom: (t, int) => t = "subarray" - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + @deprecated({ + reason: "Use `TypedArray.toString` instead.", + migrate: TypedArray.toString(), + }) + @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.every` instead.", + migrate: TypedArray.every(), + }) + @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filter` instead.", + migrate: TypedArray.filter(), + }) + @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.find` instead.", + migrate: TypedArray.find(), + }) + @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndex` instead.", + migrate: TypedArray.findIndex(), + }) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEach` instead.", + migrate: TypedArray.forEach(), + }) + @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.map` instead.", + migrate: TypedArray.map(), + }) + @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.reduce` instead.", + migrate: TypedArray.reduce(), + }) + @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @val external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `TypedArray.reduceRight` instead.", + migrate: TypedArray.reduceRight(), + }) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" - @new external make: array => t = "Int8Array" + @deprecated({ + reason: "Use `TypedArray.some` instead.", + migrate: TypedArray.some(), + }) + @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" + + @deprecated({ + reason: "Use `Int8Array.Constants.bytesPerElement` instead.", + migrate: Int8Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Int8Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Int8Array.fromArray` instead.", + migrate: Int8Array.fromArray(), + }) + @new + external make: array => t = "Int8Array" /** can throw */ @new external fromBuffer: array_buffer => t = "Int8Array" @@ -169,19 +423,39 @@ module Int8Array = { **param** offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Int8Array" + @deprecated({ + reason: "Use `Int8Array.fromBufferToEnd` instead.", + migrate: Int8Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Int8Array" /** **raise** Js.Exn.Error raises Js exception **param** offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Int8Array.fromBufferWithRange` instead.", + migrate: Int8Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int8Array" - @new external fromLength: int => t = "Int8Array" - @val external from: array_like => t = "Int8Array.from" + @deprecated({ + reason: "Use `Int8Array.fromLength` instead.", + migrate: Int8Array.fromLength(), + }) + @new + external fromLength: int => t = "Int8Array" + @deprecated({ + reason: "Use `Int8Array.fromArrayLikeOrIterable` instead.", + migrate: Int8Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Int8Array.from" /* *Array.of is redundant, use make */ } @@ -198,93 +472,326 @@ module Uint8Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArray` instead.", + migrate: TypedArray.setArray(), + }) + @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - @send external reverseInPlace: t => t = "reverse" + @deprecated({ + reason: "Use `TypedArray.fillAll` instead.", + migrate: TypedArray.fillAll(), + }) + @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external sortInPlace: t => t = "sort" + @deprecated({ + reason: "Use `TypedArray.reverse` instead.", + migrate: TypedArray.reverse(), + }) + @send + external reverseInPlace: t => t = "reverse" + + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use an appropriate comparator (e.g. Int.compare).") + ), + }) + @send + external sortInPlace: t => t = "sort" @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + @deprecated({ + reason: "Use `TypedArray.includes` instead.", + migrate: TypedArray.includes(), + }) + @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOf` instead.", + migrate: TypedArray.indexOf(), + }) + @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(","), + }) + @send + external join: t => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(), + }) + @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOf` instead.", + migrate: TypedArray.lastIndexOf(), + }) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({ + reason: "Use `TypedArray.copy` instead.", + migrate: TypedArray.copy(), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) + @send + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" + external subarrayFrom: (t, int) => t = "subarray" - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + @deprecated({ + reason: "Use `TypedArray.toString` instead.", + migrate: TypedArray.toString(), + }) + @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.every` instead.", + migrate: TypedArray.every(), + }) + @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filter` instead.", + migrate: TypedArray.filter(), + }) + @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.find` instead.", + migrate: TypedArray.find(), + }) + @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndex` instead.", + migrate: TypedArray.findIndex(), + }) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEach` instead.", + migrate: TypedArray.forEach(), + }) + @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.map` instead.", + migrate: TypedArray.map(), + }) + @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.reduce` instead.", + migrate: TypedArray.reduce(), + }) + @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @val external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `TypedArray.reduceRight` instead.", + migrate: TypedArray.reduceRight(), + }) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" - @new external make: array => t = "Uint8Array" + @deprecated({ + reason: "Use `TypedArray.some` instead.", + migrate: TypedArray.some(), + }) + @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" + + @deprecated({ + reason: "Use `Uint8Array.Constants.bytesPerElement` instead.", + migrate: Uint8Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint8Array.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint8Array.fromArray` instead.", + migrate: Uint8Array.fromArray(), + }) + @new + external make: array => t = "Uint8Array" /** can throw */ @new external fromBuffer: array_buffer => t = "Uint8Array" @@ -294,19 +801,39 @@ module Uint8Array = { **param** offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" + @deprecated({ + reason: "Use `Uint8Array.fromBufferToEnd` instead.", + migrate: Uint8Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Uint8Array" /** **raise** Js.Exn.Error raises Js exception **param** offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Uint8Array.fromBufferWithRange` instead.", + migrate: Uint8Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8Array" - @new external fromLength: int => t = "Uint8Array" - @val external from: array_like => t = "Uint8Array.from" + @deprecated({ + reason: "Use `Uint8Array.fromLength` instead.", + migrate: Uint8Array.fromLength(), + }) + @new + external fromLength: int => t = "Uint8Array" + @deprecated({ + reason: "Use `Uint8Array.fromArrayLikeOrIterable` instead.", + migrate: Uint8Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint8Array.from" /* *Array.of is redundant, use make */ } @@ -323,93 +850,326 @@ module Uint8ClampedArray = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArray` instead.", + migrate: TypedArray.setArray(), + }) + @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({ + reason: "Use `TypedArray.length` instead.", + migrate: TypedArray.length(), + }) + @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - @send external reverseInPlace: t => t = "reverse" + @deprecated({ + reason: "Use `TypedArray.fillAll` instead.", + migrate: TypedArray.fillAll(), + }) + @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external sortInPlace: t => t = "sort" + @deprecated({ + reason: "Use `TypedArray.reverse` instead.", + migrate: TypedArray.reverse(), + }) + @send + external reverseInPlace: t => t = "reverse" + + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use an appropriate comparator (e.g. Int.compare).") + ), + }) + @send + external sortInPlace: t => t = "sort" @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + @deprecated({ + reason: "Use `TypedArray.includes` instead.", + migrate: TypedArray.includes(), + }) + @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOf` instead.", + migrate: TypedArray.indexOf(), + }) + @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(","), + }) + @send + external join: t => string = "join" + @deprecated({ + reason: "Use `TypedArray.joinWith` instead.", + migrate: TypedArray.joinWith(), + }) + @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOf` instead.", + migrate: TypedArray.lastIndexOf(), + }) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({ + reason: "Use `TypedArray.copy` instead.", + migrate: TypedArray.copy(), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) + @send + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" + external subarrayFrom: (t, int) => t = "subarray" - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + @deprecated({ + reason: "Use `TypedArray.toString` instead.", + migrate: TypedArray.toString(), + }) + @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.every` instead.", + migrate: TypedArray.every(), + }) + @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filter` instead.", + migrate: TypedArray.filter(), + }) + @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.find` instead.", + migrate: TypedArray.find(), + }) + @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndex` instead.", + migrate: TypedArray.findIndex(), + }) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEach` instead.", + migrate: TypedArray.forEach(), + }) + @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.map` instead.", + migrate: TypedArray.map(), + }) + @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.reduce` instead.", + migrate: TypedArray.reduce(), + }) + @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @val external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `TypedArray.reduceRight` instead.", + migrate: TypedArray.reduceRight(), + }) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" - @new external make: array => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `TypedArray.some` instead.", + migrate: TypedArray.some(), + }) + @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" + + @deprecated({ + reason: "Use `Uint8ClampedArray.Constants.bytesPerElement` instead.", + migrate: Uint8ClampedArray.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint8ClampedArray.BYTES_PER_ELEMENT" + + @deprecated({ + reason: "Use `Uint8ClampedArray.fromArray` instead.", + migrate: Uint8ClampedArray.fromArray(), + }) + @new + external make: array => t = "Uint8ClampedArray" /** can throw */ @new external fromBuffer: array_buffer => t = "Uint8ClampedArray" @@ -419,19 +1179,39 @@ module Uint8ClampedArray = { **param** offset is in bytes */ - @new - external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromBufferToEnd` instead.", + migrate: Uint8ClampedArray.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) + @new external fromBufferOffset: (array_buffer, int) => t = "Uint8ClampedArray" /** **raise** Js.Exn.Error raises Js exception **param** offset is in bytes, length in elements */ + @deprecated({ + reason: "Use `Uint8ClampedArray.fromBufferWithRange` instead.", + migrate: Uint8ClampedArray.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) @new external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint8ClampedArray" - @new external fromLength: int => t = "Uint8ClampedArray" - @val external from: array_like => t = "Uint8ClampedArray.from" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromLength` instead.", + migrate: Uint8ClampedArray.fromLength(), + }) + @new + external fromLength: int => t = "Uint8ClampedArray" + @deprecated({ + reason: "Use `Uint8ClampedArray.fromArrayLikeOrIterable` instead.", + migrate: Uint8ClampedArray.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint8ClampedArray.from" /* *Array.of is redundant, use make */ } @@ -448,89 +1228,239 @@ module Int16Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({reason: "Use `TypedArray.setArray` instead.", migrate: TypedArray.setArray()}) @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({reason: "Use `TypedArray.length` instead.", migrate: TypedArray.length()}) @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external /* end mapped below */ - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - @send external reverseInPlace: t => t = "reverse" + @deprecated({reason: "Use `TypedArray.fillAll` instead.", migrate: TypedArray.fillAll()}) @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({reason: "Use `TypedArray.reverse` instead.", migrate: TypedArray.reverse()}) @send + external reverseInPlace: t => t = "reverse" - /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use an appropriate comparator (e.g. Int.compare).") + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({reason: "Use `TypedArray.sort` instead.", migrate: TypedArray.sort()}) @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + /* Accessor functions */ + @deprecated({reason: "Use `TypedArray.includes` instead.", migrate: TypedArray.includes()}) @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @deprecated({reason: "Use `TypedArray.indexOf` instead.", migrate: TypedArray.indexOf()}) @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith(",")}) + @send + external join: t => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith()}) @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({reason: "Use `TypedArray.lastIndexOf` instead.", migrate: TypedArray.lastIndexOf()}) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({reason: "Use `TypedArray.copy` instead.", migrate: TypedArray.copy()}) @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" - - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + external subarrayFrom: (t, int) => t = "subarray" + + @deprecated({reason: "Use `TypedArray.toString` instead.", migrate: TypedArray.toString()}) @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" - - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" - - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({reason: "Use `TypedArray.every` instead.", migrate: TypedArray.every()}) @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" + + @deprecated({reason: "Use `TypedArray.filter` instead.", migrate: TypedArray.filter()}) @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" + + @deprecated({reason: "Use `TypedArray.find` instead.", migrate: TypedArray.find()}) @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({reason: "Use `TypedArray.findIndex` instead.", migrate: TypedArray.findIndex()}) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + + @deprecated({reason: "Use `TypedArray.forEach` instead.", migrate: TypedArray.forEach()}) @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({reason: "Use `TypedArray.map` instead.", migrate: TypedArray.map()}) @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + + @deprecated({reason: "Use `TypedArray.reduce` instead.", migrate: TypedArray.reduce()}) @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({reason: "Use `TypedArray.reduceRight` instead.", migrate: TypedArray.reduceRight()}) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @deprecated({reason: "Use `TypedArray.some` instead.", migrate: TypedArray.some()}) @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" @val external _BYTES_PER_ELEMENT: int = "Int16Array.BYTES_PER_ELEMENT" @@ -657,11 +1587,19 @@ module Uint16Array = { @send external some: (t, elt => bool) => bool = "some" @send external somei: (t, (elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `Uint16Array.Constants.bytesPerElement` instead.", + migrate: Uint16Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint16Array.BYTES_PER_ELEMENT" - @new external make: array => t = "Uint16Array" + @deprecated({reason: "Use `Uint16Array.fromArray` instead.", migrate: Uint16Array.fromArray()}) + @new + external make: array => t = "Uint16Array" /** can throw */ @new + @deprecated({reason: "Use `Uint16Array.fromBuffer` instead.", migrate: Uint16Array.fromBuffer()}) external fromBuffer: array_buffer => t = "Uint16Array" /** @@ -670,6 +1608,10 @@ module Uint16Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Uint16Array.fromBufferToEnd` instead.", + migrate: Uint16Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Uint16Array" /** @@ -678,10 +1620,24 @@ module Uint16Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Uint16Array.fromBufferWithRange", + migrate: Uint16Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint16Array" - @new external fromLength: int => t = "Uint16Array" - @val external from: array_like => t = "Uint16Array.from" + @deprecated({reason: "Use `Uint16Array.fromLength` instead.", migrate: Uint16Array.fromLength()}) + @new + external fromLength: int => t = "Uint16Array" + @deprecated({ + reason: "Use `Uint16Array.fromArrayLikeOrIterable` instead.", + migrate: Uint16Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint16Array.from" /* *Array.of is redundant, use make */ } @@ -698,95 +1654,249 @@ module Int32Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({reason: "Use `TypedArray.setArray` instead.", migrate: TypedArray.setArray()}) @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({reason: "Use `TypedArray.length` instead.", migrate: TypedArray.length()}) @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @deprecated({reason: "Use `TypedArray.fillAll` instead.", migrate: TypedArray.fillAll()}) @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external reverseInPlace: t => t = "reverse" + @deprecated({reason: "Use `TypedArray.reverse` instead.", migrate: TypedArray.reverse()}) @send + external reverseInPlace: t => t = "reverse" - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use an appropriate comparator (e.g. Int.compare).") + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({reason: "Use `TypedArray.sort` instead.", migrate: TypedArray.sort()}) @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ - - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({reason: "Use `TypedArray.includes` instead.", migrate: TypedArray.includes()}) @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @deprecated({reason: "Use `TypedArray.indexOf` instead.", migrate: TypedArray.indexOf()}) @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith(",")}) + @send + external join: t => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith()}) @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({reason: "Use `TypedArray.lastIndexOf` instead.", migrate: TypedArray.lastIndexOf()}) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({reason: "Use `TypedArray.copy` instead.", migrate: TypedArray.copy()}) @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" - - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + external subarrayFrom: (t, int) => t = "subarray" + + @deprecated({reason: "Use `TypedArray.toString` instead.", migrate: TypedArray.toString()}) @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" - - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" - - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" - - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" - - /* commented out until bs has a plan for iterators - external keys : t -> int array_iter = "" [@@send] - */ - - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + @deprecated({reason: "Use `TypedArray.every` instead.", migrate: TypedArray.every()}) @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" + + @deprecated({reason: "Use `TypedArray.filter` instead.", migrate: TypedArray.filter()}) @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" + + @deprecated({reason: "Use `TypedArray.find` instead.", migrate: TypedArray.find()}) @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" + @deprecated({reason: "Use `TypedArray.findIndex` instead.", migrate: TypedArray.findIndex()}) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + + @deprecated({reason: "Use `TypedArray.forEach` instead.", migrate: TypedArray.forEach()}) @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + /* commented out until bs has a plan for iterators + external keys : t -> int array_iter = "" [@@send] + */ - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({reason: "Use `TypedArray.map` instead.", migrate: TypedArray.map()}) @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + + @deprecated({reason: "Use `TypedArray.reduce` instead.", migrate: TypedArray.reduce()}) @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" + + @deprecated({reason: "Use `TypedArray.reduceRight` instead.", migrate: TypedArray.reduceRight()}) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @deprecated({reason: "Use `TypedArray.some` instead.", migrate: TypedArray.some()}) @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `Int32Array.Constants.bytesPerElement` instead.", + migrate: Int32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Int32Array.BYTES_PER_ELEMENT" - @new external make: array => t = "Int32Array" + @deprecated({reason: "Use `Int32Array.fromArray` instead.", migrate: Int32Array.fromArray()}) @new + external make: array => t = "Int32Array" /** can throw */ - @new + @new @deprecated({reason: "Use `Int32Array.fromBuffer", migrate: Int32Array.fromBuffer()}) external fromBuffer: array_buffer => t = "Int32Array" /** @@ -795,6 +1905,10 @@ module Int32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Int32Array.fromBufferToEnd` instead.", + migrate: Int32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Int32Array" /** @@ -803,10 +1917,24 @@ module Int32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Int32Array.fromBufferWithRange", + migrate: Int32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Int32Array" - @new external fromLength: int => t = "Int32Array" - @val external from: array_like => t = "Int32Array.from" + @deprecated({reason: "Use `Int32Array.fromLength` instead.", migrate: Int32Array.fromLength()}) + @new + external fromLength: int => t = "Int32Array" + @deprecated({ + reason: "Use `Int32Array.fromArrayLikeOrIterable` instead.", + migrate: Int32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Int32Array.from" /* *Array.of is redundant, use make */ } @@ -823,95 +1951,251 @@ module Uint32Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({reason: "Use `TypedArray.setArray` instead.", migrate: TypedArray.setArray()}) @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({reason: "Use `TypedArray.length` instead.", migrate: TypedArray.length()}) @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @deprecated({reason: "Use `TypedArray.fillAll` instead.", migrate: TypedArray.fillAll()}) @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - @send external reverseInPlace: t => t = "reverse" + @deprecated({reason: "Use `TypedArray.reverse` instead.", migrate: TypedArray.reverse()}) @send + external reverseInPlace: t => t = "reverse" - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_("This needs a comparator function. Use an appropriate comparator (e.g. Int.compare).") + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({reason: "Use `TypedArray.sort` instead.", migrate: TypedArray.sort()}) @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ - - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({reason: "Use `TypedArray.includes` instead.", migrate: TypedArray.includes()}) @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @deprecated({reason: "Use `TypedArray.indexOf` instead.", migrate: TypedArray.indexOf()}) @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith(",")}) + @send + external join: t => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith()}) @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({reason: "Use `TypedArray.lastIndexOf` instead.", migrate: TypedArray.lastIndexOf()}) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({reason: "Use `TypedArray.copy` instead.", migrate: TypedArray.copy()}) @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" - - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + external subarrayFrom: (t, int) => t = "subarray" + + @deprecated({reason: "Use `TypedArray.toString` instead.", migrate: TypedArray.toString()}) @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" - - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" - - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({reason: "Use `TypedArray.every` instead.", migrate: TypedArray.every()}) @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" + + @deprecated({reason: "Use `TypedArray.filter` instead.", migrate: TypedArray.filter()}) @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" + + @deprecated({reason: "Use `TypedArray.find` instead.", migrate: TypedArray.find()}) @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({reason: "Use `TypedArray.findIndex` instead.", migrate: TypedArray.findIndex()}) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + + @deprecated({reason: "Use `TypedArray.forEach` instead.", migrate: TypedArray.forEach()}) @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({reason: "Use `TypedArray.map` instead.", migrate: TypedArray.map()}) @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + + @deprecated({reason: "Use `TypedArray.reduce` instead.", migrate: TypedArray.reduce()}) @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({reason: "Use `TypedArray.reduceRight` instead.", migrate: TypedArray.reduceRight()}) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @deprecated({reason: "Use `TypedArray.some` instead.", migrate: TypedArray.some()}) @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `Uint32Array.Constants.bytesPerElement` instead.", + migrate: Uint32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Uint32Array.BYTES_PER_ELEMENT" - @new external make: array => t = "Uint32Array" + @deprecated({reason: "Use `Uint32Array.fromArray` instead.", migrate: Uint32Array.fromArray()}) + @new + external make: array => t = "Uint32Array" /** can throw */ @new + @deprecated({reason: "Use `Uint32Array.fromBuffer` instead.", migrate: Uint32Array.fromBuffer()}) external fromBuffer: array_buffer => t = "Uint32Array" /** @@ -920,6 +2204,10 @@ module Uint32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Uint32Array.fromBufferToEnd` instead.", + migrate: Uint32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Uint32Array" /** @@ -928,10 +2216,24 @@ module Uint32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Uint32Array.fromBufferWithRange` instead.", + migrate: Uint32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Uint32Array" - @new external fromLength: int => t = "Uint32Array" - @val external from: array_like => t = "Uint32Array.from" + @deprecated({reason: "Use `Uint32Array.fromLength` instead.", migrate: Uint32Array.fromLength()}) + @new + external fromLength: int => t = "Uint32Array" + @deprecated({ + reason: "Use `Uint32Array.fromArrayLikeOrIterable` instead.", + migrate: Uint32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Uint32Array.from" /* *Array.of is redundant, use make */ } @@ -951,95 +2253,256 @@ module Float32Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({reason: "Use `TypedArray.setArray` instead.", migrate: TypedArray.setArray()}) @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({reason: "Use `TypedArray.length` instead.", migrate: TypedArray.length()}) @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - - @send external reverseInPlace: t => t = "reverse" - - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @deprecated({reason: "Use `TypedArray.fillAll` instead.", migrate: TypedArray.fillAll()}) @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @deprecated({reason: "Use `TypedArray.reverse` instead.", migrate: TypedArray.reverse()}) @send + external reverseInPlace: t => t = "reverse" + + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_( + "This needs a comparator function. Use an appropriate comparator (e.g. Float.compare)." + ) + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({reason: "Use `TypedArray.sort` instead.", migrate: TypedArray.sort()}) @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ - - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({reason: "Use `TypedArray.includes` instead.", migrate: TypedArray.includes()}) @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @deprecated({reason: "Use `TypedArray.indexOf` instead.", migrate: TypedArray.indexOf()}) @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith(",")}) + @send + external join: t => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith()}) @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({reason: "Use `TypedArray.lastIndexOf` instead.", migrate: TypedArray.lastIndexOf()}) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({reason: "Use `TypedArray.copy` instead.", migrate: TypedArray.copy()}) @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" - - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + external subarrayFrom: (t, int) => t = "subarray" + + @deprecated({reason: "Use `TypedArray.toString` instead.", migrate: TypedArray.toString()}) @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" - - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" - - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({reason: "Use `TypedArray.every` instead.", migrate: TypedArray.every()}) @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" + + @deprecated({reason: "Use `TypedArray.filter` instead.", migrate: TypedArray.filter()}) @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" + + @deprecated({reason: "Use `TypedArray.find` instead.", migrate: TypedArray.find()}) @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({reason: "Use `TypedArray.findIndex` instead.", migrate: TypedArray.findIndex()}) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + + @deprecated({reason: "Use `TypedArray.forEach` instead.", migrate: TypedArray.forEach()}) @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({reason: "Use `TypedArray.map` instead.", migrate: TypedArray.map()}) @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + + @deprecated({reason: "Use `TypedArray.reduce` instead.", migrate: TypedArray.reduce()}) @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({reason: "Use `TypedArray.reduceRight` instead.", migrate: TypedArray.reduceRight()}) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @deprecated({reason: "Use `TypedArray.some` instead.", migrate: TypedArray.some()}) @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `Float32Array.Constants.bytesPerElement` instead.", + migrate: Float32Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Float32Array.BYTES_PER_ELEMENT" - @new external make: array => t = "Float32Array" + @deprecated({reason: "Use `Float32Array.fromArray` instead.", migrate: Float32Array.fromArray()}) + @new + external make: array => t = "Float32Array" /** can throw */ @new + @deprecated({ + reason: "Use `Float32Array.fromBuffer` instead.", + migrate: Float32Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Float32Array" /** @@ -1048,6 +2511,10 @@ module Float32Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Float32Array.fromBufferToEnd` instead.", + migrate: Float32Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Float32Array" /** @@ -1056,10 +2523,27 @@ module Float32Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Float32Array.fromBufferWithRange` instead.", + migrate: Float32Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float32Array" - @new external fromLength: int => t = "Float32Array" - @val external from: array_like => t = "Float32Array.from" + @deprecated({ + reason: "Use `Float32Array.fromLength` instead.", + migrate: Float32Array.fromLength(), + }) + @new + external fromLength: int => t = "Float32Array" + @deprecated({ + reason: "Use `Float32Array.fromArrayLikeOrIterable` instead.", + migrate: Float32Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Float32Array.from" /* *Array.of is redundant, use make */ } @@ -1076,95 +2560,256 @@ module Float64Array = { @get external byteLength: t => int = "byteLength" @get external byteOffset: t => int = "byteOffset" - @send external setArray: (t, array) => unit = "set" - @send external setArrayOffset: (t, array, int) => unit = "set" + @deprecated({reason: "Use `TypedArray.setArray` instead.", migrate: TypedArray.setArray()}) @send + external setArray: (t, array) => unit = "set" + @deprecated({ + reason: "Use `TypedArray.setArrayFrom` instead.", + migrate: TypedArray.setArrayFrom(%insert.unlabelledArgument(2)), + }) + @send + external setArrayOffset: (t, array, int) => unit = "set" /* There's also an overload for typed arrays, but don't know how to model that without subtyping */ /* Array interface(-ish) */ - @get external length: t => int = "length" + @deprecated({reason: "Use `TypedArray.length` instead.", migrate: TypedArray.length()}) @get + external length: t => int = "length" /* Mutator functions */ - @send external copyWithin: (t, ~to_: int) => t = "copyWithin" - @send external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" - @send external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" - - @send external fillInPlace: (t, elt) => t = "fill" - @send external fillFromInPlace: (t, elt, ~from: int) => t = "fill" - @send external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" - - @send external reverseInPlace: t => t = "reverse" - - @send external sortInPlace: t => t = "sort" - @send external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" + @deprecated({ + reason: "Use `TypedArray.copyAllWithin` instead.", + migrate: TypedArray.copyAllWithin(~target=%insert.labelledArgument("to_")), + }) + @send + external copyWithin: (t, ~to_: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithinToEnd` instead.", + migrate: TypedArray.copyWithinToEnd( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("from"), + ), + }) + @send + external copyWithinFrom: (t, ~to_: int, ~from: int) => t = "copyWithin" + @deprecated({ + reason: "Use `TypedArray.copyWithin` instead.", + migrate: TypedArray.copyWithin( + ~target=%insert.labelledArgument("to_"), + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external copyWithinFromRange: (t, ~to_: int, ~start: int, ~end_: int) => t = "copyWithin" + + @deprecated({reason: "Use `TypedArray.fillAll` instead.", migrate: TypedArray.fillAll()}) @send + external fillInPlace: (t, elt) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fillToEnd` instead.", + migrate: TypedArray.fillToEnd(~start=%insert.labelledArgument("from")), + }) + @send + external fillFromInPlace: (t, elt, ~from: int) => t = "fill" + @deprecated({ + reason: "Use `TypedArray.fill` instead.", + migrate: TypedArray.fill( + ~start=%insert.labelledArgument("start"), + ~end=%insert.labelledArgument("end_"), + ), + }) + @send + external fillRangeInPlace: (t, elt, ~start: int, ~end_: int) => t = "fill" + + @deprecated({reason: "Use `TypedArray.reverse` instead.", migrate: TypedArray.reverse()}) @send + external reverseInPlace: t => t = "reverse" + + @deprecated({ + reason: "Use `TypedArray.toSorted` instead.", + migrate: TypedArray.toSorted((a, b) => + %todo_( + "This needs a comparator function. Use an appropriate comparator (e.g. Float.compare)." + ) + ), + }) + @send + external sortInPlace: t => t = "sort" + @deprecated({reason: "Use `TypedArray.sort` instead.", migrate: TypedArray.sort()}) @send + external sortInPlaceWith: (t, (elt, elt) => int) => t = "sort" /* Accessor functions */ - @send external includes: (t, elt) => bool = "includes" /* ES2016 */ - - @send external indexOf: (t, elt) => int = "indexOf" - @send external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" + @deprecated({reason: "Use `TypedArray.includes` instead.", migrate: TypedArray.includes()}) @send + external includes: (t, elt) => bool = "includes" /* ES2016 */ + + @deprecated({reason: "Use `TypedArray.indexOf` instead.", migrate: TypedArray.indexOf()}) @send + external indexOf: (t, elt) => int = "indexOf" + @deprecated({ + reason: "Use `TypedArray.indexOfFrom` instead.", + migrate: TypedArray.indexOfFrom(%insert.labelledArgument("from")), + }) + @send + external indexOfFrom: (t, elt, ~from: int) => int = "indexOf" - @send external join: t => string = "join" - @send external joinWith: (t, string) => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith(",")}) + @send + external join: t => string = "join" + @deprecated({reason: "Use `TypedArray.joinWith` instead.", migrate: TypedArray.joinWith()}) @send + external joinWith: (t, string) => string = "join" - @send external lastIndexOf: (t, elt) => int = "lastIndexOf" - @send external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" + @deprecated({reason: "Use `TypedArray.lastIndexOf` instead.", migrate: TypedArray.lastIndexOf()}) + @send + external lastIndexOf: (t, elt) => int = "lastIndexOf" + @deprecated({ + reason: "Use `TypedArray.lastIndexOfFrom` instead.", + migrate: TypedArray.lastIndexOfFrom(%insert.labelledArgument("from")), + }) + @send + external lastIndexOfFrom: (t, elt, ~from: int) => int = "lastIndexOf" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.slice` instead.", + migrate: TypedArray.slice(~end=%insert.labelledArgument("end_")), + }) + @send external slice: (t, ~start: int, ~end_: int) => t = "slice" + + @deprecated({reason: "Use `TypedArray.copy` instead.", migrate: TypedArray.copy()}) @send + external copy: t => t = "slice" + @deprecated({ + reason: "Use `TypedArray.sliceToEnd` instead.", + migrate: TypedArray.sliceToEnd(~start=%insert.unlabelledArgument(1)), + }) @send - external slice: (t, ~start: int, ~end_: int) => t = "slice" - - @send external copy: t => t = "slice" - @send external sliceFrom: (t, int) => t = "slice" + external sliceFrom: (t, int) => t = "slice" /** `start` is inclusive, `end_` exclusive */ + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~end=%insert.labelledArgument("end_")), + }) + @send external subarray: (t, ~start: int, ~end_: int) => t = "subarray" + + @deprecated({ + reason: "Use `TypedArray.subarray` instead.", + migrate: TypedArray.subarray(~start=%insert.unlabelledArgument(1)), + }) @send - external subarray: (t, ~start: int, ~end_: int) => t = "subarray" - - @send external subarrayFrom: (t, int) => t = "subarray" - - @send external toString: t => string = "toString" - @send external toLocaleString: t => string = "toLocaleString" + external subarrayFrom: (t, int) => t = "subarray" + + @deprecated({reason: "Use `TypedArray.toString` instead.", migrate: TypedArray.toString()}) @send + external toString: t => string = "toString" + @deprecated({ + reason: "Use `TypedArray.toLocaleString` instead.", + migrate: TypedArray.toLocaleString(), + }) + @send + external toLocaleString: t => string = "toLocaleString" /* Iteration functions */ /* commented out until bs has a plan for iterators external entries : t -> (int * elt) array_iter = "" [@@send] */ - @send external every: (t, elt => bool) => bool = "every" - @send external everyi: (t, (elt, int) => bool) => bool = "every" - - @send external filter: (t, elt => bool) => t = "filter" - @send external filteri: (t, (elt, int) => bool) => t = "filter" - - @send external find: (t, elt => bool) => Js_undefined.t = "find" - @send external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - - @send external findIndex: (t, elt => bool) => int = "findIndex" - @send external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + @deprecated({reason: "Use `TypedArray.every` instead.", migrate: TypedArray.every()}) @send + external every: (t, elt => bool) => bool = "every" + @deprecated({ + reason: "Use `TypedArray.everyWithIndex` instead.", + migrate: TypedArray.everyWithIndex(), + }) + @send + external everyi: (t, (elt, int) => bool) => bool = "every" + + @deprecated({reason: "Use `TypedArray.filter` instead.", migrate: TypedArray.filter()}) @send + external filter: (t, elt => bool) => t = "filter" + @deprecated({ + reason: "Use `TypedArray.filterWithIndex` instead.", + migrate: TypedArray.filterWithIndex(), + }) + @send + external filteri: (t, (elt, int) => bool) => t = "filter" + + @deprecated({reason: "Use `TypedArray.find` instead.", migrate: TypedArray.find()}) @send + external find: (t, elt => bool) => Js_undefined.t = "find" + @deprecated({ + reason: "Use `TypedArray.findWithIndex` instead.", + migrate: TypedArray.findWithIndex(), + }) + @send + external findi: (t, (elt, int) => bool) => Js_undefined.t = "find" - @send external forEach: (t, elt => unit) => unit = "forEach" - @send external forEachi: (t, (elt, int) => unit) => unit = "forEach" + @deprecated({reason: "Use `TypedArray.findIndex` instead.", migrate: TypedArray.findIndex()}) + @send + external findIndex: (t, elt => bool) => int = "findIndex" + @deprecated({ + reason: "Use `TypedArray.findIndexWithIndex` instead.", + migrate: TypedArray.findIndexWithIndex(), + }) + @send + external findIndexi: (t, (elt, int) => bool) => int = "findIndex" + + @deprecated({reason: "Use `TypedArray.forEach` instead.", migrate: TypedArray.forEach()}) @send + external forEach: (t, elt => unit) => unit = "forEach" + @deprecated({ + reason: "Use `TypedArray.forEachWithIndex` instead.", + migrate: TypedArray.forEachWithIndex(), + }) + @send + external forEachi: (t, (elt, int) => unit) => unit = "forEach" /* commented out until bs has a plan for iterators external keys : t -> int array_iter = "" [@@send] */ - @send external map: (t, elt => 'b) => typed_array<'b> = "map" - @send external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" - - @send external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" - @send external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - - @send external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" - @send external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + @deprecated({reason: "Use `TypedArray.map` instead.", migrate: TypedArray.map()}) @send + external map: (t, elt => 'b) => typed_array<'b> = "map" + @deprecated({ + reason: "Use `TypedArray.mapWithIndex` instead.", + migrate: TypedArray.mapWithIndex(), + }) + @send + external mapi: (t, (elt, int) => 'b) => typed_array<'b> = "map" + + @deprecated({reason: "Use `TypedArray.reduce` instead.", migrate: TypedArray.reduce()}) @send + external reduce: (t, ('b, elt) => 'b, 'b) => 'b = "reduce" + @deprecated({ + reason: "Use `TypedArray.reduceWithIndex` instead.", + migrate: TypedArray.reduceWithIndex(), + }) + @send + external reducei: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduce" - @send external some: (t, elt => bool) => bool = "some" - @send external somei: (t, (elt, int) => bool) => bool = "some" + @deprecated({reason: "Use `TypedArray.reduceRight` instead.", migrate: TypedArray.reduceRight()}) + @send + external reduceRight: (t, ('b, elt) => 'b, 'b) => 'b = "reduceRight" + @deprecated({ + reason: "Use `TypedArray.reduceRightWithIndex` instead.", + migrate: TypedArray.reduceRightWithIndex(), + }) + @send + external reduceRighti: (t, ('b, elt, int) => 'b, 'b) => 'b = "reduceRight" + + @deprecated({reason: "Use `TypedArray.some` instead.", migrate: TypedArray.some()}) @send + external some: (t, elt => bool) => bool = "some" + @deprecated({ + reason: "Use `TypedArray.someWithIndex` instead.", + migrate: TypedArray.someWithIndex(), + }) + @send + external somei: (t, (elt, int) => bool) => bool = "some" - @val external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" + @deprecated({ + reason: "Use `Float64Array.Constants.bytesPerElement` instead.", + migrate: Float64Array.Constants.bytesPerElement, + }) + @val + external _BYTES_PER_ELEMENT: int = "Float64Array.BYTES_PER_ELEMENT" - @new external make: array => t = "Float64Array" + @deprecated({reason: "Use `Float64Array.fromArray` instead.", migrate: Float64Array.fromArray()}) + @new + external make: array => t = "Float64Array" /** can throw */ @new + @deprecated({ + reason: "Use `Float64Array.fromBuffer` instead.", + migrate: Float64Array.fromBuffer(), + }) external fromBuffer: array_buffer => t = "Float64Array" /** @@ -1173,6 +2818,10 @@ module Float64Array = { **param** offset is in bytes */ @new + @deprecated({ + reason: "Use `Float64Array.fromBufferToEnd` instead.", + migrate: Float64Array.fromBufferToEnd(~byteOffset=%insert.unlabelledArgument(1)), + }) external fromBufferOffset: (array_buffer, int) => t = "Float64Array" /** @@ -1181,10 +2830,27 @@ module Float64Array = { **param** offset is in bytes, length in elements */ @new + @deprecated({ + reason: "Use `Float64Array.fromBufferWithRange` instead.", + migrate: Float64Array.fromBufferWithRange( + ~byteOffset=%insert.labelledArgument("offset"), + ~length=%insert.labelledArgument("length"), + ), + }) external fromBufferRange: (array_buffer, ~offset: int, ~length: int) => t = "Float64Array" - @new external fromLength: int => t = "Float64Array" - @val external from: array_like => t = "Float64Array.from" + @deprecated({ + reason: "Use `Float64Array.fromLength` instead.", + migrate: Float64Array.fromLength(), + }) + @new + external fromLength: int => t = "Float64Array" + @deprecated({ + reason: "Use `Float64Array.fromArrayLikeOrIterable` instead.", + migrate: Float64Array.fromArrayLikeOrIterable(), + }) + @val + external from: array_like => t = "Float64Array.from" /* *Array.of is redundant, use make */ } diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array.res.expected new file mode 100644 index 0000000000..4f4f598538 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array.res.expected @@ -0,0 +1,8 @@ +let arr1 = Int8Array.fromArray([1, 2, 3]) + +let len = arr1->TypedArray.length + +let bytes = Int8Array.Constants.bytesPerElement +let off = Int8Array.fromBufferToEnd(ArrayBuffer.make(8), ~byteOffset=2) +let range = Int8Array.fromBufferWithRange(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array2.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array2.res.expected new file mode 100644 index 0000000000..35d4cb885e --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_typed_array2.res.expected @@ -0,0 +1,19 @@ +let arr = Int8Array.fromArray([1, 2, 3]) + +let len1 = arr->TypedArray.length +let includes1 = arr->TypedArray.includes(2) +let idxFrom1 = arr->TypedArray.indexOfFrom(2, 1) + +let slice1 = arr->TypedArray.slice(~start=1, ~end=2) +let sliceFrom1 = arr->TypedArray.sliceToEnd(~start=1) + +let map1 = arr->TypedArray.map(x => x + 1) +let reduce1 = arr->TypedArray.reduce((acc, x) => acc + x, 0) + +let bytes = Int8Array.Constants.bytesPerElement + +let fromBufToEnd = Int8Array.fromBufferToEnd(ArrayBuffer.make(8), ~byteOffset=2) +let fromBufRange = Int8Array.fromBufferWithRange(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) + +let fromLength = Int8Array.fromLength(3) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array.res new file mode 100644 index 0000000000..fbc29713c2 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array.res @@ -0,0 +1,7 @@ +let arr1 = Js.Typed_array.Int8Array.make([1, 2, 3]) + +let len = arr1->Js.Typed_array.Int8Array.length + +let bytes = Js.Typed_array.Int8Array._BYTES_PER_ELEMENT +let off = Js.Typed_array.Int8Array.fromBufferOffset(ArrayBuffer.make(8), 2) +let range = Js.Typed_array.Int8Array.fromBufferRange(ArrayBuffer.make(8), ~offset=2, ~length=2) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array2.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array2.res new file mode 100644 index 0000000000..636d79123a --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_typed_array2.res @@ -0,0 +1,22 @@ +let arr = Js.TypedArray2.Int8Array.make([1, 2, 3]) + +let len1 = arr->Js.TypedArray2.Int8Array.length +let includes1 = arr->Js.TypedArray2.Int8Array.includes(2) +let idxFrom1 = arr->Js.TypedArray2.Int8Array.indexOfFrom(2, ~from=1) + +let slice1 = arr->Js.TypedArray2.Int8Array.slice(~start=1, ~end_=2) +let sliceFrom1 = arr->Js.TypedArray2.Int8Array.sliceFrom(1) + +let map1 = arr->Js.TypedArray2.Int8Array.map(x => x + 1) +let reduce1 = arr->Js.TypedArray2.Int8Array.reduce((acc, x) => acc + x, 0) + +let bytes = Js.TypedArray2.Int8Array._BYTES_PER_ELEMENT + +let fromBufToEnd = Js.TypedArray2.Int8Array.fromBufferOffset(ArrayBuffer.make(8), 2) +let fromBufRange = Js.TypedArray2.Int8Array.fromBufferRange( + ArrayBuffer.make(8), + ~offset=2, + ~length=2, +) + +let fromLength = Js.TypedArray2.Int8Array.fromLength(3) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array.res new file mode 100644 index 0000000000..3020b2501f --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array.res @@ -0,0 +1,9 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js_typed_array.res. +let arr1 = Int8Array.fromArray([1, 2, 3]) + +let len = arr1->TypedArray.length + +let bytes = Int8Array.Constants.bytesPerElement +let off = Int8Array.fromBufferToEnd(ArrayBuffer.make(8), ~byteOffset=2) +let range = Int8Array.fromBufferWithRange(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array2.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array2.res new file mode 100644 index 0000000000..5b48a43624 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_typed_array2.res @@ -0,0 +1,20 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Js_typed_array2.res. +let arr = Int8Array.fromArray([1, 2, 3]) + +let len1 = arr->TypedArray.length +let includes1 = arr->TypedArray.includes(2) +let idxFrom1 = arr->TypedArray.indexOfFrom(2, 1) + +let slice1 = arr->TypedArray.slice(~start=1, ~end=2) +let sliceFrom1 = arr->TypedArray.sliceToEnd(~start=1) + +let map1 = arr->TypedArray.map(x => x + 1) +let reduce1 = arr->TypedArray.reduce((acc, x) => acc + x, 0) + +let bytes = Int8Array.Constants.bytesPerElement + +let fromBufToEnd = Int8Array.fromBufferToEnd(ArrayBuffer.make(8), ~byteOffset=2) +let fromBufRange = Int8Array.fromBufferWithRange(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) + +let fromLength = Int8Array.fromLength(3) From dfe4425aa2fb1dc50d2aa4cbd90d7c26daa246e0 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 14:32:47 +0200 Subject: [PATCH 24/41] format --- compiler/ml/typetexp.ml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/ml/typetexp.ml b/compiler/ml/typetexp.ml index 33b543b285..268ffb362f 100644 --- a/compiler/ml/typetexp.ml +++ b/compiler/ml/typetexp.ml @@ -120,7 +120,8 @@ let find_type env loc lid = env loc lid in let decl = Env.find_type path env in - Builtin_attributes.check_deprecated loc decl.type_attributes (Path.name path); + Builtin_attributes.check_deprecated ~deprecated_context:Cmt_utils.Reference + loc decl.type_attributes (Path.name path); (path, decl) let find_constructor = From 84e04c7517095401de91083d92b6c2861ca1db73 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 14:33:15 +0200 Subject: [PATCH 25/41] support replacing types --- packages/@rescript/runtime/Js_dict.res | 4 ++ packages/@rescript/runtime/Js_dict.resi | 4 ++ .../StdlibMigration_Dict.res.expected | 4 +- .../Migrated_StdlibMigration_Dict.res | 4 +- tools/src/migrate.ml | 63 +++++++++++++++++++ 5 files changed, 75 insertions(+), 4 deletions(-) diff --git a/packages/@rescript/runtime/Js_dict.res b/packages/@rescript/runtime/Js_dict.res index af8cb2d762..8b5bee3f76 100644 --- a/packages/@rescript/runtime/Js_dict.res +++ b/packages/@rescript/runtime/Js_dict.res @@ -25,6 +25,10 @@ /*** Provides a simple key-value dictionary abstraction over native JavaScript objects */ /** The dict type */ +@deprecated({ + reason: "Use `dict` directly instead.", + migrate: %replace.type(: dict), +}) type t<'a> = dict<'a> /** The key type, an alias of string */ diff --git a/packages/@rescript/runtime/Js_dict.resi b/packages/@rescript/runtime/Js_dict.resi index 5f7a841b15..ca0660f667 100644 --- a/packages/@rescript/runtime/Js_dict.resi +++ b/packages/@rescript/runtime/Js_dict.resi @@ -39,6 +39,10 @@ Dictionary type (ie an '{ }' JS object). However it is restricted to hold a single type; therefore values must have the same type. This Dictionary type is mostly used with the Js_json.t type. */ +@deprecated({ + reason: "Use `dict` directly instead.", + migrate: %replace.type(: dict), +}) type t<'a> = dict<'a> /** diff --git a/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected index af24b116db..2cacd2c0d4 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Dict.res.expected @@ -18,11 +18,11 @@ let values2 = Dict.valuesToArray(d) let entries1 = d->Dict.toArray let entries2 = Dict.toArray(d) -let dStr: Js.Dict.t = Dict.make() +let dStr: dict = Dict.make() let del1 = dStr->Dict.delete("k") let del2 = Dict.delete(dStr, "k") -let empty1: Js.Dict.t = Dict.make() +let empty1: dict = Dict.make() let fromArray1 = [("a", 1), ("b", 2)]->Dict.fromArray let fromArray2 = Dict.fromArray([("a", 1), ("b", 2)]) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res index 4391c59509..990ab3b5e0 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Dict.res @@ -20,11 +20,11 @@ let values2 = Dict.valuesToArray(d) let entries1 = d->Dict.toArray let entries2 = Dict.toArray(d) -let dStr: Js.Dict.t = Dict.make() +let dStr: dict = Dict.make() let del1 = dStr->Dict.delete("k") let del2 = Dict.delete(dStr, "k") -let empty1: Js.Dict.t = Dict.make() +let empty1: dict = Dict.make() let fromArray1 = [("a", 1), ("b", 2)]->Dict.fromArray let fromArray2 = Dict.fromArray([("a", 1), ("b", 2)]) diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index e1f0c5db28..577f385c8b 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -276,6 +276,20 @@ module MapperUtils = struct renamed @ template_args_to_insert end +module TypeReplace = struct + let ext_replace_type = "replace.type" + + (* Extract a core_type payload from an expression extension of the form + %replace.type(: ) *) + let core_type_of_expr_extension (expr : Parsetree.expression) = + match expr.pexp_desc with + | Pexp_extension ({txt}, payload) when txt = ext_replace_type -> ( + match payload with + | PTyp ct -> Some ct + | _ -> None) + | _ -> None +end + type args_ctx = { labelled: (string, Parsetree.expression) Hashtbl.t; unlabelled: (int, Parsetree.expression) Hashtbl.t; @@ -552,6 +566,55 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = { Ast_mapper.default_mapper with extension = remap_needed_extensions; + (* Replace deprecated type references when a %replace.type(: ...) template + is provided. *) + typ = + (fun mapper (ct : Parsetree.core_type) -> + match ct.ptyp_desc with + | Ptyp_constr ({loc}, args) -> ( + (* Build a lookup of deprecated type references (by source loc) -> + core_type template. *) + let loc_contains (a : Location.t) (b : Location.t) = + let a_start = a.Location.loc_start.pos_cnum in + let a_end = a.Location.loc_end.pos_cnum in + let b_start = b.Location.loc_start.pos_cnum in + let b_end = b.Location.loc_end.pos_cnum in + a_start <= b_start && a_end >= b_end + in + let replace_template_opt = + (* We expect the cmt to have recorded deprecations for type + references without a specific context; we also only consider + entries whose migration_template is a %replace.type(: ...). *) + deprecated_used + |> List.find_map (fun (d : Cmt_utils.deprecated_used) -> + match d.migration_template with + | Some e -> ( + match TypeReplace.core_type_of_expr_extension e with + | Some ct + when loc_contains loc d.source_loc + || loc_contains d.source_loc loc -> + Some ct + | _ -> None) + | None -> None) + in + match replace_template_opt with + | Some template_ct -> ( + (* Transfer all source type arguments as-is. *) + let mapped_args = List.map (mapper.Ast_mapper.typ mapper) args in + match template_ct.ptyp_desc with + | Ptyp_constr (new_lid, templ_args) -> + let new_args = templ_args @ mapped_args in + let ct' = + {ct with ptyp_desc = Ptyp_constr (new_lid, new_args)} + in + mapper.Ast_mapper.typ mapper ct' + | _ -> + (* If the template isn't a constructor, fall back to the + template itself and drop the original args. *) + let ct' = {template_ct with ptyp_loc = ct.ptyp_loc} in + mapper.Ast_mapper.typ mapper ct') + | None -> Ast_mapper.default_mapper.typ mapper ct) + | _ -> Ast_mapper.default_mapper.typ mapper ct); expr = (fun mapper exp -> match exp with From 1cc2b54c0e2a972e7eb99995f78e3da8f9a0807d Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 15:01:41 +0200 Subject: [PATCH 26/41] more type replacement migrations --- packages/@rescript/runtime/Js_array.res | 4 ++++ packages/@rescript/runtime/Js_array2.res | 4 ++++ packages/@rescript/runtime/Js_date.res | 4 ++++ packages/@rescript/runtime/Js_dict.res | 4 ---- packages/@rescript/runtime/Js_dict.resi | 4 ++++ packages/@rescript/runtime/Js_global.res | 8 ++++++++ packages/@rescript/runtime/Js_json.resi | 4 ++++ packages/@rescript/runtime/Js_map.res | 4 ++++ packages/@rescript/runtime/Js_null.resi | 4 ++++ packages/@rescript/runtime/Js_null_undefined.resi | 4 ++++ packages/@rescript/runtime/Js_option.resi | 4 ++++ packages/@rescript/runtime/Js_re.res | 4 ++++ packages/@rescript/runtime/Js_result.resi | 5 ++++- packages/@rescript/runtime/Js_set.res | 4 ++++ packages/@rescript/runtime/Js_string.res | 4 ++++ packages/@rescript/runtime/Js_string2.res | 4 ++++ packages/@rescript/runtime/Js_types.resi | 4 ++++ packages/@rescript/runtime/Js_undefined.resi | 4 ++++ packages/@rescript/runtime/Js_weakmap.res | 4 ++++ packages/@rescript/runtime/Js_weakset.res | 4 ++++ .../src/expected/StdlibMigration_Array.res.expected | 4 ++++ .../src/expected/StdlibMigration_Date.res.expected | 3 +++ .../src/expected/StdlibMigration_Global.res.expected | 8 ++++---- .../src/expected/StdlibMigration_JSON.res.expected | 4 ++-- .../src/expected/StdlibMigration_Js_Re.res.expected | 3 +++ .../src/expected/StdlibMigration_Map.res.expected | 3 +++ .../src/expected/StdlibMigration_Null.res.expected | 3 +++ .../src/expected/StdlibMigration_Option.res.expected | 3 +++ .../src/expected/StdlibMigration_Result.res.expected | 2 ++ .../src/expected/StdlibMigration_Set.res.expected | 3 +++ .../src/expected/StdlibMigration_String.res.expected | 4 ++++ .../src/expected/StdlibMigration_WeakMap.res.expected | 3 +++ .../src/expected/StdlibMigration_WeakSet.res.expected | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Array.res | 4 ++++ tests/tools_tests/src/migrate/StdlibMigration_Date.res | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Map.res | 2 ++ tests/tools_tests/src/migrate/StdlibMigration_Null.res | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Option.res | 3 +++ tests/tools_tests/src/migrate/StdlibMigration_Result.res | 1 + tests/tools_tests/src/migrate/StdlibMigration_Set.res | 2 ++ tests/tools_tests/src/migrate/StdlibMigration_String.res | 4 ++++ tests/tools_tests/src/migrate/StdlibMigration_WeakMap.res | 2 ++ tests/tools_tests/src/migrate/StdlibMigration_WeakSet.res | 2 ++ .../migrate/migrated/Migrated_StdlibMigration_Array.res | 4 ++++ .../migrate/migrated/Migrated_StdlibMigration_Date.res | 3 +++ .../migrate/migrated/Migrated_StdlibMigration_Global.res | 8 ++++---- .../migrate/migrated/Migrated_StdlibMigration_JSON.res | 4 ++-- .../migrate/migrated/Migrated_StdlibMigration_Js_Re.res | 3 +++ .../src/migrate/migrated/Migrated_StdlibMigration_Map.res | 4 ++++ .../migrate/migrated/Migrated_StdlibMigration_Null.res | 3 +++ .../migrate/migrated/Migrated_StdlibMigration_Option.res | 3 +++ .../migrate/migrated/Migrated_StdlibMigration_Result.res | 3 +++ .../src/migrate/migrated/Migrated_StdlibMigration_Set.res | 4 ++++ .../migrate/migrated/Migrated_StdlibMigration_String.res | 4 ++++ .../migrate/migrated/Migrated_StdlibMigration_WeakMap.res | 4 ++++ .../migrate/migrated/Migrated_StdlibMigration_WeakSet.res | 4 ++++ 57 files changed, 194 insertions(+), 17 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Map.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Result.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Set.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_WeakMap.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_WeakSet.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Map.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Result.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Set.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_WeakMap.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_WeakSet.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Map.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Set.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakMap.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakSet.res diff --git a/packages/@rescript/runtime/Js_array.res b/packages/@rescript/runtime/Js_array.res index 3319d8ede9..688a48c030 100644 --- a/packages/@rescript/runtime/Js_array.res +++ b/packages/@rescript/runtime/Js_array.res @@ -33,6 +33,10 @@ parameter in the function. /** The type used to describe a JavaScript array. */ +@deprecated({ + reason: "Use `array` directly instead.", + migrate: %replace.type(: array), +}) type t<'a> = array<'a> /** diff --git a/packages/@rescript/runtime/Js_array2.res b/packages/@rescript/runtime/Js_array2.res index 79d89a950a..3a35e3aeb6 100644 --- a/packages/@rescript/runtime/Js_array2.res +++ b/packages/@rescript/runtime/Js_array2.res @@ -54,6 +54,10 @@ let result = { /** The type used to describe a JavaScript array. */ +@deprecated({ + reason: "Use `array` directly instead.", + migrate: %replace.type(: array), +}) type t<'a> = array<'a> /** diff --git a/packages/@rescript/runtime/Js_date.res b/packages/@rescript/runtime/Js_date.res index be002df106..85d79b25ad 100644 --- a/packages/@rescript/runtime/Js_date.res +++ b/packages/@rescript/runtime/Js_date.res @@ -29,6 +29,10 @@ on MDN.) JavaScript stores dates as the number of milliseconds since the UNIX *epoch*, midnight 1 January 1970, UTC. */ +@deprecated({ + reason: "Use `Date.t` instead.", + migrate: %replace.type(: Date.t), +}) type t = Stdlib_Date.t /** diff --git a/packages/@rescript/runtime/Js_dict.res b/packages/@rescript/runtime/Js_dict.res index 8b5bee3f76..af8cb2d762 100644 --- a/packages/@rescript/runtime/Js_dict.res +++ b/packages/@rescript/runtime/Js_dict.res @@ -25,10 +25,6 @@ /*** Provides a simple key-value dictionary abstraction over native JavaScript objects */ /** The dict type */ -@deprecated({ - reason: "Use `dict` directly instead.", - migrate: %replace.type(: dict), -}) type t<'a> = dict<'a> /** The key type, an alias of string */ diff --git a/packages/@rescript/runtime/Js_dict.resi b/packages/@rescript/runtime/Js_dict.resi index ca0660f667..9f0eb68c72 100644 --- a/packages/@rescript/runtime/Js_dict.resi +++ b/packages/@rescript/runtime/Js_dict.resi @@ -48,6 +48,10 @@ type t<'a> = dict<'a> /** The type for dictionary keys. This means that dictionaries *must* use `string`s as their keys. */ +@deprecated({ + reason: "Use `string` directly instead.", + migrate: %replace.type(: string), +}) type key = string /** diff --git a/packages/@rescript/runtime/Js_global.res b/packages/@rescript/runtime/Js_global.res index f7abba205b..6fee58a024 100644 --- a/packages/@rescript/runtime/Js_global.res +++ b/packages/@rescript/runtime/Js_global.res @@ -27,9 +27,17 @@ Contains functions available in the global scope (`window` in a browser context) */ /** Identify an interval started by `Js.Global.setInterval`. */ +@deprecated({ + reason: "Use `intervalId` directly instead.", + migrate: %replace.type(: intervalId), +}) type intervalId = Stdlib_Global.intervalId /** Identify timeout started by `Js.Global.setTimeout`. */ +@deprecated({ + reason: "Use `timeoutId` directly instead.", + migrate: %replace.type(: timeoutId), +}) type timeoutId = Stdlib_Global.timeoutId /** diff --git a/packages/@rescript/runtime/Js_json.resi b/packages/@rescript/runtime/Js_json.resi index 7e18bf6828..9ce7a629a3 100644 --- a/packages/@rescript/runtime/Js_json.resi +++ b/packages/@rescript/runtime/Js_json.resi @@ -31,6 +31,10 @@ Efficient JSON encoding using JavaScript API /* ## Types */ /** The JSON data structure */ +@deprecated({ + reason: "Use `JSON.t` instead.", + migrate: %replace.type(: JSON.t), +}) @unboxed type rec t = Stdlib_JSON.t = | Boolean(bool) diff --git a/packages/@rescript/runtime/Js_map.res b/packages/@rescript/runtime/Js_map.res index 1f9cbdf19f..827c66b9ab 100644 --- a/packages/@rescript/runtime/Js_map.res +++ b/packages/@rescript/runtime/Js_map.res @@ -1,3 +1,7 @@ /*** ES6 Map API */ +@deprecated({ + reason: "Use `Map.t` instead.", + migrate: %replace.type(: Map.t), +}) type t<'k, 'v> = Stdlib_Map.t<'k, 'v> diff --git a/packages/@rescript/runtime/Js_null.resi b/packages/@rescript/runtime/Js_null.resi index a61a216174..1f7df3256b 100644 --- a/packages/@rescript/runtime/Js_null.resi +++ b/packages/@rescript/runtime/Js_null.resi @@ -24,6 +24,10 @@ /*** Provides functionality for dealing with the `Js.null<'a>` type */ +@deprecated({ + reason: "Use `null` directly instead.", + migrate: %replace.type(: null), +}) @unboxed type t<+'a> = Primitive_js_extern.null<'a> = Value('a) | @as(null) Null diff --git a/packages/@rescript/runtime/Js_null_undefined.resi b/packages/@rescript/runtime/Js_null_undefined.resi index 4bd9305ada..132efe7b8f 100644 --- a/packages/@rescript/runtime/Js_null_undefined.resi +++ b/packages/@rescript/runtime/Js_null_undefined.resi @@ -26,6 +26,10 @@ Contains functionality for dealing with values that can be both `null` and `undefined` */ +@deprecated({ + reason: "Use `nullable` directly instead.", + migrate: %replace.type(: nullable), +}) @unboxed type t<+'a> = Primitive_js_extern.nullable<'a> = Value('a) | @as(null) Null | @as(undefined) Undefined diff --git a/packages/@rescript/runtime/Js_option.resi b/packages/@rescript/runtime/Js_option.resi index 1275dfc8cb..1dd6765b2c 100644 --- a/packages/@rescript/runtime/Js_option.resi +++ b/packages/@rescript/runtime/Js_option.resi @@ -22,6 +22,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +@deprecated({ + reason: "Use `option` directly instead.", + migrate: %replace.type(: option), +}) type t<'a> = option<'a> @deprecated({ diff --git a/packages/@rescript/runtime/Js_re.res b/packages/@rescript/runtime/Js_re.res index 0a66e52b3a..b275c56ddf 100644 --- a/packages/@rescript/runtime/Js_re.res +++ b/packages/@rescript/runtime/Js_re.res @@ -31,6 +31,10 @@ and subsequent uses will continue the search from the previous [`lastIndex`](). */ /** The RegExp object. */ +@deprecated({ + reason: "Use `RegExp.t` instead.", + migrate: %replace.type(: RegExp.t), +}) type t = Stdlib_RegExp.t /** The result of a executing a RegExp on a string. */ diff --git a/packages/@rescript/runtime/Js_result.resi b/packages/@rescript/runtime/Js_result.resi index 8cb2ab13f3..740fdc149c 100644 --- a/packages/@rescript/runtime/Js_result.resi +++ b/packages/@rescript/runtime/Js_result.resi @@ -22,7 +22,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -@deprecated("Please use `Belt.Result.t` instead") +@deprecated({ + reason: "Use `result` directly instead.", + migrate: %replace.type(: result), +}) type t<+'good, +'bad> = | Ok('good) | Error('bad) diff --git a/packages/@rescript/runtime/Js_set.res b/packages/@rescript/runtime/Js_set.res index bb195cd4f4..80d89dbb81 100644 --- a/packages/@rescript/runtime/Js_set.res +++ b/packages/@rescript/runtime/Js_set.res @@ -1,3 +1,7 @@ /*** ES6 Set API */ +@deprecated({ + reason: "Use `Set.t` instead.", + migrate: %replace.type(: Set.t), +}) type t<'a> = Stdlib_Set.t<'a> diff --git a/packages/@rescript/runtime/Js_string.res b/packages/@rescript/runtime/Js_string.res index a1df479520..099a403209 100644 --- a/packages/@rescript/runtime/Js_string.res +++ b/packages/@rescript/runtime/Js_string.res @@ -26,6 +26,10 @@ @@warning("-103") +@deprecated({ + reason: "Use `string` directly instead.", + migrate: %replace.type(: string), +}) type t = string /** diff --git a/packages/@rescript/runtime/Js_string2.res b/packages/@rescript/runtime/Js_string2.res index 34257c5a3b..c545e2f910 100644 --- a/packages/@rescript/runtime/Js_string2.res +++ b/packages/@rescript/runtime/Js_string2.res @@ -24,6 +24,10 @@ /*** Provide bindings to JS string. Optimized for pipe-first. */ +@deprecated({ + reason: "Use `string` directly instead.", + migrate: %replace.type(: string), +}) type t = string /** diff --git a/packages/@rescript/runtime/Js_types.resi b/packages/@rescript/runtime/Js_types.resi index 7ac929ff11..911170c06f 100644 --- a/packages/@rescript/runtime/Js_types.resi +++ b/packages/@rescript/runtime/Js_types.resi @@ -25,6 +25,10 @@ /*** Provide utilities for manipulating JS types. */ /** Js symbol type (only available in ES6) */ +@deprecated({ + reason: "Use `Symbol.t` instead.", + migrate: %replace.type(: Symbol.t), +}) type symbol = Stdlib_Symbol.t type obj_val = Stdlib_Type.Classify.object diff --git a/packages/@rescript/runtime/Js_undefined.resi b/packages/@rescript/runtime/Js_undefined.resi index c900832f25..b625fa8919 100644 --- a/packages/@rescript/runtime/Js_undefined.resi +++ b/packages/@rescript/runtime/Js_undefined.resi @@ -25,6 +25,10 @@ /*** Provides functionality for dealing with the `Js.undefined<'a>` type */ /** Local alias for `Js.undefined<'a>` */ +@deprecated({ + reason: "Use `undefined` directly instead.", + migrate: %replace.type(: undefined), +}) type t<+'a> = Primitive_js_extern.undefined<'a> /** Constructs a value of `Js.undefined<'a>` containing a value of `'a`. */ diff --git a/packages/@rescript/runtime/Js_weakmap.res b/packages/@rescript/runtime/Js_weakmap.res index 152ecb2be6..c034ba108e 100644 --- a/packages/@rescript/runtime/Js_weakmap.res +++ b/packages/@rescript/runtime/Js_weakmap.res @@ -1,3 +1,7 @@ /*** ES6 WeakMap API */ +@deprecated({ + reason: "Use `WeakMap.t` instead.", + migrate: %replace.type(: WeakMap.t), +}) type t<'k, 'v> = Stdlib_WeakMap.t<'k, 'v> diff --git a/packages/@rescript/runtime/Js_weakset.res b/packages/@rescript/runtime/Js_weakset.res index 492912f2af..bb5851460f 100644 --- a/packages/@rescript/runtime/Js_weakset.res +++ b/packages/@rescript/runtime/Js_weakset.res @@ -1,3 +1,7 @@ /*** ES6 WeakSet API */ +@deprecated({ + reason: "Use `WeakSet.t` instead.", + migrate: %replace.type(: WeakSet.t), +}) type t<'a> = Stdlib_WeakSet.t<'a> diff --git a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected index 32235a9f50..b191cec284 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected @@ -170,3 +170,7 @@ let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc let pipeChain = [1, 2, 3]->Array.map(x => x * 2)->Array.filter(x => x > 2)->Array.reduce(0, (acc, x) => acc + x) +// Type alias migrations +let arrT: array = [1, 2, 3] +let arr2T: array = [1, 2, 3] + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected index fa0108faf1..2b3dd5658b 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Date.res.expected @@ -186,3 +186,6 @@ let s9 = d2->Date.toUTCString let j1 = d2->Date.toJSON let j2 = d2->Date.toJSON +// Type alias migration +external someDate: Date.t = "someDate" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected index f0ff03a9eb..69e573d135 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Global.res.expected @@ -1,10 +1,10 @@ -let t1: Js.Global.timeoutId = setTimeout(() => (), 1000) -let t2: Js.Global.timeoutId = setTimeoutFloat(() => (), 1000.0) +let t1: timeoutId = setTimeout(() => (), 1000) +let t2: timeoutId = setTimeoutFloat(() => (), 1000.0) clearTimeout(t1) -let i1: Js.Global.intervalId = setInterval(() => (), 2000) -let i2: Js.Global.intervalId = setIntervalFloat(() => (), 2000.0) +let i1: intervalId = setInterval(() => (), 2000) +let i2: intervalId = setIntervalFloat(() => (), 2000.0) clearInterval(i1) diff --git a/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected index f5e4af5f9c..14df9f8c38 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected @@ -1,5 +1,5 @@ -external someJson: Js_json.t = "someJson" -external strToJson: string => Js_json.t = "strToJson" +external someJson: JSON.t = "someJson" +external strToJson: string => JSON.t = "strToJson" let decodeString1 = switch someJson { | JSON.String(str) => Some(str) diff --git a/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected index 5788ed39cf..73388f2bed 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Js_Re.res.expected @@ -31,6 +31,9 @@ let exec2 = RegExp.exec(re2, "Foo bar") let test1 = re2->RegExp.test("Foo bar") let test2 = RegExp.test(re2, "Foo bar") +// Type alias migration +external reT: RegExp.t = "re" + let matches_access = switch re2->RegExp.exec("Foo bar") { | None => 0 | Some(r) => RegExp.Result.matches(r)->Array.length diff --git a/tests/tools_tests/src/expected/StdlibMigration_Map.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Map.res.expected new file mode 100644 index 0000000000..ef71502bff --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Map.res.expected @@ -0,0 +1,3 @@ +// Type alias migration for Js.Map.t +external m: Map.t = "m" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected index 14a42abc06..4783a18ad2 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Null.res.expected @@ -31,3 +31,6 @@ let test1 = Null.null === Null.null let test2 = Null.null === Null.null let test3 = Null.make(5)->Null.map(v => v)->Null.equal(Null, (a, b) => a === b) +// Type alias migration +let nullT: null = Null.make(1) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected index 91f561a0c7..76a8b69111 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Option.res.expected @@ -29,3 +29,6 @@ let filter1 = Option.filter(Some(1), x => x > 0) let firstSome1 = Option.orElse(Some(1), None) let firstSome2 = Option.orElse(Some(1), None) +// Type alias migration +let optT: option = Some(1) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected new file mode 100644 index 0000000000..8eb9b9cb94 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected @@ -0,0 +1,2 @@ +let res: result = Ok(1) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Set.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Set.res.expected new file mode 100644 index 0000000000..3abe912e07 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Set.res.expected @@ -0,0 +1,3 @@ +// Type alias migration for Js.Set.t +external s: Set.t = "s" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_String.res.expected b/tests/tools_tests/src/expected/StdlibMigration_String.res.expected index 031edd3828..df8a911420 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_String.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_String.res.expected @@ -124,3 +124,7 @@ let toLocaleUpperCase2 = String.toLocaleUpperCase("abcde") let trim1 = "abcde"->String.trim let trim2 = String.trim("abcde") +// Type alias migrations +let sT: string = "abc" +let s2T: string = "def" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_WeakMap.res.expected b/tests/tools_tests/src/expected/StdlibMigration_WeakMap.res.expected new file mode 100644 index 0000000000..8dfa5ef102 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_WeakMap.res.expected @@ -0,0 +1,3 @@ +// Type alias migration for Js.WeakMap.t +external wm: WeakMap.t<{..}, int> = "wm" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_WeakSet.res.expected b/tests/tools_tests/src/expected/StdlibMigration_WeakSet.res.expected new file mode 100644 index 0000000000..aa547b1e22 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_WeakSet.res.expected @@ -0,0 +1,3 @@ +// Type alias migration for Js.WeakSet.t +external ws: WeakSet.t<{..}> = "ws" + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Array.res b/tests/tools_tests/src/migrate/StdlibMigration_Array.res index f2ce25c807..c457b93b2e 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Array.res @@ -173,3 +173,7 @@ let pipeChain = ->Js.Array2.map(x => x * 2) ->Js.Array2.filter(x => x > 2) ->Js.Array2.reduce((acc, x) => acc + x, 0) + +// Type alias migrations +let arrT: Js.Array.t = [1, 2, 3] +let arr2T: Js.Array2.t = [1, 2, 3] diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Date.res b/tests/tools_tests/src/migrate/StdlibMigration_Date.res index 09ad744b65..5621f35480 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Date.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Date.res @@ -134,3 +134,6 @@ let setYr = d2->Js.Date.setYear(1999.0) let s9 = d2->Js.Date.toGMTString let j1 = d2->Js.Date.toJSON let j2 = d2->Js.Date.toJSONUnsafe + +// Type alias migration +external someDate: Js.Date.t = "someDate" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res index bec13cff93..818abba994 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Js_Re.res @@ -31,6 +31,9 @@ let exec2 = Js.Re.exec_(re2, "Foo bar") let test1 = re2->Js.Re.test_("Foo bar") let test2 = Js.Re.test_(re2, "Foo bar") +// Type alias migration +external reT: Js.Re.t = "re" + let matches_access = switch re2->Js.Re.exec_("Foo bar") { | None => 0 | Some(r) => Js.Re.matches(r)->Array.length diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Map.res b/tests/tools_tests/src/migrate/StdlibMigration_Map.res new file mode 100644 index 0000000000..942aea0246 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Map.res @@ -0,0 +1,2 @@ +// Type alias migration for Js.Map.t +external m: Js.Map.t = "m" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Null.res b/tests/tools_tests/src/migrate/StdlibMigration_Null.res index e0081a11be..f88c148f5c 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Null.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Null.res @@ -30,3 +30,6 @@ let to_opt2 = Js.Null.to_opt(Js.Null.return(4)) let test1 = Js.Null.empty->Js.Null.test let test2 = Js.Null.test(Js.Null.empty) let test3 = Js.Null.return(5)->Js.Null.bind(v => v)->Js.Null.test + +// Type alias migration +let nullT: Js.Null.t = Js.Null.return(1) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Option.res b/tests/tools_tests/src/migrate/StdlibMigration_Option.res index 4c60e251dd..b781219ed3 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Option.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Option.res @@ -28,3 +28,6 @@ let filter1 = Js.Option.filter(x => x > 0, Some(1)) let firstSome1 = Js.Option.firstSome(Some(1), None) let firstSome2 = Some(1)->Js.Option.firstSome(None) + +// Type alias migration +let optT: Js.Option.t = Some(1) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Result.res b/tests/tools_tests/src/migrate/StdlibMigration_Result.res new file mode 100644 index 0000000000..fa13b37e34 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Result.res @@ -0,0 +1 @@ +let res: Js.Result.t = Ok(1) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Set.res b/tests/tools_tests/src/migrate/StdlibMigration_Set.res new file mode 100644 index 0000000000..f8818cde87 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Set.res @@ -0,0 +1,2 @@ +// Type alias migration for Js.Set.t +external s: Js.Set.t = "s" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_String.res b/tests/tools_tests/src/migrate/StdlibMigration_String.res index a67821e71f..edf01733c7 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_String.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_String.res @@ -123,3 +123,7 @@ let toLocaleUpperCase2 = Js.String2.toLocaleUpperCase("abcde") let trim1 = "abcde"->Js.String2.trim let trim2 = Js.String2.trim("abcde") + +// Type alias migrations +let sT: Js.String.t = "abc" +let s2T: Js.String2.t = "def" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_WeakMap.res b/tests/tools_tests/src/migrate/StdlibMigration_WeakMap.res new file mode 100644 index 0000000000..0b4cd98ad2 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_WeakMap.res @@ -0,0 +1,2 @@ +// Type alias migration for Js.WeakMap.t +external wm: Js.WeakMap.t<{..}, int> = "wm" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_WeakSet.res b/tests/tools_tests/src/migrate/StdlibMigration_WeakSet.res new file mode 100644 index 0000000000..35d811fc18 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_WeakSet.res @@ -0,0 +1,2 @@ +// Type alias migration for Js.WeakSet.t +external ws: Js.WeakSet.t<{..}> = "ws" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res index d94e7340c6..0e93e4060d 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res @@ -171,3 +171,7 @@ let reduceRighti2 = Array.reduceRightWithIndex([1, 2, 3], 0, (acc, x, i) => acc let pipeChain = [1, 2, 3]->Array.map(x => x * 2)->Array.filter(x => x > 2)->Array.reduce(0, (acc, x) => acc + x) + +// Type alias migrations +let arrT: array = [1, 2, 3] +let arr2T: array = [1, 2, 3] diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res index ba866356f3..2df5dd3ff5 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Date.res @@ -187,3 +187,6 @@ let setYr = d2->Js.Date.setYear(1999.0) let s9 = d2->Date.toUTCString let j1 = d2->Date.toJSON let j2 = d2->Date.toJSON + +// Type alias migration +external someDate: Date.t = "someDate" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res index a079afd25f..80e8767e68 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Global.res @@ -1,12 +1,12 @@ // This file is autogenerated so it can be type checked. // It's the migrated version of src/migrate/StdlibMigration_Global.res. -let t1: Js.Global.timeoutId = setTimeout(() => (), 1000) -let t2: Js.Global.timeoutId = setTimeoutFloat(() => (), 1000.0) +let t1: timeoutId = setTimeout(() => (), 1000) +let t2: timeoutId = setTimeoutFloat(() => (), 1000.0) clearTimeout(t1) -let i1: Js.Global.intervalId = setInterval(() => (), 2000) -let i2: Js.Global.intervalId = setIntervalFloat(() => (), 2000.0) +let i1: intervalId = setInterval(() => (), 2000) +let i2: intervalId = setIntervalFloat(() => (), 2000.0) clearInterval(i1) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res index 103bd0109c..12491053d9 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res @@ -1,7 +1,7 @@ // This file is autogenerated so it can be type checked. // It's the migrated version of src/migrate/StdlibMigration_JSON.res. -external someJson: Js_json.t = "someJson" -external strToJson: string => Js_json.t = "strToJson" +external someJson: JSON.t = "someJson" +external strToJson: string => JSON.t = "strToJson" let decodeString1 = switch someJson { | JSON.String(str) => Some(str) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res index b952f005d9..d059c10e9c 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Js_Re.res @@ -33,6 +33,9 @@ let exec2 = RegExp.exec(re2, "Foo bar") let test1 = re2->RegExp.test("Foo bar") let test2 = RegExp.test(re2, "Foo bar") +// Type alias migration +external reT: RegExp.t = "re" + let matches_access = switch re2->RegExp.exec("Foo bar") { | None => 0 | Some(r) => RegExp.Result.matches(r)->Array.length diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Map.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Map.res new file mode 100644 index 0000000000..5100bef070 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Map.res @@ -0,0 +1,4 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Map.res. +// Type alias migration for Js.Map.t +external m: Map.t = "m" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res index d418565f7b..9671fa2d00 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Null.res @@ -32,3 +32,6 @@ let to_opt2 = Null.toOption(Null.make(4)) let test1 = Null.null === Null.null let test2 = Null.null === Null.null let test3 = Null.make(5)->Null.map(v => v)->Null.equal(Null, (a, b) => a === b) + +// Type alias migration +let nullT: null = Null.make(1) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res index bacd4299b1..ecd5f7f4a9 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Option.res @@ -30,3 +30,6 @@ let filter1 = Option.filter(Some(1), x => x > 0) let firstSome1 = Option.orElse(Some(1), None) let firstSome2 = Option.orElse(Some(1), None) + +// Type alias migration +let optT: option = Some(1) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res new file mode 100644 index 0000000000..dfd2a7de62 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res @@ -0,0 +1,3 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Result.res. +let res: result = Ok(1) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Set.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Set.res new file mode 100644 index 0000000000..7d1576ebee --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Set.res @@ -0,0 +1,4 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Set.res. +// Type alias migration for Js.Set.t +external s: Set.t = "s" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res index 9e67e14937..14b9b7ab35 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_String.res @@ -125,3 +125,7 @@ let toLocaleUpperCase2 = String.toLocaleUpperCase("abcde") let trim1 = "abcde"->String.trim let trim2 = String.trim("abcde") + +// Type alias migrations +let sT: string = "abc" +let s2T: string = "def" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakMap.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakMap.res new file mode 100644 index 0000000000..afb50c990c --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakMap.res @@ -0,0 +1,4 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_WeakMap.res. +// Type alias migration for Js.WeakMap.t +external wm: WeakMap.t<{..}, int> = "wm" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakSet.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakSet.res new file mode 100644 index 0000000000..af9ad046c2 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_WeakSet.res @@ -0,0 +1,4 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_WeakSet.res. +// Type alias migration for Js.WeakSet.t +external ws: WeakSet.t<{..}> = "ws" From c36e4fa7d43affa8a928b3adcb9aa3da8d290821 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 18:03:13 +0200 Subject: [PATCH 27/41] support @apply.transforms for applying transforms, and add migrations for Js_promise and Js_promise2 --- packages/@rescript/runtime/Js_promise.res | 109 +++++++++++++++--- packages/@rescript/runtime/Js_promise2.res | 87 ++++++++++++-- .../StdlibMigration_Promise.res.expected | 40 +++++++ .../StdlibMigration_Promise2.res.expected | 41 +++++++ .../src/migrate/StdlibMigration_Promise.res | 39 +++++++ .../src/migrate/StdlibMigration_Promise2.res | 44 +++++++ .../Migrated_StdlibMigration_Promise.res | 41 +++++++ .../Migrated_StdlibMigration_Promise2.res | 42 +++++++ tools/src/migrate.ml | 91 ++++++++++++++- tools/src/transforms.ml | 59 ++++++++++ 10 files changed, 564 insertions(+), 29 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Promise.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Promise2.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Promise.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Promise2.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise2.res create mode 100644 tools/src/transforms.ml diff --git a/packages/@rescript/runtime/Js_promise.res b/packages/@rescript/runtime/Js_promise.res index 5960b5efdf..4e63c2a2fe 100644 --- a/packages/@rescript/runtime/Js_promise.res +++ b/packages/@rescript/runtime/Js_promise.res @@ -32,7 +32,16 @@ https://rescript-lang.org/docs/manual/latest/promise#promise-legacy @@warning("-103") +@deprecated({ + reason: "Use `promise` directly instead.", + migrate: %replace.type(: promise), +}) type t<+'a> = promise<'a> + +@deprecated({ + reason: "Use `exn` directly instead.", + migrate: %replace.type(: exn), +}) type error = Js_promise2.error /* @@ -43,21 +52,62 @@ type error ``` */ +@deprecated({ + reason: "Use `Promise.make` instead.", + migrate: Promise.make( + @apply.transforms(["labelledToUnlabelledArgumentsInFnDefinition"]) + %insert.unlabelledArgument(0), + ), +}) @new external make: ((~resolve: 'a => unit, ~reject: exn => unit) => unit) => promise<'a> = "Promise" /* `make (fun resolve reject -> .. )` */ -@val @scope("Promise") external resolve: 'a => promise<'a> = "resolve" -@val @scope("Promise") external reject: exn => promise<'a> = "reject" - -@val @scope("Promise") external all: array> => promise> = "all" - -@val @scope("Promise") external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" - -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.resolve` instead.", + migrate: Promise.resolve(), +}) +@val +@scope("Promise") +external resolve: 'a => promise<'a> = "resolve" +@deprecated({ + reason: "Use `Promise.reject` instead.", + migrate: Promise.reject(), +}) +@val +@scope("Promise") +external reject: exn => promise<'a> = "reject" + +@deprecated({ + reason: "Use `Promise.all` instead.", + migrate: Promise.all(), +}) +@val +@scope("Promise") +external all: array> => promise> = "all" + +@deprecated({ + reason: "Use `Promise.all2` instead.", + migrate: Promise.all2(), +}) +@val +@scope("Promise") +external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" + +@deprecated({ + reason: "Use `Promise.all3` instead.", + migrate: Promise.all3(), +}) +@val +@scope("Promise") external all3: ((promise<'a0>, promise<'a1>, promise<'a2>)) => promise<('a0, 'a1, 'a2)> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all4` instead.", + migrate: Promise.all4(), +}) +@val +@scope("Promise") external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => promise<( 'a0, 'a1, @@ -65,7 +115,12 @@ external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => pro 'a3, )> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all5` instead.", + migrate: Promise.all5(), +}) +@val +@scope("Promise") external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>)) => promise<( 'a0, 'a1, @@ -74,18 +129,44 @@ external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise 'a4, )> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all6` instead.", + migrate: Promise.all6(), +}) +@val +@scope("Promise") external all6: ( (promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>, promise<'a5>) ) => promise<('a0, 'a1, 'a2, 'a3, 'a4, 'a5)> = "all" -@val @scope("Promise") external race: array> => promise<'a> = "race" - -@send external then_: (promise<'a>, 'a => promise<'b>) => promise<'b> = "then" +@deprecated({ + reason: "Use `Promise.race` instead.", + migrate: Promise.race(), +}) +@val +@scope("Promise") +external race: array> => promise<'a> = "race" + +@deprecated({ + reason: "Use `Promise.then` instead.", + migrate: Promise.then(), +}) +@send +external then_: (promise<'a>, 'a => promise<'b>) => promise<'b> = "then" +@deprecated({ + reason: "Use `Promise.then` instead.", + migrate: Promise.then(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), + migrateInPipeChain: Promise.then(%insert.unlabelledArgument(0)), +}) let then_ = (arg1, obj) => then_(obj, arg1) @send external catch: (promise<'a>, error => promise<'a>) => promise<'a> = "catch" +@deprecated({ + reason: "Use `Promise.catch` instead.", + migrate: Promise.catch(%insert.unlabelledArgument(1), %insert.unlabelledArgument(0)), + migrateInPipeChain: Promise.catch(%insert.unlabelledArgument(0)), +}) let catch = (arg1, obj) => catch(obj, arg1) /* ` p|> catch handler` Note in JS the returned promise type is actually runtime dependent, diff --git a/packages/@rescript/runtime/Js_promise2.res b/packages/@rescript/runtime/Js_promise2.res index 8bdaae73fe..9f0b3b2aeb 100644 --- a/packages/@rescript/runtime/Js_promise2.res +++ b/packages/@rescript/runtime/Js_promise2.res @@ -1,7 +1,15 @@ +@deprecated({ + reason: "Use `promise` directly instead.", + migrate: %replace.type(: promise), +}) type t<+'a> = promise<'a> type error /** Type-safe t-first then */ +@deprecated({ + reason: "Use `Promise.then` instead.", + migrate: Promise.then(), +}) let then: (promise<'a>, 'a => promise<'b>) => promise<'b> = %raw(` function(p, cont) { return Promise.resolve(p).then(cont) @@ -9,26 +17,71 @@ let then: (promise<'a>, 'a => promise<'b>) => promise<'b> = %raw(` `) /** Type-safe t-first catch */ +@deprecated({ + reason: "Use `Promise.catch` instead.", + migrate: Promise.catch(), +}) let catch: (promise<'a>, error => promise<'a>) => promise<'a> = %raw(` function(p, cont) { return Promise.resolve(p).catch(cont) } `) +@deprecated({ + reason: "Use `Promise.make` instead.", + migrate: Promise.make( + @apply.transforms(["labelledToUnlabelledArgumentsInFnDefinition"]) + %insert.unlabelledArgument(0), + ), +}) @new external make: ((~resolve: 'a => unit, ~reject: exn => unit) => unit) => promise<'a> = "Promise" -@val @scope("Promise") external resolve: 'a => promise<'a> = "resolve" -@val @scope("Promise") external reject: exn => promise<'a> = "reject" +@deprecated({ + reason: "Use `Promise.resolve` instead.", + migrate: Promise.resolve(), +}) +@val +@scope("Promise") +external resolve: 'a => promise<'a> = "resolve" +@deprecated({ + reason: "Use `Promise.reject` instead.", + migrate: Promise.reject(), +}) +@val +@scope("Promise") +external reject: exn => promise<'a> = "reject" -@val @scope("Promise") external all: array> => promise> = "all" +@deprecated({ + reason: "Use `Promise.all` instead.", + migrate: Promise.all(), +}) +@val +@scope("Promise") +external all: array> => promise> = "all" -@val @scope("Promise") external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" +@deprecated({ + reason: "Use `Promise.all2` instead.", + migrate: Promise.all2(), +}) +@val +@scope("Promise") +external all2: ((promise<'a0>, promise<'a1>)) => promise<('a0, 'a1)> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all3` instead.", + migrate: Promise.all3(), +}) +@val +@scope("Promise") external all3: ((promise<'a0>, promise<'a1>, promise<'a2>)) => promise<('a0, 'a1, 'a2)> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all4` instead.", + migrate: Promise.all4(), +}) +@val +@scope("Promise") external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => promise<( 'a0, 'a1, @@ -36,7 +89,12 @@ external all4: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>)) => pro 'a3, )> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all5` instead.", + migrate: Promise.all5(), +}) +@val +@scope("Promise") external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>)) => promise<( 'a0, 'a1, @@ -45,12 +103,23 @@ external all5: ((promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise 'a4, )> = "all" -@val @scope("Promise") +@deprecated({ + reason: "Use `Promise.all6` instead.", + migrate: Promise.all6(), +}) +@val +@scope("Promise") external all6: ( (promise<'a0>, promise<'a1>, promise<'a2>, promise<'a3>, promise<'a4>, promise<'a5>) ) => promise<('a0, 'a1, 'a2, 'a3, 'a4, 'a5)> = "all" -@val @scope("Promise") external race: array> => promise<'a> = "race" +@deprecated({ + reason: "Use `Promise.race` instead.", + migrate: Promise.race(), +}) +@val +@scope("Promise") +external race: array> => promise<'a> = "race" external unsafe_async: 'a => promise<'a> = "%identity" external unsafe_await: promise<'a> => 'a = "%await" diff --git a/tests/tools_tests/src/expected/StdlibMigration_Promise.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Promise.res.expected new file mode 100644 index 0000000000..d87b962e98 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Promise.res.expected @@ -0,0 +1,40 @@ +let p1 = Promise.resolve(1) +let p2 = Promise.reject(Failure("err")) + +let all1 = Promise.all([Promise.resolve(1), Promise.resolve(2)]) +let all2 = Promise.all2((Promise.resolve(1), Promise.resolve(2))) +let all3 = Promise.all3((Promise.resolve(1), Promise.resolve(2), Promise.resolve(3))) +let all4 = Promise.all4(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), +)) +let all5 = Promise.all5(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), +)) +let all6 = Promise.all6(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), + Promise.resolve(6), +)) + +let race1 = Promise.race([Promise.resolve(10), Promise.resolve(20)]) + +let thenPipe = Promise.resolve(1)->Js.Promise.then_(x => Promise.resolve(x + 1), _) +let thenDirect = Js.Promise.then_(x => Promise.resolve(x + 1), Promise.resolve(1)) + +// Type alias migration +external p: promise = "p" + +// let catchPipe = Js.Promise.resolve(1)->Js.Promise.catch(_e => Js.Promise.resolve(0), _) +// let catchDirect = Js.Promise.catch(_e => Js.Promise.resolve(0), Js.Promise.resolve(1)) +let make1 = Promise.make((resolve, reject) => resolve(1)) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Promise2.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Promise2.res.expected new file mode 100644 index 0000000000..349b6d5096 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Promise2.res.expected @@ -0,0 +1,41 @@ +let p1 = Promise.resolve(1) +let p2 = Promise.reject(Failure("err")) + +let all1 = Promise.all([Promise.resolve(1), Promise.resolve(2)]) +let all2 = Promise.all2((Promise.resolve(1), Promise.resolve(2))) +let all3 = Promise.all3((Promise.resolve(1), Promise.resolve(2), Promise.resolve(3))) + +let all4 = Promise.all4(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), +)) +let all5 = Promise.all5(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), +)) +let all6 = Promise.all6(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), + Promise.resolve(6), +)) + +let race1 = Promise.race([Promise.resolve(10), Promise.resolve(20)]) + +let thenPipe = Promise.resolve(1)->Js.Promise2.then(x => Promise.resolve(x + 1)) +let thenDirect = Js.Promise2.then(Promise.resolve(1), x => Promise.resolve(x + 1)) + +// Type alias migration +external p2: promise = "p2" + +// let catchPipe = Js.Promise2.resolve(1)->Js.Promise2.catch(_e => Js.Promise2.resolve(0)) +// let catchDirect = Js.Promise2.catch(Js.Promise2.resolve(1), _e => Js.Promise2.resolve(0)) +let make1 = Promise.make((resolve, reject) => resolve(1)) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Promise.res b/tests/tools_tests/src/migrate/StdlibMigration_Promise.res new file mode 100644 index 0000000000..1d04a4a38d --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Promise.res @@ -0,0 +1,39 @@ +let p1 = Js.Promise.resolve(1) +let p2 = Js.Promise.reject(Failure("err")) + +let all1 = Js.Promise.all([Js.Promise.resolve(1), Js.Promise.resolve(2)]) +let all2 = Js.Promise.all2((Js.Promise.resolve(1), Js.Promise.resolve(2))) +let all3 = Js.Promise.all3((Js.Promise.resolve(1), Js.Promise.resolve(2), Js.Promise.resolve(3))) +let all4 = Js.Promise.all4(( + Js.Promise.resolve(1), + Js.Promise.resolve(2), + Js.Promise.resolve(3), + Js.Promise.resolve(4), +)) +let all5 = Js.Promise.all5(( + Js.Promise.resolve(1), + Js.Promise.resolve(2), + Js.Promise.resolve(3), + Js.Promise.resolve(4), + Js.Promise.resolve(5), +)) +let all6 = Js.Promise.all6(( + Js.Promise.resolve(1), + Js.Promise.resolve(2), + Js.Promise.resolve(3), + Js.Promise.resolve(4), + Js.Promise.resolve(5), + Js.Promise.resolve(6), +)) + +let race1 = Js.Promise.race([Js.Promise.resolve(10), Js.Promise.resolve(20)]) + +let thenPipe = Js.Promise.resolve(1)->Js.Promise.then_(x => Js.Promise.resolve(x + 1), _) +let thenDirect = Js.Promise.then_(x => Js.Promise.resolve(x + 1), Js.Promise.resolve(1)) + +// Type alias migration +external p: Js.Promise.t = "p" + +// let catchPipe = Js.Promise.resolve(1)->Js.Promise.catch(_e => Js.Promise.resolve(0), _) +// let catchDirect = Js.Promise.catch(_e => Js.Promise.resolve(0), Js.Promise.resolve(1)) +let make1 = Js.Promise.make((~resolve, ~reject) => resolve(1)) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Promise2.res b/tests/tools_tests/src/migrate/StdlibMigration_Promise2.res new file mode 100644 index 0000000000..5ab3884bee --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Promise2.res @@ -0,0 +1,44 @@ +let p1 = Js.Promise2.resolve(1) +let p2 = Js.Promise2.reject(Failure("err")) + +let all1 = Js.Promise2.all([Js.Promise2.resolve(1), Js.Promise2.resolve(2)]) +let all2 = Js.Promise2.all2((Js.Promise2.resolve(1), Js.Promise2.resolve(2))) +let all3 = Js.Promise2.all3(( + Js.Promise2.resolve(1), + Js.Promise2.resolve(2), + Js.Promise2.resolve(3), +)) + +let all4 = Js.Promise2.all4(( + Js.Promise2.resolve(1), + Js.Promise2.resolve(2), + Js.Promise2.resolve(3), + Js.Promise2.resolve(4), +)) +let all5 = Js.Promise2.all5(( + Js.Promise2.resolve(1), + Js.Promise2.resolve(2), + Js.Promise2.resolve(3), + Js.Promise2.resolve(4), + Js.Promise2.resolve(5), +)) +let all6 = Js.Promise2.all6(( + Js.Promise2.resolve(1), + Js.Promise2.resolve(2), + Js.Promise2.resolve(3), + Js.Promise2.resolve(4), + Js.Promise2.resolve(5), + Js.Promise2.resolve(6), +)) + +let race1 = Js.Promise2.race([Js.Promise2.resolve(10), Js.Promise2.resolve(20)]) + +let thenPipe = Js.Promise2.resolve(1)->Js.Promise2.then(x => Js.Promise2.resolve(x + 1)) +let thenDirect = Js.Promise2.then(Js.Promise2.resolve(1), x => Js.Promise2.resolve(x + 1)) + +// Type alias migration +external p2: Js.Promise2.t = "p2" + +// let catchPipe = Js.Promise2.resolve(1)->Js.Promise2.catch(_e => Js.Promise2.resolve(0)) +// let catchDirect = Js.Promise2.catch(Js.Promise2.resolve(1), _e => Js.Promise2.resolve(0)) +let make1 = Js.Promise2.make((~resolve, ~reject) => resolve(1)) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise.res new file mode 100644 index 0000000000..55997fcaea --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise.res @@ -0,0 +1,41 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Promise.res. +let p1 = Promise.resolve(1) +let p2 = Promise.reject(Failure("err")) + +let all1 = Promise.all([Promise.resolve(1), Promise.resolve(2)]) +let all2 = Promise.all2((Promise.resolve(1), Promise.resolve(2))) +let all3 = Promise.all3((Promise.resolve(1), Promise.resolve(2), Promise.resolve(3))) +let all4 = Promise.all4(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), +)) +let all5 = Promise.all5(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), +)) +let all6 = Promise.all6(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), + Promise.resolve(6), +)) + +let race1 = Promise.race([Promise.resolve(10), Promise.resolve(20)]) + +let thenPipe = Promise.resolve(1)->Js.Promise.then_(x => Promise.resolve(x + 1), _) +let thenDirect = Js.Promise.then_(x => Promise.resolve(x + 1), Promise.resolve(1)) + +// Type alias migration +external p: promise = "p" + +// let catchPipe = Js.Promise.resolve(1)->Js.Promise.catch(_e => Js.Promise.resolve(0), _) +// let catchDirect = Js.Promise.catch(_e => Js.Promise.resolve(0), Js.Promise.resolve(1)) +let make1 = Promise.make((resolve, reject) => resolve(1)) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise2.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise2.res new file mode 100644 index 0000000000..3b711592f2 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Promise2.res @@ -0,0 +1,42 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Promise2.res. +let p1 = Promise.resolve(1) +let p2 = Promise.reject(Failure("err")) + +let all1 = Promise.all([Promise.resolve(1), Promise.resolve(2)]) +let all2 = Promise.all2((Promise.resolve(1), Promise.resolve(2))) +let all3 = Promise.all3((Promise.resolve(1), Promise.resolve(2), Promise.resolve(3))) + +let all4 = Promise.all4(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), +)) +let all5 = Promise.all5(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), +)) +let all6 = Promise.all6(( + Promise.resolve(1), + Promise.resolve(2), + Promise.resolve(3), + Promise.resolve(4), + Promise.resolve(5), + Promise.resolve(6), +)) + +let race1 = Promise.race([Promise.resolve(10), Promise.resolve(20)]) + +let thenPipe = Promise.resolve(1)->Js.Promise2.then(x => Promise.resolve(x + 1)) +let thenDirect = Js.Promise2.then(Promise.resolve(1), x => Promise.resolve(x + 1)) + +// Type alias migration +external p2: promise = "p2" + +// let catchPipe = Js.Promise2.resolve(1)->Js.Promise2.catch(_e => Js.Promise2.resolve(0)) +// let catchDirect = Js.Promise2.catch(Js.Promise2.resolve(1), _e => Js.Promise2.resolve(0)) +let make1 = Promise.make((resolve, reject) => resolve(1)) diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index 577f385c8b..d21dfd04e8 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -64,6 +64,66 @@ module ExprUtils = struct end module MapperUtils = struct + module ApplyTransforms = struct + let attr_name = "apply.transforms" + + let split_attrs (attrs : Parsetree.attributes) = + List.partition (fun ({Location.txt}, _) -> txt = attr_name) attrs + + let names_of_payload (payload : Parsetree.payload) : string list = + match payload with + | Parsetree.PStr + [ + {pstr_desc = Parsetree.Pstr_eval ({pexp_desc = Pexp_array elems}, _)}; + ] -> + elems + |> List.filter_map (fun (e : Parsetree.expression) -> + match e.pexp_desc with + | Pexp_constant (Pconst_string (s, _)) -> Some s + | _ -> None) + | _ -> [] + + let apply_names (names : string list) (e : Parsetree.expression) : + Parsetree.expression = + List.fold_left + (fun acc name -> + match Transforms.get name with + | Some f -> f acc + | None -> acc) + e names + + (* Apply transforms found on a separate attribute set to a replacement + expression, preserving non-transform attributes by attaching them to the + replacement. *) + let apply_to_replacement ~(attrs : Parsetree.attributes) + (e : Parsetree.expression) : Parsetree.expression = + let transform_attrs, other_attrs = split_attrs attrs in + if Ext_list.is_empty transform_attrs then + if Ext_list.is_empty attrs then e + else {e with pexp_attributes = attrs @ e.pexp_attributes} + else + let names = + transform_attrs + |> List.concat_map (fun (_id, payload) -> names_of_payload payload) + in + let e' = apply_names names e in + if Ext_list.is_empty other_attrs then e' + else {e' with pexp_attributes = other_attrs @ e'.pexp_attributes} + + (* Apply transforms attached to an expression itself and drop the + transform attributes afterwards. *) + let apply_on_self (e : Parsetree.expression) : Parsetree.expression = + let transform_attrs, other_attrs = split_attrs e.pexp_attributes in + if Ext_list.is_empty transform_attrs then e + else + let names = + transform_attrs + |> List.concat_map (fun (_id, payload) -> names_of_payload payload) + in + let e' = {e with pexp_attributes = other_attrs} in + apply_names names e' + end + (* Collect placeholder usages anywhere inside an expression. *) let collect_placeholders (expr : Parsetree.expression) = let labelled = ref StringSet.empty in @@ -87,7 +147,7 @@ module MapperUtils = struct (!labelled, !unlabelled) (* Replace placeholders anywhere inside an expression using the given - source arguments. *) + source arguments. Use the generic replacement transform applier. *) let replace_placeholders_in_expr (expr : Parsetree.expression) (source_args : (Asttypes.arg_label * Parsetree.expression) list) = let labelled = Hashtbl.create 8 in @@ -113,11 +173,15 @@ module MapperUtils = struct match InsertExt.placeholder_of_expr exp with | Some (InsertExt.Labelled name) -> ( match find (`Labelled name) with - | Some arg -> arg + | Some arg -> + ApplyTransforms.apply_to_replacement ~attrs:exp.pexp_attributes + arg | None -> exp) | Some (InsertExt.Unlabelled i) -> ( match find (`Unlabelled i) with - | Some arg -> arg + | Some arg -> + ApplyTransforms.apply_to_replacement ~attrs:exp.pexp_attributes + arg | None -> exp) | None -> Ast_mapper.default_mapper.expr mapper exp); } @@ -324,11 +388,15 @@ let replace_from_args_ctx_in_expr expr args_ctx = match InsertExt.placeholder_of_expr exp with | Some (InsertExt.Labelled name) -> ( match find_in_args_ctx args_ctx (`Labelled name) with - | Some arg -> arg + | Some arg -> + MapperUtils.ApplyTransforms.apply_to_replacement + ~attrs:exp.pexp_attributes arg | None -> exp) | Some (InsertExt.Unlabelled i) -> ( match find_in_args_ctx args_ctx (`Unlabelled i) with - | Some arg -> arg + | Some arg -> + MapperUtils.ApplyTransforms.apply_to_replacement + ~attrs:exp.pexp_attributes arg | None -> exp) | None -> Ast_mapper.default_mapper.expr mapper exp); } @@ -697,9 +765,20 @@ let migrate ~entryPointFile ~outputMode = | Some {cmt_extra_info = {deprecated_used}} -> let mapper = makeMapper deprecated_used in let astMapped = mapper.structure mapper parsetree in + (* Second pass: apply any post-migration transforms signaled via @apply.transforms *) + let apply_transforms = + let expr mapper (e : Parsetree.expression) = + let e = Ast_mapper.default_mapper.expr mapper e in + MapperUtils.ApplyTransforms.apply_on_self e + in + {Ast_mapper.default_mapper with expr} + in + let astTransformed = + apply_transforms.structure apply_transforms astMapped + in Ok ( Res_printer.print_implementation - ~width:Res_printer.default_print_width astMapped ~comments, + ~width:Res_printer.default_print_width astTransformed ~comments, source ) else if Filename.check_suffix path ".resi" then let parser = diff --git a/tools/src/transforms.ml b/tools/src/transforms.ml new file mode 100644 index 0000000000..5fd196323d --- /dev/null +++ b/tools/src/transforms.ml @@ -0,0 +1,59 @@ +let labelledToUnlabelledArgumentsInFnDefinition (e : Parsetree.expression) : + Parsetree.expression = + (* `(~a, ~b, ~c) => ...` to `(a, b, c) => ...` *) + let rec dropLabels (e : Parsetree.expression) : Parsetree.expression = + match e.pexp_desc with + | Pexp_fun + {arg_label = Labelled _ | Optional _; default; lhs; rhs; arity; async} + -> + { + e with + pexp_desc = + Pexp_fun + { + arg_label = Nolabel; + default; + lhs; + rhs = dropLabels rhs; + arity; + async; + }; + } + | Pexp_fun {arg_label; default; lhs; rhs; arity; async} -> + { + e with + pexp_desc = + Pexp_fun {arg_label; default; lhs; rhs = dropLabels rhs; arity; async}; + } + | _ -> e + in + dropLabels e + +let makerFnToRecord (e : Parsetree.expression) : Parsetree.expression = + (* `ReactDOM.Style.make(~width="12px", ~height="12px", ())` to `{height: "12px", width: "12px"}` *) + e + +let dictFromArrayToDictLiteralSyntax (e : Parsetree.expression) : + Parsetree.expression = + (* `Dict.fromArray([("a", 1), ("b", 2)])` to `dict{"a": 1, "b": 2}` *) + (* Elgible if all keys are strings *) + e + +let convertedLiteralToPureLiteral (e : Parsetree.expression) : + Parsetree.expression = + (* `Float.fromInt(1)` to `1.`, *) + e + +(* Registry of available transforms *) +type transform = Parsetree.expression -> Parsetree.expression + +let registry : (string * transform) list = + [ + ( "labelledToUnlabelledArgumentsInFnDefinition", + labelledToUnlabelledArgumentsInFnDefinition ); + ("makerFnToRecord", makerFnToRecord); + ("dictFromArrayToDictLiteralSyntax", dictFromArrayToDictLiteralSyntax); + ("convertedLiteralToPureLiteral", convertedLiteralToPureLiteral); + ] + +let get (id : string) : transform option = List.assoc_opt id registry From 4862be952001930ae03fb084a53e3d7c79d24ecb Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 19:39:24 +0200 Subject: [PATCH 28/41] refactor a bit and add transform for dropping unit args in apply --- packages/@rescript/runtime/Js_date.res | 78 ++++++--- packages/@rescript/runtime/Js_math.res | 3 +- tools/src/migrate.ml | 233 ++++++++++++------------- tools/src/transforms.ml | 24 +++ 4 files changed, 191 insertions(+), 147 deletions(-) diff --git a/packages/@rescript/runtime/Js_date.res b/packages/@rescript/runtime/Js_date.res index 85d79b25ad..50a7c23f57 100644 --- a/packages/@rescript/runtime/Js_date.res +++ b/packages/@rescript/runtime/Js_date.res @@ -127,7 +127,8 @@ let november1 = Js.Date.makeWithYM(~year=2020.0, ~month=10.0, ()) */ @deprecated({ reason: "Use `Date.makeWithYM` instead.", - migrate: Date.makeWithYM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.makeWithYM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ), @@ -144,7 +145,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.makeWithYMD` instead.", - migrate: Date.makeWithYMD( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.makeWithYMD( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -162,7 +164,8 @@ on MDN. Fractional parts of the arguments are ignored. */ @deprecated({ reason: "Use `Date.makeWithYMDH` instead.", - migrate: Date.makeWithYMDH( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.makeWithYMDH( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -182,7 +185,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.makeWithYMDHM` instead.", - migrate: Date.makeWithYMDHM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.makeWithYMDHM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -223,7 +227,8 @@ Js.Date.makeWithYMDHMS( */ @deprecated({ reason: "Use `Date.makeWithYMDHMS` instead.", - migrate: Date.makeWithYMDHMS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.makeWithYMDHMS( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -258,7 +263,8 @@ let november1 = Js.Date.utcWithYM(~year=2020.0, ~month=10.0, ()) */ @deprecated({ reason: "Use `Date.UTC.makeWithYM` instead.", - migrate: Date.UTC.makeWithYM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.UTC.makeWithYM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ), @@ -275,7 +281,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.UTC.makeWithYMD` instead.", - migrate: Date.UTC.makeWithYMD( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.UTC.makeWithYMD( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -294,7 +301,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.UTC.makeWithYMDH` instead.", - migrate: Date.UTC.makeWithYMDH( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.UTC.makeWithYMDH( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -314,7 +322,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.UTC.makeWithYMDHM` instead.", - migrate: Date.UTC.makeWithYMDHM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.UTC.makeWithYMDHM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -343,7 +352,8 @@ on MDN. */ @deprecated({ reason: "Use `Date.UTC.makeWithYMDHMS` instead.", - migrate: Date.UTC.makeWithYMDHMS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.UTC.makeWithYMDHMS( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -797,7 +807,8 @@ future == Js.Date.getTime(date1) */ @deprecated({ reason: "Use `Date.setFullYearM` instead.", - migrate: Date.setFullYearM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setFullYearM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ), @@ -825,7 +836,8 @@ future == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setFullYearMD` instead.", - migrate: Date.setFullYearMD( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setFullYearMD( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -876,7 +888,8 @@ futureTime == Js.Date.getTime(date1) */ @deprecated({ reason: "Use `Date.setHoursM` instead.", - migrate: Date.setHoursM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setHoursM( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ), @@ -904,7 +917,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setHoursMS` instead.", - migrate: Date.setHoursMS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setHoursMS( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), @@ -940,7 +954,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setHoursMSMs` instead.", - migrate: Date.setHoursMSMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setHoursMSMs( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), @@ -1023,7 +1038,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setMinutesS` instead.", - migrate: Date.setMinutesS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setMinutesS( ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ), @@ -1050,7 +1066,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setMinutesSMs` instead.", - migrate: Date.setMinutesSMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setMinutesSMs( ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), @@ -1145,7 +1162,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setSecondsMs` instead.", - migrate: Date.setSecondsMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setSecondsMs( ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), ), @@ -1237,7 +1255,8 @@ future == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCFullYearM` instead.", - migrate: Date.setUTCFullYearM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCFullYearM( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ), @@ -1264,7 +1283,8 @@ future == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCFullYearMD` instead.", - migrate: Date.setUTCFullYearMD( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCFullYearMD( ~year=Float.toInt(%insert.labelledArgument("year")), ~month=Float.toInt(%insert.labelledArgument("month")), ~day=Float.toInt(%insert.labelledArgument("date")), @@ -1315,7 +1335,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCHoursM` instead.", - migrate: Date.setUTCHoursM( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCHoursM( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ), @@ -1343,7 +1364,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCHoursMS` instead.", - migrate: Date.setUTCHoursMS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCHoursMS( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), @@ -1379,7 +1401,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCHoursMSMs` instead.", - migrate: Date.setUTCHoursMSMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCHoursMSMs( ~hours=Float.toInt(%insert.labelledArgument("hours")), ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), @@ -1460,7 +1483,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCMinutesS` instead.", - migrate: Date.setUTCMinutesS( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCMinutesS( ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ), @@ -1493,7 +1517,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCMinutesSMs` instead.", - migrate: Date.setUTCMinutesSMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCMinutesSMs( ~minutes=Float.toInt(%insert.labelledArgument("minutes")), ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), @@ -1592,7 +1617,8 @@ futureTime == Js.Date.getTime(date1) @send @deprecated({ reason: "Use `Date.setUTCSecondsMs` instead.", - migrate: Date.setUTCSecondsMs( + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Date.setUTCSecondsMs( ~seconds=Float.toInt(%insert.labelledArgument("seconds")), ~milliseconds=Float.toInt(%insert.labelledArgument("milliseconds")), ), diff --git a/packages/@rescript/runtime/Js_math.res b/packages/@rescript/runtime/Js_math.res index 29dda7b623..8b964d07f8 100644 --- a/packages/@rescript/runtime/Js_math.res +++ b/packages/@rescript/runtime/Js_math.res @@ -260,7 +260,8 @@ Js.Math.atan2(~x=-0.0, ~y=-5.0, ()) == -.Js.Math._PI /. 2.0 */ @deprecated({ reason: "Use `Math.atan2` instead.", - migrate: Math.atan2(~y=%insert.labelledArgument("y"), ~x=%insert.labelledArgument("x")), + migrate: @apply.transforms(["dropUnitArgumentsInApply"]) + Math.atan2(~y=%insert.labelledArgument("y"), ~x=%insert.labelledArgument("x")), }) @val @scope("Math") diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index d21dfd04e8..229a8a79fb 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -6,6 +6,11 @@ module IntSet = Set.Make (Int) (* Public API: migrate ~entryPointFile ~outputMode *) +let is_unit_expr (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_construct ({txt = Lident "()"}, None) -> true + | _ -> false + module InsertExt = struct type placeholder = Labelled of string | Unlabelled of int @@ -92,23 +97,10 @@ module MapperUtils = struct | None -> acc) e names - (* Apply transforms found on a separate attribute set to a replacement - expression, preserving non-transform attributes by attaching them to the - replacement. *) - let apply_to_replacement ~(attrs : Parsetree.attributes) + let attach_to_replacement ~(attrs : Parsetree.attributes) (e : Parsetree.expression) : Parsetree.expression = - let transform_attrs, other_attrs = split_attrs attrs in - if Ext_list.is_empty transform_attrs then - if Ext_list.is_empty attrs then e - else {e with pexp_attributes = attrs @ e.pexp_attributes} - else - let names = - transform_attrs - |> List.concat_map (fun (_id, payload) -> names_of_payload payload) - in - let e' = apply_names names e in - if Ext_list.is_empty other_attrs then e' - else {e' with pexp_attributes = other_attrs @ e'.pexp_attributes} + if Ext_list.is_empty attrs then e + else {e with pexp_attributes = attrs @ e.pexp_attributes} (* Apply transforms attached to an expression itself and drop the transform attributes afterwards. *) @@ -174,13 +166,13 @@ module MapperUtils = struct | Some (InsertExt.Labelled name) -> ( match find (`Labelled name) with | Some arg -> - ApplyTransforms.apply_to_replacement ~attrs:exp.pexp_attributes + ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg | None -> exp) | Some (InsertExt.Unlabelled i) -> ( match find (`Unlabelled i) with | Some arg -> - ApplyTransforms.apply_to_replacement ~attrs:exp.pexp_attributes + ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg | None -> exp) | None -> Ast_mapper.default_mapper.expr mapper exp); @@ -213,12 +205,6 @@ module MapperUtils = struct - unlabelled_positions_to_insert: 0-based indices of unlabelled source args to drop *) let get_template_args_to_insert mapper template_args source_args = - let is_unit_expr (e : Parsetree.expression) = - match e.pexp_desc with - | Pexp_construct ({txt = Lident "()"}, None) -> true - | _ -> false - in - (* For each template argument, decide whether it is a placeholder that should be substituted from the source call, or a concrete argument which should be preserved (after mapping through the mapper). @@ -233,12 +219,9 @@ module MapperUtils = struct original call's arguments. *) let labelled_used_here, unlabelled_used_here = collect_placeholders arg in let arg_replaced = replace_placeholders_in_expr arg source_args in - if is_unit_expr arg_replaced then - (rev_args, used_labelled, used_unlabelled) - else - ( (label, mapper.Ast_mapper.expr mapper arg_replaced) :: rev_args, - StringSet.union used_labelled labelled_used_here, - IntSet.union used_unlabelled unlabelled_used_here ) + ( (label, mapper.Ast_mapper.expr mapper arg_replaced) :: rev_args, + StringSet.union used_labelled labelled_used_here, + IntSet.union used_unlabelled unlabelled_used_here ) in let rev_args, labelled_set, unlabelled_set = List.fold_left accumulate_template_arg @@ -288,20 +271,6 @@ module MapperUtils = struct let dropped = drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped in - (* Also drop any unit arguments that remain from the source call. *) - let is_unit_expr (e : Parsetree.expression) = - match e.pexp_desc with - | Pexp_construct ({txt = Lident "()"}, None) -> true - | _ -> false - in - let dropped = - List.filter - (fun (label, arg) -> - match label with - | Asttypes.Nolabel -> not (is_unit_expr arg) - | _ -> true) - dropped - in let renamed = rename_labels dropped ~labelled_args_map in renamed @ template_args_to_insert @@ -322,20 +291,6 @@ module MapperUtils = struct ~unlabelled_positions_to_insert:adjusted_unlabelled_to_drop ~will_be_mapped in - (* Drop any unit arguments that remain from the source call. *) - let is_unit_expr (e : Parsetree.expression) = - match e.pexp_desc with - | Pexp_construct ({txt = Lident "()"}, None) -> true - | _ -> false - in - let dropped = - List.filter - (fun (label, arg) -> - match label with - | Asttypes.Nolabel -> not (is_unit_expr arg) - | _ -> true) - dropped - in let renamed = rename_labels dropped ~labelled_args_map in renamed @ template_args_to_insert end @@ -389,13 +344,13 @@ let replace_from_args_ctx_in_expr expr args_ctx = | Some (InsertExt.Labelled name) -> ( match find_in_args_ctx args_ctx (`Labelled name) with | Some arg -> - MapperUtils.ApplyTransforms.apply_to_replacement + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg | None -> exp) | Some (InsertExt.Unlabelled i) -> ( match find_in_args_ctx args_ctx (`Unlabelled i) with | Some arg -> - MapperUtils.ApplyTransforms.apply_to_replacement + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg | None -> exp) | None -> Ast_mapper.default_mapper.expr mapper exp); @@ -432,7 +387,15 @@ module Template = struct let of_expr = function | {Parsetree.pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} -> - Some (Apply {funct; args; partial; transformed_jsx}) + (* Normalize templates like `f()` to just `f` by dropping a single unit + argument. This treats `String.concat()` as the function reference + `String.concat`, not a call with a unit argument. *) + let args' = + match args with + | [(_lbl, e)] when is_unit_expr e -> [] + | _ -> args + in + Some (Apply {funct; args = args'; partial; transformed_jsx}) | {Parsetree.pexp_desc = Pexp_match (expr, cases)} -> Some (Match {expr; cases}) | _ -> None @@ -441,33 +404,44 @@ module Template = struct ~transformed_jsx = {exp with pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} - (* Apply a non-piped migration template to a direct call. *) - let apply_direct ~mapper ~template ~call_args (exp : Parsetree.expression) = + let apply_direct ~mapper ~template ~template_attrs ~call_args + (exp : Parsetree.expression) = match template with | Match {expr; cases} -> - { - exp with - pexp_desc = Pexp_match (replace_from_args_in_expr expr call_args, cases); - } + let res = + { + exp with + pexp_desc = + Pexp_match (replace_from_args_in_expr expr call_args, cases); + } + in + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> let migrated_args = MapperUtils.apply_migration_template mapper template_args call_args in - mk_apply exp ~funct:template_funct ~args:migrated_args ~partial - ~transformed_jsx + let res = + mk_apply exp ~funct:template_funct ~args:migrated_args ~partial + ~transformed_jsx + in + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + res - (* Apply a piped migration template. The `lhs` is the value being piped and - `pipe_args` are the arguments in the right-hand call (if any). *) - let apply_piped ~mapper ~template ~lhs ~pipe_args ~funct + let apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct (exp : Parsetree.expression) = match template with | Match {expr; cases} -> - { - exp with - pexp_desc = Pexp_match (replace_from_args_in_expr expr [lhs], cases); - } + let res = + { + exp with + pexp_desc = Pexp_match (replace_from_args_in_expr expr [lhs], cases); + } + in + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -476,20 +450,20 @@ module Template = struct MapperUtils.migrate_piped_args mapper ~template_args ~lhs ~pipe_args:pipe_args_mapped in + let inner = Ast_helper.Exp.apply template_funct migrated_args in + let inner_with_attrs = + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + inner + in mk_apply exp ~funct - ~args: - [ - lhs; - (Asttypes.Nolabel, Ast_helper.Exp.apply template_funct migrated_args); - ] + ~args:[lhs; (Asttypes.Nolabel, inner_with_attrs)] ~partial ~transformed_jsx - (* Like apply_piped, but when there are no pipe args and the template has no - arguments to insert, collapse to `funct lhs template_funct`. *) - let apply_piped_maybe_empty ~mapper ~template ~lhs ~pipe_args ~funct - (exp : Parsetree.expression) = + let apply_piped_maybe_empty ~mapper ~template ~template_attrs ~lhs ~pipe_args + ~funct (exp : Parsetree.expression) = match template with - | Match _ -> apply_piped ~mapper ~template ~lhs ~pipe_args ~funct exp + | Match _ -> + apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct exp | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -498,31 +472,45 @@ module Template = struct MapperUtils.get_template_args_to_insert mapper template_args [] in if Ext_list.is_empty template_args_to_insert then - mk_apply exp ~funct - ~args:[lhs; (Asttypes.Nolabel, template_funct)] - ~partial ~transformed_jsx + let res = + mk_apply exp ~funct + ~args: + [ + lhs; + ( Asttypes.Nolabel, + MapperUtils.ApplyTransforms.attach_to_replacement + ~attrs:template_attrs template_funct ); + ] + ~partial ~transformed_jsx + in + res else + let inner = + Ast_helper.Exp.apply template_funct template_args_to_insert + in + let inner_with_attrs = + MapperUtils.ApplyTransforms.attach_to_replacement + ~attrs:template_attrs inner + in mk_apply exp ~funct - ~args: - [ - lhs; - ( Asttypes.Nolabel, - Ast_helper.Exp.apply template_funct template_args_to_insert ); - ] + ~args:[lhs; (Asttypes.Nolabel, inner_with_attrs)] ~partial ~transformed_jsx - else apply_piped ~mapper ~template ~lhs ~pipe_args ~funct exp + else + apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct exp - (* Handle the special case of a single-step pipe where we are allowed to - collapse the pipe into a direct call. *) - let apply_single_pipe_collapse ~mapper ~template ~lhs_exp ~pipe_args - (exp : Parsetree.expression) = + let apply_single_pipe_collapse ~mapper ~template ~template_attrs ~lhs_exp + ~pipe_args (exp : Parsetree.expression) = match template with | Match {expr; cases} -> - Ast_helper.Exp.match_ - (replace_from_args_in_expr expr - ((Asttypes.Nolabel, lhs_exp) - :: ArgUtils.map_expr_args mapper pipe_args)) - cases + let res = + Ast_helper.Exp.match_ + (replace_from_args_in_expr expr + ((Asttypes.Nolabel, lhs_exp) + :: ArgUtils.map_expr_args mapper pipe_args)) + cases + in + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + res | Apply { funct = templ_f; @@ -535,30 +523,33 @@ module Template = struct MapperUtils.apply_migration_template mapper templ_args ((Asttypes.Nolabel, lhs_exp) :: pipe_args_mapped) in - mk_apply exp ~funct:templ_f ~args:migrated_args ~partial:tpartial - ~transformed_jsx:tjsx + let res = + mk_apply exp ~funct:templ_f ~args:migrated_args ~partial:tpartial + ~transformed_jsx:tjsx + in + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs + res end (* Apply a direct-call migration template to a call site. *) let apply_template_direct mapper template_expr call_args exp = match Template.of_expr template_expr with - | Some template -> Template.apply_direct ~mapper ~template ~call_args exp + | Some template -> + Template.apply_direct ~mapper ~template + ~template_attrs:template_expr.pexp_attributes ~call_args exp | None -> exp -(* Choose a template to use for piped forms, preferring a specific piped - template when available and valid; otherwise fall back to the direct - template. *) let choose_template_for_piped (deprecated_info : Cmt_utils.deprecated_used) = match deprecated_info.migration_in_pipe_chain_template with | Some e -> ( match Template.of_expr e with - | Some t -> Some t + | Some t -> Some (t, e.pexp_attributes) | None -> None) | None -> ( match deprecated_info.migration_template with | Some e2 -> ( match Template.of_expr e2 with - | Some t -> Some t + | Some t -> Some (t, e2.pexp_attributes) | None -> None) | None -> None) @@ -576,14 +567,15 @@ let apply_single_step_or_piped ~mapper | Some e -> ( match Template.of_expr e with | Some t -> - Template.apply_single_pipe_collapse ~mapper ~template:t ~lhs_exp - ~pipe_args exp + Template.apply_single_pipe_collapse ~mapper ~template:t + ~template_attrs:e.pexp_attributes ~lhs_exp ~pipe_args exp | None -> ( match deprecated_info.migration_in_pipe_chain_template with | Some e2 -> ( match Template.of_expr e2 with | Some t -> - Template.apply_piped ~mapper ~template:t ~lhs ~pipe_args ~funct exp + Template.apply_piped ~mapper ~template:t + ~template_attrs:e2.pexp_attributes ~lhs ~pipe_args ~funct exp | None -> exp) | None -> exp)) | None -> ( @@ -591,14 +583,15 @@ let apply_single_step_or_piped ~mapper | Some e2 -> ( match Template.of_expr e2 with | Some t -> - Template.apply_piped ~mapper ~template:t ~lhs ~pipe_args ~funct exp + Template.apply_piped ~mapper ~template:t + ~template_attrs:e2.pexp_attributes ~lhs ~pipe_args ~funct exp | None -> exp) | None -> exp) else match choose_template_for_piped deprecated_info with - | Some t -> - Template.apply_piped_maybe_empty ~mapper ~template:t ~lhs ~pipe_args - ~funct exp + | Some (t, attrs) -> + Template.apply_piped_maybe_empty ~mapper ~template:t ~template_attrs:attrs + ~lhs ~pipe_args ~funct exp | None -> exp let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = diff --git a/tools/src/transforms.ml b/tools/src/transforms.ml index 5fd196323d..694a5c4e4b 100644 --- a/tools/src/transforms.ml +++ b/tools/src/transforms.ml @@ -44,6 +44,29 @@ let convertedLiteralToPureLiteral (e : Parsetree.expression) : (* `Float.fromInt(1)` to `1.`, *) e +let dropUnitArgumentsInApply (e : Parsetree.expression) : Parsetree.expression = + (* Drop only unlabelled unit arguments from an application expression. *) + let is_unit_expr (e : Parsetree.expression) = + match e.pexp_desc with + | Pexp_construct ({txt = Lident "()"}, None) -> true + | _ -> false + in + match e.pexp_desc with + | Pexp_apply {funct; args; partial; transformed_jsx} -> + let args' = + List.filter + (fun (label, arg) -> + match label with + | Asttypes.Nolabel -> not (is_unit_expr arg) + | _ -> true) + args + in + { + e with + pexp_desc = Pexp_apply {funct; args = args'; partial; transformed_jsx}; + } + | _ -> e + (* Registry of available transforms *) type transform = Parsetree.expression -> Parsetree.expression @@ -54,6 +77,7 @@ let registry : (string * transform) list = ("makerFnToRecord", makerFnToRecord); ("dictFromArrayToDictLiteralSyntax", dictFromArrayToDictLiteralSyntax); ("convertedLiteralToPureLiteral", convertedLiteralToPureLiteral); + ("dropUnitArgumentsInApply", dropUnitArgumentsInApply); ] let get (id : string) : transform option = List.assoc_opt id registry From ff36697a9e42261f5a836a613d095d4ebba4d134 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Sun, 31 Aug 2025 21:46:13 +0200 Subject: [PATCH 29/41] refactor --- tools/src/migrate.ml | 339 +++++++++++++++++++------------------------ 1 file changed, 148 insertions(+), 191 deletions(-) diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index 229a8a79fb..05d0f574bf 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -68,6 +68,8 @@ module ExprUtils = struct | _ -> false end +type args = (Asttypes.arg_label * Parsetree.expression) list + module MapperUtils = struct module ApplyTransforms = struct let attr_name = "apply.transforms" @@ -138,10 +140,8 @@ module MapperUtils = struct iter.expr iter expr; (!labelled, !unlabelled) - (* Replace placeholders anywhere inside an expression using the given - source arguments. Use the generic replacement transform applier. *) - let replace_placeholders_in_expr (expr : Parsetree.expression) - (source_args : (Asttypes.arg_label * Parsetree.expression) list) = + (* Build lookup tables for labelled and unlabelled source args. *) + let build_source_arg_tables (source_args : args) = let labelled = Hashtbl.create 8 in let unlabelled = Hashtbl.create 8 in let idx = ref 0 in @@ -153,10 +153,13 @@ module MapperUtils = struct incr idx | Asttypes.Labelled {txt} | Optional {txt} -> Hashtbl.replace labelled txt arg); - let find = function - | `Labelled name -> Hashtbl.find_opt labelled name - | `Unlabelled i -> Hashtbl.find_opt unlabelled i - in + (labelled, unlabelled) + + (* Replace placeholders anywhere inside an expression using the given + source arguments. *) + let replace_placeholders_in_expr (expr : Parsetree.expression) + (source_args : args) = + let labelled, unlabelled = build_source_arg_tables source_args in let mapper = { Ast_mapper.default_mapper with @@ -164,13 +167,13 @@ module MapperUtils = struct (fun mapper exp -> match InsertExt.placeholder_of_expr exp with | Some (InsertExt.Labelled name) -> ( - match find (`Labelled name) with + match Hashtbl.find_opt labelled name with | Some arg -> ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg | None -> exp) | Some (InsertExt.Unlabelled i) -> ( - match find (`Unlabelled i) with + match Hashtbl.find_opt unlabelled i with | Some arg -> ApplyTransforms.attach_to_replacement ~attrs:exp.pexp_attributes arg @@ -180,7 +183,7 @@ module MapperUtils = struct in mapper.expr mapper expr - let build_labelled_args_map template_args = + let build_labelled_args_map (template_args : args) = template_args |> List.filter_map (fun (label, arg) -> match (label, InsertExt.placeholder_of_expr arg) with @@ -201,10 +204,17 @@ module MapperUtils = struct Returns: - template_args_to_insert: args to append to the final call - - labelled_will_be_mapped: names of labelled source args that are consumed - - unlabelled_positions_to_insert: 0-based indices of unlabelled source args to drop + - labelled_names_to_drop: names of labelled source args consumed + - unlabelled_positions_to_drop: 0-based indices of unlabelled source args to drop *) - let get_template_args_to_insert mapper template_args source_args = + type template_resolution = { + args_to_insert: args; + labelled_to_drop: StringSet.t; + unlabelled_to_drop: IntSet.t; + } + + let get_template_args_to_insert mapper (template_args : args) + (source_args : args) : template_resolution = (* For each template argument, decide whether it is a placeholder that should be substituted from the source call, or a concrete argument which should be preserved (after mapping through the mapper). @@ -228,71 +238,84 @@ module MapperUtils = struct ([], StringSet.empty, IntSet.empty) template_args in - (List.rev rev_args, labelled_set, unlabelled_set) + { + args_to_insert = List.rev rev_args; + labelled_to_drop = labelled_set; + unlabelled_to_drop = unlabelled_set; + } - let drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped = + (* Drop consumed source arguments. + - unlabelled_positions_to_drop: 0-based indices of Nolabel args to drop + - labelled_names_to_drop: names of labelled/optional args to drop *) + let drop_args (source_args : args) ~unlabelled_positions_to_drop + ~labelled_names_to_drop = let _, rev = List.fold_left (fun (idx, acc) (label, arg) -> match label with | Asttypes.Nolabel -> - let drop = IntSet.mem idx unlabelled_positions_to_insert in + let drop = IntSet.mem idx unlabelled_positions_to_drop in let idx' = idx + 1 in if drop then (idx', acc) else (idx', (label, arg) :: acc) | Asttypes.Labelled {txt} | Optional {txt} -> - if StringSet.mem txt will_be_mapped then (idx, acc) + if StringSet.mem txt labelled_names_to_drop then (idx, acc) else (idx, (label, arg) :: acc)) (0, []) source_args in List.rev rev - let rename_labels source_args ~labelled_args_map = + let rename_labels (source_args : args) ~labelled_args_map = source_args |> List.map (fun (label, arg) -> match label with - | Asttypes.Labelled ({loc; txt} as l) -> - if StringMap.mem txt labelled_args_map then - let mapped = StringMap.find txt labelled_args_map in - (Asttypes.Labelled {loc; txt = mapped}, arg) - else (Asttypes.Labelled l, arg) - | Optional ({loc; txt} as l) -> - if StringMap.mem txt labelled_args_map then - let mapped = StringMap.find txt labelled_args_map in - (Optional {loc; txt = mapped}, arg) - else (Optional l, arg) + | Asttypes.Labelled ({loc; txt} as l) -> ( + match StringMap.find_opt txt labelled_args_map with + | Some mapped -> (Asttypes.Labelled {loc; txt = mapped}, arg) + | None -> (Asttypes.Labelled l, arg)) + | Optional ({loc; txt} as l) -> ( + match StringMap.find_opt txt labelled_args_map with + | Some mapped -> (Optional {loc; txt = mapped}, arg) + | None -> (Optional l, arg)) | _ -> (label, arg)) - let apply_migration_template mapper template_args source_args = + let apply_migration_template mapper (template_args : args) + (source_args : args) = let labelled_args_map = build_labelled_args_map template_args in - let template_args_to_insert, will_be_mapped, unlabelled_positions_to_insert - = + let resolution = get_template_args_to_insert mapper template_args source_args in let dropped = - drop_args source_args ~unlabelled_positions_to_insert ~will_be_mapped + drop_args source_args + ~unlabelled_positions_to_drop:resolution.unlabelled_to_drop + ~labelled_names_to_drop:resolution.labelled_to_drop in let renamed = rename_labels dropped ~labelled_args_map in - renamed @ template_args_to_insert + renamed @ resolution.args_to_insert + + (* Adjust unlabelled drop positions for piped calls where the LHS occupies + position 0 in placeholder resolution, but is not part of the inner call's + argument list. *) + let shift_unlabelled_drop_for_piped set = + IntSet.fold + (fun i acc -> if i > 0 then IntSet.add (i - 1) acc else acc) + set IntSet.empty let migrate_piped_args mapper ~template_args ~lhs ~pipe_args = let full_source_args = lhs :: pipe_args in - let template_args_to_insert, will_be_mapped, unlabelled_positions_to_insert - = + let resolution = get_template_args_to_insert mapper template_args full_source_args in let labelled_args_map = build_labelled_args_map template_args in let adjusted_unlabelled_to_drop = - IntSet.fold - (fun i acc -> if i > 0 then IntSet.add (i - 1) acc else acc) - unlabelled_positions_to_insert IntSet.empty + shift_unlabelled_drop_for_piped resolution.unlabelled_to_drop in let dropped = drop_args pipe_args - ~unlabelled_positions_to_insert:adjusted_unlabelled_to_drop - ~will_be_mapped + ~unlabelled_positions_to_drop:adjusted_unlabelled_to_drop + ~labelled_names_to_drop:resolution.labelled_to_drop in let renamed = rename_labels dropped ~labelled_args_map in - renamed @ template_args_to_insert + renamed @ resolution.args_to_insert end module TypeReplace = struct @@ -309,58 +332,6 @@ module TypeReplace = struct | _ -> None end -type args_ctx = { - labelled: (string, Parsetree.expression) Hashtbl.t; - unlabelled: (int, Parsetree.expression) Hashtbl.t; -} - -let build_args_ctx args : args_ctx = - let labelled = Hashtbl.create 8 in - let unlabelled = Hashtbl.create 8 in - let idx = ref 0 in - args - |> List.iter (fun (lbl, arg) -> - match lbl with - | Asttypes.Nolabel -> - Hashtbl.replace unlabelled !idx arg; - incr idx - | Asttypes.Labelled {txt} | Optional {txt} -> - Hashtbl.replace labelled txt arg); - {labelled; unlabelled} - -let find_in_args_ctx args_ctx - (find_this : [`Labelled of string | `Unlabelled of int]) = - match find_this with - | `Labelled name -> Hashtbl.find_opt args_ctx.labelled name - | `Unlabelled i -> Hashtbl.find_opt args_ctx.unlabelled i - -let replace_from_args_ctx_in_expr expr args_ctx = - let mapper = - { - Ast_mapper.default_mapper with - expr = - (fun mapper exp -> - match InsertExt.placeholder_of_expr exp with - | Some (InsertExt.Labelled name) -> ( - match find_in_args_ctx args_ctx (`Labelled name) with - | Some arg -> - MapperUtils.ApplyTransforms.attach_to_replacement - ~attrs:exp.pexp_attributes arg - | None -> exp) - | Some (InsertExt.Unlabelled i) -> ( - match find_in_args_ctx args_ctx (`Unlabelled i) with - | Some arg -> - MapperUtils.ApplyTransforms.attach_to_replacement - ~attrs:exp.pexp_attributes arg - | None -> exp) - | None -> Ast_mapper.default_mapper.expr mapper exp); - } - in - mapper.expr mapper expr - -let replace_from_args_in_expr expr source_args = - replace_from_args_ctx_in_expr expr (build_args_ctx source_args) - let remap_needed_extensions (mapper : Ast_mapper.mapper) (ext : Parsetree.extension) : Parsetree.extension = match ext with @@ -378,12 +349,15 @@ module Template = struct type t = | Apply of { funct: Parsetree.expression; - args: (Asttypes.arg_label * Parsetree.expression) list; + args: args; partial: bool; transformed_jsx: bool; } | Match of {expr: Parsetree.expression; cases: Parsetree.case list} + let attach attrs e = + MapperUtils.ApplyTransforms.attach_to_replacement ~attrs e + let of_expr = function | {Parsetree.pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} -> @@ -400,6 +374,12 @@ module Template = struct Some (Match {expr; cases}) | _ -> None + let of_expr_with_attrs (e : Parsetree.expression) : + (t * Parsetree.attributes) option = + match of_expr e with + | Some t -> Some (t, e.pexp_attributes) + | None -> None + let mk_apply (exp : Parsetree.expression) ~funct ~args ~partial ~transformed_jsx = {exp with pexp_desc = Pexp_apply {funct; args; partial; transformed_jsx}} @@ -412,11 +392,11 @@ module Template = struct { exp with pexp_desc = - Pexp_match (replace_from_args_in_expr expr call_args, cases); + Pexp_match + (MapperUtils.replace_placeholders_in_expr expr call_args, cases); } in - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - res + attach template_attrs res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -427,8 +407,7 @@ module Template = struct mk_apply exp ~funct:template_funct ~args:migrated_args ~partial ~transformed_jsx in - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - res + attach template_attrs res let apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct (exp : Parsetree.expression) = @@ -437,11 +416,12 @@ module Template = struct let res = { exp with - pexp_desc = Pexp_match (replace_from_args_in_expr expr [lhs], cases); + pexp_desc = + Pexp_match + (MapperUtils.replace_placeholders_in_expr expr [lhs], cases); } in - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - res + attach template_attrs res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -451,10 +431,7 @@ module Template = struct ~pipe_args:pipe_args_mapped in let inner = Ast_helper.Exp.apply template_funct migrated_args in - let inner_with_attrs = - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - inner - in + let inner_with_attrs = attach template_attrs inner in mk_apply exp ~funct ~args:[lhs; (Asttypes.Nolabel, inner_with_attrs)] ~partial ~transformed_jsx @@ -468,30 +445,22 @@ module Template = struct {funct = template_funct; args = template_args; partial; transformed_jsx} -> if Ext_list.is_empty pipe_args then - let template_args_to_insert, _, _ = + let resolution = MapperUtils.get_template_args_to_insert mapper template_args [] in - if Ext_list.is_empty template_args_to_insert then + if Ext_list.is_empty resolution.args_to_insert then let res = mk_apply exp ~funct ~args: - [ - lhs; - ( Asttypes.Nolabel, - MapperUtils.ApplyTransforms.attach_to_replacement - ~attrs:template_attrs template_funct ); - ] + [lhs; (Asttypes.Nolabel, attach template_attrs template_funct)] ~partial ~transformed_jsx in res else let inner = - Ast_helper.Exp.apply template_funct template_args_to_insert - in - let inner_with_attrs = - MapperUtils.ApplyTransforms.attach_to_replacement - ~attrs:template_attrs inner + Ast_helper.Exp.apply template_funct resolution.args_to_insert in + let inner_with_attrs = attach template_attrs inner in mk_apply exp ~funct ~args:[lhs; (Asttypes.Nolabel, inner_with_attrs)] ~partial ~transformed_jsx @@ -504,13 +473,12 @@ module Template = struct | Match {expr; cases} -> let res = Ast_helper.Exp.match_ - (replace_from_args_in_expr expr + (MapperUtils.replace_placeholders_in_expr expr ((Asttypes.Nolabel, lhs_exp) :: ArgUtils.map_expr_args mapper pipe_args)) cases in - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - res + attach template_attrs res | Apply { funct = templ_f; @@ -527,8 +495,7 @@ module Template = struct mk_apply exp ~funct:templ_f ~args:migrated_args ~partial:tpartial ~transformed_jsx:tjsx in - MapperUtils.ApplyTransforms.attach_to_replacement ~attrs:template_attrs - res + attach template_attrs res end (* Apply a direct-call migration template to a call site. *) @@ -539,19 +506,7 @@ let apply_template_direct mapper template_expr call_args exp = ~template_attrs:template_expr.pexp_attributes ~call_args exp | None -> exp -let choose_template_for_piped (deprecated_info : Cmt_utils.deprecated_used) = - match deprecated_info.migration_in_pipe_chain_template with - | Some e -> ( - match Template.of_expr e with - | Some t -> Some (t, e.pexp_attributes) - | None -> None) - | None -> ( - match deprecated_info.migration_template with - | Some e2 -> ( - match Template.of_expr e2 with - | Some t -> Some (t, e2.pexp_attributes) - | None -> None) - | None -> None) +(* Helper removed: inline selection logic where needed for clarity. *) (* Apply migration for a single-step pipe if possible, else use the piped template. Mirrors the previous inline logic from the mapper. *) @@ -559,36 +514,34 @@ let apply_single_step_or_piped ~mapper ~(deprecated_info : Cmt_utils.deprecated_used) ~lhs ~lhs_exp ~pipe_args ~funct exp = let is_single_pipe_step = not (ExprUtils.is_pipe_apply lhs_exp) in - if - is_single_pipe_step - && Option.is_some deprecated_info.migration_in_pipe_chain_template - then + let in_pipe_template = + match deprecated_info.migration_in_pipe_chain_template with + | Some e -> Template.of_expr_with_attrs e + | None -> None + in + let direct_template = match deprecated_info.migration_template with - | Some e -> ( - match Template.of_expr e with - | Some t -> - Template.apply_single_pipe_collapse ~mapper ~template:t - ~template_attrs:e.pexp_attributes ~lhs_exp ~pipe_args exp - | None -> ( - match deprecated_info.migration_in_pipe_chain_template with - | Some e2 -> ( - match Template.of_expr e2 with - | Some t -> - Template.apply_piped ~mapper ~template:t - ~template_attrs:e2.pexp_attributes ~lhs ~pipe_args ~funct exp - | None -> exp) - | None -> exp)) + | Some e -> Template.of_expr_with_attrs e + | None -> None + in + if is_single_pipe_step && Option.is_some in_pipe_template then + match direct_template with + | Some (t, attrs) -> + Template.apply_single_pipe_collapse ~mapper ~template:t + ~template_attrs:attrs ~lhs_exp ~pipe_args exp | None -> ( - match deprecated_info.migration_in_pipe_chain_template with - | Some e2 -> ( - match Template.of_expr e2 with - | Some t -> - Template.apply_piped ~mapper ~template:t - ~template_attrs:e2.pexp_attributes ~lhs ~pipe_args ~funct exp - | None -> exp) + match in_pipe_template with + | Some (t, attrs) -> + Template.apply_piped ~mapper ~template:t ~template_attrs:attrs ~lhs + ~pipe_args ~funct exp | None -> exp) else - match choose_template_for_piped deprecated_info with + let chosen = + match in_pipe_template with + | None -> direct_template + | some_tpl -> some_tpl + in + match chosen with | Some (t, attrs) -> Template.apply_piped_maybe_empty ~mapper ~template:t ~template_attrs:attrs ~lhs ~pipe_args ~funct exp @@ -623,6 +576,35 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = |> List.iter (fun ({Cmt_utils.source_loc} as d) -> Hashtbl.replace loc_to_deprecated_reference source_loc d); + (* Helpers for type replacement lookups *) + let loc_contains (a : Location.t) (b : Location.t) = + let a_start = a.Location.loc_start.pos_cnum in + let a_end = a.Location.loc_end.pos_cnum in + let b_start = b.Location.loc_start.pos_cnum in + let b_end = b.Location.loc_end.pos_cnum in + a_start <= b_start && a_end >= b_end + in + (* Prefilter deprecations that have a %replace.type(: ) payload. *) + let type_replace_deprecations : + (Cmt_utils.deprecated_used * Parsetree.core_type) list = + deprecated_used + |> List.filter_map (fun (d : Cmt_utils.deprecated_used) -> + match d.migration_template with + | Some e -> ( + match TypeReplace.core_type_of_expr_extension e with + | Some ct -> Some (d, ct) + | None -> None) + | None -> None) + in + let find_type_replace_template (loc : Location.t) : Parsetree.core_type option + = + type_replace_deprecations + |> List.find_map (fun ((d : Cmt_utils.deprecated_used), ct) -> + if loc_contains loc d.source_loc || loc_contains d.source_loc loc + then Some ct + else None) + in + let mapper = { Ast_mapper.default_mapper with @@ -633,32 +615,7 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = (fun mapper (ct : Parsetree.core_type) -> match ct.ptyp_desc with | Ptyp_constr ({loc}, args) -> ( - (* Build a lookup of deprecated type references (by source loc) -> - core_type template. *) - let loc_contains (a : Location.t) (b : Location.t) = - let a_start = a.Location.loc_start.pos_cnum in - let a_end = a.Location.loc_end.pos_cnum in - let b_start = b.Location.loc_start.pos_cnum in - let b_end = b.Location.loc_end.pos_cnum in - a_start <= b_start && a_end >= b_end - in - let replace_template_opt = - (* We expect the cmt to have recorded deprecations for type - references without a specific context; we also only consider - entries whose migration_template is a %replace.type(: ...). *) - deprecated_used - |> List.find_map (fun (d : Cmt_utils.deprecated_used) -> - match d.migration_template with - | Some e -> ( - match TypeReplace.core_type_of_expr_extension e with - | Some ct - when loc_contains loc d.source_loc - || loc_contains d.source_loc loc -> - Some ct - | _ -> None) - | None -> None) - in - match replace_template_opt with + match find_type_replace_template loc with | Some template_ct -> ( (* Transfer all source type arguments as-is. *) let mapped_args = List.map (mapper.Ast_mapper.typ mapper) args in @@ -671,7 +628,7 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) = mapper.Ast_mapper.typ mapper ct' | _ -> (* If the template isn't a constructor, fall back to the - template itself and drop the original args. *) + template itself and drop the original args. *) let ct' = {template_ct with ptyp_loc = ct.ptyp_loc} in mapper.Ast_mapper.typ mapper ct') | None -> Ast_mapper.default_mapper.typ mapper ct) From e78f030ae28962c60ffd09969bebf0f8db01f29a Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 1 Sep 2025 15:11:35 +0200 Subject: [PATCH 30/41] finish js_json migration --- packages/@rescript/runtime/Js_json.resi | 101 ++++++++++++++++-- packages/@rescript/runtime/Stdlib_JSON.res | 6 ++ packages/@rescript/runtime/Stdlib_JSON.resi | 37 +++++-- .../StdlibMigration_JSON.res.expected | 34 +++--- .../src/migrate/StdlibMigration_JSON.res | 15 +++ .../Migrated_StdlibMigration_JSON.res | 34 +++--- 6 files changed, 182 insertions(+), 45 deletions(-) diff --git a/packages/@rescript/runtime/Js_json.resi b/packages/@rescript/runtime/Js_json.resi index 9ce7a629a3..3930582945 100644 --- a/packages/@rescript/runtime/Js_json.resi +++ b/packages/@rescript/runtime/Js_json.resi @@ -44,6 +44,7 @@ type rec t = Stdlib_JSON.t = | Object(dict) | Array(array) +@deprecated("This functionality has been deprecated and will be removed in v13.") module Kind: { type json = t /** Underlying type of a JSON value */ @@ -56,6 +57,7 @@ module Kind: { | Null: t } +@deprecated("This functionality has been deprecated and will be removed in v13.") type tagged_t = | JSONFalse | JSONTrue @@ -67,48 +69,67 @@ type tagged_t = /* ## Accessors */ +@deprecated("This functionality has been deprecated and will be removed in v13.") let classify: t => tagged_t /** `test(v, kind)` returns `true` if `v` is of `kind`. */ +@deprecated("This functionality has been deprecated and will be removed in v13.") let test: ('a, Kind.t<'b>) => bool /** `decodeString(json)` returns `Some(s)` if `json` is a `string`, `None` otherwise. */ @deprecated({ - reason: "Use pattern matching instead.", - migrate: switch %insert.unlabelledArgument(0) { - | JSON.String(str) => Some(str) - | _ => None - }, + reason: "Use `JSON.Decode.string` instead.", + migrate: JSON.Decode.string(), }) let decodeString: t => option /** `decodeNumber(json)` returns `Some(n)` if `json` is a `number`, `None` otherwise. */ +@deprecated({ + reason: "Use `JSON.Decode.float` instead.", + migrate: JSON.Decode.float(), +}) let decodeNumber: t => option /** `decodeObject(json)` returns `Some(o)` if `json` is an `object`, `None` otherwise. */ +@deprecated({ + reason: "Use `JSON.Decode.object` instead.", + migrate: JSON.Decode.object(), +}) let decodeObject: t => option> /** `decodeArray(json)` returns `Some(a)` if `json` is an `array`, `None` otherwise. */ +@deprecated({ + reason: "Use `JSON.Decode.array` instead.", + migrate: JSON.Decode.array(), +}) let decodeArray: t => option> /** `decodeBoolean(json)` returns `Some(b)` if `json` is a `boolean`, `None` otherwise. */ +@deprecated({ + reason: "Use `JSON.Decode.bool` instead.", + migrate: JSON.Decode.bool(), +}) let decodeBoolean: t => option /** `decodeNull(json)` returns `Some(null)` if `json` is a `null`, `None` otherwise. */ +@deprecated({ + reason: "Use JSON.Decode.null instead.", + migrate: JSON.Decode.null(), +}) let decodeNull: t => option> /* ## Constructors */ @@ -119,22 +140,46 @@ let decodeNull: t => option> */ /** `null` is the singleton null JSON value. */ +@deprecated({ + reason: "Use `JSON.Encode.null` instead.", + migrate: JSON.Encode.null, +}) @val external null: t = "null" /** `string(s)` makes a JSON string of the `string` `s`. */ +@deprecated({ + reason: "Use `JSON.Encode.string` instead.", + migrate: JSON.Encode.string(), +}) external string: string => t = "%identity" /** `number(n)` makes a JSON number of the `float` `n`. */ +@deprecated({ + reason: "Use `JSON.Encode.float` instead.", + migrate: JSON.Encode.float(), +}) external number: float => t = "%identity" /** `boolean(b)` makes a JSON boolean of the `bool` `b`. */ +@deprecated({ + reason: "Use `JSON.Encode.bool` instead.", + migrate: JSON.Encode.bool(), +}) external boolean: bool => t = "%identity" /** `object_(dict)` makes a JSON object of the `dict`. */ +@deprecated({ + reason: "Use `JSON.Encode.object` instead.", + migrate: JSON.Encode.object(), +}) external object_: dict => t = "%identity" /** `array_(a)` makes a JSON array of the `Js.Json.t` array `a`. */ +@deprecated({ + reason: "Use `JSON.Encode.array` instead.", + migrate: JSON.Encode.array(), +}) external array: array => t = "%identity" /* @@ -144,15 +189,31 @@ external array: array => t = "%identity" */ /** `stringArray(a)` makes a JSON array of the `string` array `a`. */ +@deprecated({ + reason: "Use `JSON.Encode.stringArray` instead.", + migrate: JSON.Encode.stringArray(), +}) external stringArray: array => t = "%identity" /** `numberArray(a)` makes a JSON array of the `float` array `a`. */ +@deprecated({ + reason: "Use `JSON.Encode.floatArray` instead.", + migrate: JSON.Encode.floatArray(), +}) external numberArray: array => t = "%identity" /** `booleanArray(a)` makes a JSON array of the `bool` array `a`. */ +@deprecated({ + reason: "Use `JSON.Encode.boolArray` instead.", + migrate: JSON.Encode.boolArray(), +}) external booleanArray: array => t = "%identity" /** `objectArray(a) makes a JSON array of the `JsDict.t` array `a`. */ +@deprecated({ + reason: "Use `JSON.Encode.objectArray` instead.", + migrate: JSON.Encode.objectArray(), +}) external objectArray: array> => t = "%identity" /* ## String conversion */ @@ -207,7 +268,12 @@ let getIds = s => { Js.log(getIds(` { "ids" : [1, 2, 3 ] } `)) ``` */ -@val @scope("JSON") +@deprecated({ + reason: "Use `JSON.parseOrThrow` instead.", + migrate: JSON.parseOrThrow(), +}) +@val +@scope("JSON") external parseExn: string => t = "parse" /** @@ -229,7 +295,12 @@ Js.Dict.set(dict, "likes", Js.Json.stringArray(["ReScript", "ocaml", "js"])) Js.log(Js.Json.stringify(Js.Json.object_(dict))) ``` */ -@val @scope("JSON") +@deprecated({ + reason: "Use `JSON.stringify` instead.", + migrate: JSON.stringify(), +}) +@val +@scope("JSON") external stringify: t => string = "stringify" /** @@ -251,7 +322,12 @@ Js.Dict.set(dict, "likes", Js.Json.stringArray(["ReScript", "ocaml", "js"])) Js.log(Js.Json.stringifyWithSpace(Js.Json.object_(dict), 2)) ``` */ -@val @scope("JSON") +@deprecated({ + reason: "Use `JSON.stringify` with optional `~space` instead.", + migrate: JSON.stringify(~space=%insert.unlabelledArgument(2)), +}) +@val +@scope("JSON") external stringifyWithSpace: (t, @as(json`null`) _, int) => string = "stringify" /** @@ -264,7 +340,12 @@ external stringifyWithSpace: (t, @as(json`null`) _, int) => string = "stringify" Js.log(Js.Json.stringifyAny(["hello", "world"])) ``` */ -@val @scope("JSON") +@deprecated({ + reason: "Use `JSON.stringifyAny` instead.", + migrate: JSON.stringifyAny(), +}) +@val +@scope("JSON") external stringifyAny: 'a => option = "stringify" /** @@ -275,6 +356,7 @@ It is unsafe in two aspects - It may throw during parsing - when you cast it to a specific type, it may have a type mismatch */ +@deprecated("This functionality has been deprecated and will be removed in v13.") let deserializeUnsafe: string => 'a /** @@ -283,4 +365,5 @@ It will raise in such situations: - There are cycles - Some JS engines can not stringify deeply nested json objects */ +@deprecated("This functionality has been deprecated and will be removed in v13.") let serializeExn: 'a => string diff --git a/packages/@rescript/runtime/Stdlib_JSON.res b/packages/@rescript/runtime/Stdlib_JSON.res index 4535a5f7b3..68b34075f4 100644 --- a/packages/@rescript/runtime/Stdlib_JSON.res +++ b/packages/@rescript/runtime/Stdlib_JSON.res @@ -82,6 +82,12 @@ module Encode = { external float: float => t = "%identity" external object: dict => t = "%identity" external array: array => t = "%identity" + + external stringArray: array => t = "%identity" + external floatArray: array => t = "%identity" + external intArray: array => t = "%identity" + external boolArray: array => t = "%identity" + external objectArray: array> => t = "%identity" } module Decode = { diff --git a/packages/@rescript/runtime/Stdlib_JSON.resi b/packages/@rescript/runtime/Stdlib_JSON.resi index 6a6f6279c5..6613ea88b4 100644 --- a/packages/@rescript/runtime/Stdlib_JSON.resi +++ b/packages/@rescript/runtime/Stdlib_JSON.resi @@ -654,7 +654,7 @@ module Classify: { module Encode: { /** - Returns a boolean as a JSON object. + Returns a boolean as JSON. ## Examples ```rescript @@ -664,7 +664,7 @@ module Encode: { external bool: bool => t = "%identity" /** - Returns null as a JSON object. + Returns null as a JSON value. ## Examples ```rescript @@ -674,7 +674,7 @@ module Encode: { external null: t = "#null" /** - Returns a string as a JSON object. + Returns a string as JSON. ## Examples ```rescript @@ -684,7 +684,7 @@ module Encode: { external string: string => t = "%identity" /** - Returns an int as a JSON object. + Returns an int as JSON. ## Examples ```rescript @@ -694,7 +694,7 @@ module Encode: { external int: int => t = "%identity" /** - Returns a float as a JSON object. + Returns a float as JSON. ## Examples ```rescript @@ -719,7 +719,7 @@ module Encode: { external object: dict => t = "%identity" /** - Returns an array as a JSON object. + Returns an array as JSON. ## Examples ```rescript @@ -729,6 +729,31 @@ module Encode: { ``` */ external array: array => t = "%identity" + + /** + Returns an array of strings as a JSON object. + */ + external stringArray: array => t = "%identity" + + /** + Returns an array of floats as a JSON object. + */ + external floatArray: array => t = "%identity" + + /** + Returns an array of integers as a JSON object. + */ + external intArray: array => t = "%identity" + + /** + Returns an array of booleans as a JSON object. + */ + external boolArray: array => t = "%identity" + + /** + Returns an array of objects as a JSON object. + */ + external objectArray: array> => t = "%identity" } module Decode: { diff --git a/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected index 14df9f8c38..5f8cd42d0f 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_JSON.res.expected @@ -1,19 +1,23 @@ external someJson: JSON.t = "someJson" external strToJson: string => JSON.t = "strToJson" -let decodeString1 = switch someJson { -| JSON.String(str) => Some(str) -| _ => None -} -let decodeString2 = switch someJson { -| JSON.String(str) => Some(str) -| _ => None -} -let decodeString3 = switch [1, 2, 3] -->Array.map(v => v->Int.toString) -->Array.join(" ") -->strToJson { -| JSON.String(str) => Some(str) -| _ => None -} +let decodeString1 = someJson->JSON.Decode.string +let decodeString2 = JSON.Decode.string(someJson) +let decodeString3 = + [1, 2, 3]->Array.map(v => v->Int.toString)->Array.join(" ")->strToJson->JSON.Decode.string + +let decodeNumber1 = someJson->JSON.Decode.float +let decodeNumber2 = JSON.Decode.float(someJson) + +let decodeObject1 = someJson->JSON.Decode.object +let decodeObject2 = JSON.Decode.object(someJson) + +let decodeArray1 = someJson->JSON.Decode.array +let decodeArray2 = JSON.Decode.array(someJson) + +let decodeBoolean1 = someJson->JSON.Decode.bool +let decodeBoolean2 = JSON.Decode.bool(someJson) + +let decodeNull1 = someJson->JSON.Decode.null +let decodeNull2 = JSON.Decode.null(someJson) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_JSON.res b/tests/tools_tests/src/migrate/StdlibMigration_JSON.res index 60e13379a2..ae75c80b96 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_JSON.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_JSON.res @@ -9,3 +9,18 @@ let decodeString3 = ->Array.join(" ") ->strToJson ->Js_json.decodeString + +let decodeNumber1 = someJson->Js_json.decodeNumber +let decodeNumber2 = Js_json.decodeNumber(someJson) + +let decodeObject1 = someJson->Js_json.decodeObject +let decodeObject2 = Js_json.decodeObject(someJson) + +let decodeArray1 = someJson->Js_json.decodeArray +let decodeArray2 = Js_json.decodeArray(someJson) + +let decodeBoolean1 = someJson->Js_json.decodeBoolean +let decodeBoolean2 = Js_json.decodeBoolean(someJson) + +let decodeNull1 = someJson->Js_json.decodeNull +let decodeNull2 = Js_json.decodeNull(someJson) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res index 12491053d9..54e72a78ce 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON.res @@ -3,18 +3,22 @@ external someJson: JSON.t = "someJson" external strToJson: string => JSON.t = "strToJson" -let decodeString1 = switch someJson { -| JSON.String(str) => Some(str) -| _ => None -} -let decodeString2 = switch someJson { -| JSON.String(str) => Some(str) -| _ => None -} -let decodeString3 = switch [1, 2, 3] -->Array.map(v => v->Int.toString) -->Array.join(" ") -->strToJson { -| JSON.String(str) => Some(str) -| _ => None -} +let decodeString1 = someJson->JSON.Decode.string +let decodeString2 = JSON.Decode.string(someJson) +let decodeString3 = + [1, 2, 3]->Array.map(v => v->Int.toString)->Array.join(" ")->strToJson->JSON.Decode.string + +let decodeNumber1 = someJson->JSON.Decode.float +let decodeNumber2 = JSON.Decode.float(someJson) + +let decodeObject1 = someJson->JSON.Decode.object +let decodeObject2 = JSON.Decode.object(someJson) + +let decodeArray1 = someJson->JSON.Decode.array +let decodeArray2 = JSON.Decode.array(someJson) + +let decodeBoolean1 = someJson->JSON.Decode.bool +let decodeBoolean2 = JSON.Decode.bool(someJson) + +let decodeNull1 = someJson->JSON.Decode.null +let decodeNull2 = JSON.Decode.null(someJson) From 9be8a97704584e45588e07d1da7279d7da718799 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 1 Sep 2025 18:37:52 +0200 Subject: [PATCH 31/41] more migrations --- packages/@rescript/runtime/Js_result.res | 5 +- .../runtime/Stdlib_BigInt64Array.res | 28 ++++- .../runtime/Stdlib_BigUint64Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Float32Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Float64Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Int16Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Int8Array.res | 28 ++++- packages/@rescript/runtime/Stdlib_JSON.res | 107 ++++++++++++++++-- .../@rescript/runtime/Stdlib_Uint16Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Uint32Array.res | 28 ++++- .../@rescript/runtime/Stdlib_Uint8Array.res | 28 ++++- .../StdlibMigration_ArrayAppend.res.expected | 3 + ...Migration_JSON_ParseStringify.res.expected | 15 +++ .../StdlibMigration_JSON_Stdlib.res.expected | 15 +++ .../StdlibMigration_Result.res.expected | 1 + ...ation_TypedArray_Constructors.res.expected | 4 + ...ibMigration_TypedArray_Stdlib.res.expected | 4 + .../migrate/StdlibMigration_JSON_Stdlib.res | 14 +++ .../src/migrate/StdlibMigration_Result.res | 1 + .../StdlibMigration_TypedArray_Stdlib.res | 3 + .../Migrated_StdlibMigration_JSON_Stdlib.res | 16 +++ .../Migrated_StdlibMigration_Result.res | 1 + ...ated_StdlibMigration_TypedArray_Stdlib.res | 5 + 23 files changed, 406 insertions(+), 40 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_ArrayAppend.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_JSON_ParseStringify.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_JSON_Stdlib.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_TypedArray_Constructors.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_TypedArray_Stdlib.res.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_JSON_Stdlib.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_TypedArray_Stdlib.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON_Stdlib.res create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_TypedArray_Stdlib.res diff --git a/packages/@rescript/runtime/Js_result.res b/packages/@rescript/runtime/Js_result.res index 8cb2ab13f3..3b65dff42b 100644 --- a/packages/@rescript/runtime/Js_result.res +++ b/packages/@rescript/runtime/Js_result.res @@ -22,7 +22,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -@deprecated("Please use `Belt.Result.t` instead") +@deprecated({ + reason: "Use `result` directly instead", + migrate: %replace.type(: result), +}) type t<+'good, +'bad> = | Ok('good) | Error('bad) diff --git a/packages/@rescript/runtime/Stdlib_BigInt64Array.res b/packages/@rescript/runtime/Stdlib_BigInt64Array.res index c90f743a99..5f82615564 100644 --- a/packages/@rescript/runtime/Stdlib_BigInt64Array.res +++ b/packages/@rescript/runtime/Stdlib_BigInt64Array.res @@ -27,14 +27,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: BigInt64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "BigInt64Array" /** `fromBufferWithRange` creates a `BigInt64Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array/BigInt64Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: BigInt64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "BigInt64Array" @@ -52,7 +67,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => bigint=?) => t = "BigI /** `fromArrayLikeOrIterableWithMap` creates a `BigInt64Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: BigInt64Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => bigint) => t = "BigInt64Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_BigUint64Array.res b/packages/@rescript/runtime/Stdlib_BigUint64Array.res index 6bce30f6f6..f0f74b3f51 100644 --- a/packages/@rescript/runtime/Stdlib_BigUint64Array.res +++ b/packages/@rescript/runtime/Stdlib_BigUint64Array.res @@ -27,14 +27,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: BigUint64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "BigUint64Array" /** `fromBufferWithRange` creates a `BigUint64Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigUint64Array/BigUint64Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: BigUint64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "BigUint64Array" @@ -52,7 +67,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => bigint=?) => t = "BigU /** `fromArrayLikeOrIterableWithMap` creates a `BigUint64Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: BigUint64Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => bigint) => t = "BigUint64Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Float32Array.res b/packages/@rescript/runtime/Stdlib_Float32Array.res index 1a0ccc51b5..e76c84c81c 100644 --- a/packages/@rescript/runtime/Stdlib_Float32Array.res +++ b/packages/@rescript/runtime/Stdlib_Float32Array.res @@ -27,14 +27,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Float32Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Float32Array" /** `fromBufferWithRange` creates a `Float32Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array/Float32Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Float32Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Float32Array" @@ -52,7 +67,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => float=?) => t = "Float /** `fromArrayLikeOrIterableWithMap` creates a `Float32Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Float32Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => float) => t = "Float32Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Float64Array.res b/packages/@rescript/runtime/Stdlib_Float64Array.res index 7884de062a..75ffb8a02c 100644 --- a/packages/@rescript/runtime/Stdlib_Float64Array.res +++ b/packages/@rescript/runtime/Stdlib_Float64Array.res @@ -27,14 +27,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Float64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Float64Array" /** `fromBufferWithRange` creates a `Float64Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array/Float64Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Float64Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Float64Array" @@ -52,7 +67,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => float=?) => t = "Float /** `fromArrayLikeOrIterableWithMap` creates a `Float64Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Float64Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => float) => t = "Float64Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Int16Array.res b/packages/@rescript/runtime/Stdlib_Int16Array.res index 615d6dcf96..36c9380cc5 100644 --- a/packages/@rescript/runtime/Stdlib_Int16Array.res +++ b/packages/@rescript/runtime/Stdlib_Int16Array.res @@ -26,14 +26,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Int16Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Int16Array" /** `fromBufferWithRange` creates a `Int16Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array/Int16Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Int16Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Int16Array" @@ -51,7 +66,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => int=?) => t = "Int16Ar /** `fromArrayLikeOrIterableWithMap` creates a `Int16Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Int16Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => int) => t = "Int16Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Int8Array.res b/packages/@rescript/runtime/Stdlib_Int8Array.res index f8b2d9b596..3907bd57ad 100644 --- a/packages/@rescript/runtime/Stdlib_Int8Array.res +++ b/packages/@rescript/runtime/Stdlib_Int8Array.res @@ -26,14 +26,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Int8Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Int8Array" /** `fromBufferWithRange` creates a `Int8Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array/Int8Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Int8Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Int8Array" @@ -51,7 +66,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => int=?) => t = "Int8Arr /** `fromArrayLikeOrIterableWithMap` creates a `Int8Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Int8Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => int) => t = "Int8Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_JSON.res b/packages/@rescript/runtime/Stdlib_JSON.res index 68b34075f4..a52adb027e 100644 --- a/packages/@rescript/runtime/Stdlib_JSON.res +++ b/packages/@rescript/runtime/Stdlib_JSON.res @@ -12,37 +12,120 @@ type replacer = Keys(array) | Replacer((string, t) => t) @raises @val external parseOrThrow: (string, ~reviver: (string, t) => t=?) => t = "JSON.parse" -@deprecated("Use `parseOrThrow` instead") @raises @val +@deprecated({ + reason: "Use `JSON.parseOrThrow` instead", + migrate: JSON.parseOrThrow(), +}) +@raises +@val external parseExn: (string, ~reviver: (string, t) => t=?) => t = "JSON.parse" -@deprecated("Use `parseOrThrow` with optional parameter instead") @raises @val +@deprecated({ + reason: "Use `JSON.parseOrThrow` with optional parameter instead", + migrate: JSON.parseOrThrow(%insert.unlabelledArgument(0), ~reviver=%insert.unlabelledArgument(1)), +}) +@raises +@val external parseExnWithReviver: (string, (string, t) => t) => t = "JSON.parse" @val external stringify: (t, ~replacer: replacer=?, ~space: int=?) => string = "JSON.stringify" -@deprecated("Use `stringify` with optional parameter instead") @val +@deprecated({ + reason: "Use `JSON.stringify` with optional parameter instead", + migrate: JSON.stringify(%insert.unlabelledArgument(0), ~space=%insert.unlabelledArgument(2)), +}) +@val external stringifyWithIndent: (t, @as(json`null`) _, int) => string = "JSON.stringify" -@deprecated("Use `stringify` with optional parameter instead") @val +@deprecated({ + reason: "Use `JSON.stringify` with optional parameter instead", + migrate: JSON.stringify( + %insert.unlabelledArgument(0), + ~replacer=Replacer(%insert.unlabelledArgument(1)), + ), +}) +@val external stringifyWithReplacer: (t, (string, t) => t) => string = "JSON.stringify" -@deprecated("Use `stringify` with optional parameters instead") @val +@deprecated({ + reason: "Use `JSON.stringify` with optional parameters instead", + migrate: JSON.stringify( + %insert.unlabelledArgument(0), + ~replacer=Replacer(%insert.unlabelledArgument(1)), + ~space=%insert.unlabelledArgument(2), + ), +}) +@val external stringifyWithReplacerAndIndent: (t, (string, t) => t, int) => string = "JSON.stringify" -@deprecated("Use `stringify` with optional parameter instead") @val +@deprecated({ + reason: "Use `JSON.stringify` with optional parameter instead", + migrate: JSON.stringify( + %insert.unlabelledArgument(0), + ~replacer=Keys(%insert.unlabelledArgument(1)), + ), +}) +@val external stringifyWithFilter: (t, array) => string = "JSON.stringify" -@deprecated("Use `stringify` with optional parameters instead") @val +@deprecated({ + reason: "Use `JSON.stringify` with optional parameters instead", + migrate: JSON.stringify( + %insert.unlabelledArgument(0), + ~replacer=Keys(%insert.unlabelledArgument(1)), + ~space=%insert.unlabelledArgument(2), + ), +}) +@val external stringifyWithFilterAndIndent: (t, array, int) => string = "JSON.stringify" @raises @val external stringifyAny: ('a, ~replacer: replacer=?, ~space: int=?) => option = "JSON.stringify" -@deprecated("Use `stringifyAny` with optional parameter instead") @raises @val +@deprecated({ + reason: "Use `JSON.stringifyAny` with optional parameter instead", + migrate: JSON.stringifyAny(%insert.unlabelledArgument(0), ~space=%insert.unlabelledArgument(2)), +}) +@raises +@val external stringifyAnyWithIndent: ('a, @as(json`null`) _, int) => option = "JSON.stringify" -@deprecated("Use `stringifyAny` with optional parameter instead") @raises @val +@deprecated({ + reason: "Use `JSON.stringifyAny` with optional parameter instead", + migrate: JSON.stringifyAny( + %insert.unlabelledArgument(0), + ~replacer=Replacer(%insert.unlabelledArgument(1)), + ), +}) +@raises +@val external stringifyAnyWithReplacer: ('a, (string, t) => t) => option = "JSON.stringify" -@deprecated("Use `stringifyAny` with optional parameters instead") @raises @val +@deprecated({ + reason: "Use `JSON.stringifyAny` with optional parameters instead", + migrate: JSON.stringifyAny( + %insert.unlabelledArgument(0), + ~replacer=Replacer(%insert.unlabelledArgument(1)), + ~space=%insert.unlabelledArgument(2), + ), +}) +@raises +@val external stringifyAnyWithReplacerAndIndent: ('a, (string, t) => t, int) => option = "JSON.stringify" -@deprecated("Use `stringifyAny` with optional parameter instead") @raises @val +@deprecated({ + reason: "Use `JSON.stringifyAny` with optional parameter instead", + migrate: JSON.stringifyAny( + %insert.unlabelledArgument(0), + ~replacer=Keys(%insert.unlabelledArgument(1)), + ), +}) +@raises +@val external stringifyAnyWithFilter: ('a, array) => string = "JSON.stringify" -@deprecated("Use `stringifyAny` with optional parameters instead") @raises @val +@deprecated({ + reason: "Use `JSON.stringifyAny` with optional parameters instead", + migrate: JSON.stringifyAny( + %insert.unlabelledArgument(0), + ~replacer=Keys(%insert.unlabelledArgument(1)), + ~space=%insert.unlabelledArgument(2), + ), +}) +@raises +@val external stringifyAnyWithFilterAndIndent: ('a, array, int) => string = "JSON.stringify" module Classify = { diff --git a/packages/@rescript/runtime/Stdlib_Uint16Array.res b/packages/@rescript/runtime/Stdlib_Uint16Array.res index a080ae7f41..af16a1e4b1 100644 --- a/packages/@rescript/runtime/Stdlib_Uint16Array.res +++ b/packages/@rescript/runtime/Stdlib_Uint16Array.res @@ -26,14 +26,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint16Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Uint16Array" /** `fromBufferWithRange` creates a `Uint16Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array/Uint16Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint16Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Uint16Array" @@ -51,7 +66,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => int=?) => t = "Uint16A /** `fromArrayLikeOrIterableWithMap` creates a `Uint16Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Uint16Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => int) => t = "Uint16Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Uint32Array.res b/packages/@rescript/runtime/Stdlib_Uint32Array.res index 27f5850be9..dd954a00fd 100644 --- a/packages/@rescript/runtime/Stdlib_Uint32Array.res +++ b/packages/@rescript/runtime/Stdlib_Uint32Array.res @@ -26,14 +26,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint32Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Uint32Array" /** `fromBufferWithRange` creates a `Uint32Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array/Uint32Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint32Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Uint32Array" @@ -51,7 +66,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => int=?) => t = "Uint32A /** `fromArrayLikeOrIterableWithMap` creates a `Uint32Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Uint32Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => int) => t = "Uint32Array.from" /** diff --git a/packages/@rescript/runtime/Stdlib_Uint8Array.res b/packages/@rescript/runtime/Stdlib_Uint8Array.res index 45519fe144..00e0acb2dd 100644 --- a/packages/@rescript/runtime/Stdlib_Uint8Array.res +++ b/packages/@rescript/runtime/Stdlib_Uint8Array.res @@ -26,14 +26,29 @@ external fromBuffer: (Stdlib_ArrayBuffer.t, ~byteOffset: int=?, ~length: int=?) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint8Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ), +}) +@new external fromBufferToEnd: (Stdlib_ArrayBuffer.t, ~byteOffset: int) => t = "Uint8Array" /** `fromBufferWithRange` creates a `Uint8Array` from an `ArrayBuffer.t`, starting at a particular offset and consuming `length` **bytes**. See [TypedArray constructor on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array/Uint8Array) **Note:** This is a potentially unsafe operation. Ensure the buffer is large enough and only accessed within its bounds. */ -@deprecated("Use `fromBuffer` instead") @new +@deprecated({ + reason: "Use `fromBuffer` instead", + migrate: Uint8Array.fromBuffer( + %insert.unlabelledArgument(0), + ~byteOffset=%insert.labelledArgument("byteOffset"), + ~length=%insert.labelledArgument("length"), + ), +}) +@new external fromBufferWithRange: (Stdlib_ArrayBuffer.t, ~byteOffset: int, ~length: int) => t = "Uint8Array" @@ -51,7 +66,14 @@ external fromArrayLikeOrIterable: ('a, ~map: ('b, int) => int=?) => t = "Uint8Ar /** `fromArrayLikeOrIterableWithMap` creates a `Uint8Array` from an array-like or iterable object and applies the mapping function to each item. The mapping function expects (value, index). See [TypedArray.from on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from) */ -@deprecated("Use `fromArrayLikeOrIterable` instead") @val +@deprecated({ + reason: "Use `fromArrayLikeOrIterable` instead", + migrate: Uint8Array.fromArrayLikeOrIterable( + %insert.unlabelledArgument(0), + ~map=%insert.unlabelledArgument(1), + ), +}) +@val external fromArrayLikeOrIterableWithMap: ('a, ('b, int) => int) => t = "Uint8Array.from" /** diff --git a/tests/tools_tests/src/expected/StdlibMigration_ArrayAppend.res.expected b/tests/tools_tests/src/expected/StdlibMigration_ArrayAppend.res.expected new file mode 100644 index 0000000000..3d3d701e8d --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_ArrayAppend.res.expected @@ -0,0 +1,3 @@ +let ys = Array.concat([1], [2]) +let zs = [1]->Array.concat([1], [2]) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_JSON_ParseStringify.res.expected b/tests/tools_tests/src/expected/StdlibMigration_JSON_ParseStringify.res.expected new file mode 100644 index 0000000000..5711d673ac --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_JSON_ParseStringify.res.expected @@ -0,0 +1,15 @@ +let p1 = JSON.parseExn("{}", ~reviver=(k, v) => v) +let p2 = JSON.parseExnWithReviver("{}", (k, v) => v) + +let s1 = JSON.stringifyWithIndent(JSON.Object(dict{}), 2) +let s2 = JSON.stringifyWithReplacer(JSON.Number(1.), (k, v) => v) +let s3 = JSON.stringifyWithReplacerAndIndent(JSON.Boolean(true), (k, v) => v, 2) +let s4 = JSON.stringifyWithFilter(JSON.Array([JSON.Number(1.)]), ["a"]) +let s5 = JSON.stringifyWithFilterAndIndent(JSON.Array([JSON.Number(1.)]), ["a"], 2) + +let a1 = JSON.stringifyAnyWithIndent(1, 2) +let a2 = JSON.stringifyAnyWithReplacer(1, (k, v) => v) +let a3 = JSON.stringifyAnyWithReplacerAndIndent(1, (k, v) => v, 2) +let a4 = JSON.stringifyAnyWithFilter(1, ["a"]) +let a5 = JSON.stringifyAnyWithFilterAndIndent(1, ["a"], 2) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_JSON_Stdlib.res.expected b/tests/tools_tests/src/expected/StdlibMigration_JSON_Stdlib.res.expected new file mode 100644 index 0000000000..5711d673ac --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_JSON_Stdlib.res.expected @@ -0,0 +1,15 @@ +let p1 = JSON.parseExn("{}", ~reviver=(k, v) => v) +let p2 = JSON.parseExnWithReviver("{}", (k, v) => v) + +let s1 = JSON.stringifyWithIndent(JSON.Object(dict{}), 2) +let s2 = JSON.stringifyWithReplacer(JSON.Number(1.), (k, v) => v) +let s3 = JSON.stringifyWithReplacerAndIndent(JSON.Boolean(true), (k, v) => v, 2) +let s4 = JSON.stringifyWithFilter(JSON.Array([JSON.Number(1.)]), ["a"]) +let s5 = JSON.stringifyWithFilterAndIndent(JSON.Array([JSON.Number(1.)]), ["a"], 2) + +let a1 = JSON.stringifyAnyWithIndent(1, 2) +let a2 = JSON.stringifyAnyWithReplacer(1, (k, v) => v) +let a3 = JSON.stringifyAnyWithReplacerAndIndent(1, (k, v) => v, 2) +let a4 = JSON.stringifyAnyWithFilter(1, ["a"]) +let a5 = JSON.stringifyAnyWithFilterAndIndent(1, ["a"], 2) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected index 8eb9b9cb94..6451db2701 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Result.res.expected @@ -1,2 +1,3 @@ +type r = result let res: result = Ok(1) diff --git a/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Constructors.res.expected b/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Constructors.res.expected new file mode 100644 index 0000000000..d91e6d05d6 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Constructors.res.expected @@ -0,0 +1,4 @@ +let a = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2) +let b = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) +let c = Uint8Array.fromArrayLikeOrIterable([1, 2], ~map=(v, i) => v) + diff --git a/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Stdlib.res.expected b/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Stdlib.res.expected new file mode 100644 index 0000000000..d91e6d05d6 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_TypedArray_Stdlib.res.expected @@ -0,0 +1,4 @@ +let a = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2) +let b = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) +let c = Uint8Array.fromArrayLikeOrIterable([1, 2], ~map=(v, i) => v) + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_JSON_Stdlib.res b/tests/tools_tests/src/migrate/StdlibMigration_JSON_Stdlib.res new file mode 100644 index 0000000000..ea62bd0294 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_JSON_Stdlib.res @@ -0,0 +1,14 @@ +let p1 = JSON.parseExn("{}", ~reviver=(k, v) => v) +let p2 = JSON.parseExnWithReviver("{}", (k, v) => v) + +let s1 = JSON.stringifyWithIndent(JSON.Object(dict{}), 2) +let s2 = JSON.stringifyWithReplacer(JSON.Number(1.), (k, v) => v) +let s3 = JSON.stringifyWithReplacerAndIndent(JSON.Boolean(true), (k, v) => v, 2) +let s4 = JSON.stringifyWithFilter(JSON.Array([JSON.Number(1.)]), ["a"]) +let s5 = JSON.stringifyWithFilterAndIndent(JSON.Array([JSON.Number(1.)]), ["a"], 2) + +let a1 = JSON.stringifyAnyWithIndent(1, 2) +let a2 = JSON.stringifyAnyWithReplacer(1, (k, v) => v) +let a3 = JSON.stringifyAnyWithReplacerAndIndent(1, (k, v) => v, 2) +let a4 = JSON.stringifyAnyWithFilter(1, ["a"]) +let a5 = JSON.stringifyAnyWithFilterAndIndent(1, ["a"], 2) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Result.res b/tests/tools_tests/src/migrate/StdlibMigration_Result.res index fa13b37e34..ed79392944 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_Result.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_Result.res @@ -1 +1,2 @@ +type r = Js.Result.t let res: Js.Result.t = Ok(1) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_TypedArray_Stdlib.res b/tests/tools_tests/src/migrate/StdlibMigration_TypedArray_Stdlib.res new file mode 100644 index 0000000000..7d60393ab3 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_TypedArray_Stdlib.res @@ -0,0 +1,3 @@ +let a = Uint8Array.fromBufferToEnd(ArrayBuffer.make(8), ~byteOffset=2) +let b = Uint8Array.fromBufferWithRange(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) +let c = Uint8Array.fromArrayLikeOrIterableWithMap([1, 2], (v, i) => v) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON_Stdlib.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON_Stdlib.res new file mode 100644 index 0000000000..8c0e689c9f --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_JSON_Stdlib.res @@ -0,0 +1,16 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_JSON_Stdlib.res. +let p1 = JSON.parseExn("{}", ~reviver=(k, v) => v) +let p2 = JSON.parseExnWithReviver("{}", (k, v) => v) + +let s1 = JSON.stringifyWithIndent(JSON.Object(dict{}), 2) +let s2 = JSON.stringifyWithReplacer(JSON.Number(1.), (k, v) => v) +let s3 = JSON.stringifyWithReplacerAndIndent(JSON.Boolean(true), (k, v) => v, 2) +let s4 = JSON.stringifyWithFilter(JSON.Array([JSON.Number(1.)]), ["a"]) +let s5 = JSON.stringifyWithFilterAndIndent(JSON.Array([JSON.Number(1.)]), ["a"], 2) + +let a1 = JSON.stringifyAnyWithIndent(1, 2) +let a2 = JSON.stringifyAnyWithReplacer(1, (k, v) => v) +let a3 = JSON.stringifyAnyWithReplacerAndIndent(1, (k, v) => v, 2) +let a4 = JSON.stringifyAnyWithFilter(1, ["a"]) +let a5 = JSON.stringifyAnyWithFilterAndIndent(1, ["a"], 2) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res index dfd2a7de62..8047545816 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Result.res @@ -1,3 +1,4 @@ // This file is autogenerated so it can be type checked. // It's the migrated version of src/migrate/StdlibMigration_Result.res. +type r = result let res: result = Ok(1) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_TypedArray_Stdlib.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_TypedArray_Stdlib.res new file mode 100644 index 0000000000..e8f2e0ace8 --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_TypedArray_Stdlib.res @@ -0,0 +1,5 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_TypedArray_Stdlib.res. +let a = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2) +let b = Uint8Array.fromBuffer(ArrayBuffer.make(8), ~byteOffset=2, ~length=2) +let c = Uint8Array.fromArrayLikeOrIterable([1, 2], ~map=(v, i) => v) From 6d1169de062058c6d7ff435e8ce68880d3726127 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Mon, 1 Sep 2025 20:53:30 +0200 Subject: [PATCH 32/41] remove unused Match template --- tools/src/migrate.ml | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index 05d0f574bf..02cb648cc4 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -353,7 +353,6 @@ module Template = struct partial: bool; transformed_jsx: bool; } - | Match of {expr: Parsetree.expression; cases: Parsetree.case list} let attach attrs e = MapperUtils.ApplyTransforms.attach_to_replacement ~attrs e @@ -370,8 +369,6 @@ module Template = struct | _ -> args in Some (Apply {funct; args = args'; partial; transformed_jsx}) - | {Parsetree.pexp_desc = Pexp_match (expr, cases)} -> - Some (Match {expr; cases}) | _ -> None let of_expr_with_attrs (e : Parsetree.expression) : @@ -387,16 +384,6 @@ module Template = struct let apply_direct ~mapper ~template ~template_attrs ~call_args (exp : Parsetree.expression) = match template with - | Match {expr; cases} -> - let res = - { - exp with - pexp_desc = - Pexp_match - (MapperUtils.replace_placeholders_in_expr expr call_args, cases); - } - in - attach template_attrs res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -412,16 +399,6 @@ module Template = struct let apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct (exp : Parsetree.expression) = match template with - | Match {expr; cases} -> - let res = - { - exp with - pexp_desc = - Pexp_match - (MapperUtils.replace_placeholders_in_expr expr [lhs], cases); - } - in - attach template_attrs res | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -439,8 +416,6 @@ module Template = struct let apply_piped_maybe_empty ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct (exp : Parsetree.expression) = match template with - | Match _ -> - apply_piped ~mapper ~template ~template_attrs ~lhs ~pipe_args ~funct exp | Apply {funct = template_funct; args = template_args; partial; transformed_jsx} -> @@ -470,15 +445,6 @@ module Template = struct let apply_single_pipe_collapse ~mapper ~template ~template_attrs ~lhs_exp ~pipe_args (exp : Parsetree.expression) = match template with - | Match {expr; cases} -> - let res = - Ast_helper.Exp.match_ - (MapperUtils.replace_placeholders_in_expr expr - ((Asttypes.Nolabel, lhs_exp) - :: ArgUtils.map_expr_args mapper pipe_args)) - cases - in - attach template_attrs res | Apply { funct = templ_f; From 1b4f4bef34f58f558ff601285be88a7014fda4ad Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 15:53:01 +0200 Subject: [PATCH 33/41] more migrations --- packages/@rescript/runtime/Js_array2.res | 4 ++++ .../src/expected/StdlibMigration_Array.res.expected | 2 +- .../src/expected/StdlibMigration_BigInt.res.expected | 1 + tests/tools_tests/src/migrate/StdlibMigration_BigInt.res | 1 + .../src/migrate/migrated/Migrated_StdlibMigration_Array.res | 2 +- .../src/migrate/migrated/Migrated_StdlibMigration_BigInt.res | 1 + 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/@rescript/runtime/Js_array2.res b/packages/@rescript/runtime/Js_array2.res index 3a35e3aeb6..2dfc1238be 100644 --- a/packages/@rescript/runtime/Js_array2.res +++ b/packages/@rescript/runtime/Js_array2.res @@ -63,6 +63,10 @@ type t<'a> = array<'a> /** A type used to describe JavaScript objects that are like an array or are iterable. */ +@deprecated({ + reason: "Use `Array.arrayLike` directly instead.", + migrate: %replace.type(: Array.arrayLike), +}) type array_like<'a> = Stdlib_Array.arrayLike<'a> /* commented out until bs has a plan for iterators diff --git a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected index b191cec284..e2c93c904b 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Array.res.expected @@ -4,7 +4,7 @@ let shift2 = Array.shift([1, 2, 3]) let slice1 = [1, 2, 3]->Array.slice(~start=1, ~end=2) let slice2 = Array.slice([1, 2, 3], ~start=1, ~end=2) -external someArrayLike: Js_array2.array_like = "whatever" +external someArrayLike: Array.arrayLike = "whatever" let from1 = someArrayLike->Array.fromArrayLike let from2 = Array.fromArrayLike(someArrayLike) diff --git a/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected index 727a58ab09..f6ef79a8fa 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_BigInt.res.expected @@ -3,6 +3,7 @@ let fromStringExn2 = BigInt.fromStringOrThrow("123") let land1 = 7n & 4n let land2 = 7n & 4n +let land3 = 7n->BigInt.toString->BigInt.fromStringOrThrow->BigInt.bitwiseAnd(4n) let lor1 = 7n->BigInt.bitwiseOr(4n) let lor2 = BigInt.bitwiseOr(7n, 4n) diff --git a/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res b/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res index 219f3dd56f..4503044abc 100644 --- a/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res +++ b/tests/tools_tests/src/migrate/StdlibMigration_BigInt.res @@ -3,6 +3,7 @@ let fromStringExn2 = Js.BigInt.fromStringExn("123") let land1 = 7n->Js.BigInt.land(4n) let land2 = Js.BigInt.land(7n, 4n) +let land3 = 7n->Js.BigInt.toString->Js.BigInt.fromStringExn->Js.BigInt.land(4n) let lor1 = 7n->Js.BigInt.lor(4n) let lor2 = Js.BigInt.lor(7n, 4n) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res index 0e93e4060d..47ceb8cd25 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res @@ -6,7 +6,7 @@ let shift2 = Array.shift([1, 2, 3]) let slice1 = [1, 2, 3]->Array.slice(~start=1, ~end=2) let slice2 = Array.slice([1, 2, 3], ~start=1, ~end=2) -external someArrayLike: Js_array2.array_like = "whatever" +external someArrayLike: Array.arrayLike = "whatever" let from1 = someArrayLike->Array.fromArrayLike let from2 = Array.fromArrayLike(someArrayLike) diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res index 846cb3d7ae..ead6d51481 100644 --- a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_BigInt.res @@ -5,6 +5,7 @@ let fromStringExn2 = BigInt.fromStringOrThrow("123") let land1 = 7n & 4n let land2 = 7n & 4n +let land3 = 7n->BigInt.toString->BigInt.fromStringOrThrow->BigInt.bitwiseAnd(4n) let lor1 = 7n->BigInt.bitwiseOr(4n) let lor2 = BigInt.bitwiseOr(7n, 4n) From 82c3b520208a471060192b0ed31d897578602dbe Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 15:57:46 +0200 Subject: [PATCH 34/41] update test fixtures --- rewatch/tests/snapshots/dependency-cycle.txt | 20 +++++++++---------- rewatch/tests/snapshots/remove-file.txt | 20 +++++++++---------- rewatch/tests/snapshots/rename-file.txt | 20 +++++++++---------- .../tests/snapshots/rename-interface-file.txt | 20 +++++++++---------- .../expected/dict_coercion.res.expected | 11 +++++----- .../expected/dict_inference.res.expected | 14 +++++-------- .../super_errors/fixtures/dict_coercion.res | 6 +++--- .../super_errors/fixtures/dict_inference.res | 8 ++++---- 8 files changed, 57 insertions(+), 62 deletions(-) diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 2e2412a38f..ad89ae975c 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -2,16 +2,6 @@ Cleaned 0/110 Parsed 6 source files Compiled 2 modules - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -64,6 +54,16 @@ Compiled 2 modules Use `Array.joinUnsafe` instead. + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index d1ed672e27..131b34560b 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -2,6 +2,16 @@ Cleaned 0/110 Parsed 4 source files Compiled 5 modules + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,16 +64,6 @@ Compiled 5 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep01/src/Dep01.res:2:9-14 diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index b4c542aab9..4c79d58f47 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -2,6 +2,16 @@ Cleaned 0/110 Parsed 5 source files Compiled 5 modules + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,16 +64,6 @@ Compiled 5 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index ef2ff1a174..d75803b2ae 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -3,16 +3,6 @@ Cleaned 1/110 Parsed 6 source files Compiled 7 modules - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -65,6 +55,16 @@ Compiled 7 modules Use `Array.joinUnsafe` instead. + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/tests/build_tests/super_errors/expected/dict_coercion.res.expected b/tests/build_tests/super_errors/expected/dict_coercion.res.expected index 5e7889860a..d616487f83 100644 --- a/tests/build_tests/super_errors/expected/dict_coercion.res.expected +++ b/tests/build_tests/super_errors/expected/dict_coercion.res.expected @@ -1,10 +1,9 @@ We've found a bug for you! - /.../fixtures/dict_coercion.res:7:10-30 + /.../fixtures/dict_coercion.res:1:12-21 - 5 │ type fakeDict<'t> = {dictValuesType?: 't} - 6 │ - 7 │ let d = (dict :> fakeDict) - 8 │ + 1 │ let dict = Dict.empty() + 2 │ dict->Dict.set("someKey1", 1) + 3 │ dict->Dict.set("someKey2", 2) - Type Js.Dict.t = dict is not a subtype of fakeDict \ No newline at end of file + The value empty can't be found in Dict \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/dict_inference.res.expected b/tests/build_tests/super_errors/expected/dict_inference.res.expected index d7a4a84f49..c1b8bea66a 100644 --- a/tests/build_tests/super_errors/expected/dict_inference.res.expected +++ b/tests/build_tests/super_errors/expected/dict_inference.res.expected @@ -1,13 +1,9 @@ We've found a bug for you! - /.../fixtures/dict_inference.res:4:31-33 + /.../fixtures/dict_inference.res:1:12-21 - 2 │ dict->Js.Dict.set("someKey1", 1) - 3 │ dict->Js.Dict.set("someKey2", 2) - 4 │ dict->Js.Dict.set("someKey2", "2") - 5 │ + 1 │ let dict = Dict.empty() + 2 │ dict->Dict.set("someKey1", 1) + 3 │ dict->Dict.set("someKey2", 2) - This has type: string - But this function argument is expecting: int - - You can convert string to int with Int.fromString. \ No newline at end of file + The value empty can't be found in Dict \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/dict_coercion.res b/tests/build_tests/super_errors/fixtures/dict_coercion.res index b58fe32d9a..f33a252b57 100644 --- a/tests/build_tests/super_errors/fixtures/dict_coercion.res +++ b/tests/build_tests/super_errors/fixtures/dict_coercion.res @@ -1,6 +1,6 @@ -let dict = Js.Dict.empty() -dict->Js.Dict.set("someKey1", 1) -dict->Js.Dict.set("someKey2", 2) +let dict = Dict.empty() +dict->Dict.set("someKey1", 1) +dict->Dict.set("someKey2", 2) type fakeDict<'t> = {dictValuesType?: 't} diff --git a/tests/build_tests/super_errors/fixtures/dict_inference.res b/tests/build_tests/super_errors/fixtures/dict_inference.res index 703f0c672e..e2165df8fa 100644 --- a/tests/build_tests/super_errors/fixtures/dict_inference.res +++ b/tests/build_tests/super_errors/fixtures/dict_inference.res @@ -1,4 +1,4 @@ -let dict = Js.Dict.empty() -dict->Js.Dict.set("someKey1", 1) -dict->Js.Dict.set("someKey2", 2) -dict->Js.Dict.set("someKey2", "2") +let dict = Dict.empty() +dict->Dict.set("someKey1", 1) +dict->Dict.set("someKey2", 2) +dict->Dict.set("someKey2", "2") From deb56cb355a404d369281820ed179485398d4899 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 15:58:25 +0200 Subject: [PATCH 35/41] update test fixtures --- .../super_errors/expected/dict_coercion.res.expected | 11 ++++++----- .../super_errors/expected/dict_inference.res.expected | 10 +++++++--- .../super_errors/fixtures/dict_coercion.res | 2 +- .../super_errors/fixtures/dict_inference.res | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/tests/build_tests/super_errors/expected/dict_coercion.res.expected b/tests/build_tests/super_errors/expected/dict_coercion.res.expected index d616487f83..2007f230da 100644 --- a/tests/build_tests/super_errors/expected/dict_coercion.res.expected +++ b/tests/build_tests/super_errors/expected/dict_coercion.res.expected @@ -1,9 +1,10 @@ We've found a bug for you! - /.../fixtures/dict_coercion.res:1:12-21 + /.../fixtures/dict_coercion.res:7:10-30 - 1 │ let dict = Dict.empty() - 2 │ dict->Dict.set("someKey1", 1) - 3 │ dict->Dict.set("someKey2", 2) + 5 │ type fakeDict<'t> = {dictValuesType?: 't} + 6 │ + 7 │ let d = (dict :> fakeDict) + 8 │ - The value empty can't be found in Dict \ No newline at end of file + Type dict is not a subtype of fakeDict \ No newline at end of file diff --git a/tests/build_tests/super_errors/expected/dict_inference.res.expected b/tests/build_tests/super_errors/expected/dict_inference.res.expected index c1b8bea66a..05533fed97 100644 --- a/tests/build_tests/super_errors/expected/dict_inference.res.expected +++ b/tests/build_tests/super_errors/expected/dict_inference.res.expected @@ -1,9 +1,13 @@ We've found a bug for you! - /.../fixtures/dict_inference.res:1:12-21 + /.../fixtures/dict_inference.res:4:28-30 - 1 │ let dict = Dict.empty() 2 │ dict->Dict.set("someKey1", 1) 3 │ dict->Dict.set("someKey2", 2) + 4 │ dict->Dict.set("someKey2", "2") + 5 │ - The value empty can't be found in Dict \ No newline at end of file + This has type: string + But this function argument is expecting: int + + You can convert string to int with Int.fromString. \ No newline at end of file diff --git a/tests/build_tests/super_errors/fixtures/dict_coercion.res b/tests/build_tests/super_errors/fixtures/dict_coercion.res index f33a252b57..764006ad7b 100644 --- a/tests/build_tests/super_errors/fixtures/dict_coercion.res +++ b/tests/build_tests/super_errors/fixtures/dict_coercion.res @@ -1,4 +1,4 @@ -let dict = Dict.empty() +let dict = Dict.make() dict->Dict.set("someKey1", 1) dict->Dict.set("someKey2", 2) diff --git a/tests/build_tests/super_errors/fixtures/dict_inference.res b/tests/build_tests/super_errors/fixtures/dict_inference.res index e2165df8fa..b57243cf77 100644 --- a/tests/build_tests/super_errors/fixtures/dict_inference.res +++ b/tests/build_tests/super_errors/fixtures/dict_inference.res @@ -1,4 +1,4 @@ -let dict = Dict.empty() +let dict = Dict.make() dict->Dict.set("someKey1", 1) dict->Dict.set("someKey2", 2) dict->Dict.set("someKey2", "2") From 866eea75138b700f807f5794693a2e4e94ec9172 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 16:02:56 +0200 Subject: [PATCH 36/41] more fixtures --- ...-dev-dependency-used-by-non-dev-source.txt | 20 ++++++++-------- rewatch/tests/snapshots/dependency-cycle.txt | 20 ++++++++-------- rewatch/tests/snapshots/remove-file.txt | 24 +++++++++---------- .../snapshots/rename-file-internal-dep.txt | 20 ++++++++-------- .../snapshots/rename-file-with-interface.txt | 20 ++++++++-------- rewatch/tests/snapshots/rename-file.txt | 20 ++++++++-------- .../tests/snapshots/rename-interface-file.txt | 20 ++++++++-------- 7 files changed, 72 insertions(+), 72 deletions(-) diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index e919bf8438..9d74512d9e 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -2,16 +2,6 @@ Cleaned 0/113 Parsed 4 source files Compiled 3 modules - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -64,6 +54,16 @@ Compiled 3 modules Use `Array.joinUnsafe` instead. + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index ad89ae975c..2e2412a38f 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -2,6 +2,16 @@ Cleaned 0/110 Parsed 6 source files Compiled 2 modules + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,16 +64,6 @@ Compiled 2 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index 131b34560b..8840c8dd9e 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -12,6 +12,18 @@ Compiled 5 modules Use `Console.log` instead. + Warning number 3 + /packages/dep01/src/Dep01.res:2:9-14 + + 1 │ let log = () => { + 2 │ Js.log("02") + 3 │ Dep02.log() + 4 │ } + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -64,18 +76,6 @@ Compiled 5 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/main/src/Main.res:1:1-6 diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index 06ab229ea1..bfac3225cd 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -2,16 +2,6 @@ Cleaned 1/110 Parsed 6 source files Compiled 8 modules - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -64,6 +54,16 @@ Compiled 8 modules Use `Array.joinUnsafe` instead. + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index a4e563ccaa..dbdeb91f7f 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -3,6 +3,16 @@ Cleaned 2/110 Parsed 6 source files Compiled 7 modules + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -55,16 +65,6 @@ Compiled 7 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index 4c79d58f47..b4c542aab9 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -2,16 +2,6 @@ Cleaned 0/110 Parsed 5 source files Compiled 5 modules - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -64,6 +54,16 @@ Compiled 5 modules Use `Array.joinUnsafe` instead. + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index d75803b2ae..ef2ff1a174 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -3,6 +3,16 @@ Cleaned 1/110 Parsed 6 source files Compiled 7 modules + Warning number 3 + /packages/new-namespace/src/Other_module.res:1:17-22 + + 1 │ let bla = () => Js.log("bla") + 2 │ + + deprecated: Js.log + Use `Console.log` instead. + + Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -55,16 +65,6 @@ Compiled 7 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 From d95b2a7b907cc5a968a85156cb448ad38dbd78be Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 16:11:26 +0200 Subject: [PATCH 37/41] remove --- rewatch/testrepo/packages/main/src/Main2.mjs | 20 ---- .../new-namespace/src/Other_module.res | 2 +- .../new-namespace/src/Other_module2.mjs | 11 --- ...-dev-dependency-used-by-non-dev-source.txt | 14 +-- rewatch/tests/snapshots/dependency-cycle.txt | 16 +--- rewatch/tests/snapshots/remove-file.txt | 16 +--- .../rename-file-internal-dep-namespace.txt | 92 ++++--------------- .../snapshots/rename-file-internal-dep.txt | 16 +--- .../snapshots/rename-file-with-interface.txt | 16 +--- rewatch/tests/snapshots/rename-file.txt | 16 +--- .../tests/snapshots/rename-interface-file.txt | 16 +--- 11 files changed, 41 insertions(+), 194 deletions(-) delete mode 100644 rewatch/testrepo/packages/main/src/Main2.mjs delete mode 100644 rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs diff --git a/rewatch/testrepo/packages/main/src/Main2.mjs b/rewatch/testrepo/packages/main/src/Main2.mjs deleted file mode 100644 index e4df550c4b..0000000000 --- a/rewatch/testrepo/packages/main/src/Main2.mjs +++ /dev/null @@ -1,20 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - -import * as Dep01 from "@testrepo/dep01/src/Dep01.mjs"; -import * as InternalDep from "./InternalDep.mjs"; - -console.log("01"); - -Dep01.log(); - -console.log(InternalDep.value); - -let $$Array; - -let $$String; - -export { - $$Array, - $$String, -} -/* Not a pure module */ diff --git a/rewatch/testrepo/packages/new-namespace/src/Other_module.res b/rewatch/testrepo/packages/new-namespace/src/Other_module.res index b265646f33..fe8c6a7fcb 100644 --- a/rewatch/testrepo/packages/new-namespace/src/Other_module.res +++ b/rewatch/testrepo/packages/new-namespace/src/Other_module.res @@ -1 +1 @@ -let bla = () => Js.log("bla") +let bla = () => Console.log("bla") diff --git a/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs b/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs deleted file mode 100644 index 0f2f321053..0000000000 --- a/rewatch/testrepo/packages/new-namespace/src/Other_module2.mjs +++ /dev/null @@ -1,11 +0,0 @@ -// Generated by ReScript, PLEASE EDIT WITH CARE - - -function bla() { - console.log("bla"); -} - -export { - bla, -} -/* No side effect */ diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index 9d74512d9e..14f5ab8751 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -1,5 +1,5 @@ -Cleaned 0/113 -Parsed 4 source files +Cleaned 0/114 +Parsed 3 source files Compiled 3 modules Warning number 3 @@ -54,16 +54,6 @@ Compiled 3 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 2e2412a38f..5d4caa1d7c 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,16 +1,6 @@ -Cleaned 0/110 -Parsed 6 source files -Compiled 2 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 0/111 +Parsed 5 source files +Compiled 1 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index 8840c8dd9e..a5d30d692a 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,16 +1,6 @@ -Cleaned 0/110 -Parsed 4 source files -Compiled 5 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 0/111 +Parsed 3 source files +Compiled 3 modules Warning number 3 /packages/dep01/src/Dep01.res:2:9-14 diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt index c54b428e24..5ebd406dce 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt @@ -1,6 +1,6 @@ -Cleaned 1/111 +Cleaned 2/112 Parsed 5 source files -Compiled 7 modules +Compiled 4 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,76 +54,6 @@ Compiled 7 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module2.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -133,3 +63,21 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. + + We've found a bug for you! + /packages/new-namespace/src/NS_alias.res:2:1-16 + + 1 │ let hello_world = () => "Hello world" + 2 │ Other_module.bla() + 3 │ + + The module or file Other_module can't be found. + - If it's a third-party dependency: + - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? + + + Hint: Did you mean Other_module2? + + +Incremental build failed. Error:  Failed to Compile. See Errors Above diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index bfac3225cd..38fab94155 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,6 +1,6 @@ -Cleaned 1/110 -Parsed 6 source files -Compiled 8 modules +Cleaned 1/111 +Parsed 5 source files +Compiled 5 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,16 +54,6 @@ Compiled 8 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index dbdeb91f7f..e7d1a0157a 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,17 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/110 -Parsed 6 source files -Compiled 7 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 2/111 +Parsed 5 source files +Compiled 5 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index b4c542aab9..d667900122 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,6 +1,6 @@ -Cleaned 0/110 -Parsed 5 source files -Compiled 5 modules +Cleaned 0/111 +Parsed 4 source files +Compiled 4 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 @@ -54,16 +54,6 @@ Compiled 5 modules Use `Array.joinUnsafe` instead. - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - - Warning number 3 /packages/dep02/src/Dep02.res:2:37-42 diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index ef2ff1a174..cf6be97e84 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,17 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/110 -Parsed 6 source files -Compiled 7 modules - - Warning number 3 - /packages/new-namespace/src/Other_module.res:1:17-22 - - 1 │ let bla = () => Js.log("bla") - 2 │ - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 1/111 +Parsed 5 source files +Compiled 5 modules Warning number 3 /packages/dep02/src/Array.res:6:16-33 From cd5e1a3152fe9620be75e9697b73215f3801bf98 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 16:19:16 +0200 Subject: [PATCH 38/41] more --- rewatch/testrepo/packages/dep01/src/Dep01.res | 2 +- rewatch/testrepo/packages/dep02/src/Array.mjs | 5 +- rewatch/testrepo/packages/dep02/src/Array.res | 14 +-- rewatch/testrepo/packages/dep02/src/Dep02.res | 4 +- .../with-dev-deps/test/FileToTest_test.res | 2 +- ...-dev-dependency-used-by-non-dev-source.txt | 59 +-------- rewatch/tests/snapshots/dependency-cycle.txt | 59 +-------- rewatch/tests/snapshots/remove-file.txt | 113 ++++-------------- .../rename-file-internal-dep-namespace.txt | 59 +-------- .../snapshots/rename-file-internal-dep.txt | 95 +-------------- .../snapshots/rename-file-with-interface.txt | 94 +-------------- rewatch/tests/snapshots/rename-file.txt | 94 +-------------- .../tests/snapshots/rename-interface-file.txt | 94 +-------------- 13 files changed, 55 insertions(+), 639 deletions(-) diff --git a/rewatch/testrepo/packages/dep01/src/Dep01.res b/rewatch/testrepo/packages/dep01/src/Dep01.res index f3b84140c1..6868ee6495 100644 --- a/rewatch/testrepo/packages/dep01/src/Dep01.res +++ b/rewatch/testrepo/packages/dep01/src/Dep01.res @@ -1,4 +1,4 @@ let log = () => { - Js.log("02") + Console.log("02") Dep02.log() } diff --git a/rewatch/testrepo/packages/dep02/src/Array.mjs b/rewatch/testrepo/packages/dep02/src/Array.mjs index 8b7653917d..833aba905f 100644 --- a/rewatch/testrepo/packages/dep02/src/Array.mjs +++ b/rewatch/testrepo/packages/dep02/src/Array.mjs @@ -1,6 +1,5 @@ // Generated by ReScript, PLEASE EDIT WITH CARE -import * as Js_array from "@rescript/runtime/lib/es6/Js_array.js"; import * as Belt_Array from "@rescript/runtime/lib/es6/Belt_Array.js"; import * as Belt_SortArray from "@rescript/runtime/lib/es6/Belt_SortArray.js"; import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js"; @@ -46,11 +45,11 @@ function flatten(t) { } function find(t, fn) { - return Js_array.find(fn, t); + return fn.find(t); } function findIndex(t, fn) { - return Js_array.findIndex(fn, t); + return fn.findIndex(t); } function filter(prim0, prim1) { diff --git a/rewatch/testrepo/packages/dep02/src/Array.res b/rewatch/testrepo/packages/dep02/src/Array.res index 60e6fe5d10..0f4ee137cb 100644 --- a/rewatch/testrepo/packages/dep02/src/Array.res +++ b/rewatch/testrepo/packages/dep02/src/Array.res @@ -3,7 +3,7 @@ include Belt.Array let at = get -let includes = Js.Array2.includes +let includes = Array.includes let head = t => t->get(0) @@ -21,15 +21,15 @@ let prepend = (t, v) => [v]->concat(t) let flatMap = (t, fn) => t->map(fn)->concatMany -let mapi = Js.Array2.mapi +let mapi = Array.mapWithIndex let flatten = t => t->flatMap(x => x) -let find = (t, fn) => Js.Array.find(fn, t) +let find = (t, fn) => Array.find(fn, t) -let findIndex = (t, fn) => Js.Array.findIndex(fn, t) +let findIndex = (t, fn) => Array.findIndex(fn, t) -let filter = Js.Array2.filter +let filter = Array.filter let reject = (t, fn) => t->filter(el => !fn(el)) @@ -45,7 +45,7 @@ let sortBy = (t, fn) => let sortByRaw = Belt.SortArray.stableSortBy module String = { - let joinWith = Js.Array2.joinWith + let joinWith = Array.join let join = joinWith(_, "") } @@ -164,7 +164,7 @@ let drop = (t, i) => { t->sliceToEnd(start) } -let unsafePop = Js.Array.pop +let unsafePop = Array.pop module Int = { let sum = xs => reduce(xs, 0, (a, b) => a + b) diff --git a/rewatch/testrepo/packages/dep02/src/Dep02.res b/rewatch/testrepo/packages/dep02/src/Dep02.res index e832615245..55c756ac60 100644 --- a/rewatch/testrepo/packages/dep02/src/Dep02.res +++ b/rewatch/testrepo/packages/dep02/src/Dep02.res @@ -1,3 +1,3 @@ open Array -let log = () => ["a", "b"]->forEach(Js.log) -Js.log(NS.Alias.hello_world()) +let log = () => ["a", "b"]->forEach(Console.log) +Console.log(NS.Alias.hello_world()) diff --git a/rewatch/testrepo/packages/with-dev-deps/test/FileToTest_test.res b/rewatch/testrepo/packages/with-dev-deps/test/FileToTest_test.res index 45c4bf01a4..04b846d3ee 100644 --- a/rewatch/testrepo/packages/with-dev-deps/test/FileToTest_test.res +++ b/rewatch/testrepo/packages/with-dev-deps/test/FileToTest_test.res @@ -2,5 +2,5 @@ let res = FileToTest.add(1, 2) let expected = 3 if res !== expected { - failwith("Expected " ++ expected->Js.Int.toString ++ ", got " ++ res->Js.Int.toString) + failwith("Expected " ++ expected->Int.toString ++ ", got " ++ res->Int.toString) } diff --git a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt index 14f5ab8751..fcf2118183 100644 --- a/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt +++ b/rewatch/tests/snapshots/bs-dev-dependency-used-by-non-dev-source.txt @@ -1,59 +1,6 @@ -Cleaned 0/114 -Parsed 3 source files -Compiled 3 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - +Cleaned 0/115 +Parsed 2 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 5d4caa1d7c..7651c5636d 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,59 +1,6 @@ -Cleaned 0/111 -Parsed 5 source files -Compiled 1 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - +Cleaned 0/114 +Parsed 2 source files +Compiled 0 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index a5d30d692a..57f673688a 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,95 +1,6 @@ -Cleaned 0/111 -Parsed 3 source files -Compiled 3 modules - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 1/114 +Parsed 1 source files +Compiled 1 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. @@ -99,3 +10,21 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. + + We've found a bug for you! + /packages/dep01/src/Dep01.res:3:9-17 + + 1 │ let log = () => { + 2 │ Console.log("02") + 3 │ Dep02.log() + 4 │ } + 5 │ + + The module or file Dep02 can't be found. + - If it's a third-party dependency: + - Did you add it to the "dependencies" or "dev-dependencies" in rescript.json? + - Did you include the file's directory to the "sources" in rescript.json? + + + +Incremental build failed. Error:  Failed to Compile. See Errors Above diff --git a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt index 5ebd406dce..17dcaaf94c 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep-namespace.txt @@ -1,59 +1,6 @@ -Cleaned 2/112 -Parsed 5 source files -Compiled 4 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - +Cleaned 2/115 +Parsed 2 source files +Compiled 3 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index 38fab94155..047eab0e92 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,95 +1,6 @@ -Cleaned 1/111 -Parsed 5 source files -Compiled 5 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 1/114 +Parsed 2 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index e7d1a0157a..a738c69e20 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,95 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/111 -Parsed 5 source files -Compiled 5 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 2/114 +Parsed 2 source files +Compiled 2 modules Warning number 3 /packages/main/src/Main.res:1:1-6 diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index d667900122..0ae2d00652 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,94 +1,6 @@ -Cleaned 0/111 -Parsed 4 source files -Compiled 4 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 0/114 +Parsed 1 source files +Compiled 1 modules Warning number 3 /packages/main/src/Main2.res:1:1-6 diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index cf6be97e84..8a8928aec5 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,95 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/111 -Parsed 5 source files -Compiled 5 modules - - Warning number 3 - /packages/dep02/src/Array.res:6:16-33 - - 4 │ let at = get - 5 │ - 6 │ let includes = Js.Array2.includes - 7 │ - 8 │ let head = t => t->get(0) - - deprecated: Js.Array2.includes - Use `Array.includes` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:24:12-25 - - 22 │ let flatMap = (t, fn) => t->map(fn)->concatMany - 23 │ - 24 │ let mapi = Js.Array2.mapi - 25 │ - 26 │ let flatten = t => t->flatMap(x => x) - - deprecated: Js.Array2.mapi - Use `Array.mapWithIndex` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:32:14-29 - - 30 │ let findIndex = (t, fn) => Js.Array.findIndex(fn, t) - 31 │ - 32 │ let filter = Js.Array2.filter - 33 │ - 34 │ let reject = (t, fn) => t->filter(el => !fn(el)) - - deprecated: Js.Array2.filter - Use `Array.filter` instead. - - - Warning number 3 - /packages/dep02/src/Array.res:48:18-35 - - 46 │ - 47 │ module String = { - 48 │ let joinWith = Js.Array2.joinWith - 49 │ let join = joinWith(_, "") - 50 │ } - - deprecated: Js.Array2.joinWith - Use `Array.joinUnsafe` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:2:37-42 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep02/src/Dep02.res:3:1-6 - - 1 │ open Array - 2 │ let log = () => ["a", "b"]->forEach(Js.log) - 3 │ Js.log(NS.Alias.hello_world()) - 4 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/dep01/src/Dep01.res:2:9-14 - - 1 │ let log = () => { - 2 │ Js.log("02") - 3 │ Dep02.log() - 4 │ } - - deprecated: Js.log - Use `Console.log` instead. - +Cleaned 1/114 +Parsed 2 source files +Compiled 3 modules Warning number 3 /packages/main/src/Main.res:1:1-6 From cfd915a0c7cbb69e3669a077fcb49c4b4108f1d5 Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 16:22:18 +0200 Subject: [PATCH 39/41] more --- rewatch/testrepo/packages/main/src/Main.res | 4 +-- rewatch/tests/snapshots/dependency-cycle.txt | 4 +-- rewatch/tests/snapshots/remove-file.txt | 4 +-- .../snapshots/rename-file-internal-dep.txt | 30 ++---------------- .../snapshots/rename-file-with-interface.txt | 29 ++--------------- rewatch/tests/snapshots/rename-file.txt | 27 +--------------- .../tests/snapshots/rename-interface-file.txt | 31 ++----------------- 7 files changed, 15 insertions(+), 114 deletions(-) diff --git a/rewatch/testrepo/packages/main/src/Main.res b/rewatch/testrepo/packages/main/src/Main.res index 619e734d77..3182ad4c75 100644 --- a/rewatch/testrepo/packages/main/src/Main.res +++ b/rewatch/testrepo/packages/main/src/Main.res @@ -1,7 +1,7 @@ -Js.log("01") +Console.log("01") Dep01.log() -Js.log(InternalDep.value) +Console.log(InternalDep.value) module Array = Belt.Array module String = Js.String diff --git a/rewatch/tests/snapshots/dependency-cycle.txt b/rewatch/tests/snapshots/dependency-cycle.txt index 7651c5636d..2b90a0c8e2 100644 --- a/rewatch/tests/snapshots/dependency-cycle.txt +++ b/rewatch/tests/snapshots/dependency-cycle.txt @@ -1,5 +1,5 @@ -Cleaned 0/114 -Parsed 2 source files +Cleaned 0/115 +Parsed 1 source files Compiled 0 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. diff --git a/rewatch/tests/snapshots/remove-file.txt b/rewatch/tests/snapshots/remove-file.txt index 57f673688a..896c12f0e7 100644 --- a/rewatch/tests/snapshots/remove-file.txt +++ b/rewatch/tests/snapshots/remove-file.txt @@ -1,5 +1,5 @@ -Cleaned 1/114 -Parsed 1 source files +Cleaned 1/115 +Parsed 0 source files Compiled 1 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. diff --git a/rewatch/tests/snapshots/rename-file-internal-dep.txt b/rewatch/tests/snapshots/rename-file-internal-dep.txt index 047eab0e92..2e206fd913 100644 --- a/rewatch/tests/snapshots/rename-file-internal-dep.txt +++ b/rewatch/tests/snapshots/rename-file-internal-dep.txt @@ -1,4 +1,4 @@ -Cleaned 1/114 +Cleaned 2/115 Parsed 2 source files Compiled 2 modules @@ -11,36 +11,12 @@ Use 'dev-dependencies' instead. The field 'bsc-flags' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'compiler-flags' instead. - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - We've found a bug for you! - /packages/main/src/Main.res:4:8-24 + /packages/main/src/Main.res:4:13-29 2 │ Dep01.log() 3 │ - 4 │ Js.log(InternalDep.value) + 4 │ Console.log(InternalDep.value) 5 │ 6 │ module Array = Belt.Array diff --git a/rewatch/tests/snapshots/rename-file-with-interface.txt b/rewatch/tests/snapshots/rename-file-with-interface.txt index a738c69e20..3202fc9a0c 100644 --- a/rewatch/tests/snapshots/rename-file-with-interface.txt +++ b/rewatch/tests/snapshots/rename-file-with-interface.txt @@ -1,33 +1,8 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface.resi -Cleaned 2/114 -Parsed 2 source files +Cleaned 2/115 +Parsed 1 source files Compiled 2 modules - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - - The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-file.txt b/rewatch/tests/snapshots/rename-file.txt index 0ae2d00652..760b9fda3b 100644 --- a/rewatch/tests/snapshots/rename-file.txt +++ b/rewatch/tests/snapshots/rename-file.txt @@ -1,32 +1,7 @@ -Cleaned 0/114 +Cleaned 1/115 Parsed 1 source files Compiled 1 modules - Warning number 3 - /packages/main/src/Main2.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main2.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - - The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. diff --git a/rewatch/tests/snapshots/rename-interface-file.txt b/rewatch/tests/snapshots/rename-interface-file.txt index 8a8928aec5..621f151afb 100644 --- a/rewatch/tests/snapshots/rename-interface-file.txt +++ b/rewatch/tests/snapshots/rename-interface-file.txt @@ -1,32 +1,7 @@  No implementation file found for interface file (skipping): src/ModuleWithInterface2.resi -Cleaned 1/114 -Parsed 2 source files -Compiled 3 modules - - Warning number 3 - /packages/main/src/Main.res:1:1-6 - - 1 │ Js.log("01") - 2 │ Dep01.log() - 3 │ - - deprecated: Js.log - Use `Console.log` instead. - - - Warning number 3 - /packages/main/src/Main.res:4:1-6 - - 2 │ Dep01.log() - 3 │ - 4 │ Js.log(InternalDep.value) - 5 │ - 6 │ module Array = Belt.Array - - deprecated: Js.log - Use `Console.log` instead. - - +Cleaned 1/115 +Parsed 1 source files +Compiled 2 modules The field 'bs-dependencies' found in the package config of '@testrepo/deprecated-config' is deprecated and will be removed in a future version. Use 'dependencies' instead. From d8cc5688bb017b277284e9f067c68e1b9d172ebb Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 20:28:41 +0200 Subject: [PATCH 40/41] migrate .resi files as well --- .../StdlibMigration_Interface.res.expected | 9 +++++++ .../StdlibMigration_Interface.resi.expected | 11 ++++++++ .../src/migrate/StdlibMigration_Interface.res | 8 ++++++ .../migrate/StdlibMigration_Interface.resi | 10 +++++++ .../Migrated_StdlibMigration_Interface.res | 10 +++++++ tools/src/migrate.ml | 26 ++++++++++++++++--- 6 files changed, 71 insertions(+), 3 deletions(-) create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Interface.res.expected create mode 100644 tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Interface.res create mode 100644 tests/tools_tests/src/migrate/StdlibMigration_Interface.resi create mode 100644 tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Interface.res diff --git a/tests/tools_tests/src/expected/StdlibMigration_Interface.res.expected b/tests/tools_tests/src/expected/StdlibMigration_Interface.res.expected new file mode 100644 index 0000000000..7906b96b41 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Interface.res.expected @@ -0,0 +1,9 @@ +/* Implementation to satisfy interface build for tests */ + +external arr: array = "arr" +external reT: RegExp.t = "re" +external json: JSON.t = "json" +external nestedArr: array = "nestedArr" + +external useSet: Set.t => unit = "useSet" + diff --git a/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected b/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected new file mode 100644 index 0000000000..ced36390b9 --- /dev/null +++ b/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected @@ -0,0 +1,11 @@ +/* Migration tests for interface (.resi) files using stdlib deprecations */ + +// Type alias migrations exercised via externals +external arr: JSON.t = "arr" +external reT: Js.Re.t = "re" +external json: Js.Json.t = "json" +external nestedArr: Js.Array.t = "nestedArr" + +// Function type using a deprecated alias +external useSet: Js.Set.t => unit = "useSet" + diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Interface.res b/tests/tools_tests/src/migrate/StdlibMigration_Interface.res new file mode 100644 index 0000000000..acb6e7ed5c --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Interface.res @@ -0,0 +1,8 @@ +/* Implementation to satisfy interface build for tests */ + +external arr: Js.Array.t = "arr" +external reT: Js.Re.t = "re" +external json: Js.Json.t = "json" +external nestedArr: Js.Array.t = "nestedArr" + +external useSet: Js.Set.t => unit = "useSet" diff --git a/tests/tools_tests/src/migrate/StdlibMigration_Interface.resi b/tests/tools_tests/src/migrate/StdlibMigration_Interface.resi new file mode 100644 index 0000000000..f9c987eea5 --- /dev/null +++ b/tests/tools_tests/src/migrate/StdlibMigration_Interface.resi @@ -0,0 +1,10 @@ +/* Migration tests for interface (.resi) files using stdlib deprecations */ + +// Type alias migrations exercised via externals +external arr: Js.Array.t = "arr" +external reT: Js.Re.t = "re" +external json: Js.Json.t = "json" +external nestedArr: Js.Array.t = "nestedArr" + +// Function type using a deprecated alias +external useSet: Js.Set.t => unit = "useSet" diff --git a/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Interface.res b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Interface.res new file mode 100644 index 0000000000..5c10829b6d --- /dev/null +++ b/tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Interface.res @@ -0,0 +1,10 @@ +// This file is autogenerated so it can be type checked. +// It's the migrated version of src/migrate/StdlibMigration_Interface.res. +/* Implementation to satisfy interface build for tests */ + +external arr: array = "arr" +external reT: RegExp.t = "re" +external json: JSON.t = "json" +external nestedArr: array = "nestedArr" + +external useSet: Set.t => unit = "useSet" diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index 02cb648cc4..b9756a4714 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -703,9 +703,29 @@ let migrate ~entryPointFile ~outputMode = let {Res_driver.parsetree = signature; comments; source} = parser ~filename:path in - let mapper = makeMapper [] in - let astMapped = mapper.signature mapper signature in - Ok (Res_printer.print_interface astMapped ~comments, source) + (* Load cmti/cmt info to obtain deprecation migration templates, just like .res *) + match + (* Prefer implementation cmt info when available, since cmti may not + record deprecated usages. Fallback to cmti if needed. *) + let impl_path = + if Filename.check_suffix path ".resi" then + Filename.chop_suffix path ".resi" ^ ".res" + else path + in + match Cmt.loadCmtInfosFromPath ~path:impl_path with + | Some infos -> Some infos + | None -> Cmt.loadCmtInfosFromPath ~path + with + | None -> + Error + (Printf.sprintf + "error: failed to run migration for %s because build artifacts \ + could not be found. try to build the project" + path) + | Some {cmt_extra_info = {deprecated_used}} -> + let mapper = makeMapper deprecated_used in + let astMapped = mapper.signature mapper signature in + Ok (Res_printer.print_interface astMapped ~comments, source) else Error (Printf.sprintf From c5cce74e93f211adcb0a053343c8e7c6d2215faa Mon Sep 17 00:00:00 2001 From: Gabriel Nordeborn Date: Thu, 4 Sep 2025 21:15:19 +0200 Subject: [PATCH 41/41] fix resi --- compiler/ml/cmt_format.ml | 12 ++++++++++-- .../StdlibMigration_Interface.resi.expected | 10 +++++----- tools/src/migrate.ml | 15 ++------------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/compiler/ml/cmt_format.ml b/compiler/ml/cmt_format.ml index 864aba2016..ff30fc0043 100644 --- a/compiler/ml/cmt_format.ml +++ b/compiler/ml/cmt_format.ml @@ -167,7 +167,15 @@ let get_saved_types () = !saved_types let set_saved_types l = saved_types := l let record_deprecated_used ?deprecated_context ?migration_template ?migration_in_pipe_chain_template source_loc deprecated_text = - deprecated_used := {Cmt_utils.source_loc; deprecated_text; migration_template; migration_in_pipe_chain_template; context = deprecated_context} :: !deprecated_used + deprecated_used := + { + Cmt_utils.source_loc; + deprecated_text; + migration_template; + migration_in_pipe_chain_template; + context = deprecated_context; + } + :: !deprecated_used let _ = Cmt_utils.record_deprecated_used := record_deprecated_used @@ -210,4 +218,4 @@ let save_cmt filename modname binary_annots sourcefile initial_env cmi = output_cmt oc cmt) end; clear () -#endif \ No newline at end of file +#endif diff --git a/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected b/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected index ced36390b9..d6ce02a731 100644 --- a/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected +++ b/tests/tools_tests/src/expected/StdlibMigration_Interface.resi.expected @@ -1,11 +1,11 @@ /* Migration tests for interface (.resi) files using stdlib deprecations */ // Type alias migrations exercised via externals -external arr: JSON.t = "arr" -external reT: Js.Re.t = "re" -external json: Js.Json.t = "json" -external nestedArr: Js.Array.t = "nestedArr" +external arr: array = "arr" +external reT: RegExp.t = "re" +external json: JSON.t = "json" +external nestedArr: array = "nestedArr" // Function type using a deprecated alias -external useSet: Js.Set.t => unit = "useSet" +external useSet: Set.t => unit = "useSet" diff --git a/tools/src/migrate.ml b/tools/src/migrate.ml index b9756a4714..0a1a357745 100644 --- a/tools/src/migrate.ml +++ b/tools/src/migrate.ml @@ -703,19 +703,8 @@ let migrate ~entryPointFile ~outputMode = let {Res_driver.parsetree = signature; comments; source} = parser ~filename:path in - (* Load cmti/cmt info to obtain deprecation migration templates, just like .res *) - match - (* Prefer implementation cmt info when available, since cmti may not - record deprecated usages. Fallback to cmti if needed. *) - let impl_path = - if Filename.check_suffix path ".resi" then - Filename.chop_suffix path ".resi" ^ ".res" - else path - in - match Cmt.loadCmtInfosFromPath ~path:impl_path with - | Some infos -> Some infos - | None -> Cmt.loadCmtInfosFromPath ~path - with + + match Cmt.loadCmtInfosFromPath ~path with | None -> Error (Printf.sprintf