Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions crates/oxc_parser/src/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,11 @@ pub fn rest_element_property_name(span: Span) -> OxcDiagnostic {
ts_error("2566", "A rest element cannot have a property name.").with_label(span)
}

#[cold]
pub fn a_rest_element_cannot_have_an_initializer(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("A rest element cannot have an initializer.").with_label(span)
}

// ================================= MODIFIERS =================================

#[cold]
Expand Down
9 changes: 7 additions & 2 deletions crates/oxc_parser/src/js/binding.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,17 @@ impl<'a> ParserImpl<'a> {
// 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`
// function foo([...x = []]) { }
// ^^^^ A rest element cannot have an initializer
let argument = self
.context(Context::In, Context::empty(), |p| p.parse_initializer(init_span, pattern))?;
let span = self.end_span(span);
if let BindingPatternKind::AssignmentPattern(pat) = &argument.kind {
self.error(diagnostics::a_rest_element_cannot_have_an_initializer(pat.span));
}

Ok(self.ast.binding_rest_element(span, argument))
Ok(self.ast.binding_rest_element(self.end_span(span), argument))
}

/// `BindingProperty`[Yield, Await] :
Expand Down
22 changes: 0 additions & 22 deletions crates/oxc_semantic/src/checker/javascript.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,28 +973,6 @@ pub fn check_object_property(prop: &ObjectProperty, ctx: &SemanticBuilder<'_>) {
}
}

fn a_rest_parameter_cannot_have_an_initializer(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("A rest parameter cannot have an initializer").with_label(span)
}

pub fn check_formal_parameters(params: &FormalParameters, ctx: &SemanticBuilder<'_>) {
if let Some(rest) = &params.rest {
if let BindingPatternKind::AssignmentPattern(pat) = &rest.argument.kind {
ctx.error(a_rest_parameter_cannot_have_an_initializer(pat.span));
}
}
}

pub fn check_array_pattern(pattern: &ArrayPattern, ctx: &SemanticBuilder<'_>) {
// function foo([...x = []]) { }
// ^^^^ A rest element cannot have an initializer
if let Some(rest) = &pattern.rest {
if let BindingPatternKind::AssignmentPattern(pat) = &rest.argument.kind {
ctx.error(a_rest_parameter_cannot_have_an_initializer(pat.span));
}
}
}

fn assignment_is_not_simple(span: Span) -> OxcDiagnostic {
OxcDiagnostic::error("Invalid left-hand side in assignment").with_label(span)
}
Expand Down
2 changes: 0 additions & 2 deletions crates/oxc_semantic/src/checker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,9 @@ pub fn check<'a>(node: &AstNode<'a>, ctx: &SemanticBuilder<'a>) {
AstKind::Super(sup) => js::check_super(sup, node, ctx),

AstKind::FormalParameters(params) => {
js::check_formal_parameters(params, ctx);
ts::check_formal_parameters(params, ctx);
}
AstKind::ArrayPattern(pat) => {
js::check_array_pattern(pat, ctx);
ts::check_array_pattern(pat, ctx);
}

Expand Down
8 changes: 5 additions & 3 deletions tasks/coverage/snapshots/estree_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -867,7 +867,7 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/restParameterNot
A rest parameter must be last in a parameter list
Mismatch: tasks/coverage/typescript/tests/cases/compiler/restParameterWithBindingPattern1.ts
Expect to Parse: tasks/coverage/typescript/tests/cases/compiler/restParameterWithBindingPattern3.ts
A rest element cannot have a property name.
A rest element cannot have an initializer.
tasks/coverage/typescript/tests/cases/compiler/reuseTypeAnnotationImportTypeInGlobalThisTypeArgument.ts
Unexpected estree file content error: 2 != 4

Expand Down Expand Up @@ -1304,7 +1304,8 @@ Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/re
Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern2.ts
Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern3.ts
Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithAssignmentPattern4.ts
Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithInitializer1.ts
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithInitializer1.ts
A rest element cannot have an initializer.
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restElementWithInitializer2.ts
Cannot assign to this expression
Mismatch: tasks/coverage/typescript/tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts
Expand Down Expand Up @@ -2257,7 +2258,8 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmasc
Unexpected token
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList1.ts
A rest parameter must be last in a parameter list
Mismatch: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList10.ts
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList10.ts
A rest element cannot have an initializer.
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList11.ts
A rest parameter cannot be optional
Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/parser/ecmascript5/ParameterLists/parserParameterList9.ts
Expand Down
20 changes: 19 additions & 1 deletion tasks/coverage/snapshots/parser_babel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4373,6 +4373,12 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
· ────
╰────

× A rest element cannot have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/278/input.js:1:18]
1 │ function f(a, ...b = 0)
· ─────
╰────

× Unexpected token
╭─[babel/packages/babel-parser/test/fixtures/es2015/uncategorised/278/input.js:1:24]
1 │ function f(a, ...b = 0)
Expand Down Expand Up @@ -5794,13 +5800,25 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
· ─────
╰────

× A rest element cannot have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/22/input.js:1:9]
1 │ var {...x = 1} = {}
· ─────
╰────

× Invalid rest element
╭─[babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/22/input.js:1:9]
1 │ var {...x = 1} = {}
· ─────
╰────
help: Expected identifier in rest element

× A rest element cannot have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/23/input.js:1:19]
1 │ function test({...x = 1}) {}
· ─────
╰────

× Invalid rest element
╭─[babel/packages/babel-parser/test/fixtures/es2018/object-rest-spread/23/input.js:1:19]
1 │ function test({...x = 1}) {}
Expand Down Expand Up @@ -11225,7 +11243,7 @@ Expect to Parse: tasks/coverage/babel/packages/babel-parser/test/fixtures/typesc
· ────
╰────

× A rest parameter cannot have an initializer
× A rest element cannot have an initializer.
╭─[babel/packages/babel-parser/test/fixtures/esprima/invalid-syntax/migrated_0260/input.js:1:15]
1 │ function x(...a = 1){}
· ─────
Expand Down
Loading
Loading