Skip to content

Commit 1fc5f26

Browse files
tomblindPerryvw
authored andcommitted
Support for spread operator on iterables (#569)
* Support for spread operator on iterables fixes #534 * adressing feedback on test
1 parent c304078 commit 1fc5f26

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

src/LuaLib.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export enum LuaLibFeature {
4444
WeakMap = "WeakMap",
4545
WeakSet = "WeakSet",
4646
SourceMapTraceBack = "SourceMapTraceBack",
47+
Spread = "Spread",
4748
StringConcat = "StringConcat",
4849
StringEndsWith = "StringEndsWith",
4950
StringReplace = "StringReplace",
@@ -63,6 +64,7 @@ const luaLibDependencies: {[lib in LuaLibFeature]?: LuaLibFeature[]} = {
6364
Set: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol],
6465
WeakMap: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol],
6566
WeakSet: [LuaLibFeature.InstanceOf, LuaLibFeature.Iterator, LuaLibFeature.Symbol],
67+
Spread: [LuaLibFeature.Iterator],
6668
SymbolRegistry: [LuaLibFeature.Symbol],
6769
};
6870

src/LuaTransformer.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4566,9 +4566,14 @@ export class LuaTransformer {
45664566
const innerExpression = this.expectExpression(this.transformExpression(expression.expression));
45674567
if (tsHelper.isTupleReturnCall(expression.expression, this.checker)) {
45684568
return innerExpression;
4569-
} else {
4569+
}
4570+
4571+
const type = this.checker.getTypeAtLocation(expression.expression);
4572+
if (tsHelper.isArrayType(type, this.checker, this.program)) {
45704573
return this.createUnpackCall(innerExpression, expression);
45714574
}
4575+
4576+
return this.transformLuaLibFunction(LuaLibFeature.Spread, expression, innerExpression);
45724577
}
45734578

45744579
public transformStringLiteral(literal: ts.StringLiteralLike): ExpressionVisitResult {

src/lualib/Spread.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
declare function unpack<T>(this: void, list: T[], i?: number, j?: number): T[];
2+
3+
declare namespace table {
4+
export function unpack<T>(this: void, list: T[], i?: number, j?: number): T[];
5+
}
6+
7+
function __TS__Spread<T>(this: void, iterable: Iterable<T>): T[] {
8+
const arr: T[] = [];
9+
for (const item of iterable) {
10+
arr[arr.length] = item;
11+
}
12+
return (table.unpack || unpack)(arr);
13+
}

test/unit/spreadElement.spec.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,23 @@ test("Spread Element Lua JIT", () => {
4747
const lua = util.transpileString(`[...[0, 1, 2]]`, options);
4848
expect(lua).toBe("local ____ = {unpack({\n 0,\n 1,\n 2,\n})}");
4949
});
50+
51+
test("Spread Element Iterable", () => {
52+
const code = `
53+
const it = {
54+
i: -1,
55+
[Symbol.iterator]() {
56+
return this;
57+
},
58+
next() {
59+
++this.i;
60+
return {
61+
value: 2 ** this.i,
62+
done: this.i == 9,
63+
}
64+
}
65+
};
66+
const arr = [...it];
67+
return JSONStringify(arr)`;
68+
expect(JSON.parse(util.transpileAndExecute(code))).toEqual([1, 2, 4, 8, 16, 32, 64, 128, 256]);
69+
});

0 commit comments

Comments
 (0)