UNPKG

typescript-to-lua

Version:

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

247 lines 10.7 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.transformBuiltinPropertyAccessExpression = transformBuiltinPropertyAccessExpression; exports.transformBuiltinCallExpression = transformBuiltinCallExpression; exports.transformBuiltinIdentifierExpression = transformBuiltinIdentifierExpression; exports.checkForLuaLibType = checkForLuaLibType; exports.tryGetStandardLibrarySymbolOfType = tryGetStandardLibrarySymbolOfType; const ts = __importStar(require("typescript")); const lua = __importStar(require("../../LuaAST")); const lua_ast_1 = require("../utils/lua-ast"); const lualib_1 = require("../utils/lualib"); const symbols_1 = require("../utils/symbols"); const typescript_1 = require("../utils/typescript"); const call_1 = require("../visitors/call"); const array_1 = require("./array"); const console_1 = require("./console"); const function_1 = require("./function"); const global_1 = require("./global"); const math_1 = require("./math"); const number_1 = require("./number"); const object_1 = require("./object"); const promise_1 = require("./promise"); const string_1 = require("./string"); const symbol_1 = require("./symbol"); const diagnostics_1 = require("../utils/diagnostics"); const CompilerOptions_1 = require("../../CompilerOptions"); const map_1 = require("./map"); function transformBuiltinPropertyAccessExpression(context, node) { const ownerType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, ownerType, undefined)) { switch (ownerType.symbol.name) { case "NumberConstructor": return (0, number_1.transformNumberProperty)(context, node); case "Math": return (0, math_1.transformMathProperty)(context, node); case "SymbolConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Symbol); } } if ((0, typescript_1.isStringType)(context, ownerType)) { return (0, string_1.transformStringProperty)(context, node); } if ((0, typescript_1.isArrayType)(context, ownerType)) { return (0, array_1.transformArrayProperty)(context, node); } if ((0, typescript_1.isFunctionType)(ownerType)) { return (0, function_1.transformFunctionProperty)(context, node); } } function transformBuiltinCallExpression(context, node) { const expressionType = context.checker.getTypeAtLocation(node.expression); if (ts.isIdentifier(node.expression) && (0, typescript_1.isStandardLibraryType)(context, expressionType, undefined)) { checkForLuaLibType(context, expressionType); const result = (0, global_1.tryTransformBuiltinGlobalCall)(context, node, expressionType); if (result) return result; } const calledMethod = ts.getOriginalNode((0, call_1.getCalledExpression)(node)); if (ts.isPropertyAccessExpression(calledMethod)) { const globalResult = tryTransformBuiltinGlobalMethodCall(context, node, calledMethod); if (globalResult) return globalResult; const prototypeResult = tryTransformBuiltinPropertyCall(context, node, calledMethod); if (prototypeResult) return prototypeResult; // object prototype call may work even without resolved signature/type (which the other builtin calls use) // e.g. (foo as any).toString() // prototype methods take precedence (e.g. number.toString(2)) const objectResult = (0, object_1.tryTransformObjectPrototypeCall)(context, node, calledMethod); if (objectResult) return objectResult; } } function tryTransformBuiltinGlobalMethodCall(context, node, calledMethod) { const ownerType = context.checker.getTypeAtLocation(calledMethod.expression); const ownerSymbol = tryGetStandardLibrarySymbolOfType(context, ownerType); if (!ownerSymbol || ownerSymbol.parent) return; let result; switch (ownerSymbol.name) { case "ArrayConstructor": result = (0, array_1.transformArrayConstructorCall)(context, node, calledMethod); break; case "Console": result = (0, console_1.transformConsoleCall)(context, node, calledMethod); break; case "MapConstructor": result = (0, map_1.transformMapConstructorCall)(context, node, calledMethod); break; case "Math": result = (0, math_1.transformMathCall)(context, node, calledMethod); break; case "StringConstructor": result = (0, string_1.transformStringConstructorMethodCall)(context, node, calledMethod); break; case "ObjectConstructor": result = (0, object_1.transformObjectConstructorCall)(context, node, calledMethod); break; case "SymbolConstructor": result = (0, symbol_1.transformSymbolConstructorCall)(context, node, calledMethod); break; case "NumberConstructor": result = (0, number_1.transformNumberConstructorCall)(context, node, calledMethod); break; case "PromiseConstructor": result = (0, promise_1.transformPromiseConstructorCall)(context, node, calledMethod); break; } if (result && calledMethod.questionDotToken) { // e.g. console?.log() context.diagnostics.push((0, diagnostics_1.unsupportedBuiltinOptionalCall)(calledMethod)); } return result; } function tryTransformBuiltinPropertyCall(context, node, calledMethod) { const functionType = context.checker.getTypeAtLocation(node.expression); const callSymbol = tryGetStandardLibrarySymbolOfType(context, functionType); if (!callSymbol) return; const ownerSymbol = callSymbol.parent; if (!ownerSymbol || ownerSymbol.parent) return; switch (ownerSymbol.name) { case "String": return (0, string_1.transformStringPrototypeCall)(context, node, calledMethod); case "Number": return (0, number_1.transformNumberPrototypeCall)(context, node, calledMethod); case "Array": case "ReadonlyArray": return (0, array_1.transformArrayPrototypeCall)(context, node, calledMethod); case "Function": case "CallableFunction": case "NewableFunction": return (0, function_1.transformFunctionPrototypeCall)(context, node, calledMethod); } } function transformBuiltinIdentifierExpression(context, node, symbol) { switch (node.text) { case "NaN": return (0, lua_ast_1.createNaN)(node); case "Infinity": if (context.luaTarget === CompilerOptions_1.LuaTarget.Lua50) { const one = lua.createNumericLiteral(1); const zero = lua.createNumericLiteral(0); return lua.createBinaryExpression(one, zero, lua.SyntaxKind.DivisionOperator); } else { const math = lua.createIdentifier("math"); const huge = lua.createStringLiteral("huge"); return lua.createTableIndexExpression(math, huge, node); } case "globalThis": return lua.createIdentifier("_G", node, (0, symbols_1.getIdentifierSymbolId)(context, node, symbol), "globalThis"); } } const builtinErrorTypeNames = new Set([ "Error", "ErrorConstructor", "RangeError", "RangeErrorConstructor", "ReferenceError", "ReferenceErrorConstructor", "SyntaxError", "SyntaxErrorConstructor", "TypeError", "TypeErrorConstructor", "URIError", "URIErrorConstructor", ]); function checkForLuaLibType(context, type) { const symbol = type.symbol; if (!symbol || symbol.parent) return; const name = symbol.name; switch (name) { case "Map": case "MapConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Map); return; case "Set": case "SetConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Set); return; case "WeakMap": case "WeakMapConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakMap); return; case "WeakSet": case "WeakSetConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.WeakSet); return; case "Promise": case "PromiseConstructor": (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Promise); return; } if (builtinErrorTypeNames.has(name)) { (0, lualib_1.importLuaLibFeature)(context, lualib_1.LuaLibFeature.Error); } } function tryGetStandardLibrarySymbolOfType(context, type) { if (type.isUnionOrIntersection()) { for (const subType of type.types) { const symbol = tryGetStandardLibrarySymbolOfType(context, subType); if (symbol) return symbol; } } else if ((0, typescript_1.isStandardLibraryType)(context, type, undefined)) { return type.symbol; } return undefined; } //# sourceMappingURL=index.js.map