diff --git a/crates/dash_parser/src/expr.rs b/crates/dash_parser/src/expr.rs index cf0f517c..9e0f3e14 100644 --- a/crates/dash_parser/src/expr.rs +++ b/crates/dash_parser/src/expr.rs @@ -903,63 +903,69 @@ impl Parser<'_, '_> { prec: Vec, rest_binding: Option, ) -> Option { - let mut list = Vec::with_capacity(prec.len()); - - // If it is arrow function, we need to convert everything to their arrow func equivalents - for expr in prec { - // TODO: this currently breaks with types in arrow functions - // e.g. (a: number) => {} - // we need to properly convert types here too - - let (parameter, value) = match expr.kind { + fn expr_to_parameter(parser: &mut Parser<'_, '_>, expr: Expr) -> Option { + match expr.kind { ExprKind::Literal(LiteralExpr::Identifier(ident)) => { - (Parameter::Identifier(self.create_binding(ident)), None) + Some(Parameter::Identifier(parser.create_binding(ident))) } - ExprKind::Assignment(AssignmentExpr { - left: AssignmentTarget::Expr(left), - right, - .. - }) => ( - Parameter::Identifier(self.create_binding(left.kind.as_identifier()?)), - Some(*right), - ), ExprKind::Object(ObjectLiteral(properties)) => { - let destructured_id = self.local_count.inc(); + let destructured_id = parser.local_count.inc(); let mut fields = Vec::with_capacity(properties.len()); for (key, value) in properties { match key { // `x: a` aliases x to 1 ObjectMemberKind::Static(symbol) => { if let Some(alias) = value.kind.as_identifier() { - fields.push((self.local_count.inc(), symbol, Some(alias), None)) + fields.push((parser.local_count.inc(), symbol, Some(alias), None)) } else { - self.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)); + parser.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)); return None; } } // `x = 1` defaults x to 1 ObjectMemberKind::Default(symbol) => { - fields.push((self.local_count.inc(), symbol, None, Some(value))) + fields.push((parser.local_count.inc(), symbol, None, Some(value))) } - _ => self.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)), + _ => parser.error(Error::unexpected_token(value.span, TokenType::DUMMY_IDENTIFIER)), } } - ( - Parameter::Pattern(destructured_id, Pattern::Object { fields, rest: None }), - None, - ) + Some(Parameter::Pattern(destructured_id, Pattern::Object { + fields, + rest: None, + })) } _ => { - self.error(Error::Unimplemented( + parser.error(Error::Unimplemented( expr.span, format!("only assignment and identifier expressions are supported as in closure parameter recovery: {expr:?}"), )); - return None; + None } + } + } + + let mut list = Vec::with_capacity(prec.len()); + + // If it is arrow function, we need to convert everything to their arrow func equivalents + for expr in prec { + // TODO: this currently breaks with types in arrow functions + // e.g. (a: number) => {} + // we need to properly convert types here too + + let (expr, default) = if let ExprKind::Assignment(AssignmentExpr { + left: AssignmentTarget::Expr(expr), + right, + operator: TokenType::Assignment, + }) = expr.kind + { + (*expr, Some(*right)) + } else { + (expr, None) }; + let parameter = expr_to_parameter(self, expr)?; - list.push((parameter, value, None)); + list.push((parameter, default, None)); } if let Some(ident) = rest_binding {