Skip to content

Commit 896e613

Browse files
committed
dynamic import for module
1 parent c071513 commit 896e613

File tree

6 files changed

+163
-41
lines changed

6 files changed

+163
-41
lines changed

jscomp/frontend/ast_await.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ let create_await_expression (e : Parsetree.expression) =
55
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
66
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
77

8-
let create_await_module_expression (e : Parsetree.module_expr) =
8+
let create_await_module_expression ~module_type_name (e : Parsetree.module_expr)
9+
=
910
let txt = Longident.Ldot (Lident "Js", "import") in
1011
let _module_lid =
1112
match e with { pmod_desc = Pmod_ident lid } -> lid | _ -> assert false
@@ -39,7 +40,7 @@ let create_await_module_expression (e : Parsetree.module_expr) =
3940
ptyp_desc =
4041
Ptyp_package
4142
( {
42-
txt = Lident "BeltList";
43+
txt = Lident module_type_name;
4344
loc = e.pmod_loc;
4445
},
4546
[] );

jscomp/frontend/bs_builtin_ppx.ml

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,6 @@ type mapper = Bs_ast_mapper.mapper
6363
let default_mapper = Bs_ast_mapper.default_mapper
6464
let default_expr_mapper = Bs_ast_mapper.default_mapper.expr
6565
let default_pat_mapper = Bs_ast_mapper.default_mapper.pat
66-
let default_module_expr_mapper = Bs_ast_mapper.default_mapper.module_expr
6766

6867
let pat_mapper (self : mapper) (e : Parsetree.pattern) =
6968
match e.ppat_desc with
@@ -241,12 +240,6 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
241240
"Await on expression not in an async context"; *)
242241
Ast_await.create_await_expression result
243242

244-
let module_expr_mapper (self : mapper) (e : Parsetree.module_expr) =
245-
let result = default_module_expr_mapper self e in
246-
match Ast_attributes.has_await_payload e.pmod_attributes with
247-
| None -> result
248-
| Some _ -> Ast_await.create_await_module_expression result
249-
250243
let typ_mapper (self : mapper) (typ : Parsetree.core_type) =
251244
Ast_core_type_class_type.typ_mapper self typ
252245

@@ -485,6 +478,13 @@ let local_module_name =
485478
incr v;
486479
"local_" ^ string_of_int !v
487480

481+
let local_module_type_name =
482+
let v = ref 0 in
483+
fun ({ txt } : Longident.t Location.loc) ->
484+
incr v;
485+
(Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ l) "")
486+
^ string_of_int !v
487+
488488
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) :
489489
Ast_structure.t =
490490
if stru = [] then acc
@@ -548,13 +548,43 @@ let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
548548
| _ -> expand_reverse acc (structure_mapper self rest)
549549
in
550550
aux [] stru
551+
| Pstr_module
552+
({
553+
pmb_expr =
554+
{ pmod_desc = Pmod_ident { txt; loc }; pmod_attributes } as me;
555+
} as mb)
556+
(* module M = @res.await Belt.List *)
557+
when Res_parsetree_viewer.hasAwaitAttribute pmod_attributes ->
558+
let item = self.structure_item self item in
559+
let safe_module_type_name = local_module_type_name { txt; loc } in
560+
let module_type_decl =
561+
let open Ast_helper in
562+
Str.modtype ~loc
563+
(Mtd.mk ~loc
564+
{ txt = safe_module_type_name; loc }
565+
~typ:(Mty.typeof_ ~loc me))
566+
in
567+
(* module BeltList0 = module type of Belt.List *)
568+
module_type_decl
569+
:: {
570+
item with
571+
pstr_desc =
572+
Pstr_module
573+
{
574+
mb with
575+
pmb_expr =
576+
Ast_await.create_await_module_expression
577+
~module_type_name:safe_module_type_name mb.pmb_expr;
578+
};
579+
}
580+
(* module M = @res.await Belt.List *)
581+
:: structure_mapper self rest
551582
| _ -> self.structure_item self item :: structure_mapper self rest)
552583

553584
let mapper : mapper =
554585
{
555586
default_mapper with
556587
expr = expr_mapper ~async_context:(ref false) ~in_function_def:(ref false);
557-
module_expr = module_expr_mapper;
558588
pat = pat_mapper;
559589
typ = typ_mapper;
560590
class_type = class_type_mapper;

jscomp/test/Import.res

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ let _ = list{1, 2, 3}->eachIntAsync(n => Js.log2("async", n))
1111
module type BeltList = module type of Belt.List
1212
let beltAsModule = Js.import(module(Belt.List: BeltList))
1313

14-
// module M = unpack(@res.await Js.import(module(Belt.List: BeltList)))
14+
// module type BeltList0 = module type of Belt.List
15+
// module M = unpack(@res.await Js.import(module(Belt.List: BeltList0)))
1516
module M = @res.await Belt.List
1617
let each = M.forEach

lib/4.06.1/unstable/js_compiler.ml

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264810,7 +264810,8 @@ let create_await_expression (e : Parsetree.expression) =
264810264810
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
264811264811
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
264812264812

264813-
let create_await_module_expression (e : Parsetree.module_expr) =
264813+
let create_await_module_expression ~module_type_name (e : Parsetree.module_expr)
264814+
=
264814264815
let txt = Longident.Ldot (Lident "Js", "import") in
264815264816
let _module_lid =
264816264817
match e with { pmod_desc = Pmod_ident lid } -> lid | _ -> assert false
@@ -264844,7 +264845,7 @@ let create_await_module_expression (e : Parsetree.module_expr) =
264844264845
ptyp_desc =
264845264846
Ptyp_package
264846264847
( {
264847-
txt = Lident "BeltList";
264848+
txt = Lident module_type_name;
264848264849
loc = e.pmod_loc;
264849264850
},
264850264851
[] );
@@ -271342,7 +271343,6 @@ type mapper = Bs_ast_mapper.mapper
271342271343
let default_mapper = Bs_ast_mapper.default_mapper
271343271344
let default_expr_mapper = Bs_ast_mapper.default_mapper.expr
271344271345
let default_pat_mapper = Bs_ast_mapper.default_mapper.pat
271345-
let default_module_expr_mapper = Bs_ast_mapper.default_mapper.module_expr
271346271346

271347271347
let pat_mapper (self : mapper) (e : Parsetree.pattern) =
271348271348
match e.ppat_desc with
@@ -271520,12 +271520,6 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
271520271520
"Await on expression not in an async context"; *)
271521271521
Ast_await.create_await_expression result
271522271522

271523-
let module_expr_mapper (self : mapper) (e : Parsetree.module_expr) =
271524-
let result = default_module_expr_mapper self e in
271525-
match Ast_attributes.has_await_payload e.pmod_attributes with
271526-
| None -> result
271527-
| Some _ -> Ast_await.create_await_module_expression result
271528-
271529271523
let typ_mapper (self : mapper) (typ : Parsetree.core_type) =
271530271524
Ast_core_type_class_type.typ_mapper self typ
271531271525

@@ -271764,6 +271758,13 @@ let local_module_name =
271764271758
incr v;
271765271759
"local_" ^ string_of_int !v
271766271760

271761+
let local_module_type_name =
271762+
let v = ref 0 in
271763+
fun ({ txt } : Longident.t Location.loc) ->
271764+
incr v;
271765+
(Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ l) "")
271766+
^ string_of_int !v
271767+
271767271768
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) :
271768271769
Ast_structure.t =
271769271770
if stru = [] then acc
@@ -271827,13 +271828,42 @@ let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
271827271828
| _ -> expand_reverse acc (structure_mapper self rest)
271828271829
in
271829271830
aux [] stru
271831+
| Pstr_module
271832+
({
271833+
pmb_expr =
271834+
{ pmod_desc = Pmod_ident { txt; loc }; pmod_attributes } as me;
271835+
} as mb)
271836+
(* module M = @res.await Belt.List *)
271837+
when Res_parsetree_viewer.hasAwaitAttribute pmod_attributes ->
271838+
let item = self.structure_item self item in
271839+
let safe_module_type_name = local_module_type_name { txt; loc } in
271840+
let module_type_decl =
271841+
let open Ast_helper in
271842+
Str.modtype ~loc
271843+
(Mtd.mk ~loc
271844+
{ txt = safe_module_type_name; loc }
271845+
~typ:(Mty.typeof_ ~loc me))
271846+
in
271847+
(* module BeltList0 = module type of Belt.List *)
271848+
module_type_decl
271849+
:: {
271850+
item with
271851+
pstr_desc =
271852+
Pstr_module
271853+
{
271854+
mb with
271855+
pmb_expr =
271856+
Ast_await.create_await_module_expression
271857+
~module_type_name:safe_module_type_name mb.pmb_expr;
271858+
};
271859+
}
271860+
:: structure_mapper self rest
271830271861
| _ -> self.structure_item self item :: structure_mapper self rest)
271831271862

271832271863
let mapper : mapper =
271833271864
{
271834271865
default_mapper with
271835271866
expr = expr_mapper ~async_context:(ref false) ~in_function_def:(ref false);
271836-
module_expr = module_expr_mapper;
271837271867
pat = pat_mapper;
271838271868
typ = typ_mapper;
271839271869
class_type = class_type_mapper;

lib/4.06.1/unstable/js_playground_compiler.ml

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -266273,7 +266273,8 @@ let create_await_expression (e : Parsetree.expression) =
266273266273
let pexp_desc = Parsetree.Pexp_ident { txt; loc = e.pexp_loc } in
266274266274
{ e with pexp_desc = Pexp_apply ({ e with pexp_desc }, [ (Nolabel, e) ]) }
266275266275

266276-
let create_await_module_expression (e : Parsetree.module_expr) =
266276+
let create_await_module_expression ~module_type_name (e : Parsetree.module_expr)
266277+
=
266277266278
let txt = Longident.Ldot (Lident "Js", "import") in
266278266279
let _module_lid =
266279266280
match e with { pmod_desc = Pmod_ident lid } -> lid | _ -> assert false
@@ -266307,7 +266308,7 @@ let create_await_module_expression (e : Parsetree.module_expr) =
266307266308
ptyp_desc =
266308266309
Ptyp_package
266309266310
( {
266310-
txt = Lident "BeltList";
266311+
txt = Lident module_type_name;
266311266312
loc = e.pmod_loc;
266312266313
},
266313266314
[] );
@@ -272805,7 +272806,6 @@ type mapper = Bs_ast_mapper.mapper
272805272806
let default_mapper = Bs_ast_mapper.default_mapper
272806272807
let default_expr_mapper = Bs_ast_mapper.default_mapper.expr
272807272808
let default_pat_mapper = Bs_ast_mapper.default_mapper.pat
272808-
let default_module_expr_mapper = Bs_ast_mapper.default_mapper.module_expr
272809272809

272810272810
let pat_mapper (self : mapper) (e : Parsetree.pattern) =
272811272811
match e.ppat_desc with
@@ -272983,12 +272983,6 @@ let expr_mapper ~async_context ~in_function_def (self : mapper)
272983272983
"Await on expression not in an async context"; *)
272984272984
Ast_await.create_await_expression result
272985272985

272986-
let module_expr_mapper (self : mapper) (e : Parsetree.module_expr) =
272987-
let result = default_module_expr_mapper self e in
272988-
match Ast_attributes.has_await_payload e.pmod_attributes with
272989-
| None -> result
272990-
| Some _ -> Ast_await.create_await_module_expression result
272991-
272992272986
let typ_mapper (self : mapper) (typ : Parsetree.core_type) =
272993272987
Ast_core_type_class_type.typ_mapper self typ
272994272988

@@ -273227,6 +273221,13 @@ let local_module_name =
273227273221
incr v;
273228273222
"local_" ^ string_of_int !v
273229273223

273224+
let local_module_type_name =
273225+
let v = ref 0 in
273226+
fun ({ txt } : Longident.t Location.loc) ->
273227+
incr v;
273228+
(Longident.flatten txt |> List.fold_left (fun ll l -> ll ^ l) "")
273229+
^ string_of_int !v
273230+
273230273231
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) :
273231273232
Ast_structure.t =
273232273233
if stru = [] then acc
@@ -273290,13 +273291,42 @@ let rec structure_mapper (self : mapper) (stru : Ast_structure.t) =
273290273291
| _ -> expand_reverse acc (structure_mapper self rest)
273291273292
in
273292273293
aux [] stru
273294+
| Pstr_module
273295+
({
273296+
pmb_expr =
273297+
{ pmod_desc = Pmod_ident { txt; loc }; pmod_attributes } as me;
273298+
} as mb)
273299+
(* module M = @res.await Belt.List *)
273300+
when Res_parsetree_viewer.hasAwaitAttribute pmod_attributes ->
273301+
let item = self.structure_item self item in
273302+
let safe_module_type_name = local_module_type_name { txt; loc } in
273303+
let module_type_decl =
273304+
let open Ast_helper in
273305+
Str.modtype ~loc
273306+
(Mtd.mk ~loc
273307+
{ txt = safe_module_type_name; loc }
273308+
~typ:(Mty.typeof_ ~loc me))
273309+
in
273310+
(* module BeltList0 = module type of Belt.List *)
273311+
module_type_decl
273312+
:: {
273313+
item with
273314+
pstr_desc =
273315+
Pstr_module
273316+
{
273317+
mb with
273318+
pmb_expr =
273319+
Ast_await.create_await_module_expression
273320+
~module_type_name:safe_module_type_name mb.pmb_expr;
273321+
};
273322+
}
273323+
:: structure_mapper self rest
273293273324
| _ -> self.structure_item self item :: structure_mapper self rest)
273294273325

273295273326
let mapper : mapper =
273296273327
{
273297273328
default_mapper with
273298273329
expr = expr_mapper ~async_context:(ref false) ~in_function_def:(ref false);
273299-
module_expr = module_expr_mapper;
273300273330
pat = pat_mapper;
273301273331
typ = typ_mapper;
273302273332
class_type = class_type_mapper;

0 commit comments

Comments
 (0)