Skip to content

Commit 2f7ee83

Browse files
committed
Make printer plugin stateless
1 parent 00c38b6 commit 2f7ee83

File tree

5 files changed

+40
-31
lines changed

5 files changed

+40
-31
lines changed

src/Emit.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
import * as path from "path";
22
import * as ts from "typescript";
33
import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions";
4-
import { TranspiledFile, EmitHost } from "./Transpile";
5-
6-
const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length);
7-
const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/");
4+
import { EmitHost, TranspiledFile } from "./Transpile";
5+
import { normalizeSlashes, trimExtension } from "./utils";
86

97
export interface OutputFile {
108
name: string;
@@ -37,7 +35,7 @@ export function emitTranspiledFiles(
3735
if (outFile) {
3836
outPath = path.isAbsolute(outFile) ? outFile : path.resolve(baseDir, outFile);
3937
} else {
40-
outPath = trimExt(outPath) + ".lua";
38+
outPath = trimExtension(outPath) + ".lua";
4139
}
4240

4341
outPath = normalizeSlashes(outPath);
@@ -51,11 +49,11 @@ export function emitTranspiledFiles(
5149
}
5250

5351
if (declaration !== undefined) {
54-
files.push({ name: trimExt(outPath) + ".d.ts", text: declaration });
52+
files.push({ name: trimExtension(outPath) + ".d.ts", text: declaration });
5553
}
5654

5755
if (declarationMap !== undefined) {
58-
files.push({ name: trimExt(outPath) + ".d.ts.map", text: declarationMap });
56+
files.push({ name: trimExtension(outPath) + ".d.ts.map", text: declarationMap });
5957
}
6058
}
6159

src/LuaPrinter.ts

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as lua from "./LuaAST";
66
import { loadLuaLibFeatures, LuaLibFeature } from "./LuaLib";
77
import { isValidLuaIdentifier, luaKeywords } from "./transformation/utils/safe-names";
88
import { EmitHost } from "./Transpile";
9+
import { trimExtension } from "./utils";
910

1011
// https://www.lua.org/pil/2.4.html
1112
// https://www.ecma-international.org/ecma-262/10.0/index.html#table-34
@@ -76,27 +77,32 @@ function isSimpleExpression(expression: lua.Expression): boolean {
7677

7778
type SourceChunk = string | SourceNode;
7879

80+
export type Printer = (
81+
program: ts.Program,
82+
emitHost: EmitHost,
83+
fileName: string,
84+
block: lua.Block,
85+
luaLibFeatures: Set<LuaLibFeature>
86+
) => PrintResult;
87+
7988
export interface PrintResult {
8089
code: string;
8190
sourceMap: string;
8291
}
8392

84-
export type PrinterFactory = (program: ts.Program, emitHost: EmitHost) => Printer;
85-
export type Printer = LuaPrinter["print"];
86-
87-
export function createPrinter(program: ts.Program, emitHost: EmitHost, factories: PrinterFactory[]): Printer {
88-
if (factories.length === 0) {
89-
const printer = new LuaPrinter(program.getCompilerOptions(), emitHost);
90-
return (...args) => printer.print(...args);
91-
} else if (factories.length === 1) {
92-
return factories[0](program, emitHost);
93+
export function createPrinter(printers: Printer[]): Printer {
94+
if (printers.length === 0) {
95+
return (program, emitHost, fileName, ...args) =>
96+
new LuaPrinter(program.getCompilerOptions(), emitHost, fileName).print(...args);
97+
} else if (printers.length === 1) {
98+
return printers[0];
9399
} else {
94100
throw new Error("Only one plugin can specify 'createPrinter'");
95101
}
96102
}
97103

98104
export class LuaPrinter {
99-
private static operatorMap: { [key in lua.Operator]: string } = {
105+
private static operatorMap: Record<lua.Operator, string> = {
100106
[lua.SyntaxKind.AdditionOperator]: "+",
101107
[lua.SyntaxKind.SubtractionOperator]: "-",
102108
[lua.SyntaxKind.MultiplicationOperator]: "*",
@@ -125,11 +131,13 @@ export class LuaPrinter {
125131
};
126132

127133
private currentIndent = "";
128-
private sourceFile!: string;
134+
private sourceFile: string;
129135

130-
public constructor(private options: CompilerOptions, private emitHost: EmitHost) {}
136+
public constructor(private options: CompilerOptions, private emitHost: EmitHost, fileName: string) {
137+
this.sourceFile = path.basename(fileName);
138+
}
131139

132-
public print(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>, fileName: string): PrintResult {
140+
public print(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>): PrintResult {
133141
// Add traceback lualib if sourcemap traceback option is enabled
134142
if (this.options.sourceMapTraceback) {
135143
luaLibFeatures.add(LuaLibFeature.SourceMapTraceBack);
@@ -139,8 +147,8 @@ export class LuaPrinter {
139147
this.options.sourceRoot ||
140148
(this.options.outDir ? path.relative(this.options.outDir, this.options.rootDir || process.cwd()) : ".");
141149

142-
const rootSourceNode = this.printImplementation(block, luaLibFeatures, fileName);
143-
const sourceMap = this.buildSourceMap(fileName, sourceRoot, rootSourceNode);
150+
const rootSourceNode = this.printImplementation(block, luaLibFeatures);
151+
const sourceMap = this.buildSourceMap(sourceRoot, rootSourceNode);
144152

145153
let code = rootSourceNode.toString();
146154

@@ -187,7 +195,7 @@ export class LuaPrinter {
187195
return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`;
188196
}
189197

190-
private printImplementation(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>, sourceFile: string): SourceNode {
198+
private printImplementation(block: lua.Block, luaLibFeatures: Set<LuaLibFeature>): SourceNode {
191199
let header = "";
192200

193201
if (!this.options.noHeader) {
@@ -208,8 +216,6 @@ export class LuaPrinter {
208216
header += loadLuaLibFeatures(luaLibFeatures, this.emitHost);
209217
}
210218

211-
this.sourceFile = path.basename(sourceFile);
212-
213219
if (this.options.sourceMapTraceback) {
214220
header += "{#SourceMapTraceback}\n";
215221
}
@@ -796,9 +802,9 @@ export class LuaPrinter {
796802

797803
// The key difference between this and SourceNode.toStringWithSourceMap() is that SourceNodes with null line/column
798804
// will not generate 'empty' mappings in the source map that point to nothing in the original TS.
799-
private buildSourceMap(sourceFile: string, sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator {
805+
private buildSourceMap(sourceRoot: string, rootSourceNode: SourceNode): SourceMapGenerator {
800806
const map = new SourceMapGenerator({
801-
file: path.basename(sourceFile, path.extname(sourceFile)) + ".lua",
807+
file: trimExtension(this.sourceFile) + ".lua",
802808
sourceRoot,
803809
});
804810

src/Transpile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ export function transpile({
7777
}
7878

7979
const visitorMap = createVisitorMap(plugins.map(p => p.visitors).filter(isNonNull));
80-
const print = createPrinter(program, emitHost, plugins.map(p => p.createPrinter).filter(isNonNull));
80+
const printer = createPrinter(plugins.map(p => p.printer).filter(isNonNull));
8181
const processSourceFile = (sourceFile: ts.SourceFile) => {
8282
const { luaAst, luaLibFeatures, diagnostics: transformDiagnostics } = transformSourceFile(
8383
program,
@@ -86,7 +86,7 @@ export function transpile({
8686
);
8787
diagnostics.push(...transformDiagnostics);
8888
if (!options.noEmit && !options.emitDeclarationOnly) {
89-
const { code, sourceMap } = print(luaAst, luaLibFeatures, sourceFile.fileName);
89+
const { code, sourceMap } = printer(program, emitHost, sourceFile.fileName, luaAst, luaLibFeatures);
9090
updateTranspiledFile(sourceFile.fileName, { luaAst, lua: code, sourceMap });
9191
}
9292
};

src/plugins.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { PrinterFactory } from "./LuaPrinter";
1+
import { Printer } from "./LuaPrinter";
22
import { Visitors } from "./transformation/context";
33

44
export interface Plugin {
5-
createPrinter?: PrinterFactory;
5+
printer?: Printer;
66
visitors?: Visitors;
77
}

src/utils.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
import * as path from "path";
2+
3+
export const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/");
4+
export const trimExtension = (filePath: string) => filePath.slice(0, -path.extname(filePath).length);
5+
16
export function flatMap<T, U>(array: readonly T[], callback: (value: T, index: number) => U | readonly U[]): U[] {
27
const result: U[] = [];
38

0 commit comments

Comments
 (0)