UNPKG

typescript-to-lua

Version:

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

168 lines 7.83 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.sourceMapTracebackBundlePlaceholder = void 0; exports.printStackTraceBundleOverride = printStackTraceBundleOverride; exports.getBundleResult = getBundleResult; const path = __importStar(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)" : "..."; // Avoid producing a tail-call (which removes the bundle's stack frame) by assigning the `require` result to a local and returning it. const entryPath = createModulePath(entryModuleFilePath !== null && entryModuleFilePath !== void 0 ? entryModuleFilePath : entryModule, program); const entryPoint = `local ____entry = require(${entryPath}, ${args})\nreturn ____entry\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