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
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ export { LuaLibFeature } from "./LuaLib";
export * from "./LuaPrinter";
export * from "./transformation/context";
export * from "./transpilation";
export { ProcessedFile } from "./transpilation/utils";
export { EmitHost, EmitFile, ProcessedFile } from "./transpilation/utils";
23 changes: 19 additions & 4 deletions src/transpilation/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { EmitHost } from "..";
import { CompilerOptions } from "../CompilerOptions";
import { Printer } from "../LuaPrinter";
import { Visitors } from "../transformation/context";
import { getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils";
import { EmitFile, getConfigDirectory, ProcessedFile, resolvePlugin } from "./utils";

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

/**
* This function is called after TypeScriptToLua has translated the input program to Lua.
* This function is called after translating the input program to Lua, but before resolving dependencies or bundling.
*/
afterPrint?: (
program: ts.Program,
options: CompilerOptions,
emitHost: EmitHost,
result: ProcessedFile[]
) => ts.Diagnostic[] | void;

/**
* This function is called after translating the input program to Lua, after resolving dependencies and after bundling.
*/
beforeEmit?: (
program: ts.Program,
options: CompilerOptions,
emitHost: EmitHost,
result: EmitFile[]
) => ts.Diagnostic[] | void;
}

export function getPlugins(program: ts.Program, diagnostics: ts.Diagnostic[], customPlugins: Plugin[]): Plugin[] {
export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; plugins: Plugin[] } {
const diagnostics: ts.Diagnostic[] = [];
const pluginsFromOptions: Plugin[] = [];
const options = program.getCompilerOptions() as CompilerOptions;

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

return [...customPlugins, ...pluginsFromOptions];
if (options.tstlVerbose) {
console.log(`Loaded ${pluginsFromOptions.length} plugins`);
}

return { diagnostics, plugins: pluginsFromOptions };
}
10 changes: 2 additions & 8 deletions src/transpilation/transpile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CompilerOptions, validateOptions } from "../CompilerOptions";
import { createPrinter } from "../LuaPrinter";
import { createVisitorMap, transformSourceFile } from "../transformation";
import { isNonNull } from "../utils";
import { getPlugins, Plugin } from "./plugins";
import { Plugin } from "./plugins";
import { getTransformers } from "./transformers";
import { EmitHost, ProcessedFile } from "./utils";

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

Expand Down Expand Up @@ -60,12 +60,6 @@ export function getProgramTranspileResult(
}
}

const plugins = getPlugins(program, diagnostics, customPlugins);

if (options.tstlVerbose) {
console.log(`Successfully loaded ${plugins.length} plugins`);
}

for (const plugin of plugins) {
if (plugin.beforeTransform) {
const pluginDiagnostics = plugin.beforeTransform(program, options, emitHost) ?? [];
Expand Down
31 changes: 20 additions & 11 deletions src/transpilation/transpiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { CompilerOptions, isBundleEnabled } from "../CompilerOptions";
import { getLuaLibBundle } from "../LuaLib";
import { normalizeSlashes, trimExtension } from "../utils";
import { getBundleResult } from "./bundle";
import { getPlugins } from "./plugins";
import { resolveDependencies } from "./resolve";
import { getProgramTranspileResult, TranspileOptions } from "./transpile";
import { EmitFile, EmitHost, ProcessedFile } from "./utils";
Expand All @@ -29,23 +30,31 @@ export class Transpiler {

public emit(emitOptions: EmitOptions): EmitResult {
const { program, writeFile = this.emitHost.writeFile } = emitOptions;
const verbose = (program.getCompilerOptions() as CompilerOptions).tstlVerbose;
const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(
this.emitHost,
writeFile,
emitOptions
);
const options = program.getCompilerOptions() as CompilerOptions;

const { diagnostics: getPluginsDiagnostics, plugins } = getPlugins(program);

const { diagnostics, transpiledFiles: freshFiles } = getProgramTranspileResult(this.emitHost, writeFile, {
...emitOptions,
plugins,
});

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

if (verbose) {
if (options.tstlVerbose) {
console.log("Emitting output");
}

const options = program.getCompilerOptions();
for (const plugin of plugins) {
if (plugin.beforeEmit) {
const beforeEmitPluginDiagnostics = plugin.beforeEmit(program, options, this.emitHost, emitPlan) ?? [];
diagnostics.push(...beforeEmitPluginDiagnostics);
}
}

const emitBOM = options.emitBOM ?? false;
for (const { outputPath, code, sourceMap, sourceFiles } of emitPlan) {
if (verbose) {
if (options.tstlVerbose) {
console.log(`Emitting ${normalizeSlashes(outputPath)}`);
}

Expand All @@ -55,11 +64,11 @@ export class Transpiler {
}
}

if (verbose) {
if (options.tstlVerbose) {
console.log("Emit finished!");
}

return { diagnostics, emitSkipped: emitPlan.length === 0 };
return { diagnostics: getPluginsDiagnostics.concat(diagnostics), emitSkipped: emitPlan.length === 0 };
}

protected getEmitPlan(
Expand Down
1 change: 0 additions & 1 deletion src/transpilation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ interface BaseFile {
export interface ProcessedFile extends BaseFile {
fileName: string;
luaAst?: lua.File;
/** @internal */
sourceMapNode?: SourceNode;
}

Expand Down
2 changes: 1 addition & 1 deletion test/transpile/__snapshots__/project.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

exports[`should give verbose output 1`] = `
Array [
"Loaded 0 plugins",
"Parsing project settings",
"Successfully loaded 0 plugins",
"Transforming <cwd>/test/transpile/project/otherFile.ts",
"Printing <cwd>/test/transpile/project/otherFile.ts",
"Transforming <cwd>/test/transpile/project/index.ts",
Expand Down
2 changes: 1 addition & 1 deletion test/transpile/plugins/afterPrint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const plugin: tstl.Plugin = {
void emitHost;

for (const file of result) {
file.code = "-- Commented added by afterPrint plugin\n" + file.code;
file.code = "-- Comment added by afterPrint plugin\n" + file.code;
}
},
};
Expand Down
17 changes: 17 additions & 0 deletions test/transpile/plugins/beforeEmit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as ts from "typescript";
import * as tstl from "../../../src";

const plugin: tstl.Plugin = {
beforeEmit(program: ts.Program, options: tstl.CompilerOptions, emitHost: tstl.EmitHost, result: tstl.EmitFile[]) {
void program;
void options;
void emitHost;

for (const file of result) {
file.code = "-- Comment added by beforeEmit plugin\n" + file.code;
}
},
};

// eslint-disable-next-line import/no-default-export
export default plugin;
47 changes: 46 additions & 1 deletion test/transpile/plugins/plugins.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,51 @@ test("afterPrint plugin", () => {
expect(transpiledFiles).toHaveLength(2);
for (const f of transpiledFiles) {
// Expect plugin inserted extra lua at start of file
expect(f.lua).toContain("-- Commented added by afterPrint plugin");
expect(f.lua).toContain("-- Comment added by afterPrint plugin");
}
});

test("beforeEmit plugin", () => {
const { transpiledFiles } = util.testModule`
console.log("Hello, World!");
[].push(1,2,3); // Use lualib code
`
.addExtraFile(
"extrafile.ts",
`
console.log("Hello, Mars!");
`
)
.setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] })
.getLuaResult();

// 2 input files + 1 lualib_bundle
expect(transpiledFiles).toHaveLength(3);
expect(transpiledFiles.find(f => f.outPath.endsWith("lualib_bundle.lua"))).toBeDefined();
for (const f of transpiledFiles) {
// Expect plugin inserted extra lua at start of all files including lualib bundle
expect(f.lua).toContain("-- Comment added by beforeEmit plugin");
}
});

test("beforeEmit plugin bundle", () => {
const { transpiledFiles } = util.testBundle`
console.log("Hello, World!");
[].push(1,2,3); // Use lualib code
`
.addExtraFile(
"extrafile.ts",
`
console.log("Hello, Mars!");
`
)
.setOptions({ luaPlugins: [{ name: path.join(__dirname, "beforeEmit.ts") }] })
.getLuaResult();

// 1 lua bundle output
expect(transpiledFiles).toHaveLength(1);
for (const f of transpiledFiles) {
// Expect bundle to be affected by plugin
expect(f.lua).toContain("-- Comment added by beforeEmit plugin");
}
});