Skip to content

Commit

Permalink
Merge pull request #2658 from MikeMatrix/each-block-rest-destructuring
Browse files Browse the repository at this point in the history
each-block array destructuring
  • Loading branch information
Rich-Harris authored May 4, 2019
2 parents 78332cf + f69f46c commit 5a536aa
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 20 deletions.
8 changes: 6 additions & 2 deletions src/compile/nodes/EachBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,18 @@ import { new_tail } from '../utils/tail';
function unpack_destructuring(contexts: Array<{ name: string, tail: string }>, node: INode, tail: string) {
if (!node) return;

if (node.type === 'Identifier') {
if (node.type === 'Identifier' || node.type === 'RestIdentifier') {
contexts.push({
key: node,
tail
});
} else if (node.type === 'ArrayPattern') {
node.elements.forEach((element, i) => {
unpack_destructuring(contexts, element, `${tail}[${i}]`);
if (element && element.type === 'RestIdentifier') {
unpack_destructuring(contexts, element, `${tail}.slice(${i})`)
} else {
unpack_destructuring(contexts, element, `${tail}[${i}]`);
}
});
} else if (node.type === 'ObjectPattern') {
const used_properties = [];
Expand Down
30 changes: 29 additions & 1 deletion src/parse/read/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Property = {
type Context = {
start: number;
end: number;
type: 'Identifier' | 'ArrayPattern' | 'ObjectPattern';
type: 'Identifier' | 'ArrayPattern' | 'ObjectPattern' | 'RestIdentifier';
name?: string;
elements?: Context[];
properties?: Property[];
Expand All @@ -35,6 +35,13 @@ function error_on_assignment_pattern(parser: Parser) {
}
}

function error_on_rest_pattern_not_last(parser: Parser) {
parser.error({
code: 'rest-pattern-not-last',
message: 'Rest destructuring expected to be last'
}, parser.index);
}

export default function read_context(parser: Parser) {
const context: Context = {
start: parser.index,
Expand All @@ -49,6 +56,11 @@ export default function read_context(parser: Parser) {
do {
parser.allow_whitespace();

const lastContext = context.elements[context.elements.length - 1];
if (lastContext && lastContext.type === 'RestIdentifier') {
error_on_rest_pattern_not_last(parser);
}

if (parser.template[parser.index] === ',') {
context.elements.push(null);
} else {
Expand Down Expand Up @@ -138,6 +150,22 @@ export default function read_context(parser: Parser) {
context.end = parser.index;
}

else if (parser.eat('...')) {
const name = parser.read_identifier();
if (name) {
context.type = 'RestIdentifier';
context.end = parser.index;
context.name = name;
}

else {
parser.error({
code: 'invalid-context',
message: 'Expected a rest pattern'
});
}
}

else {
const name = parser.read_identifier();
if (name) {
Expand Down
2 changes: 1 addition & 1 deletion test/parser/samples/each-block-destructured/input.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{#each animals as [key, value]}
{#each animals as [key, value, ...rest]}
<p>{key}: {value}</p>
{/each}
38 changes: 22 additions & 16 deletions test/parser/samples/each-block-destructured/output.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"html": {
"start": 0,
"end": 62,
"end": 71,
"type": "Fragment",
"children": [
{
"start": 0,
"end": 62,
"end": 71,
"type": "EachBlock",
"expression": {
"type": "Identifier",
Expand All @@ -16,37 +16,37 @@
},
"children": [
{
"start": 33,
"end": 54,
"start": 42,
"end": 63,
"type": "Element",
"name": "p",
"attributes": [],
"children": [
{
"start": 36,
"end": 41,
"start": 45,
"end": 50,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 37,
"end": 40,
"start": 46,
"end": 49,
"name": "key"
}
},
{
"start": 41,
"end": 43,
"start": 50,
"end": 52,
"type": "Text",
"data": ": "
},
{
"start": 43,
"end": 50,
"start": 52,
"end": 59,
"type": "MustacheTag",
"expression": {
"type": "Identifier",
"start": 44,
"end": 49,
"start": 53,
"end": 58,
"name": "value"
}
}
Expand All @@ -55,7 +55,7 @@
],
"context": {
"start": 18,
"end": 30,
"end": 39,
"type": "ArrayPattern",
"elements": [
{
Expand All @@ -69,6 +69,12 @@
"end": 29,
"type": "Identifier",
"name": "value"
},
{
"start": 31,
"end": 38,
"type": "RestIdentifier",
"name": "rest"
}
]
}
Expand All @@ -78,4 +84,4 @@
"css": null,
"instance": null,
"module": null
}
}

0 comments on commit 5a536aa

Please sign in to comment.