UNPKG

typescript-to-lua

Version:

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

535 lines 22.8 kB
"use strict"; // Simplified Lua AST based roughly on http://lua-users.org/wiki/MetaLuaAbstractSyntaxTree, // https://www.lua.org/manual/5.3/manual.html#9 and the TS AST implementation Object.defineProperty(exports, "__esModule", { value: true }); exports.NodeFlags = exports.SyntaxKind = void 0; exports.createNode = createNode; exports.cloneNode = cloneNode; exports.setNodePosition = setNodePosition; exports.setNodeOriginal = setNodeOriginal; exports.getOriginalPos = getOriginalPos; exports.setNodeFlags = setNodeFlags; exports.isFile = isFile; exports.createFile = createFile; exports.isBlock = isBlock; exports.createBlock = createBlock; exports.isDoStatement = isDoStatement; exports.createDoStatement = createDoStatement; exports.isVariableDeclarationStatement = isVariableDeclarationStatement; exports.createVariableDeclarationStatement = createVariableDeclarationStatement; exports.isAssignmentStatement = isAssignmentStatement; exports.createAssignmentStatement = createAssignmentStatement; exports.isIfStatement = isIfStatement; exports.createIfStatement = createIfStatement; exports.isIterationStatement = isIterationStatement; exports.isWhileStatement = isWhileStatement; exports.createWhileStatement = createWhileStatement; exports.isRepeatStatement = isRepeatStatement; exports.createRepeatStatement = createRepeatStatement; exports.isForStatement = isForStatement; exports.createForStatement = createForStatement; exports.isForInStatement = isForInStatement; exports.createForInStatement = createForInStatement; exports.isGotoStatement = isGotoStatement; exports.createGotoStatement = createGotoStatement; exports.isLabelStatement = isLabelStatement; exports.createLabelStatement = createLabelStatement; exports.isReturnStatement = isReturnStatement; exports.createReturnStatement = createReturnStatement; exports.isBreakStatement = isBreakStatement; exports.createBreakStatement = createBreakStatement; exports.isContinueStatement = isContinueStatement; exports.createContinueStatement = createContinueStatement; exports.isExpressionStatement = isExpressionStatement; exports.createExpressionStatement = createExpressionStatement; exports.isNilLiteral = isNilLiteral; exports.createNilLiteral = createNilLiteral; exports.isBooleanLiteral = isBooleanLiteral; exports.createBooleanLiteral = createBooleanLiteral; exports.isDotsLiteral = isDotsLiteral; exports.createDotsLiteral = createDotsLiteral; exports.isArgLiteral = isArgLiteral; exports.createArgLiteral = createArgLiteral; exports.isNumericLiteral = isNumericLiteral; exports.createNumericLiteral = createNumericLiteral; exports.isStringLiteral = isStringLiteral; exports.createStringLiteral = createStringLiteral; exports.isLiteral = isLiteral; exports.isFunctionExpression = isFunctionExpression; exports.createFunctionExpression = createFunctionExpression; exports.isTableFieldExpression = isTableFieldExpression; exports.createTableFieldExpression = createTableFieldExpression; exports.isTableExpression = isTableExpression; exports.createTableExpression = createTableExpression; exports.isUnaryExpression = isUnaryExpression; exports.createUnaryExpression = createUnaryExpression; exports.isBinaryExpression = isBinaryExpression; exports.createBinaryExpression = createBinaryExpression; exports.isCallExpression = isCallExpression; exports.createCallExpression = createCallExpression; exports.isMethodCallExpression = isMethodCallExpression; exports.createMethodCallExpression = createMethodCallExpression; exports.isIdentifier = isIdentifier; exports.createIdentifier = createIdentifier; exports.cloneIdentifier = cloneIdentifier; exports.createAnonymousIdentifier = createAnonymousIdentifier; exports.isTableIndexExpression = isTableIndexExpression; exports.createTableIndexExpression = createTableIndexExpression; exports.isAssignmentLeftHandSideExpression = isAssignmentLeftHandSideExpression; exports.isFunctionDefinition = isFunctionDefinition; exports.isInlineFunctionExpression = isInlineFunctionExpression; exports.isParenthesizedExpression = isParenthesizedExpression; exports.createParenthesizedExpression = createParenthesizedExpression; exports.isConditionalExpression = isConditionalExpression; exports.createConditionalExpression = createConditionalExpression; // We can elide a lot of nodes especially tokens and keywords // because we don't create the AST from text const ts = require("typescript"); const utils_1 = require("./utils"); var SyntaxKind; (function (SyntaxKind) { SyntaxKind[SyntaxKind["File"] = 0] = "File"; SyntaxKind[SyntaxKind["Block"] = 1] = "Block"; // Statements SyntaxKind[SyntaxKind["DoStatement"] = 2] = "DoStatement"; SyntaxKind[SyntaxKind["VariableDeclarationStatement"] = 3] = "VariableDeclarationStatement"; SyntaxKind[SyntaxKind["AssignmentStatement"] = 4] = "AssignmentStatement"; SyntaxKind[SyntaxKind["IfStatement"] = 5] = "IfStatement"; SyntaxKind[SyntaxKind["WhileStatement"] = 6] = "WhileStatement"; SyntaxKind[SyntaxKind["RepeatStatement"] = 7] = "RepeatStatement"; SyntaxKind[SyntaxKind["ForStatement"] = 8] = "ForStatement"; SyntaxKind[SyntaxKind["ForInStatement"] = 9] = "ForInStatement"; SyntaxKind[SyntaxKind["GotoStatement"] = 10] = "GotoStatement"; SyntaxKind[SyntaxKind["LabelStatement"] = 11] = "LabelStatement"; SyntaxKind[SyntaxKind["ReturnStatement"] = 12] = "ReturnStatement"; SyntaxKind[SyntaxKind["BreakStatement"] = 13] = "BreakStatement"; SyntaxKind[SyntaxKind["ContinueStatement"] = 14] = "ContinueStatement"; SyntaxKind[SyntaxKind["ExpressionStatement"] = 15] = "ExpressionStatement"; // Expression SyntaxKind[SyntaxKind["StringLiteral"] = 16] = "StringLiteral"; SyntaxKind[SyntaxKind["NumericLiteral"] = 17] = "NumericLiteral"; SyntaxKind[SyntaxKind["NilKeyword"] = 18] = "NilKeyword"; SyntaxKind[SyntaxKind["DotsKeyword"] = 19] = "DotsKeyword"; SyntaxKind[SyntaxKind["ArgKeyword"] = 20] = "ArgKeyword"; SyntaxKind[SyntaxKind["TrueKeyword"] = 21] = "TrueKeyword"; SyntaxKind[SyntaxKind["FalseKeyword"] = 22] = "FalseKeyword"; SyntaxKind[SyntaxKind["FunctionExpression"] = 23] = "FunctionExpression"; SyntaxKind[SyntaxKind["TableFieldExpression"] = 24] = "TableFieldExpression"; SyntaxKind[SyntaxKind["TableExpression"] = 25] = "TableExpression"; SyntaxKind[SyntaxKind["UnaryExpression"] = 26] = "UnaryExpression"; SyntaxKind[SyntaxKind["BinaryExpression"] = 27] = "BinaryExpression"; SyntaxKind[SyntaxKind["CallExpression"] = 28] = "CallExpression"; SyntaxKind[SyntaxKind["MethodCallExpression"] = 29] = "MethodCallExpression"; SyntaxKind[SyntaxKind["Identifier"] = 30] = "Identifier"; SyntaxKind[SyntaxKind["TableIndexExpression"] = 31] = "TableIndexExpression"; SyntaxKind[SyntaxKind["ParenthesizedExpression"] = 32] = "ParenthesizedExpression"; SyntaxKind[SyntaxKind["ConditionalExpression"] = 33] = "ConditionalExpression"; // Operators // Arithmetic SyntaxKind[SyntaxKind["AdditionOperator"] = 34] = "AdditionOperator"; SyntaxKind[SyntaxKind["SubtractionOperator"] = 35] = "SubtractionOperator"; SyntaxKind[SyntaxKind["MultiplicationOperator"] = 36] = "MultiplicationOperator"; SyntaxKind[SyntaxKind["DivisionOperator"] = 37] = "DivisionOperator"; SyntaxKind[SyntaxKind["FloorDivisionOperator"] = 38] = "FloorDivisionOperator"; SyntaxKind[SyntaxKind["ModuloOperator"] = 39] = "ModuloOperator"; SyntaxKind[SyntaxKind["PowerOperator"] = 40] = "PowerOperator"; SyntaxKind[SyntaxKind["NegationOperator"] = 41] = "NegationOperator"; // Concat SyntaxKind[SyntaxKind["ConcatOperator"] = 42] = "ConcatOperator"; // Length SyntaxKind[SyntaxKind["LengthOperator"] = 43] = "LengthOperator"; // Relational Ops SyntaxKind[SyntaxKind["EqualityOperator"] = 44] = "EqualityOperator"; SyntaxKind[SyntaxKind["InequalityOperator"] = 45] = "InequalityOperator"; SyntaxKind[SyntaxKind["LessThanOperator"] = 46] = "LessThanOperator"; SyntaxKind[SyntaxKind["LessEqualOperator"] = 47] = "LessEqualOperator"; // Syntax Sugar `x > y` <=> `not (y <= x)` // but we should probably use them to make the output code more readable SyntaxKind[SyntaxKind["GreaterThanOperator"] = 48] = "GreaterThanOperator"; SyntaxKind[SyntaxKind["GreaterEqualOperator"] = 49] = "GreaterEqualOperator"; // Logical SyntaxKind[SyntaxKind["AndOperator"] = 50] = "AndOperator"; SyntaxKind[SyntaxKind["OrOperator"] = 51] = "OrOperator"; SyntaxKind[SyntaxKind["NotOperator"] = 52] = "NotOperator"; // Bitwise SyntaxKind[SyntaxKind["BitwiseAndOperator"] = 53] = "BitwiseAndOperator"; SyntaxKind[SyntaxKind["BitwiseOrOperator"] = 54] = "BitwiseOrOperator"; SyntaxKind[SyntaxKind["BitwiseExclusiveOrOperator"] = 55] = "BitwiseExclusiveOrOperator"; SyntaxKind[SyntaxKind["BitwiseRightShiftOperator"] = 56] = "BitwiseRightShiftOperator"; SyntaxKind[SyntaxKind["BitwiseLeftShiftOperator"] = 57] = "BitwiseLeftShiftOperator"; SyntaxKind[SyntaxKind["BitwiseNotOperator"] = 58] = "BitwiseNotOperator"; })(SyntaxKind || (exports.SyntaxKind = SyntaxKind = {})); var NodeFlags; (function (NodeFlags) { NodeFlags[NodeFlags["None"] = 0] = "None"; NodeFlags[NodeFlags["Inline"] = 1] = "Inline"; NodeFlags[NodeFlags["Declaration"] = 2] = "Declaration"; NodeFlags[NodeFlags["TableUnpackCall"] = 4] = "TableUnpackCall"; })(NodeFlags || (exports.NodeFlags = NodeFlags = {})); function createNode(kind, tsOriginal) { if (tsOriginal === undefined) { return { kind, flags: NodeFlags.None }; } const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { return { kind, line: sourcePosition.line, column: sourcePosition.column, flags: NodeFlags.None }; } else { return { kind, flags: NodeFlags.None }; } } function cloneNode(node) { return { ...node }; } function setNodePosition(node, position) { node.line = position.line; node.column = position.column; return node; } function setNodeOriginal(node, tsOriginal) { if (node === undefined) { return undefined; } const sourcePosition = getSourcePosition(tsOriginal); if (sourcePosition) { setNodePosition(node, sourcePosition); } return node; } function getSourcePosition(sourceNode) { var _a; const parseTreeNode = (_a = ts.getParseTreeNode(sourceNode)) !== null && _a !== void 0 ? _a : sourceNode; const sourceFile = parseTreeNode.getSourceFile(); if (sourceFile !== undefined && parseTreeNode.pos >= 0) { const { line, character } = ts.getLineAndCharacterOfPosition(sourceFile, parseTreeNode.pos + parseTreeNode.getLeadingTriviaWidth()); return { line, column: character }; } } function getOriginalPos(node) { return { line: node.line, column: node.column }; } function setNodeFlags(node, flags) { node.flags = flags; return node; } function isFile(node) { return node.kind === SyntaxKind.File; } function createFile(statements, luaLibFeatures, trivia, tsOriginal) { const file = createNode(SyntaxKind.File, tsOriginal); file.statements = statements; file.luaLibFeatures = luaLibFeatures; file.trivia = trivia; return file; } function isBlock(node) { return node.kind === SyntaxKind.Block; } function createBlock(statements, tsOriginal) { const block = createNode(SyntaxKind.Block, tsOriginal); block.statements = statements; return block; } function isDoStatement(node) { return node.kind === SyntaxKind.DoStatement; } function createDoStatement(statements, tsOriginal) { const statement = createNode(SyntaxKind.DoStatement, tsOriginal); statement.statements = statements; return statement; } function isVariableDeclarationStatement(node) { return node.kind === SyntaxKind.VariableDeclarationStatement; } function createVariableDeclarationStatement(left, right, tsOriginal) { const statement = createNode(SyntaxKind.VariableDeclarationStatement, tsOriginal); statement.left = (0, utils_1.castArray)(left); if (right) statement.right = (0, utils_1.castArray)(right); return statement; } function isAssignmentStatement(node) { return node.kind === SyntaxKind.AssignmentStatement; } function createAssignmentStatement(left, right, tsOriginal) { const statement = createNode(SyntaxKind.AssignmentStatement, tsOriginal); statement.left = (0, utils_1.castArray)(left); statement.right = right ? (0, utils_1.castArray)(right) : []; return statement; } function isIfStatement(node) { return node.kind === SyntaxKind.IfStatement; } function createIfStatement(condition, ifBlock, elseBlock, tsOriginal) { const statement = createNode(SyntaxKind.IfStatement, tsOriginal); statement.condition = condition; statement.ifBlock = ifBlock; statement.elseBlock = elseBlock; return statement; } function isIterationStatement(node) { return (node.kind === SyntaxKind.WhileStatement || node.kind === SyntaxKind.RepeatStatement || node.kind === SyntaxKind.ForStatement || node.kind === SyntaxKind.ForInStatement); } function isWhileStatement(node) { return node.kind === SyntaxKind.WhileStatement; } function createWhileStatement(body, condition, tsOriginal) { const statement = createNode(SyntaxKind.WhileStatement, tsOriginal); statement.body = body; statement.condition = condition; return statement; } function isRepeatStatement(node) { return node.kind === SyntaxKind.RepeatStatement; } function createRepeatStatement(body, condition, tsOriginal) { const statement = createNode(SyntaxKind.RepeatStatement, tsOriginal); statement.body = body; statement.condition = condition; return statement; } function isForStatement(node) { return node.kind === SyntaxKind.ForStatement; } function createForStatement(body, controlVariable, controlVariableInitializer, limitExpression, stepExpression, tsOriginal) { const statement = createNode(SyntaxKind.ForStatement, tsOriginal); statement.body = body; statement.controlVariable = controlVariable; statement.controlVariableInitializer = controlVariableInitializer; statement.limitExpression = limitExpression; statement.stepExpression = stepExpression; return statement; } function isForInStatement(node) { return node.kind === SyntaxKind.ForInStatement; } function createForInStatement(body, names, expressions, tsOriginal) { const statement = createNode(SyntaxKind.ForInStatement, tsOriginal); statement.body = body; statement.names = names; statement.expressions = expressions; return statement; } function isGotoStatement(node) { return node.kind === SyntaxKind.GotoStatement; } function createGotoStatement(label, tsOriginal) { const statement = createNode(SyntaxKind.GotoStatement, tsOriginal); statement.label = label; return statement; } function isLabelStatement(node) { return node.kind === SyntaxKind.LabelStatement; } function createLabelStatement(name, tsOriginal) { const statement = createNode(SyntaxKind.LabelStatement, tsOriginal); statement.name = name; return statement; } function isReturnStatement(node) { return node.kind === SyntaxKind.ReturnStatement; } function createReturnStatement(expressions, tsOriginal) { const statement = createNode(SyntaxKind.ReturnStatement, tsOriginal); statement.expressions = expressions; return statement; } function isBreakStatement(node) { return node.kind === SyntaxKind.BreakStatement; } function createBreakStatement(tsOriginal) { return createNode(SyntaxKind.BreakStatement, tsOriginal); } function isContinueStatement(node) { return node.kind === SyntaxKind.ContinueStatement; } function createContinueStatement(tsOriginal) { return createNode(SyntaxKind.ContinueStatement, tsOriginal); } function isExpressionStatement(node) { return node.kind === SyntaxKind.ExpressionStatement; } function createExpressionStatement(expressions, tsOriginal) { const statement = createNode(SyntaxKind.ExpressionStatement, tsOriginal); statement.expression = expressions; return statement; } function isNilLiteral(node) { return node.kind === SyntaxKind.NilKeyword; } function createNilLiteral(tsOriginal) { return createNode(SyntaxKind.NilKeyword, tsOriginal); } function isBooleanLiteral(node) { return node.kind === SyntaxKind.TrueKeyword || node.kind === SyntaxKind.FalseKeyword; } function createBooleanLiteral(value, tsOriginal) { return createNode(value ? SyntaxKind.TrueKeyword : SyntaxKind.FalseKeyword, tsOriginal); } function isDotsLiteral(node) { return node.kind === SyntaxKind.DotsKeyword; } function createDotsLiteral(tsOriginal) { return createNode(SyntaxKind.DotsKeyword, tsOriginal); } function isArgLiteral(node) { return node.kind === SyntaxKind.ArgKeyword; } function createArgLiteral(tsOriginal) { return createNode(SyntaxKind.ArgKeyword, tsOriginal); } function isNumericLiteral(node) { return node.kind === SyntaxKind.NumericLiteral; } function createNumericLiteral(value, tsOriginal) { const expression = createNode(SyntaxKind.NumericLiteral, tsOriginal); expression.value = value; return expression; } function isStringLiteral(node) { return node.kind === SyntaxKind.StringLiteral; } function createStringLiteral(value, tsOriginal) { const expression = createNode(SyntaxKind.StringLiteral, tsOriginal); expression.value = value; return expression; } function isLiteral(node) { return (isNilLiteral(node) || isDotsLiteral(node) || isArgLiteral(node) || isBooleanLiteral(node) || isNumericLiteral(node) || isStringLiteral(node)); } function isFunctionExpression(node) { return node.kind === SyntaxKind.FunctionExpression; } function createFunctionExpression(body, params, dots, flags = NodeFlags.None, tsOriginal) { const expression = createNode(SyntaxKind.FunctionExpression, tsOriginal); expression.body = body; expression.params = params; expression.dots = dots; expression.flags = flags; return expression; } function isTableFieldExpression(node) { return node.kind === SyntaxKind.TableFieldExpression; } function createTableFieldExpression(value, key, tsOriginal) { const expression = createNode(SyntaxKind.TableFieldExpression, tsOriginal); expression.value = value; expression.key = key; return expression; } function isTableExpression(node) { return node.kind === SyntaxKind.TableExpression; } function createTableExpression(fields = [], tsOriginal) { const expression = createNode(SyntaxKind.TableExpression, tsOriginal); expression.fields = fields; return expression; } function isUnaryExpression(node) { return node.kind === SyntaxKind.UnaryExpression; } function createUnaryExpression(operand, operator, tsOriginal) { const expression = createNode(SyntaxKind.UnaryExpression, tsOriginal); expression.operand = operand; expression.operator = operator; return expression; } function isBinaryExpression(node) { return node.kind === SyntaxKind.BinaryExpression; } function createBinaryExpression(left, right, operator, tsOriginal) { const expression = createNode(SyntaxKind.BinaryExpression, tsOriginal); expression.left = left; expression.right = right; expression.operator = operator; return expression; } function isCallExpression(node) { return node.kind === SyntaxKind.CallExpression; } function createCallExpression(expression, params, tsOriginal) { const callExpression = createNode(SyntaxKind.CallExpression, tsOriginal); callExpression.expression = expression; callExpression.params = params; return callExpression; } function isMethodCallExpression(node) { return node.kind === SyntaxKind.MethodCallExpression; } function createMethodCallExpression(prefixExpression, name, params, tsOriginal) { const callExpression = createNode(SyntaxKind.MethodCallExpression, tsOriginal); callExpression.prefixExpression = prefixExpression; callExpression.name = name; callExpression.params = params; return callExpression; } function isIdentifier(node) { return node.kind === SyntaxKind.Identifier; } function createIdentifier(text, tsOriginal, symbolId, originalName) { const expression = createNode(SyntaxKind.Identifier, tsOriginal); expression.exportable = true; expression.text = text; expression.symbolId = symbolId; expression.originalName = originalName; return expression; } function cloneIdentifier(identifier, tsOriginal) { return createIdentifier(identifier.text, tsOriginal, identifier.symbolId, identifier.originalName); } function createAnonymousIdentifier(tsOriginal) { const expression = createNode(SyntaxKind.Identifier, tsOriginal); expression.exportable = false; expression.text = "____"; return expression; } function isTableIndexExpression(node) { return node.kind === SyntaxKind.TableIndexExpression; } function createTableIndexExpression(table, index, tsOriginal) { const expression = createNode(SyntaxKind.TableIndexExpression, tsOriginal); expression.table = table; expression.index = index; return expression; } function isAssignmentLeftHandSideExpression(node) { return isIdentifier(node) || isTableIndexExpression(node); } function isFunctionDefinition(statement) { var _a; return statement.left.length === 1 && ((_a = statement.right) === null || _a === void 0 ? void 0 : _a.length) === 1 && isFunctionExpression(statement.right[0]); } function isInlineFunctionExpression(expression) { var _a; return (((_a = expression.body.statements) === null || _a === void 0 ? void 0 : _a.length) === 1 && isReturnStatement(expression.body.statements[0]) && expression.body.statements[0].expressions !== undefined && (expression.flags & NodeFlags.Inline) !== 0); } function isParenthesizedExpression(node) { return node.kind === SyntaxKind.ParenthesizedExpression; } function createParenthesizedExpression(expression, tsOriginal) { const parenthesizedExpression = createNode(SyntaxKind.ParenthesizedExpression, tsOriginal); parenthesizedExpression.expression = expression; return parenthesizedExpression; } function isConditionalExpression(node) { return node.kind === SyntaxKind.ConditionalExpression; } function createConditionalExpression(condition, whenTrue, whenFalse, tsOriginal) { const conditionalExpression = createNode(SyntaxKind.ConditionalExpression, tsOriginal); conditionalExpression.condition = condition; conditionalExpression.whenTrue = whenTrue; conditionalExpression.whenFalse = whenFalse; return conditionalExpression; } //# sourceMappingURL=LuaAST.js.map