diff --git a/crates/oxc_ast_lower/src/lib.rs b/crates/oxc_ast_lower/src/lib.rs index e6cb265a4..f605c2287 100644 --- a/crates/oxc_ast_lower/src/lib.rs +++ b/crates/oxc_ast_lower/src/lib.rs @@ -62,11 +62,6 @@ impl<'a> AstLower<'a> { self.hir.directive(directive.span, expression, directive.directive) } - fn lower_statement_or_empty(&mut self, statement: &ast::Statement<'a>) -> hir::Statement<'a> { - self.lower_statement(statement) - .unwrap_or_else(|| self.hir.empty_statement(statement.span())) - } - fn lower_statement(&mut self, statement: &ast::Statement<'a>) -> Option> { match statement { ast::Statement::BlockStatement(stmt) => { @@ -77,7 +72,7 @@ impl<'a> AstLower<'a> { ast::Statement::ContinueStatement(stmt) => Some(self.lower_continue_statement(stmt)), ast::Statement::DebuggerStatement(stmt) => Some(self.lower_debugger_statement(stmt)), ast::Statement::DoWhileStatement(stmt) => Some(self.lower_do_while_statement(stmt)), - ast::Statement::EmptyStatement(stmt) => Some(self.lower_empty_statement(stmt)), + ast::Statement::EmptyStatement(_) => None, ast::Statement::ExpressionStatement(stmt) => { Some(self.lower_expression_statement(stmt)) } @@ -124,15 +119,11 @@ impl<'a> AstLower<'a> { } fn lower_do_while_statement(&mut self, stmt: &ast::DoWhileStatement<'a>) -> hir::Statement<'a> { - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); let test = self.lower_expression(&stmt.test); self.hir.do_while_statement(stmt.span, body, test) } - fn lower_empty_statement(&mut self, stmt: &ast::EmptyStatement) -> hir::Statement<'a> { - self.hir.empty_statement(stmt.span) - } - fn lower_expression_statement( &mut self, stmt: &ast::ExpressionStatement<'a>, @@ -145,7 +136,7 @@ impl<'a> AstLower<'a> { let init = stmt.init.as_ref().map(|init| self.lower_for_statement_init(init)); let test = stmt.test.as_ref().map(|expr| self.lower_expression(expr)); let update = stmt.update.as_ref().map(|expr| self.lower_expression(expr)); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.for_statement(stmt.span, init, test, update, body) } @@ -166,14 +157,14 @@ impl<'a> AstLower<'a> { fn lower_for_in_statement(&mut self, stmt: &ast::ForInStatement<'a>) -> hir::Statement<'a> { let left = self.lower_for_statement_left(&stmt.left); let right = self.lower_expression(&stmt.right); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.for_in_statement(stmt.span, left, right, body) } fn lower_for_of_statement(&mut self, stmt: &ast::ForOfStatement<'a>) -> hir::Statement<'a> { let left = self.lower_for_statement_left(&stmt.left); let right = self.lower_expression(&stmt.right); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.for_of_statement(stmt.span, stmt.r#await, left, right, body) } @@ -193,14 +184,14 @@ impl<'a> AstLower<'a> { fn lower_if_statement(&mut self, stmt: &ast::IfStatement<'a>) -> hir::Statement<'a> { let test = self.lower_expression(&stmt.test); - let consequent = self.lower_statement_or_empty(&stmt.consequent); + let consequent = self.lower_statement(&stmt.consequent); let alternate = stmt.alternate.as_ref().and_then(|stmt| self.lower_statement(stmt)); self.hir.if_statement(stmt.span, test, consequent, alternate) } fn lower_labeled_statement(&mut self, stmt: &ast::LabeledStatement<'a>) -> hir::Statement<'a> { let label = self.lower_label_identifier(&stmt.label); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.labeled_statement(stmt.span, label, body) } @@ -253,13 +244,13 @@ impl<'a> AstLower<'a> { fn lower_while_statement(&mut self, stmt: &ast::WhileStatement<'a>) -> hir::Statement<'a> { let test = self.lower_expression(&stmt.test); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.while_statement(stmt.span, test, body) } fn lower_with_statement(&mut self, stmt: &ast::WithStatement<'a>) -> hir::Statement<'a> { let object = self.lower_expression(&stmt.object); - let body = self.lower_statement_or_empty(&stmt.body); + let body = self.lower_statement(&stmt.body); self.hir.with_statement(stmt.span, object, body) } diff --git a/crates/oxc_hir/src/hir.rs b/crates/oxc_hir/src/hir.rs index a4319caed..de6ed353b 100644 --- a/crates/oxc_hir/src/hir.rs +++ b/crates/oxc_hir/src/hir.rs @@ -960,7 +960,6 @@ pub enum Statement<'a> { ContinueStatement(Box<'a, ContinueStatement>), DebuggerStatement(Box<'a, DebuggerStatement>), DoWhileStatement(Box<'a, DoWhileStatement<'a>>), - EmptyStatement(Box<'a, EmptyStatement>), ExpressionStatement(Box<'a, ExpressionStatement<'a>>), ForInStatement(Box<'a, ForInStatement<'a>>), ForOfStatement(Box<'a, ForOfStatement<'a>>), @@ -1062,14 +1061,6 @@ pub struct VariableDeclarator<'a> { pub definite: bool, } -/// Empty Statement -#[derive(Debug, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] -pub struct EmptyStatement { - #[cfg_attr(feature = "serde", serde(flatten))] - pub span: Span, -} - /// Expression Statement #[derive(Debug, Hash)] #[cfg_attr(feature = "serde", derive(Serialize), serde(tag = "type"))] @@ -1086,7 +1077,7 @@ pub struct IfStatement<'a> { #[cfg_attr(feature = "serde", serde(flatten))] pub span: Span, pub test: Expression<'a>, - pub consequent: Statement<'a>, + pub consequent: Option>, pub alternate: Option>, } @@ -1096,7 +1087,7 @@ pub struct IfStatement<'a> { pub struct DoWhileStatement<'a> { #[cfg_attr(feature = "serde", serde(flatten))] pub span: Span, - pub body: Statement<'a>, + pub body: Option>, pub test: Expression<'a>, } @@ -1107,7 +1098,7 @@ pub struct WhileStatement<'a> { #[cfg_attr(feature = "serde", serde(flatten))] pub span: Span, pub test: Expression<'a>, - pub body: Statement<'a>, + pub body: Option>, } /// For Statement @@ -1119,7 +1110,7 @@ pub struct ForStatement<'a> { pub init: Option>, pub test: Option>, pub update: Option>, - pub body: Statement<'a>, + pub body: Option>, } #[derive(Debug, Hash)] @@ -1137,7 +1128,7 @@ pub struct ForInStatement<'a> { pub span: Span, pub left: ForStatementLeft<'a>, pub right: Expression<'a>, - pub body: Statement<'a>, + pub body: Option>, } /// For-Of Statement @@ -1149,7 +1140,7 @@ pub struct ForOfStatement<'a> { pub r#await: bool, pub left: ForStatementLeft<'a>, pub right: Expression<'a>, - pub body: Statement<'a>, + pub body: Option>, } #[derive(Debug, Hash)] @@ -1193,7 +1184,7 @@ pub struct WithStatement<'a> { #[cfg_attr(feature = "serde", serde(flatten))] pub span: Span, pub object: Expression<'a>, - pub body: Statement<'a>, + pub body: Option>, } /// Switch Statement @@ -1228,7 +1219,7 @@ pub struct LabeledStatement<'a> { #[cfg_attr(feature = "serde", serde(flatten))] pub span: Span, pub label: LabelIdentifier, - pub body: Statement<'a>, + pub body: Option>, } /// Throw Statement diff --git a/crates/oxc_hir/src/hir_builder.rs b/crates/oxc_hir/src/hir_builder.rs index 216a5aa3f..aebb17aaa 100644 --- a/crates/oxc_hir/src/hir_builder.rs +++ b/crates/oxc_hir/src/hir_builder.rs @@ -242,16 +242,12 @@ impl<'a> HirBuilder<'a> { pub fn do_while_statement( &mut self, span: Span, - body: Statement<'a>, + body: Option>, test: Expression<'a>, ) -> Statement<'a> { Statement::DoWhileStatement(self.alloc(DoWhileStatement { span, body, test })) } - pub fn empty_statement(&mut self, span: Span) -> Statement<'a> { - Statement::EmptyStatement(self.alloc(EmptyStatement { span })) - } - pub fn expression_statement( &mut self, span: Span, @@ -265,7 +261,7 @@ impl<'a> HirBuilder<'a> { span: Span, left: ForStatementLeft<'a>, right: Expression<'a>, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::ForInStatement(self.alloc(ForInStatement { span, left, right, body })) } @@ -276,7 +272,7 @@ impl<'a> HirBuilder<'a> { r#await: bool, left: ForStatementLeft<'a>, right: Expression<'a>, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::ForOfStatement(self.alloc(ForOfStatement { span, r#await, left, right, body })) } @@ -287,7 +283,7 @@ impl<'a> HirBuilder<'a> { init: Option>, test: Option>, update: Option>, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::ForStatement(self.alloc(ForStatement { span, init, test, update, body })) } @@ -296,7 +292,7 @@ impl<'a> HirBuilder<'a> { &mut self, span: Span, test: Expression<'a>, - consequent: Statement<'a>, + consequent: Option>, alternate: Option>, ) -> Statement<'a> { Statement::IfStatement(self.alloc(IfStatement { span, test, consequent, alternate })) @@ -306,7 +302,7 @@ impl<'a> HirBuilder<'a> { &mut self, span: Span, label: LabelIdentifier, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::LabeledStatement(self.alloc(LabeledStatement { span, label, body })) } @@ -364,7 +360,7 @@ impl<'a> HirBuilder<'a> { &mut self, span: Span, test: Expression<'a>, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::WhileStatement(self.alloc(WhileStatement { span, test, body })) } @@ -373,7 +369,7 @@ impl<'a> HirBuilder<'a> { &mut self, span: Span, object: Expression<'a>, - body: Statement<'a>, + body: Option>, ) -> Statement<'a> { Statement::WithStatement(self.alloc(WithStatement { span, object, body })) } diff --git a/crates/oxc_hir/src/visit_mut.rs b/crates/oxc_hir/src/visit_mut.rs index ba6ff9249..404bdc1e5 100644 --- a/crates/oxc_hir/src/visit_mut.rs +++ b/crates/oxc_hir/src/visit_mut.rs @@ -34,7 +34,6 @@ pub trait VisitMut<'a, 'b>: Sized { Statement::ContinueStatement(stmt) => self.visit_continue_statement(stmt), Statement::DebuggerStatement(stmt) => self.visit_debugger_statement(stmt), Statement::DoWhileStatement(stmt) => self.visit_do_while_statement(stmt), - Statement::EmptyStatement(stmt) => self.visit_empty_statement(stmt), Statement::ExpressionStatement(stmt) => self.visit_expression_statement(stmt), Statement::ForInStatement(stmt) => self.visit_for_in_statement(stmt), Statement::ForOfStatement(stmt) => self.visit_for_of_statement(stmt), @@ -72,12 +71,12 @@ pub trait VisitMut<'a, 'b>: Sized { fn visit_debugger_statement(&mut self, _stmt: &'b mut DebuggerStatement) {} fn visit_do_while_statement(&mut self, stmt: &'b mut DoWhileStatement<'a>) { - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } self.visit_expression(&mut stmt.test); } - fn visit_empty_statement(&mut self, _stmt: &'b mut EmptyStatement) {} - fn visit_expression_statement(&mut self, stmt: &'b mut ExpressionStatement<'a>) { self.visit_expression(&mut stmt.expression); } @@ -92,7 +91,9 @@ pub trait VisitMut<'a, 'b>: Sized { if let Some(update) = &mut stmt.update { self.visit_expression(update); } - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_for_statement_init(&mut self, init: &'b mut ForStatementInit<'a>) { @@ -107,13 +108,17 @@ pub trait VisitMut<'a, 'b>: Sized { fn visit_for_in_statement(&mut self, stmt: &'b mut ForInStatement<'a>) { self.visit_for_statement_left(&mut stmt.left); self.visit_expression(&mut stmt.right); - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_for_of_statement(&mut self, stmt: &'b mut ForOfStatement<'a>) { self.visit_for_statement_left(&mut stmt.left); self.visit_expression(&mut stmt.right); - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_for_statement_left(&mut self, left: &'b mut ForStatementLeft<'a>) { @@ -127,15 +132,19 @@ pub trait VisitMut<'a, 'b>: Sized { fn visit_if_statement(&mut self, stmt: &'b mut IfStatement<'a>) { self.visit_expression(&mut stmt.test); - self.visit_statement(&mut stmt.consequent); - if let Some(alternate) = &mut stmt.alternate { - self.visit_statement(alternate); + if let Some(stmt) = &mut stmt.consequent { + self.visit_statement(stmt); + } + if let Some(stmt) = &mut stmt.alternate { + self.visit_statement(stmt); } } fn visit_labeled_statement(&mut self, stmt: &'b mut LabeledStatement<'a>) { self.visit_label_identifier(&mut stmt.label); - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_return_statement(&mut self, stmt: &'b mut ReturnStatement<'a>) { @@ -185,12 +194,16 @@ pub trait VisitMut<'a, 'b>: Sized { fn visit_while_statement(&mut self, stmt: &'b mut WhileStatement<'a>) { self.visit_expression(&mut stmt.test); - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_with_statement(&mut self, stmt: &'b mut WithStatement<'a>) { self.visit_expression(&mut stmt.object); - self.visit_statement(&mut stmt.body); + if let Some(stmt) = &mut stmt.body { + self.visit_statement(stmt); + } } fn visit_directive(&mut self, directive: &'b mut Directive<'a>) { diff --git a/crates/oxc_minifier/src/compressor/mod.rs b/crates/oxc_minifier/src/compressor/mod.rs index 5d659e729..de9b64616 100644 --- a/crates/oxc_minifier/src/compressor/mod.rs +++ b/crates/oxc_minifier/src/compressor/mod.rs @@ -67,11 +67,6 @@ impl<'a> Compressor<'a> { /* Statements */ - #[allow(clippy::unused_self)] - fn drop_empty<'b>(&mut self, stmt: &'b Statement<'a>) -> bool { - matches!(stmt, Statement::EmptyStatement(_)) - } - /// Drop `drop_debugger` statement. /// Enabled by `compress.drop_debugger` fn drop_debugger<'b>(&mut self, stmt: &'b Statement<'a>) -> bool { @@ -129,8 +124,7 @@ impl<'a> Compressor<'a> { && self.options.loops { let dummy_test = self.hir.this_expression(SPAN); let test = std::mem::replace(&mut while_stmt.test, dummy_test); - let dummy_body = self.hir.empty_statement(SPAN); - let body = std::mem::replace(&mut while_stmt.body, dummy_body); + let body = while_stmt.body.take(); *stmt = self.hir.for_statement(SPAN, None, Some(test), None, body); } } @@ -188,7 +182,7 @@ impl<'a> Compressor<'a> { impl<'a, 'b> VisitMut<'a, 'b> for Compressor<'a> { fn visit_statements(&mut self, stmts: &'b mut Vec<'a, Statement<'a>>) { - stmts.retain(|stmt| !self.drop_empty(stmt) && !self.drop_debugger(stmt)); + stmts.retain(|stmt| !self.drop_debugger(stmt)); self.join_vars(stmts); diff --git a/crates/oxc_minifier/src/printer/gen.rs b/crates/oxc_minifier/src/printer/gen.rs index d87add260..6a29f940a 100644 --- a/crates/oxc_minifier/src/printer/gen.rs +++ b/crates/oxc_minifier/src/printer/gen.rs @@ -49,7 +49,6 @@ impl<'a> Gen for Statement<'a> { Self::ContinueStatement(stmt) => stmt.gen(p), Self::DebuggerStatement(stmt) => stmt.gen(p), Self::DoWhileStatement(stmt) => stmt.gen(p), - Self::EmptyStatement(stmt) => stmt.gen(p), Self::ExpressionStatement(stmt) => stmt.gen(p), Self::ForInStatement(stmt) => stmt.gen(p), Self::ForOfStatement(stmt) => stmt.gen(p), @@ -68,6 +67,15 @@ impl<'a> Gen for Statement<'a> { } } +impl<'a> Gen for Option> { + fn gen(&self, p: &mut Printer) { + match self { + Some(stmt) => stmt.gen(p), + None => p.print(b';'), + } + } +} + impl<'a> Gen for ExpressionStatement<'a> { fn gen(&self, p: &mut Printer) { self.expression.gen(p); @@ -80,12 +88,6 @@ impl<'a> Gen for ExpressionStatement<'a> { } } -impl Gen for EmptyStatement { - fn gen(&self, p: &mut Printer) { - p.print_semicolon(); - } -} - impl<'a> Gen for IfStatement<'a> { fn gen(&self, p: &mut Printer) { print_if(self, p); @@ -148,7 +150,7 @@ impl<'a> Gen for ForStatement<'a> { } p.print(b')'); - p.print_body(&self.body); + self.body.gen(p); } } @@ -172,7 +174,7 @@ impl<'a> Gen for ForOfStatement<'a> { fn gen_for_statement_brack_content<'a>( left: &ForStatementLeft<'a>, right: &Expression<'a>, - body: &Statement, + body: &Option, key: &[u8], p: &mut Printer, ) { @@ -183,7 +185,7 @@ fn gen_for_statement_brack_content<'a>( p.print(b' '); right.gen(p); p.print(b')'); - p.print_body(body); + body.gen(p); } impl<'a> Gen for ForStatementLeft<'a> { @@ -201,7 +203,7 @@ impl<'a> Gen for WhileStatement<'a> { p.print(b'('); self.test.gen(p); p.print(b')'); - p.print_body(&self.body); + self.body.gen(p); } } @@ -209,7 +211,7 @@ impl<'a> Gen for DoWhileStatement<'a> { fn gen(&self, p: &mut Printer) { p.print_str(b"do"); p.print(b' '); - if let Statement::BlockStatement(block) = &self.body { + if let Some(Statement::BlockStatement(block)) = &self.body { p.print_block1(block); } else { self.body.gen(p);