Skip to content

Commit aff96e7

Browse files
[js] avoid shadowing catch vars (closes #9617)
1 parent 8c095c5 commit aff96e7

File tree

4 files changed

+48
-2
lines changed

4 files changed

+48
-2
lines changed

extra/CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
eval : fixed exception message when catching compiler-generated `haxe.macro.Error` as `Dynamic` (#9600)
1818
lua : fixed lua code generation without `--main` compilation argument (#9489)
1919
php : added an overload signature for `session_set_cookie_params` function (#9507)
20+
js : fixed name collisions for catch variables to avoid closure compiler errors (#9617)
2021
nullsafety : fixed various scenarios of `if..else` branching (#9474)
2122

2223
2020-22-05 4.1.1

src/context/common.ml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ type var_scoping_flags =
107107
It's not allowed to shadow existing variables in a scope.
108108
*)
109109
| NoShadowing
110+
(**
111+
It's not allowed to shadow a `catch` variable.
112+
*)
113+
| NoCatchVarShadowing
110114
(**
111115
Local vars cannot have the same name as the current top-level package or
112116
(if in the root package) current class name
@@ -416,7 +420,7 @@ let get_config com =
416420
vs_scope = if es6 then BlockScope else FunctionScope;
417421
vs_flags =
418422
(if defined Define.JsUnflatten then ReserveAllTopLevelSymbols else ReserveAllTypesFlat)
419-
:: if es6 then [NoShadowing; SwitchCasesNoBlocks;] else [VarHoisting];
423+
:: if es6 then [NoShadowing; SwitchCasesNoBlocks;] else [VarHoisting; NoCatchVarShadowing];
420424
}
421425
}
422426
| Lua ->

src/filters/renameVars.ml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ type rename_init = {
88
mutable ri_scope : var_scope;
99
mutable ri_hoisting : bool;
1010
mutable ri_no_shadowing : bool;
11+
mutable ri_no_catch_var_shadowing : bool;
1112
mutable ri_switch_cases_no_blocks : bool;
1213
mutable ri_reserved : bool StringMap.t;
1314
mutable ri_reserve_current_top_level_symbol : bool;
@@ -50,6 +51,7 @@ let init com =
5051
ri_reserved = StringMap.empty;
5152
ri_hoisting = false;
5253
ri_no_shadowing = false;
54+
ri_no_catch_var_shadowing = false;
5355
ri_switch_cases_no_blocks = false;
5456
ri_reserve_current_top_level_symbol = false;
5557
} in
@@ -60,6 +62,8 @@ let init com =
6062
ri.ri_hoisting <- true;
6163
| NoShadowing ->
6264
ri.ri_no_shadowing <- true;
65+
| NoCatchVarShadowing ->
66+
ri.ri_no_catch_var_shadowing <- true;
6367
| SwitchCasesNoBlocks ->
6468
ri.ri_switch_cases_no_blocks <- true;
6569
| ReserveNames names ->
@@ -101,6 +105,7 @@ type scope = {
101105
type rename_context = {
102106
rc_hoisting : bool;
103107
rc_no_shadowing : bool;
108+
rc_no_catch_var_shadowing : bool;
104109
rc_switch_cases_no_blocks : bool;
105110
rc_scope : var_scope;
106111
mutable rc_reserved : bool StringMap.t;
@@ -223,7 +228,8 @@ let rec collect_vars ?(in_block=false) rc scope e =
223228
| TBlock exprs -> { catch_expr with eexpr = TBlock (v_expr :: exprs) }
224229
| _ -> { catch_expr with eexpr = TBlock [v_expr; catch_expr] }
225230
in
226-
collect_vars scope e
231+
collect_vars scope e;
232+
if rc.rc_no_catch_var_shadowing then use_var rc scope v;
227233
) catches
228234
| TSwitch (target, cases, default_opt) when rc.rc_switch_cases_no_blocks ->
229235
collect_vars scope target;
@@ -307,6 +313,7 @@ let run ctx ri e =
307313
rc_scope = ri.ri_scope;
308314
rc_hoisting = ri.ri_hoisting;
309315
rc_no_shadowing = ri.ri_no_shadowing;
316+
rc_no_catch_var_shadowing = ri.ri_no_catch_var_shadowing;
310317
rc_switch_cases_no_blocks = ri.ri_switch_cases_no_blocks;
311318
rc_reserved = ri.ri_reserved;
312319
} in
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package issues;
2+
3+
class Issue9617 {
4+
@:js('
5+
try {
6+
issues_Issue9617.dummy();
7+
} catch( _g ) {
8+
var _g1 = haxe_Exception.caught(_g);
9+
var e = _g1;
10+
var _g2 = issues_Issue9617.process(_g1);
11+
if(_g2 != null) {
12+
var e = _g2;
13+
issues_Issue9617.dummy();
14+
}
15+
}
16+
')
17+
@:analyzer(no_local_dce)
18+
static public function test() {
19+
try {
20+
dummy();
21+
} catch(e) {
22+
switch process(e) {
23+
case null:
24+
case e: dummy();
25+
}
26+
}
27+
}
28+
29+
@:pure(false) static function process(e) {
30+
return e;
31+
}
32+
33+
@:pure(false) static function dummy() {}
34+
}

0 commit comments

Comments
 (0)