UNPKG

typescript-to-lua

Version:

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

270 lines 12.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.luaLibModulesInfoFileName = exports.LuaLibFeature = void 0; exports.resolveLuaLibDir = resolveLuaLibDir; exports.getLuaLibModulesInfo = getLuaLibModulesInfo; exports.getLuaLibExportToFeatureMap = getLuaLibExportToFeatureMap; exports.readLuaLibFeature = readLuaLibFeature; exports.resolveRecursiveLualibFeatures = resolveRecursiveLualibFeatures; exports.loadInlineLualibFeatures = loadInlineLualibFeatures; exports.loadImportedLualibFeatures = loadImportedLualibFeatures; exports.getLuaLibBundle = getLuaLibBundle; exports.getLualibBundleReturn = getLualibBundleReturn; exports.buildMinimalLualibBundle = buildMinimalLualibBundle; exports.findUsedLualibFeatures = findUsedLualibFeatures; const path = require("path"); const lua = require("./LuaAST"); const CompilerOptions_1 = require("./CompilerOptions"); const utils_1 = require("./utils"); var LuaLibFeature; (function (LuaLibFeature) { LuaLibFeature["ArrayAt"] = "ArrayAt"; LuaLibFeature["ArrayConcat"] = "ArrayConcat"; LuaLibFeature["ArrayEntries"] = "ArrayEntries"; LuaLibFeature["ArrayEvery"] = "ArrayEvery"; LuaLibFeature["ArrayFill"] = "ArrayFill"; LuaLibFeature["ArrayFilter"] = "ArrayFilter"; LuaLibFeature["ArrayForEach"] = "ArrayForEach"; LuaLibFeature["ArrayFind"] = "ArrayFind"; LuaLibFeature["ArrayFindIndex"] = "ArrayFindIndex"; LuaLibFeature["ArrayFrom"] = "ArrayFrom"; LuaLibFeature["ArrayIncludes"] = "ArrayIncludes"; LuaLibFeature["ArrayIndexOf"] = "ArrayIndexOf"; LuaLibFeature["ArrayIsArray"] = "ArrayIsArray"; LuaLibFeature["ArrayJoin"] = "ArrayJoin"; LuaLibFeature["ArrayMap"] = "ArrayMap"; LuaLibFeature["ArrayPush"] = "ArrayPush"; LuaLibFeature["ArrayPushArray"] = "ArrayPushArray"; LuaLibFeature["ArrayReduce"] = "ArrayReduce"; LuaLibFeature["ArrayReduceRight"] = "ArrayReduceRight"; LuaLibFeature["ArrayReverse"] = "ArrayReverse"; LuaLibFeature["ArrayUnshift"] = "ArrayUnshift"; LuaLibFeature["ArraySort"] = "ArraySort"; LuaLibFeature["ArraySlice"] = "ArraySlice"; LuaLibFeature["ArraySome"] = "ArraySome"; LuaLibFeature["ArraySplice"] = "ArraySplice"; LuaLibFeature["ArrayToObject"] = "ArrayToObject"; LuaLibFeature["ArrayFlat"] = "ArrayFlat"; LuaLibFeature["ArrayFlatMap"] = "ArrayFlatMap"; LuaLibFeature["ArraySetLength"] = "ArraySetLength"; LuaLibFeature["ArrayToReversed"] = "ArrayToReversed"; LuaLibFeature["ArrayToSorted"] = "ArrayToSorted"; LuaLibFeature["ArrayToSpliced"] = "ArrayToSpliced"; LuaLibFeature["ArrayWith"] = "ArrayWith"; LuaLibFeature["Await"] = "Await"; LuaLibFeature["Class"] = "Class"; LuaLibFeature["ClassExtends"] = "ClassExtends"; LuaLibFeature["CloneDescriptor"] = "CloneDescriptor"; LuaLibFeature["CountVarargs"] = "CountVarargs"; LuaLibFeature["Decorate"] = "Decorate"; LuaLibFeature["DecorateLegacy"] = "DecorateLegacy"; LuaLibFeature["DecorateParam"] = "DecorateParam"; LuaLibFeature["Delete"] = "Delete"; LuaLibFeature["DelegatedYield"] = "DelegatedYield"; LuaLibFeature["DescriptorGet"] = "DescriptorGet"; LuaLibFeature["DescriptorSet"] = "DescriptorSet"; LuaLibFeature["Error"] = "Error"; LuaLibFeature["FunctionBind"] = "FunctionBind"; LuaLibFeature["Generator"] = "Generator"; LuaLibFeature["InstanceOf"] = "InstanceOf"; LuaLibFeature["InstanceOfObject"] = "InstanceOfObject"; LuaLibFeature["Iterator"] = "Iterator"; LuaLibFeature["LuaIteratorSpread"] = "LuaIteratorSpread"; LuaLibFeature["Map"] = "Map"; LuaLibFeature["MapGroupBy"] = "MapGroupBy"; LuaLibFeature["Match"] = "Match"; LuaLibFeature["MathAtan2"] = "MathAtan2"; LuaLibFeature["MathModf"] = "MathModf"; LuaLibFeature["MathSign"] = "MathSign"; LuaLibFeature["MathTrunc"] = "MathTrunc"; LuaLibFeature["New"] = "New"; LuaLibFeature["Number"] = "Number"; LuaLibFeature["NumberIsFinite"] = "NumberIsFinite"; LuaLibFeature["NumberIsInteger"] = "NumberIsInteger"; LuaLibFeature["NumberIsNaN"] = "NumberIsNaN"; LuaLibFeature["NumberParseInt"] = "ParseInt"; LuaLibFeature["NumberParseFloat"] = "ParseFloat"; LuaLibFeature["NumberToString"] = "NumberToString"; LuaLibFeature["NumberToFixed"] = "NumberToFixed"; LuaLibFeature["ObjectAssign"] = "ObjectAssign"; LuaLibFeature["ObjectDefineProperty"] = "ObjectDefineProperty"; LuaLibFeature["ObjectEntries"] = "ObjectEntries"; LuaLibFeature["ObjectFromEntries"] = "ObjectFromEntries"; LuaLibFeature["ObjectGetOwnPropertyDescriptor"] = "ObjectGetOwnPropertyDescriptor"; LuaLibFeature["ObjectGetOwnPropertyDescriptors"] = "ObjectGetOwnPropertyDescriptors"; LuaLibFeature["ObjectGroupBy"] = "ObjectGroupBy"; LuaLibFeature["ObjectKeys"] = "ObjectKeys"; LuaLibFeature["ObjectRest"] = "ObjectRest"; LuaLibFeature["ObjectValues"] = "ObjectValues"; LuaLibFeature["ParseFloat"] = "ParseFloat"; LuaLibFeature["ParseInt"] = "ParseInt"; LuaLibFeature["Promise"] = "Promise"; LuaLibFeature["PromiseAll"] = "PromiseAll"; LuaLibFeature["PromiseAllSettled"] = "PromiseAllSettled"; LuaLibFeature["PromiseAny"] = "PromiseAny"; LuaLibFeature["PromiseRace"] = "PromiseRace"; LuaLibFeature["Set"] = "Set"; LuaLibFeature["SetDescriptor"] = "SetDescriptor"; LuaLibFeature["SparseArrayNew"] = "SparseArrayNew"; LuaLibFeature["SparseArrayPush"] = "SparseArrayPush"; LuaLibFeature["SparseArraySpread"] = "SparseArraySpread"; LuaLibFeature["WeakMap"] = "WeakMap"; LuaLibFeature["WeakSet"] = "WeakSet"; LuaLibFeature["SourceMapTraceBack"] = "SourceMapTraceBack"; LuaLibFeature["Spread"] = "Spread"; LuaLibFeature["StringAccess"] = "StringAccess"; LuaLibFeature["StringCharAt"] = "StringCharAt"; LuaLibFeature["StringCharCodeAt"] = "StringCharCodeAt"; LuaLibFeature["StringEndsWith"] = "StringEndsWith"; LuaLibFeature["StringIncludes"] = "StringIncludes"; LuaLibFeature["StringPadEnd"] = "StringPadEnd"; LuaLibFeature["StringPadStart"] = "StringPadStart"; LuaLibFeature["StringReplace"] = "StringReplace"; LuaLibFeature["StringReplaceAll"] = "StringReplaceAll"; LuaLibFeature["StringSlice"] = "StringSlice"; LuaLibFeature["StringSplit"] = "StringSplit"; LuaLibFeature["StringStartsWith"] = "StringStartsWith"; LuaLibFeature["StringSubstr"] = "StringSubstr"; LuaLibFeature["StringSubstring"] = "StringSubstring"; LuaLibFeature["StringTrim"] = "StringTrim"; LuaLibFeature["StringTrimEnd"] = "StringTrimEnd"; LuaLibFeature["StringTrimStart"] = "StringTrimStart"; LuaLibFeature["Symbol"] = "Symbol"; LuaLibFeature["SymbolRegistry"] = "SymbolRegistry"; LuaLibFeature["TypeOf"] = "TypeOf"; LuaLibFeature["Unpack"] = "Unpack"; LuaLibFeature["Using"] = "Using"; LuaLibFeature["UsingAsync"] = "UsingAsync"; })(LuaLibFeature || (exports.LuaLibFeature = LuaLibFeature = {})); function resolveLuaLibDir(luaTarget) { const luaLibDir = luaTarget === CompilerOptions_1.LuaTarget.Lua50 ? "5.0" : "universal"; return path.resolve(__dirname, path.join("..", "dist", "lualib", luaLibDir)); } exports.luaLibModulesInfoFileName = "lualib_module_info.json"; const luaLibModulesInfo = new Map(); function getLuaLibModulesInfo(luaTarget, emitHost) { if (!luaLibModulesInfo.has(luaTarget)) { const lualibPath = path.join(resolveLuaLibDir(luaTarget), exports.luaLibModulesInfoFileName); const result = emitHost.readFile(lualibPath); if (result !== undefined) { luaLibModulesInfo.set(luaTarget, JSON.parse(result)); } else { throw new Error(`Could not load lualib dependencies from '${lualibPath}'`); } } return luaLibModulesInfo.get(luaTarget); } // This caches the names of lualib exports to their LuaLibFeature, avoiding a linear search for every lookup const lualibExportToFeature = new Map(); function getLuaLibExportToFeatureMap(luaTarget, emitHost) { if (!lualibExportToFeature.has(luaTarget)) { const luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost); const map = new Map(); for (const [feature, info] of Object.entries(luaLibModulesInfo)) { for (const exportName of info.exports) { map.set(exportName, feature); } } lualibExportToFeature.set(luaTarget, map); } return lualibExportToFeature.get(luaTarget); } const lualibFeatureCache = new Map(); function readLuaLibFeature(feature, luaTarget, emitHost) { const featureMap = (0, utils_1.getOrUpdate)(lualibFeatureCache, luaTarget, () => new Map()); if (!featureMap.has(feature)) { const featurePath = path.join(resolveLuaLibDir(luaTarget), `${feature}.lua`); const luaLibFeature = emitHost.readFile(featurePath); if (luaLibFeature === undefined) { throw new Error(`Could not load lualib feature from '${featurePath}'`); } featureMap.set(feature, luaLibFeature); } return featureMap.get(feature); } function resolveRecursiveLualibFeatures(features, luaTarget, emitHost, luaLibModulesInfo = getLuaLibModulesInfo(luaTarget, emitHost)) { const loadedFeatures = new Set(); const result = []; function load(feature) { var _a; if (loadedFeatures.has(feature)) return; loadedFeatures.add(feature); const dependencies = (_a = luaLibModulesInfo[feature]) === null || _a === void 0 ? void 0 : _a.dependencies; if (dependencies) { dependencies.forEach(load); } result.push(feature); } for (const feature of features) { load(feature); } return result; } function loadInlineLualibFeatures(features, luaTarget, emitHost) { return resolveRecursiveLualibFeatures(features, luaTarget, emitHost) .map(feature => readLuaLibFeature(feature, luaTarget, emitHost)) .join("\n"); } function loadImportedLualibFeatures(features, luaTarget, emitHost) { const luaLibModuleInfo = getLuaLibModulesInfo(luaTarget, emitHost); const imports = Array.from(features).flatMap(feature => luaLibModuleInfo[feature].exports); if (imports.length === 0) { return []; } const requireCall = lua.createCallExpression(lua.createIdentifier("require"), [ lua.createStringLiteral("lualib_bundle"), ]); const luaLibId = lua.createIdentifier("____lualib"); const importStatement = lua.createVariableDeclarationStatement(luaLibId, requireCall); const statements = [importStatement]; // local <export> = ____luaLib.<export> for (const item of imports) { statements.push(lua.createVariableDeclarationStatement(lua.createIdentifier(item), lua.createTableIndexExpression(luaLibId, lua.createStringLiteral(item)))); } return statements; } const luaLibBundleContent = new Map(); function getLuaLibBundle(luaTarget, emitHost) { const lualibPath = path.join(resolveLuaLibDir(luaTarget), "lualib_bundle.lua"); if (!luaLibBundleContent.has(lualibPath)) { const result = emitHost.readFile(lualibPath); if (result !== undefined) { luaLibBundleContent.set(lualibPath, result); } else { throw new Error(`Could not load lualib bundle from '${lualibPath}'`); } } return luaLibBundleContent.get(lualibPath); } function getLualibBundleReturn(exportedValues) { return `\nreturn {\n${exportedValues.map(exportName => ` ${exportName} = ${exportName}`).join(",\n")}\n}\n`; } function buildMinimalLualibBundle(features, luaTarget, emitHost) { const code = loadInlineLualibFeatures(features, luaTarget, emitHost); const moduleInfo = getLuaLibModulesInfo(luaTarget, emitHost); const exports = Array.from(features).flatMap(feature => moduleInfo[feature].exports); return code + getLualibBundleReturn(exports); } function findUsedLualibFeatures(luaTarget, emitHost, luaContents) { const features = new Set(); const exportToFeatureMap = getLuaLibExportToFeatureMap(luaTarget, emitHost); for (const lua of luaContents) { const regex = /^local (\w+) = ____lualib\.(\w+)$/gm; while (true) { const match = regex.exec(lua); if (!match) break; const [, localName, exportName] = match; if (localName !== exportName) continue; const feature = exportToFeatureMap.get(exportName); if (feature) features.add(feature); } } return features; } //# sourceMappingURL=LuaLib.js.map