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

218 lines 8.8 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 typeUtilities_1 = require("../typeUtilities"); const utility_1 = require("../utility"); function shouldCompileAsSpreadableList(elements) { const { length } = elements; for (let i = 0; i < length; i++) { if (ts.TypeGuards.isSpreadElement(elements[i])) { return i + 1 !== length; } } return false; } exports.shouldCompileAsSpreadableList = shouldCompileAsSpreadableList; function compileSpreadableList(state, elements, compile = _1.compileExpression) { // The logic here is equivalent to the compileList logic, although it looks a bit more complicated let isInArray = false; const parts = new Array(); const contexts = new Array(); const args = new Array(); let gIndex = 0; let lastContextualIndex; let lastContextualElement; for (const element of elements) { if (ts.TypeGuards.isSpreadElement(element)) { state.enterPrecedingStatementContext(); const expStr = compileSpreadExpressionOrThrow(state, utility_1.skipNodesDownwards(element.getExpression())); const context = state.exitPrecedingStatementContext(); if (context.length > 0) { lastContextualIndex = gIndex; lastContextualElement = element; } parts.push(expStr); contexts.push(context); args.push(element); gIndex++; isInArray = false; } else { let last; let lastContext; let lastElement; if (isInArray) { last = parts[parts.length - 1]; lastContext = contexts[contexts.length - 1]; lastElement = args[args.length - 1]; } else { last = new Array(); lastContext = new Array(); lastElement = new Array(); parts.push(last); contexts.push(lastContext); args.push(lastElement); } state.enterPrecedingStatementContext(); const expStr = compile(state, element); const context = state.exitPrecedingStatementContext(); if (context.length > 0) { lastContextualIndex = gIndex; lastContextualElement = element; } last.push(expStr); lastContext.push(context); lastElement.push(element); gIndex++; isInArray = true; } } if (lastContextualIndex !== undefined) { let gIter = 0; for (let i = 0; i < contexts.length; i++) { if (gIter === lastContextualIndex) { if (typeof parts[i] === "string") { state.pushPrecedingStatements(lastContextualElement, ...contexts[i]); } else { contexts[i].forEach(context => state.pushPrecedingStatements(lastContextualElement, ...context)); } break; } const part = parts[i]; if (typeof part === "string") { const arg = args[i]; const context = contexts[i]; if (context.length > 0) { state.pushPrecedingStatements(arg, ...context); } if (typeUtilities_1.shouldPushToPrecedingStatement(arg, part, context)) { let nextContext; // get nextContext if (typeof parts[i + 1] === "string") { nextContext = contexts[i + 1]; } else { const contextSet = contexts[i + 1]; nextContext = contextSet.reduce((a, x) => { a.push(...x); return a; }, new Array()); nextContext.isPushed = false; } parts[i] = state.pushPrecedingStatementToReuseableId(arg, part, nextContext); } gIter++; } else { const arg = args[i]; const context = contexts[i]; for (let j = 0; j < context.length; j++) { const subContext = context[j]; const subExp = arg[j]; const subStr = part[j]; if (subContext.length > 0) { state.pushPrecedingStatements(subExp, ...subContext); } if (typeUtilities_1.shouldPushToPrecedingStatement(subExp, subStr, subContext)) { part[j] = state.pushPrecedingStatementToReuseableId(subExp, subStr, context[j + 1]); } if (++gIter === lastContextualIndex) { state.pushPrecedingStatements(lastContextualElement, ...context[j + 1]); break; } } } } } return parts; } exports.compileSpreadableList = compileSpreadableList; function compileSpreadableListAndJoin(state, elements, shouldWrapInConcat = true, compile = _1.compileExpression) { let params = compileSpreadableList(state, elements, compile) .map(v => { if (typeof v === "string") { return v; } else { return `{ ${v.join(", ")} }`; } }) .join(", "); if (shouldWrapInConcat) { state.usesTSLibrary = true; params = `TS.array_concat(${params})`; } return params; } exports.compileSpreadableListAndJoin = compileSpreadableListAndJoin; function compileSpreadExpression(state, expression) { const expType = typeUtilities_1.getType(expression); if (typeUtilities_1.isSetType(expType)) { state.usesTSLibrary = true; return `TS.set_values(${_1.compileExpression(state, expression)})`; } else if (typeUtilities_1.isMapType(expType)) { state.usesTSLibrary = true; return `TS.map_entries(${_1.compileExpression(state, expression)})`; } else if (typeUtilities_1.isArrayType(expType)) { return _1.compileExpression(state, expression); } else if (typeUtilities_1.isStringType(expType)) { if (ts.TypeGuards.isStringLiteral(expression)) { const text = expression.getText(); const quote = text.slice(-1); return "{" + text.replace(/\\?./g, a => `${quote}${a}${quote}, `).slice(4, -7) + " }"; } else { return `string.split(${_1.compileExpression(state, expression)}, "")`; } } else if (typeUtilities_1.isIterableFunction(expType)) { state.usesTSLibrary = true; return `TS.iterableFunctionCache(${_1.compileExpression(state, expression)})`; } else if (typeUtilities_1.isIterableIterator(expType, expression)) { state.usesTSLibrary = true; return `TS.iterableCache(${_1.compileExpression(state, expression)})`; } else { state.usesTSLibrary = true; const arrName = _1.getReadableExpressionName(state, expression); return `TS.iterableCache(${arrName}[TS.Symbol_iterator](${arrName}))`; } } exports.compileSpreadExpression = compileSpreadExpression; function compileSpreadExpressionOrThrow(state, expression) { const result = compileSpreadExpression(state, expression); if (result) { return result; } else { throw new CompilerError_1.CompilerError(`Unable to spread expression of type ${typeUtilities_1.getType(expression).getText()}`, expression, CompilerError_1.CompilerErrorType.BadSpreadType); } } exports.compileSpreadExpressionOrThrow = compileSpreadExpressionOrThrow; function compileSpreadElement(state, node) { const expression = node.getExpression(); _1.checkNonAny(expression, true); if (ts.TypeGuards.isCallExpression(expression) && typeUtilities_1.isTupleReturnTypeCall(expression)) { return _1.compileCallExpression(state, expression, true); } else { return `unpack(${compileSpreadExpressionOrThrow(state, expression)})`; } } exports.compileSpreadElement = compileSpreadElement; //# sourceMappingURL=spread.js.map