Skip to content

Commit 6be388d

Browse files
committed
deprecate and migrate Exn.Error to JsExn
1 parent 0e4bbcc commit 6be388d

File tree

6 files changed

+111
-1
lines changed

6 files changed

+111
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@
1010
> - :nail_care: [Polish]
1111
> - :house: [Internal]
1212
13+
# 12.0.1 (unreleased)
14+
15+
#### :nail_care: Polish
16+
17+
- Add missing deprecation and migration for Exn.Error. https://github.com/rescript-lang/rescript/pull/8036
18+
1319
# 12.0.0
1420

1521
No changes compared to rc.5.

packages/@rescript/runtime/Stdlib_Exn.resi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,13 @@ Provide utilities for dealing with JS exceptions.
3333
})
3434
type t
3535

36-
type exn += private Error(t)
36+
type exn +=
37+
private
38+
| @deprecated({
39+
reason: "Use `JsExn` instead",
40+
migrate: %replace.variant(JsExn),
41+
})
42+
Error(t)
3743

3844
@deprecated({
3945
reason: "Use `JsExn.fromException` instead",

tests/tools_tests/src/expected/StdlibMigration_Exn.res.expected

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,13 @@ let throws5 = () => JsError.SyntaxError.throwWithMessage("err")
3939
let throws6 = () => JsError.TypeError.throwWithMessage("err")
4040
let throws7 = () => JsError.URIError.throwWithMessage("err")
4141

42+
let someThrowingJsCode = () => Some("bar")
43+
let catchingExnErrorWithSwitch = switch someThrowingJsCode() {
44+
| exception JsExn(e) => e->JsExn.message
45+
| s => s
46+
}
47+
48+
let catchingExnErrorWithTryCatch = try {someThrowingJsCode()} catch {
49+
| JsExn(e) => e->JsExn.message
50+
}
51+

tests/tools_tests/src/migrate/StdlibMigration_Exn.res

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,13 @@ let throws4 = () => Exn.raiseReferenceError("err")
3838
let throws5 = () => Exn.raiseSyntaxError("err")
3939
let throws6 = () => Exn.raiseTypeError("err")
4040
let throws7 = () => Exn.raiseUriError("err")
41+
42+
let someThrowingJsCode = () => Some("bar")
43+
let catchingExnErrorWithSwitch = switch someThrowingJsCode() {
44+
| exception Exn.Error(e) => e->Exn.message
45+
| s => s
46+
}
47+
48+
let catchingExnErrorWithTryCatch = try {someThrowingJsCode()} catch {
49+
| Exn.Error(e) => e->Exn.message
50+
}

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,13 @@ let throws4 = () => JsError.ReferenceError.throwWithMessage("err")
4040
let throws5 = () => JsError.SyntaxError.throwWithMessage("err")
4141
let throws6 = () => JsError.TypeError.throwWithMessage("err")
4242
let throws7 = () => JsError.URIError.throwWithMessage("err")
43+
44+
let someThrowingJsCode = () => Some("bar")
45+
let catchingExnErrorWithSwitch = switch someThrowingJsCode() {
46+
| exception JsExn(e) => e->JsExn.message
47+
| s => s
48+
}
49+
50+
let catchingExnErrorWithTryCatch = try {someThrowingJsCode()} catch {
51+
| JsExn(e) => e->JsExn.message
52+
}

tools/src/migrate.ml

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ module MapperUtils = struct
104104
if Ext_list.is_empty attrs then e
105105
else {e with pexp_attributes = attrs @ e.pexp_attributes}
106106

107+
let attach_attrs_to_pat ~attrs (pat : Parsetree.pattern) =
108+
if Ext_list.is_empty attrs then pat
109+
else {pat with ppat_attributes = attrs @ pat.ppat_attributes}
110+
107111
(* Apply transforms attached to an expression itself and drop the
108112
transform attributes afterwards. *)
109113
let apply_on_self (e : Parsetree.expression) : Parsetree.expression =
@@ -332,6 +336,29 @@ module TypeReplace = struct
332336
| _ -> None
333337
end
334338

339+
module VariantReplace = struct
340+
type target = {lid: Longident.t Location.loc; attrs: Parsetree.attributes}
341+
342+
let of_template (expr : Parsetree.expression) : target option =
343+
match expr.pexp_desc with
344+
| Pexp_extension
345+
( {txt = "replace.variant"},
346+
PStr
347+
[
348+
{
349+
pstr_desc =
350+
Pstr_eval
351+
({pexp_desc = Pexp_construct (lid, _); pexp_attributes}, _);
352+
};
353+
] ) ->
354+
let attrs =
355+
if Ext_list.is_empty expr.pexp_attributes then pexp_attributes
356+
else expr.pexp_attributes @ pexp_attributes
357+
in
358+
Some {lid; attrs}
359+
| _ -> None
360+
end
361+
335362
let remap_needed_extensions (mapper : Ast_mapper.mapper)
336363
(ext : Parsetree.extension) : Parsetree.extension =
337364
match ext with
@@ -551,6 +578,29 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) =
551578
|> List.iter (fun ({Cmt_utils.source_loc} as d) ->
552579
Hashtbl.replace loc_to_deprecated_reference source_loc d);
553580

581+
let deprecated_variant_constructors =
582+
deprecated_used
583+
|> List.filter_map (fun (d : Cmt_utils.deprecated_used) ->
584+
match d.migration_template with
585+
| Some template -> (
586+
match VariantReplace.of_template template with
587+
| Some target -> Some (d.source_loc, target)
588+
| None -> None)
589+
| None -> None)
590+
in
591+
let loc_to_deprecated_variant_constructor =
592+
Hashtbl.create (List.length deprecated_variant_constructors)
593+
in
594+
deprecated_variant_constructors
595+
|> List.iter (fun (loc, target) ->
596+
Hashtbl.replace loc_to_deprecated_variant_constructor loc target);
597+
598+
let find_variant_target ~loc ~lid_loc =
599+
match Hashtbl.find_opt loc_to_deprecated_variant_constructor loc with
600+
| Some _ as found -> found
601+
| None -> Hashtbl.find_opt loc_to_deprecated_variant_constructor lid_loc
602+
in
603+
554604
(* Helpers for type replacement lookups *)
555605
let loc_contains (a : Location.t) (b : Location.t) =
556606
let a_start = a.Location.loc_start.pos_cnum in
@@ -629,6 +679,13 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) =
629679
match deprecated_info.migration_template with
630680
| Some e -> apply_template_direct mapper e call_args exp
631681
| None -> exp)
682+
| {pexp_desc = Pexp_construct (lid, arg); pexp_loc} -> (
683+
match find_variant_target ~loc:pexp_loc ~lid_loc:lid.loc with
684+
| Some {VariantReplace.lid; attrs} ->
685+
let arg = Option.map (mapper.expr mapper) arg in
686+
let replaced = {exp with pexp_desc = Pexp_construct (lid, arg)} in
687+
MapperUtils.ApplyTransforms.attach_to_replacement ~attrs replaced
688+
| None -> Ast_mapper.default_mapper.expr mapper exp)
632689
| {
633690
pexp_desc =
634691
Pexp_apply
@@ -664,6 +721,17 @@ let makeMapper (deprecated_used : Cmt_utils.deprecated_used list) =
664721
~pipe_args ~funct exp
665722
| Some _ -> Ast_mapper.default_mapper.expr mapper exp)
666723
| _ -> Ast_mapper.default_mapper.expr mapper exp);
724+
pat =
725+
(fun mapper pat ->
726+
match pat with
727+
| {ppat_desc = Ppat_construct (lid, arg); ppat_loc} -> (
728+
match find_variant_target ~loc:ppat_loc ~lid_loc:lid.loc with
729+
| Some {VariantReplace.lid; attrs} ->
730+
let arg = Option.map (mapper.pat mapper) arg in
731+
let replaced = {pat with ppat_desc = Ppat_construct (lid, arg)} in
732+
MapperUtils.ApplyTransforms.attach_attrs_to_pat ~attrs replaced
733+
| None -> Ast_mapper.default_mapper.pat mapper pat)
734+
| _ -> Ast_mapper.default_mapper.pat mapper pat);
667735
}
668736
in
669737
mapper

0 commit comments

Comments
 (0)