diff options
author | 2023-04-26 21:46:35 -0700 | |
---|---|---|
committer | 2023-04-26 21:46:35 -0700 | |
commit | 75e3546f3a78cc504a7002a636d2654b598f8ff9 (patch) | |
tree | 393a974179124e34e82387b317f3280855d2bf91 | |
parent | 6c6118e2103c4d6a64b45f4970044277936f0fa4 (diff) | |
download | bun-75e3546f3a78cc504a7002a636d2654b598f8ff9.tar.gz bun-75e3546f3a78cc504a7002a636d2654b598f8ff9.tar.zst bun-75e3546f3a78cc504a7002a636d2654b598f8ff9.zip |
ensure `super()` is not merged with adjacent statements (#2757)
* ensure `super()` is not merged with adjacent statements
* add TODO
-rw-r--r-- | src/js_ast.zig | 4 | ||||
-rw-r--r-- | src/js_parser.zig | 19 |
2 files changed, 18 insertions, 5 deletions
diff --git a/src/js_ast.zig b/src/js_ast.zig index cd9f876bd..35fe6b6ec 100644 --- a/src/js_ast.zig +++ b/src/js_ast.zig @@ -2511,6 +2511,10 @@ pub const Stmt = struct { return @as(Stmt.Tag, self.data) == .s_type_script; } + pub fn isSuperCall(self: Stmt) bool { + return self.data == .s_expr and self.data.s_expr.value.data == .e_call and self.data.s_expr.value.data.e_call.target.data == .e_super; + } + pub fn empty() Stmt { return Stmt{ .data = .{ .s_empty = None }, .loc = logger.Loc{} }; } diff --git a/src/js_parser.zig b/src/js_parser.zig index abecc989c..3a35ed679 100644 --- a/src/js_parser.zig +++ b/src/js_parser.zig @@ -19154,6 +19154,9 @@ fn NewParser_( constructor_function.?.func.body.stmts = constructor_stmts.items; } + + // TODO: make sure "super()" comes before instance field initializers + // https://github.com/evanw/esbuild/blob/e9413cc4f7ab87263ea244a999c6fa1f1e34dc65/internal/js_parser/js_parser_lower.go#L2742 } var stmts_count: usize = 1 + static_members.items.len + instance_decorators.items.len + static_decorators.items.len; @@ -20128,6 +20131,12 @@ fn NewParser_( break; } + // don't merge super calls to ensure they are called before "this" is accessed + if (stmt.isSuperCall()) { + output.append(stmt) catch unreachable; + continue; + } + switch (stmt.data) { .s_empty => continue, @@ -20151,7 +20160,7 @@ fn NewParser_( // Merge adjacent expression statements if (output.items.len > 0) { var prev_stmt = &output.items[output.items.len - 1]; - if (prev_stmt.data == .s_expr) { + if (prev_stmt.data == .s_expr and !prev_stmt.isSuperCall()) { prev_stmt.data.s_expr.does_not_affect_tree_shaking = prev_stmt.data.s_expr.does_not_affect_tree_shaking and s_expr.does_not_affect_tree_shaking; prev_stmt.data.s_expr.value = prev_stmt.data.s_expr.value.joinWithComma( @@ -20166,7 +20175,7 @@ fn NewParser_( // Absorb a previous expression statement if (output.items.len > 0) { var prev_stmt = &output.items[output.items.len - 1]; - if (prev_stmt.data == .s_expr) { + if (prev_stmt.data == .s_expr and !prev_stmt.isSuperCall()) { s_switch.test_ = prev_stmt.data.s_expr.value.joinWithComma(s_switch.test_, p.allocator); output.items.len -= 1; } @@ -20176,7 +20185,7 @@ fn NewParser_( // Absorb a previous expression statement if (output.items.len > 0) { var prev_stmt = &output.items[output.items.len - 1]; - if (prev_stmt.data == .s_expr) { + if (prev_stmt.data == .s_expr and !prev_stmt.isSuperCall()) { s_if.test_ = prev_stmt.data.s_expr.value.joinWithComma(s_if.test_, p.allocator); output.items.len -= 1; } @@ -20189,7 +20198,7 @@ fn NewParser_( // Merge return statements with the previous expression statement if (output.items.len > 0 and ret.value != null) { var prev_stmt = &output.items[output.items.len - 1]; - if (prev_stmt.data == .s_expr) { + if (prev_stmt.data == .s_expr and !prev_stmt.isSuperCall()) { ret.value = prev_stmt.data.s_expr.value.joinWithComma(ret.value.?, p.allocator); prev_stmt.* = stmt; continue; @@ -20207,7 +20216,7 @@ fn NewParser_( // Merge throw statements with the previous expression statement if (output.items.len > 0) { var prev_stmt = &output.items[output.items.len - 1]; - if (prev_stmt.data == .s_expr) { + if (prev_stmt.data == .s_expr and !prev_stmt.isSuperCall()) { prev_stmt.* = p.s(S.Throw{ .value = prev_stmt.data.s_expr.value.joinWithComma( stmt.data.s_throw.value, |