Skip to content

Commit 45fa4c0

Browse files
committed
efficient implementaion for let%local
1 parent 48289d6 commit 45fa4c0

File tree

7 files changed

+215
-134
lines changed

7 files changed

+215
-134
lines changed

jscomp/syntax/bs_builtin_ppx.ml

Lines changed: 44 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -332,59 +332,69 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) =
332332
end
333333
| _ -> default_mapper.structure_item self str
334334

335+
335336
let local_module_name =
336337
let v = ref 0 in
337338
fun () ->
338339
incr v ;
339340
"local_" ^ string_of_int !v
340341

341342

342-
let expand_local loc (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
343-
Ext_list.iter stru Typemod_hide.check;
344-
let local_module_name = local_module_name () in
345-
let open Ast_helper in
346-
Str.module_
347-
~loc
348-
{ pmb_name = {txt = local_module_name; loc};
349-
pmb_expr = {
350-
pmod_desc= Pmod_structure stru;
351-
pmod_loc = loc;
352-
pmod_attributes = [] };
353-
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
354-
Str.open_ ~loc {
355-
popen_lid = {txt = Lident local_module_name; loc};
356-
popen_override = Override;
357-
popen_loc = loc;
358-
popen_attributes = []
359-
} :: acc
343+
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
344+
if stru = [] then acc
345+
else begin
346+
Ext_list.iter stru Typemod_hide.check;
347+
let local_module_name = local_module_name () in
348+
let last_loc = (List.hd stru).pstr_loc in
349+
let stru = List.rev stru in
350+
let first_loc = (List.hd stru).pstr_loc in
351+
let loc = {first_loc with loc_end = last_loc.loc_end; } in
352+
let open Ast_helper in
353+
Str.module_
354+
~loc
355+
{ pmb_name = {txt = local_module_name; loc};
356+
pmb_expr = {
357+
pmod_desc= Pmod_structure stru;
358+
pmod_loc = loc;
359+
pmod_attributes = [] };
360+
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
361+
Str.open_ ~loc {
362+
popen_lid = {txt = Lident local_module_name; loc};
363+
popen_override = Override;
364+
popen_loc = loc;
365+
popen_attributes = []
366+
} :: acc
367+
end
368+
360369

361370
let rec
362-
structure_mapper (self : mapper) stru =
371+
structure_mapper (self : mapper) (stru : Ast_structure.t) =
363372
match stru with
364373
| [] -> []
365374
| item::rest ->
366-
let new_x = self.structure_item self item in
367-
let rest = (structure_mapper self rest) in
368-
match new_x.pstr_desc with
375+
match item.pstr_desc with
369376
| Pstr_extension (({txt = ("bs.debugger.chrome" | "debugger.chrome") ;loc}, _),_)
370377
->
371378
Location.prerr_warning loc (Preprocessor "this extension can be safely removed");
372-
rest
379+
structure_mapper self rest
373380
| Pstr_extension ( ({txt = ("bs.raw"| "raw") ; loc}, payload), _attrs)
374381
->
375-
Ast_exp_handle_external.handle_raw_structure loc payload :: rest
376-
| Pstr_extension (({txt = "local"; loc}, payload),_)
382+
Ast_exp_handle_external.handle_raw_structure loc payload :: structure_mapper self rest
383+
| Pstr_extension (({txt = "local"}, _),_)
377384
->
378-
begin match payload with
379-
| PStr stru ->
380-
expand_local loc stru rest
381-
| PSig _
382-
| PTyp _
383-
| PPat _ ->
384-
Location.raise_errorf ~loc "local extension is not support"
385-
end
385+
let rec aux acc (rest : Ast_structure.t) =
386+
match rest with
387+
| {pstr_desc = Pstr_extension (({txt = "local";loc}, payload), _) } :: next ->
388+
begin match payload with
389+
| PStr work ->
390+
aux (Ext_list.rev_map_append work acc (fun x -> self.structure_item self x)) next
391+
| (PSig _ | PTyp _ | PPat _) ->
392+
Location.raise_errorf ~loc "local extension is not support"
393+
end
394+
| _ -> expand_reverse acc (structure_mapper self rest)
395+
in aux [] stru
386396
| _ ->
387-
new_x :: rest
397+
self.structure_item self item :: structure_mapper self rest
388398

389399
let unsafe_mapper : mapper =
390400
{ default_mapper with

jscomp/test/internal_unused_test.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,28 @@ function h(a, b) {
1616
return a + b | 0;
1717
}
1818

19+
var h1 = 2;
20+
21+
var h2 = h1 + 1 | 0;
22+
23+
var h4 = 2;
24+
25+
var h5 = h4 + 1 | 0;
26+
27+
var b = 5;
28+
29+
var N = {
30+
b: b
31+
};
32+
33+
console.log(h5);
34+
35+
console.log(h2);
36+
1937
console.log(c);
2038

2139
console.log(h(1, 2));
2240

2341
exports.f = f;
42+
exports.N = N;
2443
/* Not a pure module */

jscomp/test/internal_unused_test.ml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,25 @@ let h = fun[@bs] a b -> a + b
2525
]
2626

2727

28+
let%local h0 = 1
29+
30+
let%local h1 = h0 + 1
31+
32+
let%local h2 = h1 + 1
33+
34+
[%%local
35+
let h3 = 1
36+
let h4 = h3 + 1
37+
let h5 = h4 + 1
38+
]
39+
40+
module N = struct
41+
let %local a = 3
42+
let b = a + 2
43+
end
44+
45+
;; Js.log h5
46+
;; Js.log h2
2847

2948
;; Js.log f
3049

lib/4.06.1/unstable/js_compiler.ml

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -315517,58 +315517,69 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) =
315517315517
end
315518315518
| _ -> default_mapper.structure_item self str
315519315519

315520+
315520315521
let local_module_name =
315521315522
let v = ref 0 in
315522315523
fun () ->
315523315524
incr v ;
315524315525
"local_" ^ string_of_int !v
315525315526

315526315527

315527-
let expand_local loc (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
315528-
Ext_list.iter stru Typemod_hide.check;
315529-
let local_module_name = local_module_name () in
315530-
let open Ast_helper in
315531-
Str.module_
315532-
~loc
315533-
{ pmb_name = {txt = local_module_name; loc};
315534-
pmb_expr = {
315535-
pmod_desc= Pmod_structure stru;
315536-
pmod_loc = loc;
315537-
pmod_attributes = [] };
315538-
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
315539-
Str.open_ ~loc {
315540-
popen_lid = {txt = Lident local_module_name; loc};
315541-
popen_override = Override;
315542-
popen_loc = loc;
315543-
popen_attributes = []
315544-
} :: acc
315528+
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
315529+
if stru = [] then acc
315530+
else begin
315531+
Ext_list.iter stru Typemod_hide.check;
315532+
let local_module_name = local_module_name () in
315533+
let last_loc = (List.hd stru).pstr_loc in
315534+
let stru = List.rev stru in
315535+
let first_loc = (List.hd stru).pstr_loc in
315536+
let loc = {first_loc with loc_end = last_loc.loc_end; } in
315537+
let open Ast_helper in
315538+
Str.module_
315539+
~loc
315540+
{ pmb_name = {txt = local_module_name; loc};
315541+
pmb_expr = {
315542+
pmod_desc= Pmod_structure stru;
315543+
pmod_loc = loc;
315544+
pmod_attributes = [] };
315545+
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
315546+
Str.open_ ~loc {
315547+
popen_lid = {txt = Lident local_module_name; loc};
315548+
popen_override = Override;
315549+
popen_loc = loc;
315550+
popen_attributes = []
315551+
} :: acc
315552+
end
315553+
315545315554

315546315555
let rec
315547-
structure_mapper (self : mapper) stru =
315556+
structure_mapper (self : mapper) (stru : Ast_structure.t) =
315548315557
match stru with
315549315558
| [] -> []
315550315559
| item::rest ->
315551-
let new_x = self.structure_item self item in
315552-
match new_x.pstr_desc with
315560+
match item.pstr_desc with
315553315561
| Pstr_extension (({txt = ("bs.debugger.chrome" | "debugger.chrome") ;loc}, _),_)
315554315562
->
315555315563
Location.prerr_warning loc (Preprocessor "this extension can be safely removed");
315556-
(structure_mapper self rest)
315564+
structure_mapper self rest
315557315565
| Pstr_extension ( ({txt = ("bs.raw"| "raw") ; loc}, payload), _attrs)
315558315566
->
315559-
Ast_exp_handle_external.handle_raw_structure loc payload :: (structure_mapper self rest)
315560-
| Pstr_extension (({txt = "local"; loc}, payload),_)
315567+
Ast_exp_handle_external.handle_raw_structure loc payload :: structure_mapper self rest
315568+
| Pstr_extension (({txt = "local"}, _),_)
315561315569
->
315562-
begin match payload with
315563-
| PStr stru ->
315564-
expand_local loc stru (structure_mapper self rest)
315565-
| PSig _
315566-
| PTyp _
315567-
| PPat _ ->
315568-
Location.raise_errorf ~loc "local extension is not support"
315569-
end
315570+
let rec aux acc (rest : Ast_structure.t) =
315571+
match rest with
315572+
| {pstr_desc = Pstr_extension (({txt = "local";loc}, payload), _) } :: next ->
315573+
begin match payload with
315574+
| PStr work ->
315575+
aux (Ext_list.rev_map_append work acc (fun x -> self.structure_item self x)) next
315576+
| (PSig _ | PTyp _ | PPat _) ->
315577+
Location.raise_errorf ~loc "local extension is not support"
315578+
end
315579+
| _ -> expand_reverse acc (structure_mapper self rest)
315580+
in aux [] stru
315570315581
| _ ->
315571-
new_x :: (structure_mapper self rest)
315582+
self.structure_item self item :: structure_mapper self rest
315572315583

315573315584
let unsafe_mapper : mapper =
315574315585
{ default_mapper with

lib/4.06.1/unstable/js_refmt_compiler.ml

Lines changed: 44 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -315517,58 +315517,69 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) =
315517315517
end
315518315518
| _ -> default_mapper.structure_item self str
315519315519

315520+
315520315521
let local_module_name =
315521315522
let v = ref 0 in
315522315523
fun () ->
315523315524
incr v ;
315524315525
"local_" ^ string_of_int !v
315525315526

315526315527

315527-
let expand_local loc (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
315528-
Ext_list.iter stru Typemod_hide.check;
315529-
let local_module_name = local_module_name () in
315530-
let open Ast_helper in
315531-
Str.module_
315532-
~loc
315533-
{ pmb_name = {txt = local_module_name; loc};
315534-
pmb_expr = {
315535-
pmod_desc= Pmod_structure stru;
315536-
pmod_loc = loc;
315537-
pmod_attributes = [] };
315538-
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
315539-
Str.open_ ~loc {
315540-
popen_lid = {txt = Lident local_module_name; loc};
315541-
popen_override = Override;
315542-
popen_loc = loc;
315543-
popen_attributes = []
315544-
} :: acc
315528+
let expand_reverse (stru : Ast_structure.t) (acc : Ast_structure.t) : Ast_structure.t =
315529+
if stru = [] then acc
315530+
else begin
315531+
Ext_list.iter stru Typemod_hide.check;
315532+
let local_module_name = local_module_name () in
315533+
let last_loc = (List.hd stru).pstr_loc in
315534+
let stru = List.rev stru in
315535+
let first_loc = (List.hd stru).pstr_loc in
315536+
let loc = {first_loc with loc_end = last_loc.loc_end; } in
315537+
let open Ast_helper in
315538+
Str.module_
315539+
~loc
315540+
{ pmb_name = {txt = local_module_name; loc};
315541+
pmb_expr = {
315542+
pmod_desc= Pmod_structure stru;
315543+
pmod_loc = loc;
315544+
pmod_attributes = [] };
315545+
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
315546+
Str.open_ ~loc {
315547+
popen_lid = {txt = Lident local_module_name; loc};
315548+
popen_override = Override;
315549+
popen_loc = loc;
315550+
popen_attributes = []
315551+
} :: acc
315552+
end
315553+
315545315554

315546315555
let rec
315547-
structure_mapper (self : mapper) stru =
315556+
structure_mapper (self : mapper) (stru : Ast_structure.t) =
315548315557
match stru with
315549315558
| [] -> []
315550315559
| item::rest ->
315551-
let new_x = self.structure_item self item in
315552-
match new_x.pstr_desc with
315560+
match item.pstr_desc with
315553315561
| Pstr_extension (({txt = ("bs.debugger.chrome" | "debugger.chrome") ;loc}, _),_)
315554315562
->
315555315563
Location.prerr_warning loc (Preprocessor "this extension can be safely removed");
315556-
(structure_mapper self rest)
315564+
structure_mapper self rest
315557315565
| Pstr_extension ( ({txt = ("bs.raw"| "raw") ; loc}, payload), _attrs)
315558315566
->
315559-
Ast_exp_handle_external.handle_raw_structure loc payload :: (structure_mapper self rest)
315560-
| Pstr_extension (({txt = "local"; loc}, payload),_)
315567+
Ast_exp_handle_external.handle_raw_structure loc payload :: structure_mapper self rest
315568+
| Pstr_extension (({txt = "local"}, _),_)
315561315569
->
315562-
begin match payload with
315563-
| PStr stru ->
315564-
expand_local loc stru (structure_mapper self rest)
315565-
| PSig _
315566-
| PTyp _
315567-
| PPat _ ->
315568-
Location.raise_errorf ~loc "local extension is not support"
315569-
end
315570+
let rec aux acc (rest : Ast_structure.t) =
315571+
match rest with
315572+
| {pstr_desc = Pstr_extension (({txt = "local";loc}, payload), _) } :: next ->
315573+
begin match payload with
315574+
| PStr work ->
315575+
aux (Ext_list.rev_map_append work acc (fun x -> self.structure_item self x)) next
315576+
| (PSig _ | PTyp _ | PPat _) ->
315577+
Location.raise_errorf ~loc "local extension is not support"
315578+
end
315579+
| _ -> expand_reverse acc (structure_mapper self rest)
315580+
in aux [] stru
315570315581
| _ ->
315571-
new_x :: (structure_mapper self rest)
315582+
self.structure_item self item :: structure_mapper self rest
315572315583

315573315584
let unsafe_mapper : mapper =
315574315585
{ default_mapper with

0 commit comments

Comments
 (0)