Skip to content

Commit 6a9a871

Browse files
committed
support let%local which is not exported by default
In the future, we can fusing the let%local if compilation perf is the concern
1 parent 4a2abb4 commit 6a9a871

File tree

4 files changed

+111
-11
lines changed

4 files changed

+111
-11
lines changed

jscomp/syntax/bs_builtin_ppx.ml

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -270,19 +270,16 @@ let signature_item_mapper (self : mapper) (sigi : Parsetree.signature_item) =
270270
)
271271
| _ -> default_mapper.signature_item self sigi
272272

273-
273+
let local_module_name =
274+
let v = ref 0 in
275+
fun () ->
276+
incr v ;
277+
"local_" ^ (string_of_int !v)
274278

275279
let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) =
276280
match str.pstr_desc with
277-
| Pstr_extension ( ({txt = ("bs.raw"| "raw") ; loc}, payload), _attrs)
278-
->
279-
Ast_exp_handle_external.handle_raw_structure loc payload
280-
| Pstr_extension (({txt = ("bs.debugger.chrome" | "debugger.chrome") ;loc}, payload),_)
281-
->
282-
Location.prerr_warning loc (Preprocessor "this extension can be safely removed");
283-
Ast_structure.dummy_item loc
284281
| Pstr_type (
285-
_rf,
282+
_rf, (* FIXME *)
286283
(_ :: _ as tdcls )) (* [ {ptype_attributes} as tdcl ] *)->
287284
Ast_tdcls.handleTdclsInStru self str tdcls
288285
| Pstr_primitive prim when Ast_attributes.external_needs_to_be_encoded prim.pval_attributes
@@ -341,15 +338,60 @@ let structure_item_mapper (self : mapper) (str : Parsetree.structure_item) =
341338
| _ -> default_mapper.structure_item self str
342339

343340

344-
341+
let rec
342+
structure_mapper (self : mapper) stru =
343+
match stru with
344+
| [] -> []
345+
| item::rest ->
346+
let new_x = self.structure_item self item in
347+
match new_x.pstr_desc with
348+
| Pstr_extension (({txt = ("bs.debugger.chrome" | "debugger.chrome") ;loc}, _),_)
349+
->
350+
Location.prerr_warning loc (Preprocessor "this extension can be safely removed");
351+
(structure_mapper self rest)
352+
| Pstr_extension ( ({txt = ("bs.raw"| "raw") ; loc}, payload), _attrs)
353+
->
354+
Ast_exp_handle_external.handle_raw_structure loc payload :: (structure_mapper self rest)
355+
| Pstr_extension (({txt = "local"; loc}, payload),_)
356+
->
357+
begin match payload with
358+
| PStr stru ->
359+
(* check no module, no type allowed *)
360+
(* let stru = self.structure self stru in *)
361+
Ext_list.iter stru Typemod_hide.check;
362+
let local_module_name = local_module_name () in
363+
let open Ast_helper in
364+
Str.module_
365+
~loc
366+
{ pmb_name = {txt = local_module_name; loc};
367+
pmb_expr = {
368+
pmod_desc= Pmod_structure stru;
369+
pmod_loc = loc;
370+
pmod_attributes = [] };
371+
pmb_attributes = Typemod_hide.attrs; pmb_loc = loc} ::
372+
Str.open_ ~loc {
373+
popen_lid = {txt = Lident local_module_name; loc};
374+
popen_override = Override;
375+
popen_loc = loc;
376+
popen_attributes = []
377+
} :: structure_mapper self rest
378+
| PSig _
379+
| PTyp _
380+
| PPat _ ->
381+
Location.raise_errorf ~loc "local extension is not support"
382+
end
383+
| _ ->
384+
new_x :: (structure_mapper self rest)
385+
345386
let unsafe_mapper : mapper =
346387
{ default_mapper with
347388
expr = expr_mapper;
348389
typ = typ_mapper ;
349390
class_type = class_type_mapper;
350391
signature_item = signature_item_mapper ;
351392
value_bindings = Ast_tuple_pattern_flatten.value_bindings_mapper;
352-
structure_item = structure_item_mapper
393+
structure_item = structure_item_mapper;
394+
structure = structure_mapper
353395
}
354396

355397

jscomp/test/build.ninja

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,7 @@ build test/int_hashtbl_test.cmi test/int_hashtbl_test.cmj : cc test/int_hashtbl_
364364
build test/int_map.cmi test/int_map.cmj : cc test/int_map.ml | $stdlib
365365
build test/int_overflow_test.cmi test/int_overflow_test.cmj : cc test/int_overflow_test.ml | test/mt.cmj $stdlib
366366
build test/int_switch_test.cmi test/int_switch_test.cmj : cc test/int_switch_test.ml | test/mt.cmj $stdlib
367+
build test/internal_unused_test.cmi test/internal_unused_test.cmj : cc test/internal_unused_test.ml | $stdlib
367368
build test/io_test.cmi test/io_test.cmj : cc test/io_test.ml | $stdlib
368369
build test/js_array_test.cmi test/js_array_test.cmj : cc test/js_array_test.ml | test/mt.cmj $stdlib
369370
build test/js_bool_test.cmi test/js_bool_test.cmj : cc test/js_bool_test.ml | test/mt.cmj $stdlib

jscomp/test/internal_unused_test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
var Caml_exceptions = require("../../lib/js/caml_exceptions.js");
4+
5+
console.log(3);
6+
7+
var A = Caml_exceptions.create("Internal_unused_test.P1.A");
8+
9+
function f(param) {
10+
throw A;
11+
}
12+
13+
var c = 5;
14+
15+
function h(a, b) {
16+
return a + b | 0;
17+
}
18+
19+
console.log(c);
20+
21+
console.log(h(1, 2));
22+
23+
exports.f = f;
24+
/* Not a pure module */

jscomp/test/internal_unused_test.ml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
[@@@warning "A"]
2+
[@@@warnerror "a"]
3+
;; module [@internal.local] P0 = struct
4+
let a = 3 in
5+
Js.log a ; a + 2
6+
end
7+
open! P0
8+
9+
;; module [@internal.local] P1 = struct
10+
exception A
11+
let _a = 2
12+
end
13+
open! P1
14+
15+
let f () = raise A
16+
17+
let%local b = 3
18+
19+
let%local c = b + 2
20+
21+
[%%local
22+
let d = c
23+
let f = d
24+
let h = fun[@bs] a b -> a + b
25+
]
26+
27+
28+
29+
;; Js.log f
30+
31+
;; Js.log (h 1 2 [@bs])
32+
33+
(* [%%debugger.chrome] *)

0 commit comments

Comments
 (0)