Skip to content

Commit

Permalink
support combined field & parameter defaults
Browse files Browse the repository at this point in the history
  • Loading branch information
y21 committed Dec 24, 2024
1 parent a50acb3 commit ff2e2cd
Showing 1 changed file with 36 additions and 30 deletions.
66 changes: 36 additions & 30 deletions crates/dash_parser/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -903,63 +903,69 @@ impl Parser<'_, '_> {
prec: Vec<Expr>,
rest_binding: Option<Symbol>,
) -> Option<Expr> {
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<Parameter> {
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 {
Expand Down

0 comments on commit ff2e2cd

Please sign in to comment.