Skip to content

Commit 2cec2ef

Browse files
committed
Merge remote-tracking branch 'upstream/master' into transformation-pipeline-refactor
2 parents bf63f60 + d88c930 commit 2cec2ef

30 files changed

Lines changed: 618 additions & 133 deletions

package-lock.json

Lines changed: 14 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/CompilerOptions.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ export interface TransformerImport {
2020
export type CompilerOptions = OmitIndexSignature<ts.CompilerOptions> & {
2121
noImplicitSelf?: boolean;
2222
noHeader?: boolean;
23+
luaBundle?: string;
24+
luaBundleEntry?: string;
2325
luaTarget?: LuaTarget;
2426
luaLibImport?: LuaLibImportKind;
2527
noHoisting?: boolean;
@@ -41,3 +43,42 @@ export enum LuaTarget {
4143
Lua53 = "5.3",
4244
LuaJIT = "JIT",
4345
}
46+
47+
export function validateOptions(options: CompilerOptions): ts.Diagnostic[] {
48+
const diagnostics: ts.Diagnostic[] = [];
49+
50+
if (options.luaBundle && !options.luaBundleEntry) {
51+
diagnostics.push(configErrorDiagnostic(`'luaBundleEntry' is required when 'luaBundle' is enabled.`));
52+
}
53+
54+
if (options.luaBundle && options.luaLibImport === LuaLibImportKind.Inline) {
55+
diagnostics.push(
56+
configWarningDiagnostic(
57+
`Using 'luaBundle' with 'luaLibImport: "inline"' might generate duplicate code. ` +
58+
`It is recommended to use 'luaLibImport: "require"'`
59+
)
60+
);
61+
}
62+
63+
return diagnostics;
64+
}
65+
66+
const configErrorDiagnostic = (message: string): ts.Diagnostic => ({
67+
file: undefined,
68+
start: undefined,
69+
length: undefined,
70+
category: ts.DiagnosticCategory.Error,
71+
code: 0,
72+
source: "typescript-to-lua",
73+
messageText: message,
74+
});
75+
76+
const configWarningDiagnostic = (message: string): ts.Diagnostic => ({
77+
file: undefined,
78+
start: undefined,
79+
length: undefined,
80+
category: ts.DiagnosticCategory.Warning,
81+
code: 0,
82+
source: "typescript-to-lua",
83+
messageText: message,
84+
});

src/Emit.ts

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as path from "path";
22
import * as ts from "typescript";
3-
import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions";
3+
import { LuaLibImportKind } from "./CompilerOptions";
44
import { EmitHost, TranspiledFile } from "./Transpile";
55
import { normalizeSlashes, trimExtension } from "./utils";
66

@@ -11,18 +11,15 @@ export interface OutputFile {
1111

1212
let lualibContent: string;
1313
export function emitTranspiledFiles(
14-
options: CompilerOptions,
14+
program: ts.Program,
1515
transpiledFiles: TranspiledFile[],
1616
emitHost: EmitHost = ts.sys
1717
): OutputFile[] {
18-
let { rootDir, outDir, outFile, luaLibImport } = options;
18+
const options = program.getCompilerOptions();
19+
let { outDir, luaLibImport, luaBundle } = options;
1920

20-
const configFileName = options.configFilePath as string | undefined;
21-
// TODO: Use getCommonSourceDirectory
22-
const baseDir = configFileName ? path.dirname(configFileName) : process.cwd();
23-
24-
rootDir = rootDir || baseDir;
25-
outDir = outDir ? path.resolve(baseDir, outDir) : rootDir;
21+
const rootDir = program.getCommonSourceDirectory();
22+
outDir = outDir || rootDir;
2623

2724
const files: OutputFile[] = [];
2825
for (const { fileName, lua, sourceMap, declaration, declarationMap } of transpiledFiles) {
@@ -31,14 +28,8 @@ export function emitTranspiledFiles(
3128
outPath = path.resolve(outDir, path.relative(rootDir, fileName));
3229
}
3330

34-
// change extension or rename to outFile
35-
if (outFile) {
36-
outPath = path.isAbsolute(outFile) ? outFile : path.resolve(baseDir, outFile);
37-
} else {
38-
outPath = trimExtension(outPath) + ".lua";
39-
}
40-
41-
outPath = normalizeSlashes(outPath);
31+
// change extension
32+
outPath = normalizeSlashes(trimExtension(outPath) + ".lua");
4233

4334
if (lua !== undefined) {
4435
files.push({ name: outPath, text: lua });
@@ -57,22 +48,30 @@ export function emitTranspiledFiles(
5748
}
5849
}
5950

60-
if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) {
61-
if (lualibContent === undefined) {
62-
const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"));
63-
if (lualibBundle !== undefined) {
64-
lualibContent = lualibBundle;
65-
} else {
66-
throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua");
51+
if (
52+
!luaBundle &&
53+
(luaLibImport === undefined ||
54+
luaLibImport === LuaLibImportKind.Require ||
55+
luaLibImport === LuaLibImportKind.Always)
56+
) {
57+
const lualibRequired = files.some(f => f.text && f.text.includes(`require("lualib_bundle")`));
58+
if (lualibRequired) {
59+
if (lualibContent === undefined) {
60+
const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"));
61+
if (lualibBundle !== undefined) {
62+
lualibContent = lualibBundle;
63+
} else {
64+
throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua");
65+
}
6766
}
68-
}
6967

70-
let outPath = path.resolve(rootDir, "lualib_bundle.lua");
71-
if (outDir !== rootDir) {
72-
outPath = path.join(outDir, path.relative(rootDir, outPath));
73-
}
68+
let outPath = path.resolve(rootDir, "lualib_bundle.lua");
69+
if (outDir !== rootDir) {
70+
outPath = path.join(outDir, path.relative(rootDir, outPath));
71+
}
7472

75-
files.push({ name: normalizeSlashes(outPath), text: lualibContent });
73+
files.push({ name: normalizeSlashes(outPath), text: lualibContent });
74+
}
7675
}
7776

7877
return files;

src/LuaPrinter.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ const escapeStringMap: Record<string, string> = {
2323
"\0": "\\0",
2424
};
2525

26-
const escapeString = (value: string) => `"${value.replace(escapeStringRegExp, char => escapeStringMap[char] || char)}"`;
26+
export const escapeString = (value: string) =>
27+
`"${value.replace(escapeStringRegExp, char => escapeStringMap[char] || char)}"`;
2728

2829
/**
2930
* Checks that a name is valid for use in lua function declaration syntax:
@@ -85,6 +86,7 @@ export type Printer = (
8586
export interface PrintResult {
8687
code: string;
8788
sourceMap: string;
89+
sourceMapNode: SourceNode;
8890
}
8991

9092
export function createPrinter(printers: Printer[]): Printer {
@@ -158,7 +160,7 @@ export class LuaPrinter {
158160
code = code.replace("{#SourceMapTraceback}", stackTraceOverride);
159161
}
160162

161-
return { code, sourceMap: sourceMap.toString() };
163+
return { code, sourceMap: sourceMap.toString(), sourceMapNode: rootSourceNode };
162164
}
163165

164166
private printInlineSourceMap(sourceMap: SourceMapGenerator): string {
@@ -196,7 +198,7 @@ export class LuaPrinter {
196198
header += `--[[ Generated with https://github.com/TypeScriptToLua/TypeScriptToLua ]]\n`;
197199
}
198200

199-
const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Inline;
201+
const luaLibImport = this.options.luaLibImport || LuaLibImportKind.Require;
200202
if (
201203
luaLibImport === LuaLibImportKind.Always ||
202204
(luaLibImport === LuaLibImportKind.Require && luaLibFeatures.size > 0)

src/Transpile.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
import { SourceNode } from "source-map";
12
import * as ts from "typescript";
2-
import { CompilerOptions } from "./CompilerOptions";
3+
import { bundleTranspiledFiles } from "./bundle";
4+
import { CompilerOptions, validateOptions } from "./CompilerOptions";
35
import { Block } from "./LuaAST";
46
import { createPrinter } from "./LuaPrinter";
57
import { getPlugins, Plugin } from "./plugins";
@@ -14,6 +16,8 @@ export interface TranspiledFile {
1416
sourceMap?: string;
1517
declaration?: string;
1618
declarationMap?: string;
19+
/** @internal */
20+
sourceMapNode?: SourceNode;
1721
}
1822

1923
export interface TranspileResult {
@@ -30,6 +34,7 @@ export interface TranspileOptions {
3034
}
3135

3236
export interface EmitHost {
37+
getCurrentDirectory(): string;
3338
readFile(path: string): string | undefined;
3439
}
3540

@@ -42,7 +47,7 @@ export function transpile({
4247
}: TranspileOptions): TranspileResult {
4348
const options = program.getCompilerOptions() as CompilerOptions;
4449

45-
const diagnostics: ts.Diagnostic[] = [];
50+
const diagnostics = validateOptions(options);
4651
let transpiledFiles: TranspiledFile[] = [];
4752

4853
const updateTranspiledFile = (fileName: string, update: Omit<TranspiledFile, "fileName">) => {
@@ -55,7 +60,11 @@ export function transpile({
5560
};
5661

5762
if (options.noEmitOnError) {
58-
const preEmitDiagnostics = [...program.getOptionsDiagnostics(), ...program.getGlobalDiagnostics()];
63+
const preEmitDiagnostics = [
64+
...diagnostics,
65+
...program.getOptionsDiagnostics(),
66+
...program.getGlobalDiagnostics(),
67+
];
5968

6069
if (targetSourceFiles) {
6170
for (const sourceFile of targetSourceFiles) {
@@ -87,8 +96,14 @@ export function transpile({
8796
);
8897
diagnostics.push(...transformDiagnostics);
8998
if (!options.noEmit && !options.emitDeclarationOnly) {
90-
const { code, sourceMap } = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures);
91-
updateTranspiledFile(sourceFile.fileName, { luaAst, lua: code, sourceMap });
99+
const { code, sourceMap, sourceMapNode } = printer(
100+
program,
101+
emitHost,
102+
sourceFile.fileName,
103+
luaAst,
104+
luaLibFeatures
105+
);
106+
updateTranspiledFile(sourceFile.fileName, { luaAst, lua: code, sourceMap, sourceMapNode });
92107
}
93108
};
94109

@@ -139,5 +154,17 @@ export function transpile({
139154
transpiledFiles = [];
140155
}
141156

157+
if (options.luaBundle && options.luaBundleEntry) {
158+
const [bundleDiagnostics, bundle] = bundleTranspiledFiles(
159+
options.luaBundle,
160+
options.luaBundleEntry,
161+
transpiledFiles,
162+
program,
163+
emitHost
164+
);
165+
diagnostics.push(...bundleDiagnostics);
166+
transpiledFiles = [bundle];
167+
}
168+
142169
return { diagnostics, transpiledFiles };
143170
}

0 commit comments

Comments
 (0)