UNPKG

typescript-to-lua

Version:

A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!

133 lines 6.25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.sourceMapTracebackBundlePlaceholder = void 0; exports.printStackTraceBundleOverride = printStackTraceBundleOverride; exports.getBundleResult = getBundleResult; const path = require("path"); const source_map_1 = require("source-map"); const CompilerOptions_1 = require("../CompilerOptions"); const LuaPrinter_1 = require("../LuaPrinter"); const utils_1 = require("../utils"); const diagnostics_1 = require("./diagnostics"); const transpiler_1 = require("./transpiler"); const createModulePath = (pathToResolve, program) => (0, LuaPrinter_1.escapeString)((0, utils_1.formatPathToLuaPath)((0, utils_1.trimExtension)((0, transpiler_1.getEmitPathRelativeToOutDir)(pathToResolve, program)))); // Override `require` to read from ____modules table. function requireOverride(options) { const runModule = options.luaTarget === CompilerOptions_1.LuaTarget.Lua50 ? "if (table.getn(arg) > 0) then value = module(unpack(arg)) else value = module(file) end" : 'if (select("#", ...) > 0) then value = module(...) else value = module(file) end'; return ` local ____modules = {} local ____moduleCache = {} local ____originalRequire = require local function require(file, ...) if ____moduleCache[file] then return ____moduleCache[file].value end if ____modules[file] then local module = ____modules[file] local value = nil ${runModule} ____moduleCache[file] = { value = value } return value else if ____originalRequire then return ____originalRequire(file) else error("module '" .. file .. "' not found") end end end `; } exports.sourceMapTracebackBundlePlaceholder = "{#SourceMapTracebackBundle}"; function printStackTraceBundleOverride(rootNode) { const map = {}; const getLineNumber = (line, fallback) => { const data = map[line]; if (data === undefined) { return fallback; } if (typeof data === "number") { return data; } return data.line; }; const transformLineData = (data) => { if (typeof data === "number") { return data; } return `{line = ${data.line}, file = "${data.file}"}`; }; let currentLine = 1; rootNode.walk((chunk, mappedPosition) => { if (mappedPosition.line !== undefined && mappedPosition.line > 0) { const line = getLineNumber(currentLine, mappedPosition.line); map[currentLine] = { line, file: path.basename(mappedPosition.source), }; } currentLine += chunk.split("\n").length - 1; }); const mapItems = Object.entries(map).map(([line, original]) => `["${line}"] = ${transformLineData(original)}`); const mapString = "{" + mapItems.join(",") + "}"; return `__TS__SourceMapTraceBack(debug.getinfo(1).short_src, ${mapString});`; } function getBundleResult(program, files) { var _a, _b, _c; const diagnostics = []; const options = program.getCompilerOptions(); const bundleFile = (0, utils_1.cast)(options.luaBundle, utils_1.isNonNull); const entryModule = (0, utils_1.cast)(options.luaBundleEntry, utils_1.isNonNull); // Resolve project settings relative to project file. const resolvedEntryModule = path.resolve((0, transpiler_1.getProjectRoot)(program), entryModule); const outputPath = path.resolve((0, transpiler_1.getEmitOutDir)(program), bundleFile); const entryModuleFilePath = (_b = (_a = program.getSourceFile(entryModule)) === null || _a === void 0 ? void 0 : _a.fileName) !== null && _b !== void 0 ? _b : (_c = program.getSourceFile(resolvedEntryModule)) === null || _c === void 0 ? void 0 : _c.fileName; if (entryModuleFilePath === undefined) { diagnostics.push((0, diagnostics_1.couldNotFindBundleEntryPoint)(entryModule)); } // For each file: ["<module path>"] = function() <lua content> end, const moduleTableEntries = files.map(f => moduleSourceNode(f, createModulePath(f.fileName, program))); // Create ____modules table containing all entries from moduleTableEntries const moduleTable = createModuleTableNode(moduleTableEntries); // return require("<entry module path>") const args = options.luaTarget === CompilerOptions_1.LuaTarget.Lua50 ? "unpack(arg == nil and {} or arg)" : "..."; const entryPoint = `return require(${createModulePath(entryModuleFilePath !== null && entryModuleFilePath !== void 0 ? entryModuleFilePath : entryModule, program)}, ${args})\n`; const footers = []; if (options.sourceMapTraceback) { // Generates SourceMapTraceback for the entire file footers.push('local __TS__SourceMapTraceBack = require("lualib_bundle").__TS__SourceMapTraceBack\n'); footers.push(`${exports.sourceMapTracebackBundlePlaceholder}\n`); } const sourceChunks = [requireOverride(options), moduleTable, ...footers, entryPoint]; if (!options.noHeader) { sourceChunks.unshift(LuaPrinter_1.tstlHeader); } const bundleNode = joinSourceChunks(sourceChunks); let { code, map } = bundleNode.toStringWithSourceMap(); code = code.replace(exports.sourceMapTracebackBundlePlaceholder, printStackTraceBundleOverride(bundleNode)); return [ diagnostics, { outputPath, code, sourceMap: map.toString(), sourceFiles: files.flatMap(x => { var _a; return (_a = x.sourceFiles) !== null && _a !== void 0 ? _a : []; }), }, ]; } function moduleSourceNode({ code, sourceMapNode }, modulePath) { const tableEntryHead = `[${modulePath}] = function(...) \n`; const tableEntryTail = " end,\n"; return joinSourceChunks([tableEntryHead, sourceMapNode !== null && sourceMapNode !== void 0 ? sourceMapNode : code, tableEntryTail]); } function createModuleTableNode(fileChunks) { const tableHead = "____modules = {\n"; const tableEnd = "}\n"; return joinSourceChunks([tableHead, ...fileChunks, tableEnd]); } function joinSourceChunks(chunks) { return new source_map_1.SourceNode(null, null, null, chunks); } //# sourceMappingURL=bundle.js.map