typescript-to-lua
Version:
A generic TypeScript to Lua transpiler. Write your code in TypeScript and publish Lua!
535 lines • 22.8 kB
JavaScript
;
// 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