mirror of https://github.com/sveltejs/svelte
support destructuring in await (#4548)
parent
5bb5ba4c76
commit
7d1e4e82ff
@ -0,0 +1,35 @@
|
|||||||
|
import { Pattern, Identifier, RestElement } from "estree";
|
||||||
|
import { Node } from "acorn";
|
||||||
|
|
||||||
|
export default function traverse_destructure_pattern(
|
||||||
|
node: Pattern,
|
||||||
|
callback: (node: Identifier, parent: Node, key: string | number) => void
|
||||||
|
) {
|
||||||
|
function traverse(node: Pattern, parent, key) {
|
||||||
|
switch (node.type) {
|
||||||
|
case "Identifier":
|
||||||
|
return callback(node, parent, key);
|
||||||
|
case "ArrayPattern":
|
||||||
|
for (let i = 0; i < node.elements.length; i++) {
|
||||||
|
const element = node.elements[i];
|
||||||
|
traverse(element, node.elements, i);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "ObjectPattern":
|
||||||
|
for (let i = 0; i < node.properties.length; i++) {
|
||||||
|
const property = node.properties[i];
|
||||||
|
if (property.type === "Property") {
|
||||||
|
traverse(property.value, property, "value");
|
||||||
|
} else {
|
||||||
|
traverse((property as any) as RestElement, node.properties, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "RestElement":
|
||||||
|
return traverse(node.argument, node, 'argument');
|
||||||
|
case "AssignmentPattern":
|
||||||
|
return traverse(node.left, node, 'left');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
traverse(node, null, null);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
const SQUARE_BRACKET_OPEN = "[".charCodeAt(0);
|
||||||
|
const SQUARE_BRACKET_CLOSE = "]".charCodeAt(0);
|
||||||
|
const CURLY_BRACKET_OPEN = "{".charCodeAt(0);
|
||||||
|
const CURLY_BRACKET_CLOSE = "}".charCodeAt(0);
|
||||||
|
|
||||||
|
export function is_bracket_open(code) {
|
||||||
|
return code === SQUARE_BRACKET_OPEN || code === CURLY_BRACKET_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function is_bracket_close(code) {
|
||||||
|
return code === SQUARE_BRACKET_CLOSE || code === CURLY_BRACKET_CLOSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function is_bracket_pair(open, close) {
|
||||||
|
return (
|
||||||
|
(open === SQUARE_BRACKET_OPEN && close === SQUARE_BRACKET_CLOSE) ||
|
||||||
|
(open === CURLY_BRACKET_OPEN && close === CURLY_BRACKET_CLOSE)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function get_bracket_close(open) {
|
||||||
|
if (open === SQUARE_BRACKET_OPEN) {
|
||||||
|
return SQUARE_BRACKET_CLOSE;
|
||||||
|
}
|
||||||
|
if (open === CURLY_BRACKET_OPEN) {
|
||||||
|
return CURLY_BRACKET_CLOSE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
thePromise: new Promise(resolve => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
html: `
|
||||||
|
loading...
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, component, target }) {
|
||||||
|
await (component.thePromise = Promise.resolve([1, 2]));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await (component.thePromise = Promise.resolve([4, 5]));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>a: 4</p>
|
||||||
|
<p>b: 5</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await (component.thePromise = Promise.reject(['a', [6, 7]]));
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>c: a</p>
|
||||||
|
<p>d: 6</p>
|
||||||
|
<p>e: 7</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await (component.thePromise = Promise.reject(['b', [8, 9]]));
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>c: b</p>
|
||||||
|
<p>d: 8</p>
|
||||||
|
<p>e: 9</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,14 @@
|
|||||||
|
<script>
|
||||||
|
export let thePromise;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await thePromise}
|
||||||
|
loading...
|
||||||
|
{:then [ a, b ]}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
{:catch [c, [d, e]]}
|
||||||
|
<p>c: {c}</p>
|
||||||
|
<p>d: {d}</p>
|
||||||
|
<p>e: {e}</p>
|
||||||
|
{/await}
|
@ -0,0 +1,23 @@
|
|||||||
|
export default {
|
||||||
|
async test({ assert, component, target }) {
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>a: 3</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>c: 3</p>
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>c: 3</p>
|
||||||
|
<p>a: 3</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>c: 3</p>
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>c: 3</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,34 @@
|
|||||||
|
<script>
|
||||||
|
let object = Promise.resolve({ b: 2, c: 3 });
|
||||||
|
let array = Promise.resolve([1, 2]);
|
||||||
|
let objectReject = Promise.reject({ b: 2, c: 3 });
|
||||||
|
let arrayReject = Promise.reject([1, 2]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await object then { a = 3, b = 4, c }}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>c: {c}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await array then [a, b, c = 3]}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>c: {c}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await objectReject then value}
|
||||||
|
resolved
|
||||||
|
{:catch { a = 3, b = 4, c }}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>c: {c}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await arrayReject then value}
|
||||||
|
resolved
|
||||||
|
{:catch [a, b, c = 3]}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>c: {c}</p>
|
||||||
|
{/await}
|
@ -0,0 +1,63 @@
|
|||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
thePromise: new Promise(resolve => {})
|
||||||
|
},
|
||||||
|
|
||||||
|
html: `
|
||||||
|
loading...
|
||||||
|
`,
|
||||||
|
|
||||||
|
async test({ assert, component, target }) {
|
||||||
|
await (component.thePromise = Promise.resolve({ error: "error message" }));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>error: error message</p>
|
||||||
|
<p>result: undefined</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
await (component.thePromise = Promise.resolve({ result: "42" }));
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>error: undefined</p>
|
||||||
|
<p>result: 42</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await (component.thePromise = Promise.reject({
|
||||||
|
error: { message: "oops", code: "123" }
|
||||||
|
}));
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>message: oops</p>
|
||||||
|
<p>code: 123</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await (component.thePromise = Promise.reject({
|
||||||
|
error: { message: "timeout", code: "456" }
|
||||||
|
}));
|
||||||
|
} catch (e) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>message: timeout</p>
|
||||||
|
<p>code: 456</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,13 @@
|
|||||||
|
<script>
|
||||||
|
export let thePromise;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await thePromise}
|
||||||
|
loading...
|
||||||
|
{:then { result, error }}
|
||||||
|
<p>error: {error}</p>
|
||||||
|
<p>result: {result}</p>
|
||||||
|
{:catch { error: { message, code } }}
|
||||||
|
<p>message: {message}</p>
|
||||||
|
<p>code: {code}</p>
|
||||||
|
{/await}
|
@ -0,0 +1,21 @@
|
|||||||
|
export default {
|
||||||
|
async test({ assert, component, target }) {
|
||||||
|
await Promise.resolve();
|
||||||
|
|
||||||
|
assert.htmlEqual(
|
||||||
|
target.innerHTML,
|
||||||
|
`
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>rest: {"b":2,"c":3}</p>
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>rest: [3,4,5,6]</p>
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>rest: {"b":2,"c":3}</p>
|
||||||
|
<p>a: 1</p>
|
||||||
|
<p>b: 2</p>
|
||||||
|
<p>rest: [3,4,5,6]</p>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,32 @@
|
|||||||
|
<script>
|
||||||
|
let object = Promise.resolve({ a: 1, b: 2, c: 3 });
|
||||||
|
let array = Promise.resolve([1, 2, 3, 4, 5, 6]);
|
||||||
|
let objectReject = Promise.reject({ a: 1, b: 2, c: 3 });
|
||||||
|
let arrayReject = Promise.reject([1, 2, 3, 4, 5, 6]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
{#await object then { a, ...rest }}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>rest: {JSON.stringify(rest)}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await array then [a, b, ...rest]}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>rest: {JSON.stringify(rest)}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await objectReject then value}
|
||||||
|
resolved
|
||||||
|
{:catch { a, ...rest }}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>rest: {JSON.stringify(rest)}</p>
|
||||||
|
{/await}
|
||||||
|
|
||||||
|
{#await arrayReject then value}
|
||||||
|
resolved
|
||||||
|
{:catch [a, b, ...rest]}
|
||||||
|
<p>a: {a}</p>
|
||||||
|
<p>b: {b}</p>
|
||||||
|
<p>rest: {JSON.stringify(rest)}</p>
|
||||||
|
{/await}
|
Loading…
Reference in new issue