diff --git a/src/CompilerOptions.ts b/src/CompilerOptions.ts index 35004d25d..7f5562c07 100644 --- a/src/CompilerOptions.ts +++ b/src/CompilerOptions.ts @@ -1,6 +1,7 @@ import * as ts from "typescript"; import { JsxEmit } from "typescript"; import * as diagnosticFactories from "./transpilation/diagnostics"; +import { Plugin } from "./transpilation/plugins"; type OmitIndexSignature = { [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]; @@ -23,6 +24,11 @@ export interface LuaPluginImport { [option: string]: any; } +export interface InMemoryLuaPlugin { + plugin: Plugin | ((options: Record) => Plugin); + [option: string]: any; +} + export interface TypeScriptToLuaOptions { buildMode?: BuildMode; extension?: string; @@ -30,7 +36,7 @@ export interface TypeScriptToLuaOptions { luaBundleEntry?: string; luaTarget?: LuaTarget; luaLibImport?: LuaLibImportKind; - luaPlugins?: LuaPluginImport[]; + luaPlugins?: Array; noImplicitGlobalVariables?: boolean; noImplicitSelf?: boolean; noHeader?: boolean; diff --git a/src/transpilation/plugins.ts b/src/transpilation/plugins.ts index 74e4e542e..f84af2bc9 100644 --- a/src/transpilation/plugins.ts +++ b/src/transpilation/plugins.ts @@ -77,15 +77,23 @@ export function getPlugins(program: ts.Program): { diagnostics: ts.Diagnostic[]; for (const [index, pluginOption] of (options.luaPlugins ?? []).entries()) { const optionName = `tstl.luaPlugins[${index}]`; - const { error: resolveError, result: factory } = resolvePlugin( - "plugin", - `${optionName}.name`, - getConfigDirectory(options), - pluginOption.name, - pluginOption.import - ); - - if (resolveError) diagnostics.push(resolveError); + const factory = (() => { + if ("plugin" in pluginOption) { + return pluginOption.plugin; + } else { + const { error: resolveError, result: factory } = resolvePlugin( + "plugin", + `${optionName}.name`, + getConfigDirectory(options), + pluginOption.name, + pluginOption.import + ); + + if (resolveError) diagnostics.push(resolveError); + return factory; + } + })(); + if (factory === undefined) continue; const plugin = typeof factory === "function" ? factory(pluginOption) : factory; diff --git a/test/transpile/plugins/plugins.spec.ts b/test/transpile/plugins/plugins.spec.ts index 72c9e29a7..ed25ae748 100644 --- a/test/transpile/plugins/plugins.spec.ts +++ b/test/transpile/plugins/plugins.spec.ts @@ -1,5 +1,6 @@ import * as path from "path"; import * as util from "../../util"; +import { Plugin } from "../../../src/transpilation/plugins"; import * as ts from "typescript"; test("printer", () => { @@ -182,3 +183,61 @@ test("afterEmit plugin", () => { expect(diagnostic?.category).toBe(ts.DiagnosticCategory.Message); expect(diagnostic?.messageText).toContain("After emit"); }); + +test("in memory plugin", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + plugin: { + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: 1234, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin, + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +}); + +test("in memory plugin with factory", () => { + const { diagnostics } = util.testModule`` + .setOptions({ + luaPlugins: [ + { + code: 1234, + plugin: options => + ({ + afterEmit(program: ts.Program) { + return [ + { + category: ts.DiagnosticCategory.Message, + messageText: "In memory plugin diagnostic message!", + code: options.code, + file: program.getSourceFiles()[0], + start: undefined, + length: undefined, + } satisfies ts.Diagnostic, + ]; + }, + } satisfies Plugin), + }, + ], + }) + .getLuaResult(); + + expect(diagnostics).toHaveLength(1); + expect(diagnostics[0].code).toBe(1234); +});