feat: array spread

This commit is contained in:
cha0s 2024-06-26 04:15:52 -05:00
parent 694cd90645
commit ac12fafa16
2 changed files with 45 additions and 8 deletions

View File

@ -1,13 +1,43 @@
import {isSpreadElement} from '@/astride/types.js';
export default function(node, {evaluate, scope}) {
const elements = [];
const asyncSpread = Object.create(null);
let isAsync = false;
for (const element of node.elements) {
const {async, value} = evaluate(element, {scope});
isAsync = isAsync || async;
elements.push(value);
for (const index in node.elements) {
const element = node.elements[index];
if (isSpreadElement(element)) {
const {async, value} = evaluate(element.argument, {scope});
isAsync = isAsync || async;
if (async) {
elements.push(value);
asyncSpread[elements.length - 1] = true;
}
else {
elements.push(...value);
}
}
else {
const {async, value} = evaluate(element, {scope});
isAsync = isAsync || async;
elements.push(value);
}
}
return {
async: !!isAsync,
value: isAsync ? Promise.all(elements) : elements,
value: !isAsync
? elements
: Promise.all(elements).then((elementsAndOrSpreads) => {
const elements = [];
for (let i = 0; i < elementsAndOrSpreads.length; ++i) {
if (asyncSpread[i]) {
elements.push(...elementsAndOrSpreads[i]);
}
else {
elements.push(elementsAndOrSpreads[i]);
}
}
return elements;
}),
};
}

View File

@ -6,12 +6,19 @@ import expression from '@/astride/test/expression.js';
test('evaluates array of literals', async () => {
expect(evaluate(await expression('[1.5, 2, "three"]')))
.to.deep.include({value: [1.5, 2, 'three']});
});
test('evaluates array containing promises', async () => {
const evaluated = evaluate(await expression('[1.5, 2, await "three"]'));
expect(evaluated.async)
.to.equal(true);
expect(await evaluated.value)
.to.deep.equal([1.5, 2, 'three']);
});
test('evaluates array spread', async () => {
expect(evaluate(await expression('[...[4, 5, 6], 1.5, 2, "three"]')))
.to.deep.include({value: [4, 5, 6, 1.5, 2, 'three']});
const evaluated = evaluate(await expression('[...(await [4, 5, 6]), 1.5, 2, await "three"]'));
expect(evaluated.async)
.to.equal(true);
expect(await evaluated.value)
.to.deep.equal([4, 5, 6, 1.5, 2, 'three']);
});