@@ -156,10 +156,12 @@ impl<'a> PeepholeOptimizations {
156
156
157
157
/// Compress `typeof foo == "undefined"`
158
158
///
159
- /// - `typeof foo == "undefined"` (if foo is resolved) -> `foo === undefined`
160
- /// - `typeof foo != "undefined"` (if foo is resolved) -> `foo !== undefined`
161
- /// - `typeof foo == "undefined"` -> `typeof foo > "u"`
162
- /// - `typeof foo != "undefined"` -> `typeof foo < "u"`
159
+ /// - `typeof foo == "undefined"` (if foo is not resolved) -> `typeof foo > "u"`
160
+ /// - `typeof foo != "undefined"` (if foo is not resolved) -> `typeof foo < "u"`
161
+ /// - `typeof foo == "undefined"` -> `foo === undefined`
162
+ /// - `typeof foo != "undefined"` -> `foo !== undefined`
163
+ /// - `typeof foo.bar == "undefined"` -> `foo.bar === undefined` (for any expression e.g.`typeof (foo + "")`)
164
+ /// - `typeof foo.bar != "undefined"` -> `foo.bar !== undefined` (for any expression e.g.`typeof (foo + "")`)
163
165
///
164
166
/// Enabled by `compress.typeofs`
165
167
fn try_compress_typeof_undefined (
@@ -183,24 +185,19 @@ impl<'a> PeepholeOptimizations {
183
185
_ => return None ,
184
186
} ;
185
187
if let Expression :: Identifier ( ident) = & unary_expr. argument {
186
- if !ctx. is_global_reference ( ident) {
187
- let Expression :: UnaryExpression ( unary_expr) =
188
- ctx. ast . move_expression ( & mut expr. left )
189
- else {
190
- unreachable ! ( )
191
- } ;
192
- let right = ctx. ast . void_0 ( expr. right . span ( ) ) ;
193
- return Some ( ctx. ast . expression_binary (
194
- expr. span ,
195
- unary_expr. unbox ( ) . argument ,
196
- new_eq_op,
197
- right,
198
- ) ) ;
188
+ if ctx. is_global_reference ( ident) {
189
+ let left = ctx. ast . move_expression ( & mut expr. left ) ;
190
+ let right = ctx. ast . expression_string_literal ( expr. right . span ( ) , "u" , None ) ;
191
+ return Some ( ctx. ast . expression_binary ( expr. span , left, new_comp_op, right) ) ;
199
192
}
193
+ }
194
+
195
+ let Expression :: UnaryExpression ( unary_expr) = ctx. ast . move_expression ( & mut expr. left )
196
+ else {
197
+ unreachable ! ( )
200
198
} ;
201
- let left = ctx. ast . move_expression ( & mut expr. left ) ;
202
- let right = ctx. ast . expression_string_literal ( expr. right . span ( ) , "u" , None ) ;
203
- Some ( ctx. ast . expression_binary ( expr. span , left, new_comp_op, right) )
199
+ let right = ctx. ast . void_0 ( expr. right . span ( ) ) ;
200
+ Some ( ctx. ast . expression_binary ( expr. span , unary_expr. unbox ( ) . argument , new_eq_op, right) )
204
201
}
205
202
206
203
/// `a || (b || c);` -> `(a || b) || c;`
@@ -1498,6 +1495,10 @@ mod test {
1498
1495
test ( "typeof x !== 'undefined'; var x" , "x !== void 0; var x" ) ;
1499
1496
// input and output both errors with same TDZ error
1500
1497
test ( "typeof x !== 'undefined'; let x" , "x !== void 0; let x" ) ;
1498
+
1499
+ test ( "typeof x.y === 'undefined'" , "x.y === void 0" ) ;
1500
+ test ( "typeof x.y !== 'undefined'" , "x.y !== void 0" ) ;
1501
+ test ( "typeof (x + '') === 'undefined'" , "x + '' === void 0" ) ;
1501
1502
}
1502
1503
1503
1504
/// Port from <https://github.com/evanw/esbuild/blob/v0.24.2/internal/js_parser/js_parser_test.go#L4658>
@@ -1512,9 +1513,6 @@ mod test {
1512
1513
test ( "typeof x == 'undefined'" , "typeof x > 'u'" ) ;
1513
1514
test ( "'undefined' === typeof x" , "typeof x > 'u'" ) ;
1514
1515
test ( "'undefined' == typeof x" , "typeof x > 'u'" ) ;
1515
-
1516
- test ( "typeof x.y === 'undefined'" , "typeof x.y > 'u'" ) ;
1517
- test ( "typeof x.y !== 'undefined'" , "typeof x.y < 'u'" ) ;
1518
1516
}
1519
1517
1520
1518
#[ test]
0 commit comments