Skip to content

Commit 5b9d77c

Browse files
CPunisherCopilot
andauthored
feat(es/parser): Support no_paren parser option (#11359)
**Description:** There's no `ParenExpr` ast type in estree spec: https://github.com/estree/estree/blob/master/es5.md This PR is a simple and useful implementation to eliminate the usage of `paren_remover`. --------- Co-authored-by: Copilot <[email protected]>
1 parent 25f3a47 commit 5b9d77c

File tree

7 files changed

+46
-0
lines changed

7 files changed

+46
-0
lines changed

.changeset/chatty-dragons-turn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
swc_ecma_parser: major
3+
---
4+
5+
feat(es/parser): support `no_paren` parser option

crates/swc/tests/rust_api.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,7 @@ fn shopify_2_same_opt() {
130130
tsx: true,
131131
decorators: false,
132132
dts: false,
133+
no_paren: false,
133134
no_early_errors: false,
134135
disallow_ambiguous_jsx_like: false,
135136
})),

crates/swc/tests/tsc.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ fn matrix(input: &Path) -> Vec<TestUnitData> {
389389
tsx: is_jsx,
390390
decorators,
391391
dts: false,
392+
no_paren: false,
392393
no_early_errors: false,
393394
disallow_ambiguous_jsx_like: false,
394395
})),

crates/swc_ecma_parser/src/parser/expr.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2416,6 +2416,11 @@ impl<I: Tokens> Parser<I> {
24162416
} => syntax_error!(self, expr.span(), SyntaxError::SpreadInParenExpr),
24172417
ExprOrSpread { expr, .. } => expr,
24182418
};
2419+
2420+
if self.syntax().no_paren() {
2421+
return Ok(expr);
2422+
}
2423+
24192424
Ok(ParenExpr {
24202425
span: self.span(expr_start),
24212426
expr,
@@ -2445,6 +2450,11 @@ impl<I: Tokens> Parser<I> {
24452450
exprs,
24462451
}
24472452
.into();
2453+
2454+
if self.syntax().no_paren() {
2455+
return Ok(seq_expr);
2456+
}
2457+
24482458
Ok(ParenExpr {
24492459
span: self.span(expr_start),
24502460
expr: seq_expr,

crates/swc_ecma_parser/src/syntax.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,13 @@ pub struct TsSyntax {
176176
#[serde(skip, default)]
177177
pub dts: bool,
178178

179+
#[serde(default)]
180+
/// When enabled, the parser will not create ParenExpr nodes for
181+
/// parenthesized expressions. Instead, it returns the inner expression
182+
/// directly. This aligns with the ESTree spec, which does not have a
183+
/// ParenthesizedExpression type.
184+
pub no_paren: bool,
185+
179186
#[serde(skip, default)]
180187
pub no_early_errors: bool,
181188

@@ -203,6 +210,9 @@ impl TsSyntax {
203210
if self.decorators {
204211
flags |= SyntaxFlags::DECORATORS;
205212
}
213+
if self.no_paren {
214+
flags |= SyntaxFlags::NO_PAREN;
215+
}
206216
if self.dts {
207217
flags |= SyntaxFlags::DTS;
208218
}
@@ -227,6 +237,13 @@ pub struct EsSyntax {
227237
#[serde(default)]
228238
pub fn_bind: bool,
229239

240+
#[serde(default)]
241+
/// When enabled, the parser will not create ParenExpr nodes for
242+
/// parenthesized expressions. Instead, it returns the inner expression
243+
/// directly. This aligns with the ESTree spec, which does not have a
244+
/// ParenthesizedExpression type.
245+
pub no_paren: bool,
246+
230247
/// Enable decorators.
231248
#[serde(default)]
232249
pub decorators: bool,
@@ -271,6 +288,9 @@ impl EsSyntax {
271288
if self.decorators {
272289
flags |= SyntaxFlags::DECORATORS;
273290
}
291+
if self.no_paren {
292+
flags |= SyntaxFlags::NO_PAREN;
293+
}
274294
if self.decorators_before_export {
275295
flags |= SyntaxFlags::DECORATORS_BEFORE_EXPORT;
276296
}
@@ -318,6 +338,11 @@ impl SyntaxFlags {
318338
self.contains(SyntaxFlags::FN_BIND)
319339
}
320340

341+
#[inline(always)]
342+
pub const fn no_paren(&self) -> bool {
343+
self.contains(SyntaxFlags::NO_PAREN)
344+
}
345+
321346
#[inline(always)]
322347
pub const fn decorators(&self) -> bool {
323348
self.contains(SyntaxFlags::DECORATORS)
@@ -395,5 +420,6 @@ bitflags::bitflags! {
395420
const NO_EARLY_ERRORS = 1 << 11;
396421
const DISALLOW_AMBIGUOUS_JSX_LIKE = 1 << 12;
397422
const TS = 1 << 13;
423+
const NO_PAREN = 1 << 14;
398424
}
399425
}

crates/swc_ecma_transforms_base/src/fixer.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub fn fixer(comments: Option<&dyn Comments>) -> impl '_ + Pass + VisitMut {
2323
})
2424
}
2525

26+
/// [swc_ecma_parser::EsSyntax::no_paren] is another straightforward way to get
27+
/// the AST without [swc_ecma_ast::ParenExpr]
2628
pub fn paren_remover(comments: Option<&dyn Comments>) -> impl '_ + Pass + VisitMut {
2729
visit_mut_pass(Fixer {
2830
comments,

crates/swc_ecma_transforms_typescript/tests/strip_correctness.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ fn identity(entry: PathBuf) {
8585
tsx: file_name.contains("tsx"),
8686
decorators: true,
8787
dts: false,
88+
no_paren: false,
8889
no_early_errors: false,
8990
disallow_ambiguous_jsx_like: false,
9091
}),

0 commit comments

Comments
 (0)