Experimenting with array destructuring in each-blocks

pull/2658/head
Michael Braun 5 years ago
parent 85b1850b77
commit c477f50b9a

@ -9,14 +9,18 @@ import { Node as INode } from '../../interfaces';
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.type === 'RestIdentifier') {
unpack_destructuring(contexts, element, `${tail}.slice(${i})`)
} else {
unpack_destructuring(contexts, element, `${tail}[${i}]`);
}
});
} else if (node.type === 'ObjectPattern') {
node.properties.forEach((property) => {

@ -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[];
@ -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,
@ -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 {
@ -103,6 +115,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) {
@ -122,4 +150,4 @@ export default function read_context(parser: Parser) {
}
return context;
}
}

@ -1,3 +1,3 @@
{#each animals as [key, value]}
{#each animals as [key, value, ...rest]}
<p>{key}: {value}</p>
{/each}

@ -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",
@ -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"
}
}
@ -55,7 +55,7 @@
],
"context": {
"start": 18,
"end": 30,
"end": 39,
"type": "ArrayPattern",
"elements": [
{
@ -69,6 +69,12 @@
"end": 29,
"type": "Identifier",
"name": "value"
},
{
"start": 31,
"end": 38,
"type": "RestIdentifier",
"name": "rest"
}
]
}
@ -78,4 +84,4 @@
"css": null,
"instance": null,
"module": null
}
}

Loading…
Cancel
Save