diff --git a/crates/oxc_ast/src/span.rs b/crates/oxc_ast/src/span.rs index a6a299620a4e4..9e2fa1fb28fe8 100644 --- a/crates/oxc_ast/src/span.rs +++ b/crates/oxc_ast/src/span.rs @@ -28,6 +28,7 @@ impl Span { #[must_use] pub fn len(&self) -> u32 { + debug_assert!(self.start <= self.end); self.end - self.start } diff --git a/crates/oxc_parser/src/js/expression.rs b/crates/oxc_parser/src/js/expression.rs index bda2e65907008..f27755ad61323 100644 --- a/crates/oxc_parser/src/js/expression.rs +++ b/crates/oxc_parser/src/js/expression.rs @@ -196,18 +196,22 @@ impl<'a> Parser<'a> { self.ctx = self.ctx.and_in(has_in); let mut expressions = list.elements; + let paren_span = self.end_span(span); // ParenthesizedExpression is from acorn --preserveParens let expression = if expressions.len() == 1 { expressions.remove(0) } else { if expressions.is_empty() { - self.error(diagnostics::EmptyParenthesizedExpression(list.span)); + self.error(diagnostics::EmptyParenthesizedExpression(paren_span)); } - self.ast.sequence_expression(list.span, expressions) + self.ast.sequence_expression( + Span::new(paren_span.start + 1, paren_span.end - 1), + expressions, + ) }; - Ok(self.ast.parenthesized_expression(self.end_span(span), expression)) + Ok(self.ast.parenthesized_expression(paren_span, expression)) } /// Section 13.2.2 This Expression diff --git a/crates/oxc_parser/src/js/list.rs b/crates/oxc_parser/src/js/list.rs index 40dbe15378f1b..2bbcf8b609b07 100644 --- a/crates/oxc_parser/src/js/list.rs +++ b/crates/oxc_parser/src/js/list.rs @@ -184,13 +184,12 @@ impl<'a> SeparatedList<'a> for CallArguments<'a> { } pub struct SequenceExpressionList<'a> { - pub span: Span, pub elements: Vec<'a, Expression<'a>>, } impl<'a> SeparatedList<'a> for SequenceExpressionList<'a> { fn new(p: &Parser<'a>) -> Self { - Self { elements: p.ast.new_vec(), span: Span::default() } + Self { elements: p.ast.new_vec() } } fn open(&self) -> Kind { @@ -201,14 +200,6 @@ impl<'a> SeparatedList<'a> for SequenceExpressionList<'a> { Kind::RParen } - fn start_sequence(&mut self, p: &mut Parser) { - self.span = p.start_span(); - } - - fn finish_sequence(&mut self, p: &mut Parser) { - self.span = p.end_span(self.span); - } - // read everything as expression and map to it to either // ParenthesizedExpression or ArrowFormalParameters later fn parse_element(&mut self, p: &mut Parser<'a>) -> Result<()> { diff --git a/crates/oxc_parser/src/lib.rs b/crates/oxc_parser/src/lib.rs index be2b6408ac469..8d62fdff6169e 100644 --- a/crates/oxc_parser/src/lib.rs +++ b/crates/oxc_parser/src/lib.rs @@ -278,6 +278,7 @@ mod test { let fail = [ "1<(V=82<", + "x = (/* a */)", ]; for source in fail { diff --git a/crates/oxc_parser/src/list.rs b/crates/oxc_parser/src/list.rs index b66d8d2160154..6931a06f3781b 100644 --- a/crates/oxc_parser/src/list.rs +++ b/crates/oxc_parser/src/list.rs @@ -42,15 +42,11 @@ pub trait SeparatedList<'a>: Sized { Kind::Comma } - fn start_sequence(&mut self, _p: &mut Parser<'a>) {} - fn finish_sequence(&mut self, _p: &mut Parser<'a>) {} - fn parse_element(&mut self, p: &mut Parser<'a>) -> Result<()>; /// Main entry point, parse the list fn parse_list(&mut self, p: &mut Parser<'a>) -> Result<()> { p.expect(self.open())?; - self.start_sequence(p); let mut first = true; @@ -67,7 +63,6 @@ pub trait SeparatedList<'a>: Sized { self.parse_element(p)?; } - self.finish_sequence(p); p.expect(self.close())?; Ok(()) } diff --git a/tasks/coverage/babel.snap b/tasks/coverage/babel.snap index 55ea47f6299ed..144a301e63531 100644 --- a/tasks/coverage/babel.snap +++ b/tasks/coverage/babel.snap @@ -3790,7 +3790,7 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" × Empty parenthesized expression ╭─[es2015/uncategorised/250/input.js:1:1] 1 │ () <= 42 - · ▲ + · ── ╰──── × Expected a semicolon or an implicit semicolon after a statement, but found none @@ -4242,7 +4242,7 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" × Empty parenthesized expression ╭─[es2015/uncategorised/38/input.js:1:1] 1 │ console.log(typeof () => {}); - · ▲ + · ── ╰──── × Expected `,` but found `=>` @@ -8348,13 +8348,13 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" × Empty parenthesized expression ╭─[esprima/invalid-syntax/migrated_0095/input.js:1:1] 1 │ () <= 42 - · ▲ + · ── ╰──── × Empty parenthesized expression ╭─[esprima/invalid-syntax/migrated_0096/input.js:1:1] 1 │ () ? 42 - · ▲ + · ── ╰──── × Expected `:` but found `EOF` @@ -8365,7 +8365,7 @@ Expect to Parse: "typescript/types/const-type-parameters/input.ts" × Empty parenthesized expression ╭─[esprima/invalid-syntax/migrated_0097/input.js:1:1] 1 │ () + 42 - · ▲ + · ── ╰──── × Expected a semicolon or an implicit semicolon after a statement, but found none diff --git a/tasks/coverage/test262.snap b/tasks/coverage/test262.snap index fbf3888451d00..e84a24ef5acbf 100644 --- a/tasks/coverage/test262.snap +++ b/tasks/coverage/test262.snap @@ -9678,7 +9678,7 @@ Negative Passed: 3915/3915 (100.00%) ╭─[language/expressions/class/elements/syntax/early-errors/class-heritage-array-literal-arrow-heritage.js:22:1] 22 │ 23 │ var C = class extends () => {} { - · ▲ + · ── 24 │ ╰──── @@ -14737,7 +14737,7 @@ Negative Passed: 3915/3915 (100.00%) ╭─[language/expressions/in/private-field-invalid-rhs.js:23:1] 23 │ constructor() { 24 │ #field in () => {}; - · ▲ + · ── 25 │ } ╰──── @@ -20404,14 +20404,14 @@ Negative Passed: 3915/3915 (100.00%) ╭─[language/module-code/parse-err-invoke-anon-fun-decl.js:25:1] 25 │ 26 │ export default function() {}(); - · ▲ + · ── ╰──── × Empty parenthesized expression ╭─[language/module-code/parse-err-invoke-anon-gen-decl.js:27:1] 27 │ 28 │ export default function* () {}(); - · ▲ + · ── ╰──── × TS1108: A 'return' statement can only be used within a function body @@ -25084,7 +25084,7 @@ Negative Passed: 3915/3915 (100.00%) ╭─[language/statements/class/elements/syntax/early-errors/class-heritage-array-literal-arrow-heritage.js:22:1] 22 │ 23 │ class C extends () => {} { - · ▲ + · ── 24 │ ╰──── @@ -28812,7 +28812,7 @@ Negative Passed: 3915/3915 (100.00%) ╭─[language/statements/expression/S12.4_A1.js:18:1] 18 │ //CHECK#1 19 │ function(){}(); - · ▲ + · ── 20 │ // ╰──── diff --git a/tasks/coverage/typescript.snap b/tasks/coverage/typescript.snap index 70cd778e9fde7..174c607ad7046 100644 --- a/tasks/coverage/typescript.snap +++ b/tasks/coverage/typescript.snap @@ -8436,7 +8436,7 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" × Empty parenthesized expression ╭─[parser/ecmascript5/ErrorRecovery/Expressions/parserErrorRecovery_Expression1.ts:1:1] 1 │ var v = ()({}); - · ▲ + · ── ╰──── × Expected `{` but found `EOF` @@ -8688,7 +8688,7 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" ╭─[parser/ecmascript5/ErrorRecovery/parserEmptyParenthesizedExpression1.ts:1:1] 1 │ function getObj() { 2 │ ().toString(); - · ▲ + · ── 3 │ } ╰──── @@ -9218,7 +9218,7 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" ╭─[parser/ecmascript5/RegressionTests/parser509669.ts:1:1] 1 │ function foo():any { 2 │ return ():void {}; - · ▲ + · ── 3 │ } ╰──── @@ -9268,7 +9268,7 @@ Expect to Parse: "salsa/privateIdentifierExpando.ts" × Empty parenthesized expression ╭─[parser/ecmascript5/RegressionTests/parser566700.ts:1:1] 1 │ var v = ()({}); - · ▲ + · ── ╰──── × Expected a semicolon or an implicit semicolon after a statement, but found none