Skip to content

Commit 1cdd6b0

Browse files
authored
Added BeforeEmit plugin hook (#1239)
* Added BeforeEmit plugin hook * Updated verbose log snapshot
1 parent 304c203 commit 1cdd6b0

File tree

9 files changed

+107
-28
lines changed

9 files changed

+107
-28
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ export { LuaLibFeature } from "./LuaLib";
88
export * from "./LuaPrinter";
99
export * from "./transformation/context";
1010
export * from "./transpilation";
11-
export { ProcessedFile } from "./transpilation/utils";
11+
export { EmitHost, EmitFile, ProcessedFile } from "./transpilation/utils";

src/transpilation/plugins.ts

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { EmitHost } from "..";
33
import { CompilerOptions } from "../CompilerOptions";
44
import { Printer } from "../LuaPrinter";
55
import { Visitors } from "../transformation/context";
6-
import { getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils";
6+
import { EmitFile, getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils";
77

88
export interface Plugin {
99
/**
@@ -26,17 +26,28 @@ export interface Plugin {
2626
beforeTransform?: (program: ts.Program, options: CompilerOptions, emitHost: EmitHost) => ts.Diagnostic[] | void;
2727

2828
/**
29-
* This function is called after TypeScriptToLua has translated the input program to Lua.
29+
* This function is called after translating the input program to Lua, but before resolving dependencies or bundling.
3030
*/
3131
afterPrint?: (
3232
program: ts.Program,
3333
options: CompilerOptions,
3434
emitHost: EmitHost,
3535
result: ProcessedFile[]
3636
) => ts.Diagnostic[] | void;
37+
38+
/**
39+
* This function is called after translating the input program to Lua, after resolving dependencies and after bundling.
40+
*/
41+
beforeEmit?: (
42+
program: ts.Program,
43+
options: CompilerOptions,
44+
emitHost: EmitHost,
45+
result: EmitFile[]
46+
) => ts.Diagnostic[] | void;
3747
}
3848

39-
export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], customPlugins: Plugin[]): Plugin[] {
49+
export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } {
50+
const diagnostics: ts.Diagnostic[] = [];
4051
const pluginsFromOptions: Plugin[] = [];
4152
const options = program.getCompilerOptions() as CompilerOptions;
4253

@@ -58,5 +69,9 @@ export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], cu
5869
pluginsFromOptions.push(plugin);
5970
}
6071

61-
return [...customPlugins, ...pluginsFromOptions];
72+
if (options.tstlVerbose) {
73+
console.log(`Loaded ${pluginsFromOptions.length} plugins`);
74+
}
75+
76+
return { diagnostics, plugins: pluginsFromOptions };
6277
}

src/transpilation/transpile.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { CompilerOptions, validateOptions } from "../CompilerOptions";
44
import { createPrinter } from "../LuaPrinter";
55
import { createVisitorMap, transformSourceFile } from "../transformation";
66
import { isNonNull } from "../utils";
7-
import { getPlugins, Plugin } from "./plugins";
7+
import { Plugin } from "./plugins";
88
import { getTransformers } from "./transformers";
99
import { EmitHost, ProcessedFile } from "./utils";
1010

@@ -23,7 +23,7 @@ export interface TranspileResult {
2323
export function getProgramTranspileResult(
2424
emitHost: EmitHost,
2525
writeFileResult: ts.WriteFileCallback,
26-
{ program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins: customPlugins = [] }: TranspileOptions
26+
{ program, sourceFiles: targetSourceFiles, customTransformers = {}, plugins = [] }: TranspileOptions
2727
): TranspileResult {
2828
const options = program.getCompilerOptions() as CompilerOptions;
2929

@@ -60,12 +60,6 @@ export function getProgramTranspileResult(
6060
}
6161
}
6262

63-
const plugins = getPlugins(program, diagnostics, customPlugins);
64-
65-
if (options.tstlVerbose) {
66-
console.log(`Successfully loaded ${plugins.length} plugins`);
67-
}
68-
6963
for (const plugin of plugins) {
7064
if (plugin.beforeTransform) {
7165
const pluginDiagnostics = plugin.beforeTransform(program, options, emitHost) ?? [];

src/transpilation/transpiler.ts

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CompilerOptions, isBundleEnabled } from "../CompilerOptions";
44
import { getLuaLibBundle } from "../LuaLib";
55
import { normalizeSlashes, trimExtension } from "../utils";
66
import { getBundleResult } from "./bundle";
7+
import { getPlugins } from "./plugins";
78
import { resolveDependencies } from "./resolve";
89
import { getProgramTranspileResult, TranspileOptions } from "./transpile";
910
import { EmitFile, EmitHost, ProcessedFile } from "./utils";
@@ -29,23 +30,31 @@ export class Transpiler {
2930

3031
public emit(emitOptions: EmitOptions): EmitResult {
3132
const { program, writeFile = this.emitHost.writeFile } = emitOptions;
32-
const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose;
33-
const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(
34-
this.emitHost,
35-
writeFile,
36-
emitOptions
37-
);
33+
const options = program.getCompilerOptions() as CompilerOptions;
34+
35+
const { diagnostics: getPluginsDiagnostics, plugins } = getPlugins(program);
36+
37+
const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(this.emitHost, writeFile, {
38+
...emitOptions,
39+
plugins,
40+
});
3841

3942
const { emitPlan } = this.getEmitPlan(program, diagnostics, freshFiles);
4043

41-
if (verbose) {
44+
if (options.tstlVerbose) {
4245
console.log("Emitting output");
4346
}
4447

45-
const options = program.getCompilerOptions();
48+
for (const plugin of plugins) {
49+
if (plugin.beforeEmit) {
50+
const beforeEmitPluginDiagnostics = plugin.beforeEmit(program, options, this.emitHost, emitPlan) ?? [];
51+
diagnostics.push(...beforeEmitPluginDiagnostics);
52+
}
53+
}
54+
4655
const emitBOM = options.emitBOM ?? false;
4756
for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) {
48-
if (verbose) {
57+
if (options.tstlVerbose) {
4958
console.log(`Emitting ${normalizeSlashes(outputPath)}`);
5059
}
5160

@@ -55,11 +64,11 @@ export class Transpiler {
5564
}
5665
}
5766

58-
if (verbose) {
67+
if (options.tstlVerbose) {
5968
console.log("Emit finished!");
6069
}
6170

62-
return { diagnostics, emitSkipped: emitPlan.length === 0 };
71+
return { diagnostics: getPluginsDiagnostics.concat(diagnostics), emitSkipped: emitPlan.length === 0 };
6372
}
6473

6574
protected getEmitPlan(

src/transpilation/utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ interface BaseFile {
2424
export interface ProcessedFile extends BaseFile {
2525
fileName: string;
2626
luaAst?: lua.File;
27-
/** @internal */
2827
sourceMapNode?: SourceNode;
2928
}
3029

test/transpile/__snapshots__/project.spec.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22

33
exports[`should give verbose output 1`] = `
44
Array [
5+
"Loaded 0 plugins",
56
"Parsing project settings",
6-
"Successfully loaded 0 plugins",
77
"Transforming <cwd>/test/transpile/project/otherFile.ts",
88
"Printing <cwd>/test/transpile/project/otherFile.ts",
99
"Transforming <cwd>/test/transpile/project/index.ts",

test/transpile/plugins/afterPrint.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const plugin: tstl.Plugin = {
1313
void emitHost;
1414

1515
for (const file of result) {
16-
file.code = "-- Commented added by afterPrint plugin\n" + file.code;
16+
file.code = "-- Comment added by afterPrint plugin\n" + file.code;
1717
}
1818
},
1919
};
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import * as ts from "typescript";
2+
import * as tstl from "../../../src";
3+
4+
const plugin: tstl.Plugin = {
5+
beforeEmit(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost, result: tstl.EmitFile[]) {
6+
void program;
7+
void options;
8+
void emitHost;
9+
10+
for (const file of result) {
11+
file.code = "-- Comment added by beforeEmit plugin\n" + file.code;
12+
}
13+
},
14+
};
15+
16+
// eslint-disable-next-line import/no-default-export
17+
export default plugin;

test/transpile/plugins/plugins.spec.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,51 @@ test("afterPrint plugin", () => {
112112
expect(transpiledFiles).toHaveLength(2);
113113
for (const f of transpiledFiles) {
114114
// Expect plugin inserted extra lua at start of file
115-
expect(f.lua).toContain("-- Commented added by afterPrint plugin");
115+
expect(f.lua).toContain("-- Comment added by afterPrint plugin");
116+
}
117+
});
118+
119+
test("beforeEmit plugin", () => {
120+
const { transpiledFiles } = util.testModule`
121+
console.log("Hello, World!");
122+
[].push(1,2,3); // Use lualib code
123+
`
124+
.addExtraFile(
125+
"extrafile.ts",
126+
`
127+
console.log("Hello, Mars!");
128+
`
129+
)
130+
.setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] })
131+
.getLuaResult();
132+
133+
// 2 input files + 1 lualib_bundle
134+
expect(transpiledFiles).toHaveLength(3);
135+
expect(transpiledFiles.find(f => f.outPath.endsWith("lualib_bundle.lua"))).toBeDefined();
136+
for (const f of transpiledFiles) {
137+
// Expect plugin inserted extra lua at start of all files including lualib bundle
138+
expect(f.lua).toContain("-- Comment added by beforeEmit plugin");
139+
}
140+
});
141+
142+
test("beforeEmit plugin bundle", () => {
143+
const { transpiledFiles } = util.testBundle`
144+
console.log("Hello, World!");
145+
[].push(1,2,3); // Use lualib code
146+
`
147+
.addExtraFile(
148+
"extrafile.ts",
149+
`
150+
console.log("Hello, Mars!");
151+
`
152+
)
153+
.setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] })
154+
.getLuaResult();
155+
156+
// 1 lua bundle output
157+
expect(transpiledFiles).toHaveLength(1);
158+
for (const f of transpiledFiles) {
159+
// Expect bundle to be affected by plugin
160+
expect(f.lua).toContain("-- Comment added by beforeEmit plugin");
116161
}
117162
});

0 commit comments

Comments
 (0)