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
171 lines • 8.26 kB
JavaScript
;
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 compileVariableDeclaration(state, node) {
state.enterPrecedingStatementContext();
const lhs = node.getNameNode();
const rhs = utility_1.skipNodesDownwards(node.getInitializer());
const parent = utility_1.skipNodesUpwards(node.getParent());
const grandParent = utility_1.skipNodesUpwards(parent.getParent());
const isExported = ts.TypeGuards.isVariableStatement(grandParent) && grandParent.isExported();
let decKind = ts.VariableDeclarationKind.Const;
if (ts.TypeGuards.isVariableDeclarationList(parent)) {
decKind = parent.getDeclarationKind();
}
if (ts.TypeGuards.isArrayBindingPattern(lhs)) {
const isFlatBinding = lhs
.getElements()
.filter(v => ts.TypeGuards.isBindingElement(v))
.every(v => ts.TypeGuards.isIdentifier(v.getChildAtIndex(0)));
if (isFlatBinding && rhs && ts.TypeGuards.isCallExpression(rhs) && typeUtilities_1.isTupleType(typeUtilities_1.getType(rhs))) {
const names = new Array();
const values = new Array();
for (const element of lhs.getElements()) {
if (ts.TypeGuards.isBindingElement(element)) {
const nameNode = element.getNameNode();
if (ts.TypeGuards.isIdentifier(nameNode)) {
names.push(_1.compileExpression(state, nameNode));
}
}
else if (ts.TypeGuards.isOmittedExpression(element)) {
names.push("_");
}
}
values.push(_1.compileCallExpression(state, rhs, true));
if (isExported && decKind === ts.VariableDeclarationKind.Let) {
let returnValue;
_1.concatNamesAndValues(state, names, values, false, str => (returnValue = str));
return state.exitPrecedingStatementContextAndJoin() + returnValue || "";
}
else {
if (isExported && ts.TypeGuards.isVariableStatement(grandParent)) {
names.forEach(name => state.pushExport(name, grandParent));
}
let returnValue;
_1.concatNamesAndValues(state, names, values, true, str => (returnValue = str));
return state.exitPrecedingStatementContextAndJoin() + returnValue || "";
}
}
}
let result = "";
if (ts.TypeGuards.isIdentifier(lhs)) {
const name = lhs.getText();
_1.checkReserved(name, lhs, true);
if (rhs) {
if (isExported && decKind === ts.VariableDeclarationKind.Let) {
const parentName = state.getExportContextName(grandParent);
state.declarationContext.set(rhs, {
isIdentifier: false,
set: `${parentName}.${name}`,
});
const value = _1.compileExpression(state, rhs);
if (state.declarationContext.delete(rhs)) {
result += state.indent + `${parentName}.${name} = ${value};\n`;
}
}
else {
if (isExported && ts.TypeGuards.isVariableStatement(grandParent)) {
state.pushExport(name, grandParent);
}
if (typeUtilities_1.shouldHoist(grandParent, lhs)) {
state.pushHoistStack(name);
state.declarationContext.set(rhs, { isIdentifier: true, set: `${name}` });
const value = _1.compileExpression(state, rhs);
if (state.declarationContext.delete(rhs)) {
result += state.indent + `${name} = ${value};\n`;
}
}
else {
state.declarationContext.set(rhs, {
isIdentifier: true,
needsLocalizing: true,
set: `${name}`,
});
const value = _1.compileExpression(state, rhs);
if (state.declarationContext.delete(rhs)) {
result += state.indent + `local ${name} = ${value};\n`;
}
}
}
}
else if (!isExported) {
if (typeUtilities_1.shouldHoist(grandParent, lhs)) {
state.pushHoistStack(name);
}
else {
result += state.indent + `local ${name};\n`;
}
}
}
else if ((ts.TypeGuards.isArrayBindingPattern(lhs) || ts.TypeGuards.isObjectBindingPattern(lhs)) && rhs) {
// binding patterns MUST have rhs
const names = new Array();
const values = new Array();
const preStatements = new Array();
const postStatements = new Array();
let rhsStr = _1.compileExpression(state, rhs);
if (!utility_1.isCompiledIdentifier(rhsStr)) {
const id = state.getNewId();
preStatements.push(`local ${id} = ${rhsStr};`);
rhsStr = id;
}
if (ts.TypeGuards.isArrayBindingPattern(lhs)) {
const rhsType = typeUtilities_1.getType(rhs);
if (!typeUtilities_1.isArrayType(rhsType) &&
!typeUtilities_1.isMapType(rhsType) &&
!typeUtilities_1.isSetType(rhsType) &&
!typeUtilities_1.isIterableIterator(rhsType, rhs) &&
!typeUtilities_1.isIterableFunction(rhsType) &&
(typeUtilities_1.isObjectType(rhsType) || ts.TypeGuards.isThisExpression(rhs))) {
state.usesTSLibrary = true;
rhsStr = rhsStr;
const id = state.getNewId();
preStatements.push(`local ${id} = ${rhsStr}[TS.Symbol_iterator](${rhsStr});`);
rhsStr = id;
}
}
_1.getBindingData(state, names, values, preStatements, postStatements, lhs, rhsStr);
preStatements.forEach(statementStr => (result += state.indent + statementStr + "\n"));
if (values.length > 0) {
if (isExported && decKind === ts.VariableDeclarationKind.Let) {
_1.concatNamesAndValues(state, names, values, false, str => (result += str));
}
else {
if (isExported && ts.TypeGuards.isVariableStatement(grandParent)) {
names.forEach(name => state.pushExport(name, grandParent));
}
_1.concatNamesAndValues(state, names, values, true, str => (result += str));
}
}
postStatements.forEach(statementStr => (result += state.indent + statementStr + "\n"));
}
return state.exitPrecedingStatementContextAndJoin() + result;
}
exports.compileVariableDeclaration = compileVariableDeclaration;
function compileVariableDeclarationList(state, node) {
const declarationKind = node.getDeclarationKind();
if (declarationKind === ts.VariableDeclarationKind.Var) {
throw new CompilerError_1.CompilerError("'var' keyword is not supported! Use 'let' or 'const' instead.", node, CompilerError_1.CompilerErrorType.NoVarKeyword);
}
return node
.getDeclarations()
.reduce((result, declaration) => result + compileVariableDeclaration(state, declaration), "");
}
exports.compileVariableDeclarationList = compileVariableDeclarationList;
function compileVariableStatement(state, node) {
const list = node.getFirstChildByKindOrThrow(ts.SyntaxKind.VariableDeclarationList);
return compileVariableDeclarationList(state, list);
}
exports.compileVariableStatement = compileVariableStatement;
//# sourceMappingURL=variable.js.map