Skip to content

Commit cf79978

Browse files
authored
Add Array.at(index) to lualib (#1484)
1 parent 32e0daf commit cf79978

File tree

4 files changed

+46
-0
lines changed

4 files changed

+46
-0
lines changed

src/LuaLib.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { LuaTarget } from "./CompilerOptions";
55
import { getOrUpdate } from "./utils";
66

77
export enum LuaLibFeature {
8+
ArrayAt = "ArrayAt",
89
ArrayConcat = "ArrayConcat",
910
ArrayEntries = "ArrayEntries",
1011
ArrayEvery = "ArrayEvery",

src/lualib/ArrayAt.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.at
2+
// Technically the specs also allow non-numeric types to be passed as index.
3+
// However, TypeScript types the `Array.at` index param as number so we also expect only numbers
4+
// This behaviour also matches the implementation of other Array functions in lualib.
5+
export function __TS__ArrayAt<T>(this: T[], relativeIndex: number): T | undefined {
6+
const absoluteIndex = relativeIndex < 0 ? this.length + relativeIndex : relativeIndex;
7+
8+
if (absoluteIndex >= 0 && absoluteIndex < this.length) {
9+
return this[absoluteIndex];
10+
}
11+
12+
return undefined;
13+
}

src/transformation/builtins/array.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ export function transformArrayPrototypeCall(
8888

8989
const expressionName = calledMethod.name.text;
9090
switch (expressionName) {
91+
case "at":
92+
return transformLuaLibFunction(context, LuaLibFeature.ArrayAt, node, caller, ...params);
9193
case "concat":
9294
return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params);
9395
case "entries":

test/unit/builtins/array.spec.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,36 @@ test("tuple.forEach", () => {
272272
`.expectToMatchJsResult();
273273
});
274274

275+
describe("at", () => {
276+
test("valid index", () => {
277+
util.testFunction`
278+
const array = [1, 2, 3, 4];
279+
return array.at(2);
280+
`.expectToMatchJsResult();
281+
});
282+
283+
test("invalid index", () => {
284+
util.testFunction`
285+
const array = [1, 2, 3, 4];
286+
return array.at(10);
287+
`.expectToMatchJsResult();
288+
});
289+
290+
test("valid negative index", () => {
291+
util.testFunction`
292+
const array = [1, 2, 3, 4];
293+
return array.at(-2);
294+
`.expectToMatchJsResult();
295+
});
296+
297+
test("invalid negative index", () => {
298+
util.testFunction`
299+
const array = [1, 2, 3, 4];
300+
return array.at(-10);
301+
`.expectToMatchJsResult();
302+
});
303+
});
304+
275305
test("array.forEach (%p)", () => {
276306
util.testFunction`
277307
const array = [0, 1, 2, 3];

0 commit comments

Comments
 (0)