Skip to content

Commit aaa668d

Browse files
committed
Js_int migrations
1 parent 4e27a20 commit aaa668d

File tree

6 files changed

+177
-44
lines changed

6 files changed

+177
-44
lines changed

packages/@rescript/runtime/Js_int.res

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ See [`toExponential`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Re
4949
Js.log(Js.Int.toExponential(77))
5050
```
5151
*/
52+
@deprecated({
53+
reason: "Use `Int.toExponential` instead.",
54+
migrate: Int.toExponential(),
55+
})
5256
@send
5357
external toExponential: int => string = "toExponential"
5458

@@ -73,6 +77,10 @@ Js.log(Js.Int.toExponentialWithPrecision(77, ~digits=2))
7377
Js.log(Js.Int.toExponentialWithPrecision(5678, ~digits=2))
7478
```
7579
*/
80+
@deprecated({
81+
reason: "Use `Int.toExponential` instead.",
82+
migrate: Int.toExponential(~digits=%insert.labelledArgument("digits")),
83+
})
7684
@send
7785
external toExponentialWithPrecision: (int, ~digits: int) => string = "toExponential"
7886

@@ -92,6 +100,10 @@ See [`toPrecision`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe
92100
Js.log(Js.Int.toPrecision(123456789))
93101
```
94102
*/
103+
@deprecated({
104+
reason: "Use `Int.toPrecision` instead.",
105+
migrate: Int.toPrecision(),
106+
})
95107
@send
96108
external toPrecision: int => string = "toPrecision"
97109

@@ -120,6 +132,10 @@ Js.log(Js.Int.toPrecisionWithPrecision(123456789, ~digits=2))
120132
Js.log(Js.Int.toPrecisionWithPrecision(0, ~digits=2))
121133
```
122134
*/
135+
@deprecated({
136+
reason: "Use `Int.toPrecision` instead.",
137+
migrate: Int.toPrecision(~digits=%insert.labelledArgument("digits")),
138+
})
123139
@send
124140
external toPrecisionWithPrecision: (int, ~digits: int) => string = "toPrecision"
125141

@@ -136,6 +152,10 @@ See [`toString`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Referen
136152
Js.log(Js.Int.toString(123456789))
137153
```
138154
*/
155+
@deprecated({
156+
reason: "Use `Int.toString` instead.",
157+
migrate: Int.toString(),
158+
})
139159
@send
140160
external toString: int => string = "toString"
141161

@@ -161,11 +181,23 @@ Js.log(Js.Int.toStringWithRadix(3735928559, ~radix=16))
161181
Js.log(Js.Int.toStringWithRadix(123456, ~radix=36))
162182
```
163183
*/
184+
@deprecated({
185+
reason: "Use `Int.toString` instead.",
186+
migrate: Int.toString(~radix=%insert.labelledArgument("radix")),
187+
})
164188
@send
165189
external toStringWithRadix: (int, ~radix: int) => string = "toString"
166190

191+
@deprecated({
192+
reason: "Use `Int.toFloat` instead.",
193+
migrate: Int.toFloat(),
194+
})
167195
external toFloat: int => float = "%floatofint"
168196

197+
@deprecated({
198+
reason: "Use `Int.equal` instead.",
199+
migrate: Int.equal(),
200+
})
169201
let equal = (x: int, y) => x == y
170202
let max: int = 2147483647
171203
let min: int = -2147483648
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
let toExponential1 = 77->Int.toExponential
2+
let toExponential2 = Int.toExponential(77)
3+
4+
let toExponentialWithPrecision1 = 77->Int.toExponential(~digits=2)
5+
let toExponentialWithPrecision2 = Int.toExponential(77, ~digits=2)
6+
7+
let toPrecision1 = 123456789->Int.toPrecision
8+
let toPrecision2 = Int.toPrecision(123456789)
9+
10+
let toPrecisionWithPrecision1 = 123456789->Int.toPrecision(~digits=2)
11+
let toPrecisionWithPrecision2 = Int.toPrecision(123456789, ~digits=2)
12+
13+
let toString1 = 123456789->Int.toString
14+
let toString2 = Int.toString(123456789)
15+
16+
let toStringWithRadix1 = 373592855->Int.toString(~radix=16)
17+
let toStringWithRadix2 = Int.toString(373592855, ~radix=16)
18+
19+
let toFloat1 = 42->Int.toFloat
20+
let toFloat2 = Int.toFloat(42)
21+
22+
let equal1 = Js.Int.equal(1, 1)
23+
let equal2 = 1->Js.Int.equal(2)
24+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
let toExponential1 = 77->Js.Int.toExponential
2+
let toExponential2 = Js.Int.toExponential(77)
3+
4+
let toExponentialWithPrecision1 = 77->Js.Int.toExponentialWithPrecision(~digits=2)
5+
let toExponentialWithPrecision2 = Js.Int.toExponentialWithPrecision(77, ~digits=2)
6+
7+
let toPrecision1 = 123456789->Js.Int.toPrecision
8+
let toPrecision2 = Js.Int.toPrecision(123456789)
9+
10+
let toPrecisionWithPrecision1 = 123456789->Js.Int.toPrecisionWithPrecision(~digits=2)
11+
let toPrecisionWithPrecision2 = Js.Int.toPrecisionWithPrecision(123456789, ~digits=2)
12+
13+
let toString1 = 123456789->Js.Int.toString
14+
let toString2 = Js.Int.toString(123456789)
15+
16+
let toStringWithRadix1 = 373592855->Js.Int.toStringWithRadix(~radix=16)
17+
let toStringWithRadix2 = Js.Int.toStringWithRadix(373592855, ~radix=16)
18+
19+
let toFloat1 = 42->Js.Int.toFloat
20+
let toFloat2 = Js.Int.toFloat(42)
21+
22+
let equal1 = Js.Int.equal(1, 1)
23+
let equal2 = 1->Js.Int.equal(2)

tests/tools_tests/src/migrate/migrated/Migrated_StdlibMigration_Array.res

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@ let copyWithin2 = Array.copyAllWithin([1, 2, 3, 4, 5], ~target=2)
125125
let copyWithinFrom1 = [1, 2, 3, 4, 5]->Array.copyWithinToEnd(~target=0, ~start=2)
126126
let copyWithinFrom2 = Array.copyWithinToEnd([1, 2, 3, 4, 5], ~target=0, ~start=2)
127127

128-
let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~target=1, ~start=2, ~end=5)
129-
let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~target=1, ~start=2, ~end=5)
128+
let copyWithinFromRange1 = [1, 2, 3, 4, 5, 6]->Array.copyWithin(~start=2, ~target=1, ~end=5)
129+
let copyWithinFromRange2 = Array.copyWithin([1, 2, 3, 4, 5, 6], ~start=2, ~target=1, ~end=5)
130130

131131
let push1 = [1, 2, 3]->Array.push(4)
132132
let push2 = Array.push([1, 2, 3], 4)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// This file is autogenerated so it can be type checked.
2+
// It's the migrated version of src/migrate/StdlibMigration_Js_Int.res.
3+
let toExponential1 = 77->Int.toExponential
4+
let toExponential2 = Int.toExponential(77)
5+
6+
let toExponentialWithPrecision1 = 77->Int.toExponential(~digits=2)
7+
let toExponentialWithPrecision2 = Int.toExponential(77, ~digits=2)
8+
9+
let toPrecision1 = 123456789->Int.toPrecision
10+
let toPrecision2 = Int.toPrecision(123456789)
11+
12+
let toPrecisionWithPrecision1 = 123456789->Int.toPrecision(~digits=2)
13+
let toPrecisionWithPrecision2 = Int.toPrecision(123456789, ~digits=2)
14+
15+
let toString1 = 123456789->Int.toString
16+
let toString2 = Int.toString(123456789)
17+
18+
let toStringWithRadix1 = 373592855->Int.toString(~radix=16)
19+
let toStringWithRadix2 = Int.toString(373592855, ~radix=16)
20+
21+
let toFloat1 = 42->Int.toFloat
22+
let toFloat2 = Int.toFloat(42)
23+
24+
let equal1 = Js.Int.equal(1, 1)
25+
let equal2 = 1->Js.Int.equal(2)

tools/src/migrate.ml

Lines changed: 71 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,66 @@ module ExprUtils = struct
6464
end
6565

6666
module MapperUtils = struct
67+
(* Collect placeholder usages anywhere inside an expression. *)
68+
let collect_placeholders (expr : Parsetree.expression) =
69+
let labelled = ref StringSet.empty in
70+
let unlabelled = ref IntSet.empty in
71+
let open Ast_iterator in
72+
let iter =
73+
{
74+
default_iterator with
75+
expr =
76+
(fun self e ->
77+
(match InsertExt.placeholder_of_expr e with
78+
| Some (InsertExt.Labelled name) ->
79+
labelled := StringSet.add name !labelled
80+
| Some (InsertExt.Unlabelled i) when i >= 0 ->
81+
unlabelled := IntSet.add i !unlabelled
82+
| _ -> ());
83+
default_iterator.expr self e);
84+
}
85+
in
86+
iter.expr iter expr;
87+
(!labelled, !unlabelled)
88+
89+
(* Replace placeholders anywhere inside an expression using the given
90+
source arguments. *)
91+
let replace_placeholders_in_expr (expr : Parsetree.expression)
92+
(source_args : (Asttypes.arg_label * Parsetree.expression) list) =
93+
let labelled = Hashtbl.create 8 in
94+
let unlabelled = Hashtbl.create 8 in
95+
let idx = ref 0 in
96+
source_args
97+
|> List.iter (fun (lbl, arg) ->
98+
match lbl with
99+
| Asttypes.Nolabel ->
100+
Hashtbl.replace unlabelled !idx arg;
101+
incr idx
102+
| Asttypes.Labelled {txt} | Optional {txt} ->
103+
Hashtbl.replace labelled txt arg);
104+
let find = function
105+
| `Labelled name -> Hashtbl.find_opt labelled name
106+
| `Unlabelled i -> Hashtbl.find_opt unlabelled i
107+
in
108+
let mapper =
109+
{
110+
Ast_mapper.default_mapper with
111+
expr =
112+
(fun mapper exp ->
113+
match InsertExt.placeholder_of_expr exp with
114+
| Some (InsertExt.Labelled name) -> (
115+
match find (`Labelled name) with
116+
| Some arg -> arg
117+
| None -> exp)
118+
| Some (InsertExt.Unlabelled i) -> (
119+
match find (`Unlabelled i) with
120+
| Some arg -> arg
121+
| None -> exp)
122+
| None -> Ast_mapper.default_mapper.expr mapper exp);
123+
}
124+
in
125+
mapper.expr mapper expr
126+
67127
let build_labelled_args_map template_args =
68128
template_args
69129
|> List.filter_map (fun (label, arg) ->
@@ -89,23 +149,6 @@ module MapperUtils = struct
89149
- unlabelled_positions_to_insert: 0-based indices of unlabelled source args to drop
90150
*)
91151
let get_template_args_to_insert mapper template_args source_args =
92-
let find_source_labelled name =
93-
source_args
94-
|> List.find_map (fun (label, arg) ->
95-
match label with
96-
| Asttypes.Labelled {txt = l} | Optional {txt = l} ->
97-
if l = name then Some arg else None
98-
| _ -> None)
99-
in
100-
let find_source_unlabelled target =
101-
let rec loop i = function
102-
| [] -> None
103-
| (Asttypes.Nolabel, arg) :: rest ->
104-
if i = target then Some arg else loop (i + 1) rest
105-
| _ :: rest -> loop i rest
106-
in
107-
loop 0 source_args
108-
in
109152
let is_unit_expr (e : Parsetree.expression) =
110153
match e.pexp_desc with
111154
| Pexp_construct ({txt = Lident "()"}, None) -> true
@@ -121,31 +164,17 @@ module MapperUtils = struct
121164
- used_unlabelled: 0-based positions of unlabelled args consumed. *)
122165
let accumulate_template_arg (rev_args, used_labelled, used_unlabelled)
123166
(label, arg) =
124-
match InsertExt.placeholder_of_expr arg with
125-
| Some (InsertExt.Labelled name) -> (
126-
match label with
127-
| Asttypes.Nolabel -> (
128-
match find_source_labelled name with
129-
| Some arg' ->
130-
( (Asttypes.Nolabel, arg') :: rev_args,
131-
StringSet.add name used_labelled,
132-
used_unlabelled )
133-
| None -> (rev_args, used_labelled, used_unlabelled))
134-
| _ -> (rev_args, used_labelled, used_unlabelled))
135-
| Some (InsertExt.Unlabelled target) when target >= 0 -> (
136-
match find_source_unlabelled target with
137-
| Some arg' ->
138-
( (label, arg') :: rev_args,
139-
used_labelled,
140-
IntSet.add target used_unlabelled )
141-
| None -> (rev_args, used_labelled, used_unlabelled))
142-
| Some _ -> (rev_args, used_labelled, used_unlabelled)
143-
| None ->
144-
if is_unit_expr arg then (rev_args, used_labelled, used_unlabelled)
145-
else
146-
( (label, mapper.Ast_mapper.expr mapper arg) :: rev_args,
147-
used_labelled,
148-
used_unlabelled )
167+
(* Always perform nested replacement inside the argument expression,
168+
and collect which placeholders were used so we can drop them from the
169+
original call's arguments. *)
170+
let labelled_used_here, unlabelled_used_here = collect_placeholders arg in
171+
let arg_replaced = replace_placeholders_in_expr arg source_args in
172+
if is_unit_expr arg_replaced then
173+
(rev_args, used_labelled, used_unlabelled)
174+
else
175+
( (label, mapper.Ast_mapper.expr mapper arg_replaced) :: rev_args,
176+
StringSet.union used_labelled labelled_used_here,
177+
IntSet.union used_unlabelled unlabelled_used_here )
149178
in
150179
let rev_args, labelled_set, unlabelled_set =
151180
List.fold_left accumulate_template_arg

0 commit comments

Comments
 (0)