diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index 4a54ed5c2..fa0387e67 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -215,7 +215,11 @@ impl<'a> Parser<'a> { ) }; - Ok(self.ast.parenthesized_expression(paren_span, expression)) + Ok(if self.preserve_parens { + self.ast.parenthesized_expression(paren_span, expression) + } else { + expression + }) } /// Section 13.2.2 This Expression diff --git a/crates/oxc_parser/src/lexer/mod.rs b/crates/oxc_parser/src/lexer/mod.rs index cc7c4be3c..30f076b10 100644 --- a/crates/oxc_parser/src/lexer/mod.rs +++ b/crates/oxc_parser/src/lexer/mod.rs @@ -180,7 +180,7 @@ impl<'a> Lexer<'a> { /// See Section 12: /// The `InputElementRegExp` goal symbol is used in all syntactic grammar contexts /// where a `RegularExpressionLiteral` is permitted - /// Which meams the parser needs to re-tokenize on `PrimaryExpression`, + /// Which means the parser needs to re-tokenize on `PrimaryExpression`, /// `RegularExpressionLiteral` only appear on the right hand side of `PrimaryExpression` pub fn next_regex(&mut self, kind: Kind) -> Token<'a> { self.current.token.start = self.offset() diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index 07bbc14ec..8765b43a3 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -126,6 +126,10 @@ pub struct Parser<'a> { /// Ast builder for creating AST spans ast: AstBuilder<'a>, + + /// Emit `ParenthesizedExpression` in AST. + /// Default: `true` + preserve_parens: bool, } impl<'a> Parser<'a> { @@ -141,6 +145,7 @@ impl<'a> Parser<'a> { state: ParserState::new(allocator), ctx: Self::default_context(source_type), ast: AstBuilder::new(allocator), + preserve_parens: true, } } @@ -154,6 +159,16 @@ impl<'a> Parser<'a> { self } + /// Emit `ParenthesizedExpression` in AST. + /// + /// If this option is true, parenthesized expressions are represented by (non-standard) + /// `ParenthesizedExpression` nodes that have a single expression property containing the expression inside parentheses. + #[must_use] + pub fn preserve_parens(mut self, allow: bool) -> Self { + self.preserve_parens = allow; + self + } + /// Main entry point /// /// Returns an empty `Program` on unrecoverable error,