Skip to content

Commit 2d164c2

Browse files
committed
Merge remote-tracking branch 'upstream/master' into out-file
2 parents a1825a1 + de818bc commit 2d164c2

File tree

7 files changed

+75
-12
lines changed

7 files changed

+75
-12
lines changed

src/LuaLib.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ export enum LuaLibFeature {
66
ArrayEvery = "ArrayEvery",
77
ArrayFilter = "ArrayFilter",
88
ArrayForEach = "ArrayForEach",
9+
ArrayFind = "ArrayFind",
910
ArrayFindIndex = "ArrayFindIndex",
1011
ArrayIndexOf = "ArrayIndexOf",
1112
ArrayMap = "ArrayMap",

src/LuaTransformer.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5148,6 +5148,8 @@ export class LuaTransformer {
51485148
);
51495149
case "forEach":
51505150
return this.transformLuaLibFunction(LuaLibFeature.ArrayForEach, node, caller, ...params);
5151+
case "find":
5152+
return this.transformLuaLibFunction(LuaLibFeature.ArrayFind, node, caller, ...params);
51515153
case "findIndex":
51525154
return this.transformLuaLibFunction(LuaLibFeature.ArrayFindIndex, node, caller, ...params);
51535155
case "indexOf":

src/lualib/ArrayFind.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// https://www.ecma-international.org/ecma-262/10.0/index.html#sec-array.prototype.find
2+
function __TS__ArrayFind<T>(
3+
this: void,
4+
arr: T[],
5+
predicate: (value: T, index: number, obj: T[]) => unknown
6+
): T | undefined {
7+
const len = arr.length;
8+
let k = 0;
9+
while (k < len) {
10+
const elem = arr[k];
11+
if (predicate(elem, k, arr)) {
12+
return elem;
13+
}
14+
k = k + 1;
15+
}
16+
17+
return undefined;
18+
}

src/lualib/ArrayReduce.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,26 @@ function __TS__ArrayReduce<T>(
33
this: void,
44
arr: T[],
55
callbackFn: (accumulator: T, currentValue: T, index: number, array: T[]) => T,
6-
initial?: T
6+
...initial: Vararg<T>
77
): T {
88
const len = arr.length;
99

10-
if (len === 0 && initial === undefined) {
11-
// tslint:disable-next-line: no-string-throw
12-
throw "Reduce of empty array with no initial value";
13-
}
14-
1510
let k = 0;
16-
let accumulator = initial;
17-
if (initial === undefined) {
11+
let accumulator = undefined;
12+
13+
// Check if initial value is present in function call
14+
if (select("#", ...initial) !== 0) {
15+
accumulator = select(1, ...initial);
16+
} else if (len > 0) {
1817
accumulator = arr[0];
19-
k++;
18+
k = 1;
19+
} else {
20+
// tslint:disable-next-line: no-string-throw
21+
throw "Reduce of empty array with no initial value";
2022
}
2123

22-
while (k < len) {
23-
accumulator = callbackFn(accumulator, arr[k], k, arr);
24-
k = k + 1;
24+
for (const i of forRange(k, len - 1)) {
25+
accumulator = callbackFn(accumulator, arr[i], i, arr);
2526
}
2627

2728
return accumulator;

src/lualib/declarations/global.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,6 @@ declare function rawset<T, K extends keyof T>(table: T, key: K, val: T[K]): void
1616
declare function next<K, V>(table: Record<any, V>, index?: K): [K, V];
1717
declare function pcall(func: () => any): any;
1818
declare function unpack<T>(list: T[], i?: number, j?: number): T[];
19+
20+
declare function select<T>(index: number, ...args: T[]): T;
21+
declare function select<T>(index: "#", ...args: T[]): number;

src/lualib/declarations/tstl.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
/** @noSelfInFile */
22

3+
/** @vararg */
4+
interface Vararg<T> extends Array<T> {}
5+
6+
/** @forRange */
7+
declare function forRange(start: number, limit: number, step?: number): number[];
8+
39
interface LuaClass {
410
prototype: LuaObject;
511
____super?: LuaClass;

test/unit/builtins/array.spec.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,25 @@ test("array.forEach (%p)", () => {
246246
`.expectToMatchJsResult();
247247
});
248248

249+
test.each([
250+
{ array: [], predicate: "elem > 3" },
251+
{ array: [0, 2, 4, 8], predicate: "elem > 10" },
252+
{ array: [0, 2, 4, 8], predicate: "elem > 7" },
253+
{ array: [0, 2, 4, 8], predicate: "elem == 0" },
254+
{ array: [0, 2, 4, 8], predicate: "elem > 7" },
255+
{ array: [0, 2, 4, 8], predicate: "true" },
256+
{ array: [0, 2, 4, 8], predicate: "false" },
257+
])("array.find (%p)", ({ array, predicate }) => {
258+
util.testFunction`
259+
const array = ${util.valueToString(array)};
260+
return array.find((elem, index, arr) => ${predicate} && arr[index] === elem);
261+
`.expectToMatchJsResult();
262+
});
263+
249264
test.each([
250265
{ array: [], searchElement: 3 },
251266
{ array: [0, 2, 4, 8], searchElement: 10 },
267+
{ array: [0, 2, 4, 8], searchElement: 0 },
252268
{ array: [0, 2, 4, 8], searchElement: 8 },
253269
])("array.findIndex (%p)", ({ array, searchElement }) => {
254270
util.testFunction`
@@ -486,6 +502,22 @@ test.each<[[(total: number, currentItem: number, index: number, array: number[])
486502
util.testExpression`[1, 3, 5, 7].reduce(${util.valuesToString(args)})`.expectToMatchJsResult();
487503
});
488504

505+
test("array.reduce empty undefined initial", () => {
506+
util.testExpression`[].reduce(() => {}, undefined)`.expectToMatchJsResult();
507+
});
508+
509+
test("array.reduce empty no initial", () => {
510+
util.testExpression`[].reduce(() => {})`.expectToMatchJsResult(true);
511+
});
512+
513+
test("array.reduce undefined returning callback", () => {
514+
util.testFunction`
515+
const calls: Array<{ a: void, b: string }> = [];
516+
["a", "b"].reduce<void>((a, b) => { calls.push({ a, b }) }, undefined);
517+
return calls;
518+
`.expectToMatchJsResult();
519+
});
520+
489521
const genericChecks = [
490522
"function generic<T extends number[]>(array: T)",
491523
"function generic<T extends [...number[]]>(array: T)",

0 commit comments

Comments
 (0)