Skip to content

Commit 9865598

Browse files
committed
Compiler: fix es6 scopes
1 parent 606ce62 commit 9865598

File tree

5 files changed

+216
-22
lines changed

5 files changed

+216
-22
lines changed

compiler/bin-jsoo_minify/jsoo_minify.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ let f { Cmd_arg.common; output_file; use_stdin; files } =
8181
let true_ () = true in
8282
let open Config in
8383
let passes : ((unit -> bool) * (unit -> Js_traverse.mapper)) list =
84-
[ (Flag.shortvar, fun () -> new Js_traverse.rename_variable)
84+
[ (Flag.shortvar, fun () -> (new Js_traverse.rename_variable :> Js_traverse.mapper))
8585
; (true_, fun () -> new Js_traverse.simpl)
8686
; (true_, fun () -> new Js_traverse.clean)
8787
]

compiler/lib/js_traverse.ml

Lines changed: 143 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class type mapper = object
3535

3636
method class_decl : Javascript.class_declaration -> Javascript.class_declaration
3737

38+
method class_element : Javascript.class_element -> Javascript.class_element
39+
3840
method initialiser :
3941
Javascript.expression * Javascript.location
4042
-> Javascript.expression * Javascript.location
@@ -108,7 +110,7 @@ class map : mapper =
108110
; body = List.map x.body ~f:m#class_element
109111
}
110112

111-
method private class_element x =
113+
method class_element x =
112114
match x with
113115
| CEMethod (s, n, meth) -> CEMethod (s, m#class_element_name n, m#method_ meth)
114116
| CEField (s, n, i) -> CEField (s, m#class_element_name n, m#initialiser_o i)
@@ -305,6 +307,8 @@ class map : mapper =
305307
class type iterator = object
306308
method fun_decl : Javascript.function_declaration -> unit
307309

310+
method class_decl : Javascript.class_declaration -> unit
311+
308312
method early_error : Javascript.early_error -> unit
309313

310314
method expression : Javascript.expression -> unit
@@ -373,7 +377,7 @@ class iter : iterator =
373377
m#formal_parameter_list params;
374378
m#function_body body
375379

376-
method private class_decl x =
380+
method class_decl x =
377381
Option.iter x.extends ~f:m#expression;
378382
List.iter x.body ~f:m#class_element
379383

@@ -843,14 +847,19 @@ class free =
843847
m#merge_info tbody;
844848
EFun (ident, (k, params, body, nid))
845849
| EClass (ident_o, cl_decl) ->
850+
let same_level = level in
851+
let cbody = {<state_ = empty; level = same_level>} in
846852
let ident_o =
847853
Option.map
848854
~f:(fun id ->
849-
m#def_var id;
850-
m#ident id)
855+
cbody#def_var id;
856+
id)
851857
ident_o
852858
in
853-
EClass (ident_o, m#class_decl cl_decl)
859+
let cl_decl = cbody#class_decl cl_decl in
860+
cbody#record_block Normal;
861+
m#merge_block_info cbody;
862+
EClass (ident_o, cl_decl)
854863
| _ -> super#expression x
855864

856865
method record_block _ = ()
@@ -870,6 +879,16 @@ class free =
870879
m#merge_block_info tbody;
871880
b
872881

882+
method class_element x =
883+
match x with
884+
| CEStaticBLock l ->
885+
let tbody = {<state_ = empty; level = level + 1>} in
886+
let l = tbody#statements l in
887+
tbody#record_block Normal;
888+
m#merge_info tbody;
889+
CEStaticBLock l
890+
| _ -> super#class_element x
891+
873892
method statement x =
874893
match x with
875894
| Function_declaration (id, (k, params, body, nid)) ->
@@ -883,9 +902,56 @@ class free =
883902
m#merge_info tbody;
884903
Function_declaration (id, (k, params, body, nid))
885904
| Class_declaration (id, cl_decl) ->
905+
let same_level = level in
906+
let cbody = {<state_ = empty; level = same_level>} in
907+
let cl_decl = cbody#class_decl cl_decl in
908+
cbody#record_block Normal;
909+
m#merge_block_info cbody;
886910
m#def_var id;
887-
Class_declaration (id, m#class_decl cl_decl)
911+
Class_declaration (id, cl_decl)
888912
| Block b -> Block (m#block b)
913+
| For_statement (Right (((Const | Let) as k), l), e1, e2, (st, loc)) ->
914+
let same_level = level in
915+
let m' = {<state_ = empty; level = same_level>} in
916+
let l = List.map ~f:(m'#variable_declaration k) l in
917+
let e1 = Option.map ~f:m'#expression e1 in
918+
let e2 = Option.map ~f:m'#expression e2 in
919+
let st = m'#statement st in
920+
m'#record_block Normal;
921+
m#merge_block_info m';
922+
For_statement (Right (k, l), e1, e2, (st, m#loc loc))
923+
| ForIn_statement (Right (((Const | Let) as k), l), e2, (st, loc)) ->
924+
let same_level = level in
925+
let m' = {<state_ = empty; level = same_level>} in
926+
let l = m'#for_binding k l in
927+
let e2 = m'#expression e2 in
928+
let st = m'#statement st in
929+
m'#record_block Normal;
930+
m#merge_block_info m';
931+
ForIn_statement (Right (k, l), e2, (st, m#loc loc))
932+
| ForOf_statement (Right (((Const | Let) as k), l), e2, (st, loc)) ->
933+
let same_level = level in
934+
let m' = {<state_ = empty; level = same_level>} in
935+
let l = m'#for_binding k l in
936+
let e2 = m'#expression e2 in
937+
let st = m'#statement st in
938+
m'#record_block Normal;
939+
m#merge_block_info m';
940+
ForOf_statement (Right (k, l), e2, (st, m#loc loc))
941+
| Switch_statement (e, l, def, l') ->
942+
let same_level = level in
943+
let m' = {<state_ = empty; level = same_level>} in
944+
let l = List.map l ~f:(fun (e, s) -> m'#switch_case e, m'#statements s) in
945+
let l' = List.map l' ~f:(fun (e, s) -> m'#switch_case e, m'#statements s) in
946+
let def =
947+
match def with
948+
| None -> None
949+
| Some l -> Some (m'#statements l)
950+
in
951+
let e = m#expression e in
952+
m'#record_block Normal;
953+
m#merge_block_info m';
954+
Switch_statement (e, l, def, l')
889955
| Try_statement (b, w, f) ->
890956
let same_level = level in
891957
let b = m#block b in
@@ -958,24 +1024,38 @@ class rename_variable =
9581024

9591025
inherit iter as super
9601026

961-
method expression e =
962-
match e with
963-
| EClass (ido, _) ->
964-
Option.iter ido ~f:decl_var;
965-
super#expression e
966-
| _ -> super#expression e
1027+
method expression _ = ()
9671028

9681029
method fun_decl _ = ()
9691030

1031+
method class_decl _ = ()
1032+
9701033
method statement x =
9711034
match scope, x with
9721035
| Fun_block _, Function_declaration (id, fd) ->
9731036
decl_var id;
9741037
self#fun_decl fd
9751038
| Lexical_block, Function_declaration (_, fd) -> self#fun_decl fd
976-
| (Fun_block _ | Lexical_block), Class_declaration (id, _) ->
1039+
| (Lexical_block | Fun_block _), Class_declaration (id, cl_decl) ->
9771040
decl_var id;
978-
super#statement x
1041+
self#class_decl cl_decl
1042+
| _, For_statement (Right (((Const | Let) as k), l), _e1, _e2, (st, _loc)) ->
1043+
let m = {<depth = depth + 1>} in
1044+
List.iter ~f:(m#variable_declaration k) l;
1045+
m#statement st
1046+
| _, ForOf_statement (Right (((Const | Let) as k), l), _e2, (st, _loc)) ->
1047+
let m = {<depth = depth + 1>} in
1048+
m#for_binding k l;
1049+
m#statement st
1050+
| _, ForIn_statement (Right (((Const | Let) as k), l), _e2, (st, _loc)) ->
1051+
let m = {<depth = depth + 1>} in
1052+
m#for_binding k l;
1053+
m#statement st
1054+
| _, Switch_statement (_, l, def, l') ->
1055+
let m = {<depth = depth + 1>} in
1056+
List.iter l ~f:(fun (_, s) -> m#statements s);
1057+
Option.iter def ~f:(fun l -> m#statements l);
1058+
List.iter l' ~f:(fun (_, s) -> m#statements s)
9791059
| (Fun_block _ | Lexical_block), _ -> super#statement x
9801060

9811061
method variable_declaration k l =
@@ -1016,7 +1096,7 @@ class rename_variable =
10161096

10171097
val labels = StringMap.empty
10181098

1019-
method private update_state scope params iter_body =
1099+
method update_state scope params iter_body =
10201100
let declared_names = declared scope params iter_body in
10211101
{<subst = StringSet.fold
10221102
(fun name subst -> StringMap.add name (Code.Var.fresh_n name) subst)
@@ -1030,6 +1110,13 @@ class rename_variable =
10301110
| S { name = Utf8 name; _ } -> (
10311111
try V (StringMap.find name subst) with Not_found -> x)
10321112

1113+
method class_element x =
1114+
match x with
1115+
| CEStaticBLock l ->
1116+
let m' = m#update_state (Fun_block None) [] l in
1117+
CEStaticBLock (m'#statements l)
1118+
| _ -> super#class_element x
1119+
10331120
method fun_decl (k, params, body, nid) =
10341121
let ids = bound_idents_of_params params in
10351122
let m' = m#update_state (Fun_block None) ids body in
@@ -1047,6 +1134,9 @@ class rename_variable =
10471134
EFun
10481135
( Option.map ident ~f:m'#ident
10491136
, (k, m'#formal_parameter_list params, m'#function_body body, m#loc nid) )
1137+
| EClass (Some id, cl_decl) ->
1138+
let m' = m#update_state Lexical_block [ id ] [] in
1139+
EClass (Some (m'#ident id), m'#class_decl cl_decl)
10501140
| _ -> super#expression e
10511141

10521142
method statement s =
@@ -1081,6 +1171,28 @@ class rename_variable =
10811171
Function_declaration
10821172
( m#ident id
10831173
, (k, m'#formal_parameter_list params, m'#function_body body, m#loc nid) )
1174+
| For_statement (Right (((Const | Let) as k), l), e1, e2, (st, loc)) ->
1175+
let ids = List.concat_map ~f:bound_idents_of_variable_declaration l in
1176+
let m' = m#update_state Lexical_block ids [] in
1177+
For_statement
1178+
( Right (k, List.map ~f:(m'#variable_declaration k) l)
1179+
, Option.map ~f:m'#expression e1
1180+
, Option.map ~f:m'#expression e2
1181+
, (m'#statement st, m'#loc loc) )
1182+
| ForOf_statement (Right (((Const | Let) as k), l), e2, (st, loc)) ->
1183+
let ids = bound_idents_of_binding l in
1184+
let m' = m#update_state Lexical_block ids [] in
1185+
ForOf_statement
1186+
( Right (k, m'#for_binding k l)
1187+
, m'#expression e2
1188+
, (m'#statement st, m'#loc loc) )
1189+
| ForIn_statement (Right (((Const | Let) as k), l), e2, (st, loc)) ->
1190+
let ids = bound_idents_of_binding l in
1191+
let m' = m#update_state Lexical_block ids [] in
1192+
ForOf_statement
1193+
( Right (k, m'#for_binding k l)
1194+
, m'#expression e2
1195+
, (m'#statement st, m'#loc loc) )
10841196
| Block l ->
10851197
let m' = m#update_state Lexical_block [] l in
10861198
Block (m'#statements l)
@@ -1124,6 +1236,22 @@ class rename_variable =
11241236
Some (i, m'#statements catch)
11251237
in
11261238
Try_statement (block, catch, final)
1239+
| Switch_statement (e, l, def, l') ->
1240+
let all =
1241+
let r = ref [] in
1242+
Option.iter def ~f:(fun l -> r := List.rev_append l !r);
1243+
List.iter l ~f:(fun (_, s) -> r := List.rev_append s !r);
1244+
List.iter l' ~f:(fun (_, s) -> r := List.rev_append s !r);
1245+
!r
1246+
in
1247+
let m' = m#update_state Lexical_block [] all in
1248+
Switch_statement
1249+
( m#expression e
1250+
, List.map l ~f:(fun (e, s) -> m'#switch_case e, m'#statements s)
1251+
, (match def with
1252+
| None -> None
1253+
| Some l -> Some (m'#statements l))
1254+
, List.map l' ~f:(fun (e, s) -> m'#switch_case e, m'#statements s) )
11271255
| _ -> super#statement s
11281256
end
11291257

compiler/lib/js_traverse.mli

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ class type mapper = object
3434

3535
method class_decl : Javascript.class_declaration -> Javascript.class_declaration
3636

37+
method class_element : Javascript.class_element -> Javascript.class_element
38+
3739
method initialiser : expression * location -> expression * location
3840

3941
method initialiser_o : (expression * location) option -> (expression * location) option
@@ -67,6 +69,8 @@ end
6769
class type iterator = object
6870
method fun_decl : Javascript.function_declaration -> unit
6971

72+
method class_decl : Javascript.class_declaration -> unit
73+
7074
method early_error : Javascript.early_error -> unit
7175

7276
method expression : Javascript.expression -> unit
@@ -147,7 +151,15 @@ end
147151

148152
class free : freevar
149153

150-
class rename_variable : mapper
154+
type scope =
155+
| Lexical_block
156+
| Fun_block of ident option
157+
158+
class rename_variable : object ('a)
159+
inherit mapper
160+
161+
method update_state : scope -> Javascript.ident list -> Javascript.statement_list -> 'a
162+
end
151163

152164
class share_constant : mapper
153165

compiler/lib/stdlib.ml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ module Option = struct
347347
| None -> None
348348
| Some v -> Some (f v)
349349

350+
let to_list = function
351+
| None -> []
352+
| Some x -> [ x ]
353+
350354
let bind ~f x =
351355
match x with
352356
| None -> None

0 commit comments

Comments
 (0)