diff --git a/build_lualib.ts b/build_lualib.ts index a620df2ac..330a3ef04 100644 --- a/build_lualib.ts +++ b/build_lualib.ts @@ -16,4 +16,8 @@ if (fs.existsSync(bundlePath)) { fs.unlinkSync(bundlePath); } -fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature))); +const emitHost = { + readFile: (path: string) => fs.readFileSync(path, "utf-8"), + writeFile: fs.writeFileSync, +}; +fs.writeFileSync(bundlePath, LuaLib.loadFeatures(Object.values(tstl.LuaLibFeature), emitHost)); diff --git a/src/Emit.ts b/src/Emit.ts index e2004b0f9..50d5c1fdf 100644 --- a/src/Emit.ts +++ b/src/Emit.ts @@ -1,7 +1,7 @@ -import * as fs from "fs"; import * as path from "path"; +import * as ts from "typescript"; import { CompilerOptions, LuaLibImportKind } from "./CompilerOptions"; -import { TranspiledFile } from "./Transpile"; +import { TranspiledFile, EmitHost } from "./Transpile"; const trimExt = (filePath: string) => filePath.slice(0, -path.extname(filePath).length); const normalizeSlashes = (filePath: string) => filePath.replace(/\\/g, "/"); @@ -12,7 +12,11 @@ export interface OutputFile { } let lualibContent: string; -export function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: TranspiledFile[]): OutputFile[] { +export function emitTranspiledFiles( + options: CompilerOptions, + transpiledFiles: TranspiledFile[], + emitHost: EmitHost = ts.sys +): OutputFile[] { let { rootDir, outDir, outFile, luaLibImport } = options; const configFileName = options.configFilePath as string | undefined; @@ -57,7 +61,12 @@ export function emitTranspiledFiles(options: CompilerOptions, transpiledFiles: T if (luaLibImport === LuaLibImportKind.Require || luaLibImport === LuaLibImportKind.Always) { if (lualibContent === undefined) { - lualibContent = fs.readFileSync(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua"), "utf8"); + const lualibBundle = emitHost.readFile(path.resolve(__dirname, "../dist/lualib/lualib_bundle.lua")); + if (lualibBundle !== undefined) { + lualibContent = lualibBundle; + } else { + throw new Error("Could not load lualib bundle from ./dist/lualib/lualib_bundle.lua"); + } } let outPath = path.resolve(rootDir, "lualib_bundle.lua"); diff --git a/src/LuaLib.ts b/src/LuaLib.ts index 23a9711ad..d611a28bb 100644 --- a/src/LuaLib.ts +++ b/src/LuaLib.ts @@ -1,5 +1,5 @@ -import * as fs from "fs"; import * as path from "path"; +import { EmitHost } from "./Transpile"; export enum LuaLibFeature { ArrayConcat = "ArrayConcat", @@ -73,7 +73,7 @@ const luaLibDependencies: { [lib in LuaLibFeature]?: LuaLibFeature[] } = { }; export class LuaLib { - public static loadFeatures(features: Iterable): string { + public static loadFeatures(features: Iterable, emitHost: EmitHost): string { let result = ""; const loadedFeatures = new Set(); @@ -86,7 +86,12 @@ export class LuaLib { dependencies.forEach(load); } const featureFile = path.resolve(__dirname, `../dist/lualib/${feature}.lua`); - result += fs.readFileSync(featureFile).toString() + "\n"; + const luaLibFeature = emitHost.readFile(featureFile); + if (luaLibFeature !== undefined) { + result += luaLibFeature.toString() + "\n"; + } else { + throw new Error(`Could not read lualib feature ../dist/lualib/${feature}.lua`); + } } } diff --git a/src/LuaPrinter.ts b/src/LuaPrinter.ts index ebac13788..e5058cbf5 100644 --- a/src/LuaPrinter.ts +++ b/src/LuaPrinter.ts @@ -5,6 +5,7 @@ import * as tstl from "./LuaAST"; import { luaKeywords } from "./LuaKeywords"; import { LuaLib, LuaLibFeature } from "./LuaLib"; import * as tsHelper from "./TSHelper"; +import { EmitHost } from "./Transpile"; type SourceChunk = string | SourceNode; @@ -38,12 +39,15 @@ export class LuaPrinter { }; private options: CompilerOptions; + private emitHost: EmitHost; + private currentIndent: string; private sourceFile = ""; - public constructor(options: CompilerOptions) { + public constructor(options: CompilerOptions, emitHost: EmitHost) { this.options = options; + this.emitHost = emitHost; this.currentIndent = ""; } @@ -128,7 +132,7 @@ export class LuaPrinter { // Inline lualib features else if (luaLibImport === LuaLibImportKind.Inline && luaLibFeatures.size > 0) { header += "-- Lua Library inline imports\n"; - header += LuaLib.loadFeatures(luaLibFeatures); + header += LuaLib.loadFeatures(luaLibFeatures, this.emitHost); } } diff --git a/src/Transpile.ts b/src/Transpile.ts index f02810b78..b0d0d4c0a 100644 --- a/src/Transpile.ts +++ b/src/Transpile.ts @@ -27,14 +27,20 @@ export interface TranspileOptions { customTransformers?: ts.CustomTransformers; transformer?: LuaTransformer; printer?: LuaPrinter; + emitHost?: EmitHost; +} + +export interface EmitHost { + readFile(path: string): string | undefined; } export function transpile({ program, sourceFiles: targetSourceFiles, customTransformers = {}, + emitHost = ts.sys, transformer = new LuaTransformer(program), - printer = new LuaPrinter(program.getCompilerOptions()), + printer = new LuaPrinter(program.getCompilerOptions(), emitHost), }: TranspileOptions): TranspileResult { const options = program.getCompilerOptions() as CompilerOptions;