Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/CompilerOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ export interface TypeScriptToLuaOptions {
tstlVerbose?: boolean;
lua51AllowTryCatchInAsyncAwait?: boolean;
measurePerformance?: boolean;
luaLibName?: string;
luaLibEmit?: boolean;
}

export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> &
Expand Down
5 changes: 3 additions & 2 deletions src/LuaLib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ export function loadInlineLualibFeatures(
export function loadImportedLualibFeatures(
features: Iterable<LuaLibFeature>,
luaTarget: LuaTarget,
emitHost: EmitHost
emitHost: EmitHost,
luaLibName: string
): lua.Statement[] {
const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost);

Expand All @@ -239,7 +240,7 @@ export function loadImportedLualibFeatures(
}

const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [
lua.createStringLiteral("lualib_bundle"),
lua.createStringLiteral(luaLibName),
]);

const luaLibId = lua.createIdentifier("____lualib");
Expand Down
3 changes: 2 additions & 1 deletion src/LuaPrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,13 +235,14 @@ export class LuaPrinter {

const luaTarget = this.options.luaTarget ?? LuaTarget.Universal;
const luaLibImport = this.options.luaLibImport ?? LuaLibImportKind.Require;
const luaLibName = this.options.luaLibName ?? "lualib_bundle";
if (
(luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.RequireMinimal) &&
file.luaLibFeatures.size > 0
) {
// Import lualib features
sourceChunks = this.printStatementArray(
loadImportedLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost)
loadImportedLualibFeatures(file.luaLibFeatures, luaTarget, this.emitHost, luaLibName)
);
} else if (luaLibImport === LuaLibImportKind.Inline && file.luaLibFeatures.size > 0) {
// Inline lualib features
Expand Down
11 changes: 11 additions & 0 deletions src/cli/parse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ export const optionDeclarations: CommandLineOption[] = [
type: "enum",
choices: Object.values(LuaLibImportKind),
},
{
name: "luaLibName",
description: "The name of the file to store Lua library features in.",
type: "string",
},
{
name: "luaLibEmit",
description:
"Whether the Lua library file is emitted with the code. Only effective when luaLibImport is require.",
type: "boolean",
},
{
name: "luaTarget",
aliases: ["lt"],
Expand Down
2 changes: 1 addition & 1 deletion src/lualib-build/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class LuaLibPlugin implements tstl.Plugin {
let lualibBundle = orderedFeatures.map(f => exportedLualibFeatures.get(LuaLibFeature[f])).join("\n");
const exports = allFeatures.flatMap(feature => luaLibModuleInfo[feature].exports);
lualibBundle += getLualibBundleReturn(exports);
result.push({ fileName: "lualib_bundle.lua", code: lualibBundle });
result.push({ fileName: (options.luaLibName ?? "lualib_bundle") + ".lua", code: lualibBundle });

return diagnostics;
}
Expand Down
6 changes: 5 additions & 1 deletion src/transpilation/bundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,11 @@ export function getBundleResult(program: ts.Program, files: ProcessedFile[]): [t
const footers: string[] = [];
if (options.sourceMapTraceback) {
// Generates SourceMapTraceback for the entire file
footers.push('local __TS__SourceMapTraceBack = require("lualib_bundle").__TS__SourceMapTraceBack\n');
footers.push(
`local __TS__SourceMapTraceBack = require("${
options.luaLibName ?? "lualib_bundle"
}").__TS__SourceMapTraceBack\n`
);
footers.push(`${sourceMapTracebackBundlePlaceholder}\n`);
}

Expand Down
7 changes: 5 additions & 2 deletions src/transpilation/resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,11 @@ class ResolutionContext {

public resolveImport(file: ProcessedFile, required: LuaRequire): void {
// Do no resolve lualib - always use the lualib of the application entry point, not the lualib from external packages
if (required.requirePath === "lualib_bundle") {
this.resolvedFiles.set("lualib_bundle", { fileName: "lualib_bundle", code: "" });
if (required.requirePath === (this.options.luaLibName ?? "lualib_bundle")) {
this.resolvedFiles.set(this.options.luaLibName ?? "lualib_bundle", {
fileName: this.options.luaLibName ?? "lualib_bundle",
code: "",
});
return;
}

Expand Down
18 changes: 13 additions & 5 deletions src/transpilation/transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,18 +123,26 @@ export class Transpiler {
const resolutionResult = resolveDependencies(program, files, this.emitHost, plugins);
diagnostics.push(...resolutionResult.diagnostics);

const lualibRequired = resolutionResult.resolvedFiles.some(f => f.fileName === "lualib_bundle");
const lualibRequired = resolutionResult.resolvedFiles.some(
f => f.fileName === (options.luaLibName ?? "lualib_bundle")
);
if (lualibRequired) {
// Remove lualib placeholders from resolution result
resolutionResult.resolvedFiles = resolutionResult.resolvedFiles.filter(f => f.fileName !== "lualib_bundle");
resolutionResult.resolvedFiles = resolutionResult.resolvedFiles.filter(
f => f.fileName !== (options.luaLibName ?? "lualib_bundle")
);

if (options.tstlVerbose) {
console.log("Including lualib bundle");
}
// Add lualib bundle to source dir 'virtually', will be moved to correct output dir in emitPlan
const fileName = normalizeSlashes(path.resolve(getSourceDir(program), "lualib_bundle.lua"));
const code = this.getLuaLibBundleContent(options, resolutionResult.resolvedFiles);
resolutionResult.resolvedFiles.unshift({ fileName, code });
if (options.luaLibEmit !== false) {
const fileName = normalizeSlashes(
path.resolve(getSourceDir(program), (options.luaLibName ?? "lualib_bundle") + ".lua")
);
const code = this.getLuaLibBundleContent(options, resolutionResult.resolvedFiles);
resolutionResult.resolvedFiles.unshift({ fileName, code });
}
}

let emitPlan: EmitFile[];
Expand Down
4 changes: 4 additions & 0 deletions test/cli/parse.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@ describe("command line", () => {
["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }],
["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }],
["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }],
["luaLibName", "typescript", { luaLibName: "typescript" }],
["luaLibEmit", "false", { luaLibEmit: false }],

["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }],
["luaTarget", "5.1", { luaTarget: tstl.LuaTarget.Lua51 }],
Expand Down Expand Up @@ -240,6 +242,8 @@ describe("tsconfig", () => {
["luaLibImport", "none", { luaLibImport: tstl.LuaLibImportKind.None }],
["luaLibImport", "inline", { luaLibImport: tstl.LuaLibImportKind.Inline }],
["luaLibImport", "require", { luaLibImport: tstl.LuaLibImportKind.Require }],
["luaLibName", "typescript", { luaLibName: "typescript" }],
["luaLibEmit", false, { luaLibEmit: false }],

["luaTarget", "universal", { luaTarget: tstl.LuaTarget.Universal }],
["luaTarget", "5.0", { luaTarget: tstl.LuaTarget.Lua50 }],
Expand Down
19 changes: 19 additions & 0 deletions test/transpile/lualib.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,22 @@ test("Lualib bundle does not assign globals", () => {
.withLanguageExtensions()
.expectNoExecutionError();
});

test("Lualib bundle can be renamed", () => {
const result = util
.testExpression("[1, 2, 3, 4].map(n => n*n).join(' ')")
.setOptions({ luaLibName: "typescript" })
.expectNoExecutionError()
.getLuaResult();
expect(result.transpiledFiles.some(file => file.outPath.match(/lualib_bundle.lua$/))).toBeFalsy();
expect(result.transpiledFiles.some(file => file.outPath.match(/typescript.lua$/))).toBeTruthy();
});

test("Lualib bundle emission can be disabled", () => {
const result = util
.testExpression("[1, 2, 3, 4].map(n => n*n).join(' ')")
.setOptions({ luaLibEmit: false })
.expectNoTranspileException()
.getLuaResult();
expect(result.transpiledFiles.some(file => file.outPath.match(/lualib_bundle.lua$/))).toBeFalsy();
});
4 changes: 2 additions & 2 deletions test/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -456,9 +456,9 @@ export abstract class TestBuilder {
// Lua lib
if (
this.options.luaLibImport === tstl.LuaLibImportKind.Require ||
mainFile.includes('require("lualib_bundle")')
mainFile.includes(`require("${this.options.luaLibName ?? "lualib_bundle"}")`)
) {
this.injectLuaFile(L, lua, lauxlib, "lualib_bundle", readLuaLib(luaTarget));
this.injectLuaFile(L, lua, lauxlib, this.options.luaLibName ?? "lualib_bundle", readLuaLib(luaTarget));
}

// Load all transpiled files into Lua's package cache
Expand Down
10 changes: 10 additions & 0 deletions tsconfig-schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
"default": "require",
"enum": ["none", "inline", "require", "require-minimal"]
},
"luaLibName": {
"description": "The name of the file to store Lua library features in.",
"type": "string",
"default": "lualib_bundle"
},
"luaLibEmit": {
"description": "Whether the Lua library file is emitted with the code. Only effective when luaLibImport is require.",
"type": "boolean",
"default": true
},
"luaTarget": {
"description": "Specifies the Lua version you want to generate code for.",
"type": "string",
Expand Down