mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
fix(ast): parse rest parameter with the correct optional and type annotation syntax (#2686)
closes #2653
This commit is contained in:
parent
e86cd629c8
commit
6c6adb46d1
4 changed files with 67 additions and 8 deletions
|
|
@ -148,6 +148,11 @@ pub struct BindingRestElementTrailingComma(#[label] pub Span);
|
||||||
#[diagnostic(help("Expected identifier in rest element"))]
|
#[diagnostic(help("Expected identifier in rest element"))]
|
||||||
pub struct InvalidBindingRestElement(#[label] pub Span);
|
pub struct InvalidBindingRestElement(#[label] pub Span);
|
||||||
|
|
||||||
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
|
#[error("A rest parameter cannot be optional")]
|
||||||
|
#[diagnostic()]
|
||||||
|
pub struct ARestParameterCannotBeOptional(#[label] pub Span);
|
||||||
|
|
||||||
#[derive(Debug, Error, Diagnostic)]
|
#[derive(Debug, Error, Diagnostic)]
|
||||||
#[error("Cannot assign to this expression")]
|
#[error("Cannot assign to this expression")]
|
||||||
#[diagnostic()]
|
#[diagnostic()]
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,21 @@ impl<'a> ParserImpl<'a> {
|
||||||
pub(super) fn parse_rest_element(&mut self) -> Result<Box<'a, BindingRestElement<'a>>> {
|
pub(super) fn parse_rest_element(&mut self) -> Result<Box<'a, BindingRestElement<'a>>> {
|
||||||
let span = self.start_span();
|
let span = self.start_span();
|
||||||
self.bump_any(); // advance `...`
|
self.bump_any(); // advance `...`
|
||||||
let argument = self.parse_binding_pattern_with_initializer()?;
|
let init_span = self.start_span();
|
||||||
|
|
||||||
|
let kind = self.parse_binding_pattern_kind()?;
|
||||||
|
// Rest element does not allow `?`, checked in checker/typescript.rs
|
||||||
|
if self.at(Kind::Question) && self.ts_enabled() {
|
||||||
|
let span = self.cur_token().span();
|
||||||
|
self.bump_any();
|
||||||
|
self.error(diagnostics::ARestParameterCannotBeOptional(span));
|
||||||
|
}
|
||||||
|
// The span is not extended to its type_annotation
|
||||||
|
let type_annotation = self.parse_ts_type_annotation()?;
|
||||||
|
let pattern = self.ast.binding_pattern(kind, type_annotation, false);
|
||||||
|
// Rest element does not allow `= initializer`, .
|
||||||
|
let argument =
|
||||||
|
self.with_context(Context::In, |p| p.parse_initializer(init_span, pattern))?;
|
||||||
let span = self.end_span(span);
|
let span = self.end_span(span);
|
||||||
|
|
||||||
if self.at(Kind::Comma) {
|
if self.at(Kind::Comma) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
parser_babel Summary:
|
parser_babel Summary:
|
||||||
AST Parsed : 2090/2096 (99.71%)
|
AST Parsed : 2090/2096 (99.71%)
|
||||||
Positive Passed: 2083/2096 (99.38%)
|
Positive Passed: 2083/2096 (99.38%)
|
||||||
Negative Passed: 1361/1500 (90.73%)
|
Negative Passed: 1362/1500 (90.80%)
|
||||||
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
|
Expect Syntax Error: "annex-b/disabled/1.1-html-comments-close/input.js"
|
||||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js"
|
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions/input.js"
|
||||||
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
|
Expect Syntax Error: "annex-b/disabled/3.1-sloppy-labeled-functions-if-body/input.js"
|
||||||
|
|
@ -36,7 +36,6 @@ Expect Syntax Error: "es2020/dynamic-import-createImportExpression-false/invalid
|
||||||
Expect Syntax Error: "esprima/es2015-arrow-function/invalid-param-strict-mode/input.js"
|
Expect Syntax Error: "esprima/es2015-arrow-function/invalid-param-strict-mode/input.js"
|
||||||
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-binding-property-reserved/input.js"
|
Expect Syntax Error: "esprima/es2015-generator/generator-parameter-binding-property-reserved/input.js"
|
||||||
Expect Syntax Error: "esprima/invalid-syntax/migrated_0101/input.js"
|
Expect Syntax Error: "esprima/invalid-syntax/migrated_0101/input.js"
|
||||||
Expect Syntax Error: "typescript/arrow-function/async-rest-optional-parameter/input.ts"
|
|
||||||
Expect Syntax Error: "typescript/cast/satisfies-const-error/input.ts"
|
Expect Syntax Error: "typescript/cast/satisfies-const-error/input.ts"
|
||||||
Expect Syntax Error: "typescript/cast/unparenthesized-assert-and-assign/input.ts"
|
Expect Syntax Error: "typescript/cast/unparenthesized-assert-and-assign/input.ts"
|
||||||
Expect Syntax Error: "typescript/cast/unparenthesized-type-assertion-and-assign/input.ts"
|
Expect Syntax Error: "typescript/cast/unparenthesized-type-assertion-and-assign/input.ts"
|
||||||
|
|
@ -9720,6 +9719,12 @@ Expect to Parse: "typescript/types/const-type-parameters-babel-7/input.ts"
|
||||||
╰────
|
╰────
|
||||||
help: Try insert a semicolon here
|
help: Try insert a semicolon here
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[typescript/arrow-function/async-rest-optional-parameter/input.ts:1:14]
|
||||||
|
1 │ async(...args?: any[]) : any => {}
|
||||||
|
· ─
|
||||||
|
╰────
|
||||||
|
|
||||||
× Unexpected token
|
× Unexpected token
|
||||||
╭─[typescript/arrow-function/generic-tsx/input.ts:4:3]
|
╭─[typescript/arrow-function/generic-tsx/input.ts:4:3]
|
||||||
3 │
|
3 │
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
parser_typescript Summary:
|
parser_typescript Summary:
|
||||||
AST Parsed : 5240/5243 (99.94%)
|
AST Parsed : 5240/5243 (99.94%)
|
||||||
Positive Passed: 5233/5243 (99.81%)
|
Positive Passed: 5233/5243 (99.81%)
|
||||||
Negative Passed: 1060/4879 (21.73%)
|
Negative Passed: 1062/4879 (21.77%)
|
||||||
Expect Syntax Error: "compiler/ClassDeclaration10.ts"
|
Expect Syntax Error: "compiler/ClassDeclaration10.ts"
|
||||||
Expect Syntax Error: "compiler/ClassDeclaration11.ts"
|
Expect Syntax Error: "compiler/ClassDeclaration11.ts"
|
||||||
Expect Syntax Error: "compiler/ClassDeclaration13.ts"
|
Expect Syntax Error: "compiler/ClassDeclaration13.ts"
|
||||||
|
|
@ -3175,7 +3175,6 @@ Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserMo
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration3.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration3.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration4.d.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration4.d.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration5.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ModuleDeclarations/parserModuleDeclaration5.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts"
|
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList14.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList14.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList15.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList15.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList16.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList16.ts"
|
||||||
|
|
@ -3183,7 +3182,6 @@ Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParame
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList2.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList2.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList7.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList7.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList8.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList8.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts"
|
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected1.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected1.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected2.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected2.ts"
|
||||||
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected4.ts"
|
Expect Syntax Error: "conformance/parser/ecmascript5/Protected/Protected4.ts"
|
||||||
|
|
@ -6544,6 +6542,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
╰────
|
╰────
|
||||||
help: Try insert a semicolon here
|
help: Try insert a semicolon here
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[compiler/fatarrowfunctionsOptionalArgsErrors1.ts:2:8]
|
||||||
|
1 │ (arg1?, arg2) => 101;
|
||||||
|
2 │ (...arg?) => 102;
|
||||||
|
· ─
|
||||||
|
3 │ (...arg) => 103;
|
||||||
|
╰────
|
||||||
|
|
||||||
× A required parameter cannot follow an optional parameter.
|
× A required parameter cannot follow an optional parameter.
|
||||||
╭─[compiler/fatarrowfunctionsOptionalArgsErrors1.ts:1:9]
|
╭─[compiler/fatarrowfunctionsOptionalArgsErrors1.ts:1:9]
|
||||||
1 │ (arg1?, arg2) => 101;
|
1 │ (arg1?, arg2) => 101;
|
||||||
|
|
@ -6630,8 +6636,8 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
× Identifier `b` has already been declared
|
× Identifier `b` has already been declared
|
||||||
╭─[compiler/functionCall15.ts:1:25]
|
╭─[compiler/functionCall15.ts:1:25]
|
||||||
1 │ function foo(a?:string, b?:number, ...b:number[]){}
|
1 │ function foo(a?:string, b?:number, ...b:number[]){}
|
||||||
· ────┬──── ─────┬────
|
· ────┬──── ┬
|
||||||
· │ ╰── It can not be redeclared here
|
· │ ╰── It can not be redeclared here
|
||||||
· ╰── `b` has already been declared here
|
· ╰── `b` has already been declared here
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
|
@ -8610,6 +8616,13 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
· ─
|
· ─
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[compiler/restParamAsOptional.ts:1:16]
|
||||||
|
1 │ function f(...x?) { }
|
||||||
|
· ─
|
||||||
|
2 │ function f2(...x = []) { }
|
||||||
|
╰────
|
||||||
|
|
||||||
× A rest parameter cannot have an initializer
|
× A rest parameter cannot have an initializer
|
||||||
╭─[compiler/restParamAsOptional.ts:2:16]
|
╭─[compiler/restParamAsOptional.ts:2:16]
|
||||||
1 │ function f(...x?) { }
|
1 │ function f(...x?) { }
|
||||||
|
|
@ -12489,6 +12502,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
8 │ a0([1, 2, [["world"]], "string"]); // Error
|
8 │ a0([1, 2, [["world"]], "string"]); // Error
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[conformance/es6/destructuring/destructuringParameterDeclaration4.ts:14:17]
|
||||||
|
13 │ function a2(...a: someArray) { } // Error, rest parameter must be array type
|
||||||
|
14 │ function a3(...b?) { } // Error, can't be optional
|
||||||
|
· ─
|
||||||
|
15 │ function a4(...b = [1,2,3]) { } // Error, can't have initializer
|
||||||
|
╰────
|
||||||
|
|
||||||
× A rest parameter cannot have an initializer
|
× A rest parameter cannot have an initializer
|
||||||
╭─[conformance/es6/destructuring/destructuringParameterDeclaration4.ts:15:16]
|
╭─[conformance/es6/destructuring/destructuringParameterDeclaration4.ts:15:16]
|
||||||
14 │ function a3(...b?) { } // Error, can't be optional
|
14 │ function a3(...b?) { } // Error, can't be optional
|
||||||
|
|
@ -17267,6 +17288,12 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
3 │ }
|
3 │ }
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts:1:8]
|
||||||
|
1 │ (...arg?) => 102;
|
||||||
|
· ─
|
||||||
|
╰────
|
||||||
|
|
||||||
× A parameter property is only allowed in a constructor implementation.
|
× A parameter property is only allowed in a constructor implementation.
|
||||||
╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList13.ts:2:10]
|
╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList13.ts:2:10]
|
||||||
1 │ interface I {
|
1 │ interface I {
|
||||||
|
|
@ -17307,6 +17334,14 @@ Expect to Parse: "conformance/salsa/plainJSRedeclare3.ts"
|
||||||
3 │ }
|
3 │ }
|
||||||
╰────
|
╰────
|
||||||
|
|
||||||
|
× A rest parameter cannot be optional
|
||||||
|
╭─[conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts:2:14]
|
||||||
|
1 │ class C {
|
||||||
|
2 │ foo(...bar?) { }
|
||||||
|
· ─
|
||||||
|
3 │ }
|
||||||
|
╰────
|
||||||
|
|
||||||
× Expected a semicolon or an implicit semicolon after a statement, but found none
|
× Expected a semicolon or an implicit semicolon after a statement, but found none
|
||||||
╭─[conformance/parser/ecmascript5/RealWorld/parserharness.ts:1431:16]
|
╭─[conformance/parser/ecmascript5/RealWorld/parserharness.ts:1431:16]
|
||||||
1430 │ // Regex for parsing options in the format "@Alpha: Value of any sort"
|
1430 │ // Regex for parsing options in the format "@Alpha: Value of any sort"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue