Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/LuaLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum LuaLibFeature {
ArrayConcat = "ArrayConcat",
ArrayEntries = "ArrayEntries",
ArrayEvery = "ArrayEvery",
ArrayFill = "ArrayFill",
ArrayFilter = "ArrayFilter",
ArrayForEach = "ArrayForEach",
ArrayFind = "ArrayFind",
Expand Down
19 changes: 19 additions & 0 deletions src/lualib/ArrayFill.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.fill
export function __TS__ArrayFill<T>(this: T[], value: T, start?: number, end?: number): T[] {
let relativeStart = start ?? 0;
let relativeEnd = end ?? this.length;

if (relativeStart < 0) {
relativeStart += this.length;
}

if (relativeEnd < 0) {
relativeEnd += this.length;
}

for (let i = relativeStart; i < relativeEnd; i++) {
this[i] = value;
}

return this;
}
2 changes: 2 additions & 0 deletions src/transformation/builtins/array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ export function transformArrayPrototypeCall(
return transformLuaLibFunction(context, LuaLibFeature.ArrayConcat, node, caller, ...params);
case "entries":
return transformLuaLibFunction(context, LuaLibFeature.ArrayEntries, node, caller);
case "fill":
return transformLuaLibFunction(context, LuaLibFeature.ArrayFill, node, caller, ...params);
case "push":
if (node.arguments.length === 1) {
const param = params[0] ?? lua.createNilLiteral();
Expand Down
27 changes: 27 additions & 0 deletions test/unit/builtins/array.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,33 @@ test.each([
util.testExpression(literal).expectToHaveNoDiagnostics();
});

describe("array.fill", () => {
test.each(["[]", "[1]", "[1,2,3,4]"])("Fills full length of array without other parameters (%p)", arr => {
util.testExpression`${arr}.fill(5)`.expectToMatchJsResult();
});

test.each(["[1,2,3]", "[1,2,3,4,5,6]"])("Fills starting from start parameter (%p)", arr => {
util.testExpression`${arr}.fill(5, 3)`.expectToMatchJsResult();
});

test("handles negative start parameter", () => {
util.testExpression`[1,2,3,4,5,6,7].fill(8, -3)`.expectToMatchJsResult();
});

test("handles negative end parameter", () => {
util.testExpression`[1,2,3,4,5,6,7].fill(8, -5, -2)`.expectToMatchJsResult();
});

test("Fills starting from start parameter, up to ending parameter", () => {
util.testExpression`[1,2,3,4,5,6,7,8].fill(5, 2, 6)`.expectToMatchJsResult();
});

// NOTE: This is different from the default ECMAScript specification for the behavior, but for Lua this is much more useful
test("Extends size of the array if ending size is larger than array", () => {
util.testExpression`[1,2,3].fill(5, 0, 6)`.expectToEqual([5, 5, 5, 5, 5, 5]);
});
});

// Issue #1218: https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1218
test.each(["[1, 2, 3]", "undefined"])("prototype call on nullable array (%p)", value => {
util.testFunction`
Expand Down