UNPKG

roblox-ts

Version:

<div align="center"><img width=25% src="https://i.imgur.com/yCjHmng.png"></div> <h1 align="center"><a href="https://roblox-ts.github.io/">roblox-ts</a></h1> <div align="center">A TypeScript-to-Lua Compiler for Roblox</div> <br> <div align="center"> <a hr

192 lines 8.63 kB
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; }; Object.defineProperty(exports, "__esModule", { value: true }); const ts = __importStar(require("ts-morph")); const _1 = require("."); const CompilerError_1 = require("../errors/CompilerError"); const utility_1 = require("../utility"); function compileExpression(state, node) { if (ts.TypeGuards.isStringLiteral(node) || ts.TypeGuards.isNoSubstitutionTemplateLiteral(node)) { return _1.compileStringLiteral(state, node); } else if (ts.TypeGuards.isNumericLiteral(node)) { return _1.compileNumericLiteral(state, node); } else if (ts.TypeGuards.isBooleanLiteral(node)) { return _1.compileBooleanLiteral(state, node); } else if (ts.TypeGuards.isArrayLiteralExpression(node)) { return _1.compileArrayLiteralExpression(state, node); } else if (ts.TypeGuards.isObjectLiteralExpression(node)) { return _1.compileObjectLiteralExpression(state, node); } else if (ts.TypeGuards.isFunctionExpression(node) || ts.TypeGuards.isArrowFunction(node)) { return _1.compileFunctionExpression(state, node); } else if (ts.TypeGuards.isCallExpression(node)) { return _1.compileCallExpression(state, node); } else if (ts.TypeGuards.isIdentifier(node)) { return _1.compileIdentifier(state, node); } else if (ts.TypeGuards.isBinaryExpression(node)) { return _1.compileBinaryExpression(state, node); } else if (ts.TypeGuards.isPrefixUnaryExpression(node)) { return _1.compilePrefixUnaryExpression(state, node); } else if (ts.TypeGuards.isPostfixUnaryExpression(node)) { return _1.compilePostfixUnaryExpression(state, node); } else if (ts.TypeGuards.isPropertyAccessExpression(node)) { return _1.compilePropertyAccessExpression(state, node); } else if (ts.TypeGuards.isNewExpression(node)) { return _1.compileNewExpression(state, node); } else if (ts.TypeGuards.isParenthesizedExpression(node)) { return _1.compileParenthesizedExpression(state, node); } else if (ts.TypeGuards.isTemplateExpression(node)) { return _1.compileTemplateExpression(state, node); } else if (ts.TypeGuards.isTaggedTemplateExpression(node)) { return _1.compileTaggedTemplateExpression(state, node); } else if (ts.TypeGuards.isElementAccessExpression(node)) { return _1.compileElementAccessExpression(state, node); } else if (ts.TypeGuards.isAwaitExpression(node)) { return _1.compileAwaitExpression(state, node); } else if (ts.TypeGuards.isConditionalExpression(node)) { return _1.compileConditionalExpression(state, node); } else if (ts.TypeGuards.isJsxExpression(node)) { return compileExpression(state, node.getExpressionOrThrow()); } else if (ts.TypeGuards.isJsxSelfClosingElement(node)) { return _1.compileJsxSelfClosingElement(state, node); } else if (ts.TypeGuards.isJsxElement(node)) { return _1.compileJsxElement(state, node); } else if (ts.TypeGuards.isSpreadElement(node)) { return _1.compileSpreadElement(state, node); } else if (ts.TypeGuards.isClassExpression(node)) { return _1.compileClassExpression(state, node); } else if (ts.TypeGuards.isYieldExpression(node)) { return _1.compileYieldExpression(state, node); } else if (ts.TypeGuards.isOmittedExpression(node)) { return "nil"; } else if (ts.TypeGuards.isThisExpression(node)) { if (!node.getFirstAncestorByKind(ts.SyntaxKind.ClassDeclaration) && !node.getFirstAncestorByKind(ts.SyntaxKind.ObjectLiteralExpression) && !node.getFirstAncestorByKind(ts.SyntaxKind.ClassExpression)) { throw new CompilerError_1.CompilerError("'this' may only be used inside a class definition or object literal", node, CompilerError_1.CompilerErrorType.NoThisOutsideClass); } return "self"; } else if (ts.TypeGuards.isSuperExpression(node)) { return _1.compileSuperExpression(state, node); } else if (ts.TypeGuards.isAsExpression(node) || ts.TypeGuards.isTypeAssertion(node) || ts.TypeGuards.isNonNullExpression(node)) { return compileExpression(state, utility_1.skipNodesDownwards(node.getExpression())); } else if (ts.TypeGuards.isNullLiteral(node)) { throw new CompilerError_1.CompilerError("'null' is not supported! Use 'undefined' instead.", node, CompilerError_1.CompilerErrorType.NoNull); } else if (ts.TypeGuards.isTypeOfExpression(node)) { throw new CompilerError_1.CompilerError("'typeof' operator is not supported! Use `typeIs(value, type)` or `typeOf(value)` instead.", node, CompilerError_1.CompilerErrorType.NoTypeOf); } else { throw new CompilerError_1.CompilerError(`Unexpected expression ( ${node.getKindName()} ) in compileExpression`, node, CompilerError_1.CompilerErrorType.BadExpression, true); } } exports.compileExpression = compileExpression; function compileExpressionStatement(state, node) { state.enterPrecedingStatementContext(); let expStr; const expression = utility_1.skipNodesDownwards(node.getExpression()); if (ts.TypeGuards.isCallExpression(expression)) { expStr = _1.compileCallExpression(state, expression, true); } else { expStr = compileExpression(state, expression); // big set of rules for expression statements if (!ts.TypeGuards.isNewExpression(expression) && !ts.TypeGuards.isAwaitExpression(expression) && !ts.TypeGuards.isPostfixUnaryExpression(expression) && !(ts.TypeGuards.isPrefixUnaryExpression(expression) && (expression.getOperatorToken() === ts.SyntaxKind.PlusPlusToken || expression.getOperatorToken() === ts.SyntaxKind.MinusMinusToken)) && !(ts.TypeGuards.isBinaryExpression(expression) && _1.isSetToken(expression.getOperatorToken().getKind())) && !ts.TypeGuards.isYieldExpression(expression)) { expStr = `local _ = ${expStr}`; } } const result = state.exitPrecedingStatementContextAndJoin(); // this is a hack for the time being, to prevent double indenting // situations like these: ({ length } = "Hello, world!") const indent = expStr.match(/^\s+/) ? "" : state.indent; return expStr ? result + indent + expStr + ";\n" : result; } exports.compileExpressionStatement = compileExpressionStatement; function expressionModifiesVariable(node, lhs) { if (ts.TypeGuards.isPostfixUnaryExpression(node) || (ts.TypeGuards.isPrefixUnaryExpression(node) && (node.getOperatorToken() === ts.SyntaxKind.PlusPlusToken || node.getOperatorToken() === ts.SyntaxKind.MinusMinusToken))) { if (lhs) { return utility_1.isIdentifierWhoseDefinitionMatchesNode(node.getOperand(), lhs); } else { return true; } } else if (ts.TypeGuards.isBinaryExpression(node) && _1.isSetToken(node.getOperatorToken().getKind())) { if (lhs) { return utility_1.isIdentifierWhoseDefinitionMatchesNode(node.getLeft(), lhs); } else { return true; } } return false; } exports.expressionModifiesVariable = expressionModifiesVariable; function appendDeclarationIfMissing(state, possibleExpressionStatement, compiledNode) { if (compiledNode.match(/^_d+$/) || ts.TypeGuards.isExpressionStatement(utility_1.skipNodesUpwards(possibleExpressionStatement))) { return "local _ = " + compiledNode; } else { return compiledNode; } } exports.appendDeclarationIfMissing = appendDeclarationIfMissing; function placeIncrementorInStatementIfExpression(state, incrementor, incrementorStr) { if (ts.TypeGuards.isExpression(incrementor)) { if (!ts.TypeGuards.isCallExpression(incrementor) && !expressionModifiesVariable(incrementor) && !ts.TypeGuards.isVariableDeclarationList(incrementor)) { incrementorStr = `local _ = ` + incrementorStr; } } return incrementorStr; } exports.placeIncrementorInStatementIfExpression = placeIncrementorInStatementIfExpression; //# sourceMappingURL=expression.js.map