Skip to content

Commit 12cce12

Browse files
authored
support for global $vararg in bundles (#1107)
* support for global $vararg in bundles fixes #1048 To emulate normal Lua functionality, the entry point receives the global vararg and sub-modules receive their own name when evaluating `$vararg` (`...`). * using dummy vararg when wrapping bundle tests to prevent lua error Co-authored-by: Tom <tomblind@users.noreply.github.com>
1 parent d6ef529 commit 12cce12

File tree

3 files changed

+29
-5
lines changed

3 files changed

+29
-5
lines changed

src/transpilation/bundle.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,13 @@ const requireOverride = `
1616
local ____modules = {}
1717
local ____moduleCache = {}
1818
local ____originalRequire = require
19-
local function require(file)
19+
local function require(file, ...)
2020
if ____moduleCache[file] then
2121
return ____moduleCache[file].value
2222
end
2323
if ____modules[file] then
24-
____moduleCache[file] = { value = ____modules[file]() }
24+
local module = ____modules[file]
25+
____moduleCache[file] = { value = (select("#", ...) > 0) and module(...) or module(file) }
2526
return ____moduleCache[file].value
2627
else
2728
if ____originalRequire then
@@ -55,7 +56,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t
5556
const moduleTable = createModuleTableNode(moduleTableEntries);
5657

5758
// return require("<entry module path>")
58-
const entryPoint = `return require(${createModulePath(entryModule, program)})\n`;
59+
const entryPoint = `return require(${createModulePath(entryModule, program)}, ...)\n`;
5960

6061
const sourceChunks = [requireOverride, moduleTable, entryPoint];
6162

@@ -78,7 +79,7 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t
7879
}
7980

8081
function moduleSourceNode({ code, sourceMapNode }: ProcessedFile, modulePath: string): SourceNode {
81-
const tableEntryHead = `[${modulePath}] = function() `;
82+
const tableEntryHead = `[${modulePath}] = function(...) `;
8283
const tableEntryTail = " end,\n";
8384

8485
return joinSourceChunks([tableEntryHead, sourceMapNode ?? code, tableEntryTail]);

test/unit/language-extensions/vararg.spec.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ test.each([
66
'let result: string; { result = [...$vararg].join(""); }',
77
'let result: string; if (true) { result = [...$vararg].join(""); }',
88
'let result: string; do { result = [...$vararg].join(""); } while (false);',
9+
'function foo(...args: unknown[]) { return args.join(""); } const result = foo(...$vararg);',
910
])("$vararg valid use (%p)", statement => {
1011
util.testModule`
1112
${statement}
@@ -30,3 +31,25 @@ test.each([
3031
.withLanguageExtensions()
3132
.expectDiagnosticsToMatchSnapshot([invalidVarargUse.code]);
3233
});
34+
35+
test("$vararg in bundle entry point", () => {
36+
util.testModule`
37+
export const result = [...$vararg].join("");
38+
`
39+
.setMainFileName("src/main.ts")
40+
.setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" })
41+
.withLanguageExtensions()
42+
.setLuaFactory(code => `return (function(...) ${code} end)("A", "B", "C", "D")`)
43+
.expectToEqual({ result: "ABCD" });
44+
});
45+
46+
test("$vararg in bundle sub-module", () => {
47+
util.testModule`
48+
export { result } from "./module";
49+
`
50+
.setMainFileName("src/main.ts")
51+
.addExtraFile("src/module.ts", 'export const result = [...$vararg].join("")')
52+
.setOptions({ rootDir: "src", luaBundle: "bundle.lua", luaBundleEntry: "src/main.ts" })
53+
.withLanguageExtensions()
54+
.expectToEqual({ result: "module" });
55+
});

test/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -529,7 +529,7 @@ class AccessorTestBuilder extends TestBuilder {
529529
protected accessor = "";
530530

531531
protected getLuaCodeWithWrapper(code: string) {
532-
return `return (function()\n${code}\nend)()${this.accessor}`;
532+
return `return (function(...)\n${code}\nend)()${this.accessor}`;
533533
}
534534

535535
@memoize

0 commit comments

Comments
 (0)