feat: I think non-destructured rest should work now?

pull/10320/head
S. Elliott Johnson 2 years ago
parent c1bb2397dd
commit 3a726a9c39

@ -2460,9 +2460,7 @@ export const template_visitors = {
node.context.elements.forEach((argument, i) => {
if (!argument) return;
// If the argument is itself an identifier (`foo`) or is a simple rest identifier (`...foo`)
// we don't have to do anything fancy -- just push it onto the args array and make sure its
// binding expression is a call of itself.
const arg_alias = `$$arg${i}`;
/** @type {import('estree').Identifier | undefined} */
let identifier;
/** @type {import('estree').Identifier | import('estree').RestElement | string} */
@ -2470,9 +2468,6 @@ export const template_visitors = {
if (argument.type === 'Identifier') {
identifier = argument;
arg = argument;
} else if (argument.type === 'RestElement' && argument.argument.type === 'Identifier') {
identifier = argument.argument;
arg = argument;
} else if (argument.type === 'RestElement') {
arg = b.rest(b.id(`$$arg${i}`));
} else {
@ -2485,17 +2480,28 @@ export const template_visitors = {
context.state.scope.get(identifier.name)
);
binding.expression = b.call(identifier);
} else {
// If, on the other hand, it isn't an identifier, it's a destructuring expression, which could be
// a rest destructure (eg. `...[foo, bar, { baz }, ...rest]`, which, absurdly, is all valid syntax).
// In this case, we need to follow the destructuring expression to figure out what variables are being extracted.
return;
}
if (argument.type === 'RestElement' && argument.argument.type === 'Identifier') {
// this is a "simple" rest argument (not destructured), so we just need to thunkify it
const binding = /** @type {import('#compiler').Binding} */ (
context.state.scope.get(argument.argument.name)
);
binding.expression = b.call(argument.argument.name);
// TODO: where does `context.visit` go here? does it matter? i don't understand what it's for :thinkies:
declarations.push(b.let(argument.argument.name, b.thunk(b.id(`$$arg${i}`))));
return;
}
// If, on the other hand, it's a destructuring expression, which could be
// a rest destructure (eg. `...[foo, bar, { baz }, ...rest]`, which, absurdly, is all valid syntax),
// we need to follow the destructuring expression to figure out what variables are being extracted.
const paths = extract_paths(argument.type === 'RestElement' ? argument.argument : argument);
for (const path of paths) {
const name = /** @type {import('estree').Identifier} */ (path.node).name;
const binding = /** @type {import('#compiler').Binding} */ (
context.state.scope.get(name)
);
const binding = /** @type {import('#compiler').Binding} */ (context.state.scope.get(name));
declarations.push(
b.let(
path.node,
@ -2515,7 +2521,6 @@ export const template_visitors = {
binding.expression = b.call(name);
}
}
});
body = b.block([

Loading…
Cancel
Save