1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use swc_atoms::{js_word, JsWord};
use swc_ecma_ast::Stmt;
pub fn is_global_var_with_pure_property_access(s: &JsWord) -> bool {
match *s {
js_word!("JSON")
| js_word!("Array")
| js_word!("String")
| js_word!("Object")
| js_word!("Number")
| js_word!("Date")
| js_word!("BigInt")
| js_word!("Boolean")
| js_word!("Math")
| js_word!("Error") => return true,
_ => {}
}
matches!(
&**s,
"console"
| "clearInterval"
| "clearTimeout"
| "setInterval"
| "setTimeout"
| "btoa"
| "decodeURI"
| "decodeURIComponent"
| "encodeURI"
| "encodeURIComponent"
| "escape"
| "eval"
| "EvalError"
| "Function"
| "isFinite"
| "isNaN"
| "JSON"
| "parseFloat"
| "parseInt"
| "RegExp"
| "RangeError"
| "ReferenceError"
| "SyntaxError"
| "TypeError"
| "unescape"
| "URIError"
| "atob"
| "globalThis"
| "NaN"
| "Symbol"
| "Promise"
)
}
pub fn can_end_conditionally(s: &Stmt) -> bool {
fn can_end(s: &Stmt, ignore_always: bool) -> bool {
match s {
Stmt::If(s) => {
can_end(&s.cons, false)
|| s.alt
.as_deref()
.map(|s| can_end(s, false))
.unwrap_or_default()
}
Stmt::Switch(s) => s
.cases
.iter()
.any(|case| case.cons.iter().any(|s| can_end(s, false))),
Stmt::DoWhile(s) => can_end(&s.body, false),
Stmt::While(s) => can_end(&s.body, false),
Stmt::For(s) => can_end(&s.body, false),
Stmt::ForOf(s) => can_end(&s.body, false),
Stmt::ForIn(s) => can_end(&s.body, false),
Stmt::Return(..) | Stmt::Break(..) | Stmt::Continue(..) => !ignore_always,
_ => false,
}
}
can_end(s, true)
}