From 9abf963926973304654f0a076cbc80ca7cbdc385 Mon Sep 17 00:00:00 2001 From: y21 <30553356+y21@users.noreply.github.com> Date: Tue, 24 Dec 2024 22:09:54 +0100 Subject: [PATCH] support object rest destructuring in arrow functions --- crates/dash_middle/src/parser/error.rs | 4 ++-- crates/dash_parser/src/expr.rs | 17 +++++++++++++---- crates/dash_parser/src/stmt.rs | 4 ++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/crates/dash_middle/src/parser/error.rs b/crates/dash_middle/src/parser/error.rs index 2ca10347..a86b979d 100644 --- a/crates/dash_middle/src/parser/error.rs +++ b/crates/dash_middle/src/parser/error.rs @@ -48,7 +48,7 @@ pub enum Error { expect: usize, token: Token, }, - MultipleRestInDestructuring(Token), + MultipleRestInDestructuring(Span), RegexSyntaxError(Token, dash_regex::Error), IncompleteSpread(Token), /* Compiler */ @@ -311,7 +311,7 @@ impl fmt::Display for FormattableError<'_, '_> { diag.message("incorrect number of parameters for accessor"); diag.span_error(span, format!("expected {expect}, got {got}")); } - Error::MultipleRestInDestructuring(Token { span, .. }) => { + Error::MultipleRestInDestructuring(span) => { diag.message("multiple rest elements in destructuring"); diag.span_error(span, "second rest element defined here"); } diff --git a/crates/dash_parser/src/expr.rs b/crates/dash_parser/src/expr.rs index 9e0f3e14..7caf7caf 100644 --- a/crates/dash_parser/src/expr.rs +++ b/crates/dash_parser/src/expr.rs @@ -911,6 +911,7 @@ impl Parser<'_, '_> { ExprKind::Object(ObjectLiteral(properties)) => { let destructured_id = parser.local_count.inc(); let mut fields = Vec::with_capacity(properties.len()); + let mut rest = None; for (key, value) in properties { match key { // `x: a` aliases x to 1 @@ -926,14 +927,22 @@ impl Parser<'_, '_> { ObjectMemberKind::Default(symbol) => { fields.push((parser.local_count.inc(), symbol, None, Some(value))) } + ObjectMemberKind::Spread => { + if rest.is_none() { + if let Some(symbol) = value.kind.as_identifier() { + rest = Some(parser.create_binding(symbol)); + } else { + parser.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)); + } + } else { + parser.error(Error::MultipleRestInDestructuring(value.span)) + } + } _ => parser.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)), } } - Some(Parameter::Pattern(destructured_id, Pattern::Object { - fields, - rest: None, - })) + Some(Parameter::Pattern(destructured_id, Pattern::Object { fields, rest })) } _ => { parser.error(Error::Unimplemented( diff --git a/crates/dash_parser/src/stmt.rs b/crates/dash_parser/src/stmt.rs index fc282158..0f77fb8f 100644 --- a/crates/dash_parser/src/stmt.rs +++ b/crates/dash_parser/src/stmt.rs @@ -588,7 +588,7 @@ impl Parser<'_, '_> { if let Some(sym) = name.ty.as_identifier() { if rest.is_some() { // Only allow one rest operator - self.error(Error::MultipleRestInDestructuring(name)); + self.error(Error::MultipleRestInDestructuring(name.span)); return None; } @@ -665,7 +665,7 @@ impl Parser<'_, '_> { if let Some(sym) = name.ty.as_identifier() { if rest.is_some() { // Only allow one rest operator - self.error(Error::MultipleRestInDestructuring(name)); + self.error(Error::MultipleRestInDestructuring(name.span)); return None; }