Skip to content

Commit e8789fc

Browse files
committed
using table instead number for safe module type name
1 parent 98c762b commit e8789fc

File tree

3 files changed

+107
-33
lines changed

3 files changed

+107
-33
lines changed

jscomp/frontend/bs_builtin_ppx.ml

Lines changed: 49 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,10 @@ let local_module_name =
426426

427427
(* Unpack requires core_type package for type inference;
428428
use module type bindings and a function to create safe local names instead. *)
429-
let local_module_type_name =
430-
let v = ref 0 in
431-
fun ({txt} : Longident.t Location.loc) ->
432-
incr v;
433-
"__"
434-
^ (Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ l) "")
435-
^ string_of_int !v ^ "__"
429+
let local_module_type_name txt =
430+
"_"
431+
^ (Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ "_" ^ l) "")
432+
^ "__"
436433

437434
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) :
438435
Ast_structure.t =
@@ -466,14 +463,15 @@ let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) :
466463
}
467464
:: acc)
468465

469-
let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
466+
let rec structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t)
467+
=
470468
match stru with
471469
| [] -> []
472470
| item :: rest -> (
473471
match item.pstr_desc with
474472
| Pstr_extension (({txt = "bs.raw" | "raw"; loc}, payload), _attrs) ->
475473
Ast_exp_handle_external.handle_raw_structure loc payload
476-
:: structure_mapper self rest
474+
:: structure_mapper ~await_context self rest
477475
(* | Pstr_extension (({txt = "i"}, _),_)
478476
->
479477
structure_mapper self rest *)
@@ -490,7 +488,7 @@ let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
490488
next
491489
| PSig _ | PTyp _ | PPat _ ->
492490
Location.raise_errorf ~loc "private extension is not support")
493-
| _ -> expand_reverse acc (structure_mapper self rest)
491+
| _ -> expand_reverse acc (structure_mapper ~await_context self rest)
494492
in
495493
aux [] stru
496494
(* Dynamic import of module transformation: module M = @res.await Belt.List *)
@@ -499,30 +497,49 @@ let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
499497
as mb)
500498
when Res_parsetree_viewer.hasAwaitAttribute pmod_attributes ->
501499
let item = self.structure_item self item in
502-
let safe_module_type_name = local_module_type_name {txt; loc} in
500+
let safe_module_type_name = local_module_type_name txt in
501+
let has_local_module_name =
502+
Hashtbl.find_opt !await_context safe_module_type_name
503+
in
504+
(* module __Belt_List__ = module type of Belt.List *)
503505
let module_type_decl =
504-
let open Ast_helper in
505-
Str.modtype ~loc
506-
(Mtd.mk ~loc
507-
{txt = safe_module_type_name; loc}
508-
~typ:(Mty.typeof_ ~loc me))
506+
match has_local_module_name with
507+
| Some _ -> []
508+
| None ->
509+
let open Ast_helper in
510+
Hashtbl.add !await_context safe_module_type_name safe_module_type_name;
511+
[
512+
Str.modtype ~loc
513+
(Mtd.mk ~loc
514+
{txt = safe_module_type_name; loc}
515+
~typ:(Mty.typeof_ ~loc me));
516+
]
509517
in
510-
(* module __BeltList1__ = module type of Belt.List *)
511518
module_type_decl
512-
:: {
513-
item with
514-
pstr_desc =
515-
Pstr_module
516-
{
517-
mb with
518-
pmb_expr =
519-
Ast_await.create_await_module_expression
520-
~module_type_name:safe_module_type_name mb.pmb_expr;
521-
};
522-
}
523-
(* module M = @res.await Belt.List *)
524-
:: structure_mapper self rest
525-
| _ -> self.structure_item self item :: structure_mapper self rest)
519+
@ (* module M = @res.await Belt.List *)
520+
{
521+
item with
522+
pstr_desc =
523+
Pstr_module
524+
{
525+
mb with
526+
pmb_expr =
527+
Ast_await.create_await_module_expression
528+
~module_type_name:safe_module_type_name mb.pmb_expr;
529+
};
530+
}
531+
:: structure_mapper ~await_context self rest
532+
| _ ->
533+
self.structure_item self item :: structure_mapper ~await_context self rest
534+
)
535+
536+
let structure_mapper ~await_context (self : mapper) (stru : Ast_structure.t) =
537+
let await_saved = !await_context in
538+
let result =
539+
structure_mapper ~await_context:(ref (Hashtbl.create 10)) self stru
540+
in
541+
await_context := await_saved;
542+
result
526543

527544
let mapper : mapper =
528545
{
@@ -533,7 +550,7 @@ let mapper : mapper =
533550
signature_item = signature_item_mapper;
534551
value_bindings = Ast_tuple_pattern_flatten.value_bindings_mapper;
535552
structure_item = structure_item_mapper;
536-
structure = structure_mapper;
553+
structure = structure_mapper ~await_context:(ref (Hashtbl.create 10));
537554
(* Ad-hoc way to internalize stuff *)
538555
label_declaration =
539556
(fun self lbl ->

jscomp/test/Import.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,46 @@ var beltAsModule = await import("../../lib/js/belt_List.js");
4848

4949
var M = await import("../../lib/js/belt_List.js");
5050

51-
var each = M.forEach;
51+
var N0 = await import("../../lib/js/belt_List.js");
52+
53+
var O = await import("../../lib/js/belt_List.js");
54+
55+
var N1_each = O.forEach;
56+
57+
var N1 = {
58+
O: O,
59+
each: N1_each
60+
};
61+
62+
var N2 = await import("../../lib/js/belt_List.js");
63+
64+
var N_each = N2.forEach;
65+
66+
var N = {
67+
N0: N0,
68+
N1: N1,
69+
N2: N2,
70+
each: N_each
71+
};
72+
73+
var M0 = await import("../../lib/js/belt_List.js");
74+
75+
var M1 = await import("../../lib/js/belt_List.js");
76+
77+
var each = M1.forEach;
78+
79+
var M2;
80+
81+
var each2 = O.forEach;
5282

5383
exports.eachIntAsync = eachIntAsync;
5484
exports.eachIntLazy = eachIntLazy;
5585
exports.beltAsModule = beltAsModule;
5686
exports.M = M;
87+
exports.N = N;
88+
exports.M0 = M0;
89+
exports.M1 = M1;
5790
exports.each = each;
91+
exports.M2 = M2;
92+
exports.each2 = each2;
5893
/* Not a pure module */

jscomp/test/Import.res

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,25 @@ let beltAsModule = await Js.import(module(Belt.List: BeltList))
1515
// module M = unpack(@res.await Js.import(module(Belt.List: BeltList0)))
1616
module M = await Belt.List
1717
let each = M.forEach
18+
19+
module N = {
20+
module N0 = await Belt.List
21+
let each = N0.forEach
22+
23+
module N1 = {
24+
module O = await Belt.List
25+
let each = O.forEach
26+
}
27+
28+
module N2 = await Belt.List
29+
let each = N2.forEach
30+
}
31+
32+
module M0 = await Belt.List
33+
let each = M0.forEach
34+
35+
module M1 = await Belt.List
36+
let each = M1.forEach
37+
38+
module M2 = N.N1.O
39+
let each2 = M2.forEach

0 commit comments

Comments
 (0)