Skip to content

Commit

Permalink
fix: Support destructuring assignments in table expressions.
Browse files Browse the repository at this point in the history
  • Loading branch information
jheer committed Nov 17, 2020
1 parent e3da21e commit c2935d2
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 1 deletion.
1 change: 1 addition & 0 deletions src/expression/ast/constants.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const ArrayPattern = 'ArrayPattern';
export const ArrowFunctionExpression = 'ArrowFunctionExpression';
export const FunctionExpression = 'FunctionExpression';
export const Identifier = 'Identifier';
Expand Down
3 changes: 3 additions & 0 deletions src/expression/codegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ const visitors = {
FunctionExpression: func,
FunctionDeclaration: func,

ArrayPattern: (node, opt) => {
return '[' + list(node.elements, opt) + ']';
},
ObjectPattern: (node, opt) => {
return '{' + list(node.properties, opt) + '}';
},
Expand Down
15 changes: 14 additions & 1 deletion src/expression/parse.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { parse } from 'acorn';

import {
ArrayPattern,
ArrowFunctionExpression,
Column,
Constant,
Expand Down Expand Up @@ -176,6 +177,18 @@ function updateConstantNode(node, name) {
node.raw = constants[name];
}

function handleDeclaration(node, ctx) {
if (is(Identifier, node)) {
ctx.scope.add(node.name);
} else if (is(ArrayPattern, node)) {
node.elements.forEach(elm => handleDeclaration(elm, ctx));
} else if (is(ObjectPattern, node)) {
node.properties.forEach(prop => handleDeclaration(prop.value, ctx));
} else {
ctx.error('Unsupported variable declaration', node.id);
}
}

const visitors = {
FunctionDeclaration: parseError('Function definitions not allowed'),
ForStatement: parseError('For loops not allowed'),
Expand All @@ -191,7 +204,7 @@ const visitors = {
UpdateExpression: parseError('Updates not allowed'),

VariableDeclarator(node, ctx) {
ctx.scope.add(node.id.name);
handleDeclaration(node.id, ctx);
},
Identifier(node, ctx, parent) {
if (handleIdentifier(node, ctx, parent) && !ctx.scope.has(node.name)) {
Expand Down
29 changes: 29 additions & 0 deletions test/expression/parse-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,35 @@ tape('parse parses expressions with switch statements', t => {
t.end();
});

tape('parse parses expressions with destructuring assignments', t => {
const exprs = {
arr: () => {
const [start, stop, step] = op.bins('value');
return op.bin('value', start, stop, step);
},
obj: () => {
const { start, stop, step } = op.bins('value');
return op.bin('value', start, stop, step);
},
nest: () => {
const { start: [{ baz: bop }], stop, step } = op.bins('value');
return op.bin('value', bop, stop, step);
}
};

t.deepEqual(
parse(exprs, { compiler }).values,
{
arr: '{const [start,stop,step]=op[0];return fn.bin(\'value\',start,stop,step);}',
obj: '{const {start:start,stop:stop,step:step}=op[0];return fn.bin(\'value\',start,stop,step);}',
nest: '{const {start:[{baz:bop}],stop:stop,step:step}=op[0];return fn.bin(\'value\',bop,stop,step);}'
},
'parsed destructuring assignmeents'
);

t.end();
});

tape('parse throws on expressions with for loops', t => {
const exprs = {
val: () => {
Expand Down

0 comments on commit c2935d2

Please sign in to comment.