Skip to content

Commit 5a536aa

Browse files
authored
Merge pull request #2658 from MikeMatrix/each-block-rest-destructuring
each-block array destructuring
2 parents 78332cf + f69f46c commit 5a536aa

File tree

4 files changed

+58
-20
lines changed

4 files changed

+58
-20
lines changed

src/compile/nodes/EachBlock.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ import { new_tail } from '../utils/tail';
1010
function unpack_destructuring(contexts: Array<{ name: string, tail: string }>, node: INode, tail: string) {
1111
if (!node) return;
1212

13-
if (node.type === 'Identifier') {
13+
if (node.type === 'Identifier' || node.type === 'RestIdentifier') {
1414
contexts.push({
1515
key: node,
1616
tail
1717
});
1818
} else if (node.type === 'ArrayPattern') {
1919
node.elements.forEach((element, i) => {
20-
unpack_destructuring(contexts, element, `${tail}[${i}]`);
20+
if (element && element.type === 'RestIdentifier') {
21+
unpack_destructuring(contexts, element, `${tail}.slice(${i})`)
22+
} else {
23+
unpack_destructuring(contexts, element, `${tail}[${i}]`);
24+
}
2125
});
2226
} else if (node.type === 'ObjectPattern') {
2327
const used_properties = [];

src/parse/read/context.ts

+29-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ type Property = {
2020
type Context = {
2121
start: number;
2222
end: number;
23-
type: 'Identifier' | 'ArrayPattern' | 'ObjectPattern';
23+
type: 'Identifier' | 'ArrayPattern' | 'ObjectPattern' | 'RestIdentifier';
2424
name?: string;
2525
elements?: Context[];
2626
properties?: Property[];
@@ -35,6 +35,13 @@ function error_on_assignment_pattern(parser: Parser) {
3535
}
3636
}
3737

38+
function error_on_rest_pattern_not_last(parser: Parser) {
39+
parser.error({
40+
code: 'rest-pattern-not-last',
41+
message: 'Rest destructuring expected to be last'
42+
}, parser.index);
43+
}
44+
3845
export default function read_context(parser: Parser) {
3946
const context: Context = {
4047
start: parser.index,
@@ -49,6 +56,11 @@ export default function read_context(parser: Parser) {
4956
do {
5057
parser.allow_whitespace();
5158

59+
const lastContext = context.elements[context.elements.length - 1];
60+
if (lastContext && lastContext.type === 'RestIdentifier') {
61+
error_on_rest_pattern_not_last(parser);
62+
}
63+
5264
if (parser.template[parser.index] === ',') {
5365
context.elements.push(null);
5466
} else {
@@ -138,6 +150,22 @@ export default function read_context(parser: Parser) {
138150
context.end = parser.index;
139151
}
140152

153+
else if (parser.eat('...')) {
154+
const name = parser.read_identifier();
155+
if (name) {
156+
context.type = 'RestIdentifier';
157+
context.end = parser.index;
158+
context.name = name;
159+
}
160+
161+
else {
162+
parser.error({
163+
code: 'invalid-context',
164+
message: 'Expected a rest pattern'
165+
});
166+
}
167+
}
168+
141169
else {
142170
const name = parser.read_identifier();
143171
if (name) {
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
{#each animals as [key, value]}
1+
{#each animals as [key, value, ...rest]}
22
<p>{key}: {value}</p>
33
{/each}
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{
22
"html": {
33
"start": 0,
4-
"end": 62,
4+
"end": 71,
55
"type": "Fragment",
66
"children": [
77
{
88
"start": 0,
9-
"end": 62,
9+
"end": 71,
1010
"type": "EachBlock",
1111
"expression": {
1212
"type": "Identifier",
@@ -16,37 +16,37 @@
1616
},
1717
"children": [
1818
{
19-
"start": 33,
20-
"end": 54,
19+
"start": 42,
20+
"end": 63,
2121
"type": "Element",
2222
"name": "p",
2323
"attributes": [],
2424
"children": [
2525
{
26-
"start": 36,
27-
"end": 41,
26+
"start": 45,
27+
"end": 50,
2828
"type": "MustacheTag",
2929
"expression": {
3030
"type": "Identifier",
31-
"start": 37,
32-
"end": 40,
31+
"start": 46,
32+
"end": 49,
3333
"name": "key"
3434
}
3535
},
3636
{
37-
"start": 41,
38-
"end": 43,
37+
"start": 50,
38+
"end": 52,
3939
"type": "Text",
4040
"data": ": "
4141
},
4242
{
43-
"start": 43,
44-
"end": 50,
43+
"start": 52,
44+
"end": 59,
4545
"type": "MustacheTag",
4646
"expression": {
4747
"type": "Identifier",
48-
"start": 44,
49-
"end": 49,
48+
"start": 53,
49+
"end": 58,
5050
"name": "value"
5151
}
5252
}
@@ -55,7 +55,7 @@
5555
],
5656
"context": {
5757
"start": 18,
58-
"end": 30,
58+
"end": 39,
5959
"type": "ArrayPattern",
6060
"elements": [
6161
{
@@ -69,6 +69,12 @@
6969
"end": 29,
7070
"type": "Identifier",
7171
"name": "value"
72+
},
73+
{
74+
"start": 31,
75+
"end": 38,
76+
"type": "RestIdentifier",
77+
"name": "rest"
7278
}
7379
]
7480
}
@@ -78,4 +84,4 @@
7884
"css": null,
7985
"instance": null,
8086
"module": null
81-
}
87+
}

0 commit comments

Comments
 (0)