mirror of https://github.com/sveltejs/svelte
parent
f5048fcf10
commit
506ab3952e
@ -0,0 +1,114 @@
|
|||||||
|
import { Parser } from '../index';
|
||||||
|
|
||||||
|
type Identifier = {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
type: 'Identifier';
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Property = {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
type: 'Property';
|
||||||
|
key: Identifier;
|
||||||
|
value: Context;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Context = {
|
||||||
|
start: number;
|
||||||
|
end: number;
|
||||||
|
type: 'Identifier' | 'ArrayPattern' | 'ObjectPattern';
|
||||||
|
name?: string;
|
||||||
|
elements?: Context[];
|
||||||
|
properties?: Property[];
|
||||||
|
}
|
||||||
|
|
||||||
|
function errorOnAssignmentPattern(parser: Parser) {
|
||||||
|
if (parser.eat('=')) {
|
||||||
|
parser.error({
|
||||||
|
code: 'invalid-assignment-pattern',
|
||||||
|
message: 'Assignment patterns are not supported'
|
||||||
|
}, parser.index - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function readContext(parser: Parser) {
|
||||||
|
const context: Context = {
|
||||||
|
start: parser.index,
|
||||||
|
end: null,
|
||||||
|
type: null
|
||||||
|
};
|
||||||
|
|
||||||
|
if (parser.eat('[')) {
|
||||||
|
context.type = 'ArrayPattern';
|
||||||
|
context.elements = [];
|
||||||
|
|
||||||
|
do {
|
||||||
|
parser.allowWhitespace();
|
||||||
|
context.elements.push(readContext(parser));
|
||||||
|
parser.allowWhitespace();
|
||||||
|
} while (parser.eat(','));
|
||||||
|
|
||||||
|
errorOnAssignmentPattern(parser);
|
||||||
|
parser.eat(']', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (parser.eat('{')) {
|
||||||
|
context.type = 'ObjectPattern';
|
||||||
|
context.properties = [];
|
||||||
|
|
||||||
|
do {
|
||||||
|
parser.allowWhitespace();
|
||||||
|
|
||||||
|
const start = parser.index;
|
||||||
|
const name = parser.readIdentifier();
|
||||||
|
const key: Identifier = {
|
||||||
|
start,
|
||||||
|
end: parser.index,
|
||||||
|
type: 'Identifier',
|
||||||
|
name
|
||||||
|
};
|
||||||
|
parser.allowWhitespace();
|
||||||
|
|
||||||
|
const value = parser.eat(':')
|
||||||
|
? readContext(parser)
|
||||||
|
: key;
|
||||||
|
|
||||||
|
const property: Property = {
|
||||||
|
start,
|
||||||
|
end: value.end,
|
||||||
|
type: 'Property',
|
||||||
|
key,
|
||||||
|
value
|
||||||
|
};
|
||||||
|
|
||||||
|
context.properties.push(property);
|
||||||
|
|
||||||
|
parser.allowWhitespace();
|
||||||
|
} while (parser.eat(','));
|
||||||
|
|
||||||
|
errorOnAssignmentPattern(parser);
|
||||||
|
parser.eat('}', true);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
const name = parser.readIdentifier();
|
||||||
|
if (name) {
|
||||||
|
context.type = 'Identifier';
|
||||||
|
context.end = parser.index;
|
||||||
|
context.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
parser.error({
|
||||||
|
code: 'invalid-context',
|
||||||
|
message: 'Expected a name, array pattern or object pattern'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
errorOnAssignmentPattern(parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
return context;
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
export default function unpackDestructuring(
|
||||||
|
contexts: Array<{ name: string, tail: string }>,
|
||||||
|
node: Node,
|
||||||
|
tail: string
|
||||||
|
) {
|
||||||
|
if (node.type === 'Identifier') {
|
||||||
|
contexts.push({
|
||||||
|
key: node,
|
||||||
|
tail
|
||||||
|
});
|
||||||
|
} else if (node.type === 'ArrayPattern') {
|
||||||
|
node.elements.forEach((element, i) => {
|
||||||
|
unpackDestructuring(contexts, element, `${tail}[${i}]`);
|
||||||
|
});
|
||||||
|
} else if (node.type === 'ObjectPattern') {
|
||||||
|
node.properties.forEach((property) => {
|
||||||
|
unpackDestructuring(contexts, property.value, `${tail}.${property.key.name}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
export default {
|
||||||
|
data: {
|
||||||
|
animalPawsEntries: [
|
||||||
|
{ animal: 'raccoon', pawType: 'hands' },
|
||||||
|
{ animal: 'eagle', pawType: 'wings' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
html: `
|
||||||
|
<p>raccoon: hands</p>
|
||||||
|
<p>eagle: wings</p>
|
||||||
|
`,
|
||||||
|
|
||||||
|
test ( assert, component, target ) {
|
||||||
|
component.set({
|
||||||
|
animalPawsEntries: [{ animal: 'cow', pawType: 'hooves' }]
|
||||||
|
});
|
||||||
|
assert.htmlEqual( target.innerHTML, `
|
||||||
|
<p>cow: hooves</p>
|
||||||
|
`);
|
||||||
|
},
|
||||||
|
};
|
@ -0,0 +1,3 @@
|
|||||||
|
{#each animalPawsEntries as { animal, pawType } }
|
||||||
|
<p>{animal}: {pawType}</p>
|
||||||
|
{/each}
|
Loading…
Reference in new issue