Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
}
} 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 = compileExpression(state, rhs);
if (!isCompiledIdentifier(rhsStr)) {
const id = state.getNewId();
preStatements.push(`local ${id} = ${rhsStr};`);
rhsStr = id;
}
if (ts.TypeGuards.isArrayBindingPattern(lhs)) {
const rhsType = rhs.getType();
if (
!isArrayType(rhsType) &&
!isMapType(rhsType) &&
!isSetType(rhsType) &&
!isIterableIterator(rhsType, rhs) &&
!isIterableFunction(rhsType) &&
(isObjectType(rhsType) || ts.TypeGuards.isThisExpression(rhs))
) {
state.usesTSLibrary = true;
rhsStr = removeBalancedParenthesisFromStringBorders(rhsStr);
const id = state.getNewId();
preStatements.push(`local ${id} = ${rhsStr}[TS.Symbol_iterator](${rhsStr});`);
rhsStr = id;
}
}
function getIdentifierObjectProperties(
state: CompilerState,
roactSymbol: RoactSymbol,
identifier: ts.Identifier,
attributesStack: Array,
) {
const definitionNodes = identifier.getDefinitionNodes();
for (const definitionNode of definitionNodes) {
const literalExpressions = definitionNode.getChildrenOfKind(ts.SyntaxKind.ObjectLiteralExpression);
if (literalExpressions.length > 0) {
for (const literalExpression of literalExpressions) {
for (const property of literalExpression.getProperties()) {
if (
ts.TypeGuards.isPropertyAssignment(property) ||
ts.TypeGuards.isShorthandPropertyAssignment(property)
) {
const propName = property.getName();
attributesStack.push(
state.indent +
`[Roact.${toTitle(roactSymbol)}.${propName}] = ${compileExpression(
state,
identifier,
)}.${propName}`,
);
}
}
}
}
}
}
export function compileStatement(state: CompilerState, node: ts.Statement): string {
if (isTypeStatement(node) || (ts.TypeGuards.isAmbientableNode(node) && node.hasDeclareKeyword())) {
return "";
} else if (ts.TypeGuards.isBlock(node)) {
return compileBlock(state, node);
} else if (ts.TypeGuards.isImportDeclaration(node)) {
return compileImportDeclaration(state, node);
} else if (ts.TypeGuards.isImportEqualsDeclaration(node)) {
return compileImportEqualsDeclaration(state, node);
} else if (ts.TypeGuards.isExportDeclaration(node)) {
return compileExportDeclaration(state, node);
} else if (ts.TypeGuards.isFunctionDeclaration(node)) {
return compileFunctionDeclaration(state, node);
} else if (ts.TypeGuards.isClassDeclaration(node)) {
return compileClassDeclaration(state, node);
} else if (ts.TypeGuards.isNamespaceDeclaration(node)) {
return compileNamespaceDeclaration(state, node);
} else if (ts.TypeGuards.isDoStatement(node)) {
let returnValue: string | undefined;
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: string | undefined;
concatNamesAndValues(state, names, values, true, str => (returnValue = str));
return state.exitPrecedingStatementContextAndJoin() + returnValue || "";
}
}
}
let result = "";
if (ts.TypeGuards.isIdentifier(lhs)) {
const name = checkReserved(lhs);
if (rhs) {
if (isExported && decKind === ts.VariableDeclarationKind.Let) {
const parentName = state.getExportContextName(grandParent);
state.declarationContext.set(rhs, {
isIdentifier: false,
set: `${parentName}.${name}`,
});
const value = 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);
}
export function compileLoopBody(state: CompilerState, node: ts.Statement) {
const hasContinue = hasContinueDescendant(node);
let endsWithBreakOrReturn = false;
if (ts.TypeGuards.isBlock(node)) {
const statements = node.getStatements();
const lastStatement = statements[statements.length - 1];
if (lastStatement) {
if (ts.TypeGuards.isBreakStatement(lastStatement) || ts.TypeGuards.isReturnStatement(lastStatement)) {
endsWithBreakOrReturn = true;
}
}
}
let result = "";
if (hasContinue) {
state.continueId++;
result += state.indent + `local _continue_${state.continueId} = false;\n`;
result += state.indent + `repeat\n`;
state.pushIndent();
}
condValue.getDefinitions().every(a => {
const declNode = a.getDeclarationNode();
if (declNode && ts.TypeGuards.isVariableDeclaration(declNode)) {
const declParent = declNode.getParent();
if (ts.TypeGuards.isVariableDeclarationList(declParent)) {
return declParent.getDeclarationKind() === ts.VariableDeclarationKind.Const;
}
}
return false;
}))
);
export function isMethodDeclaration(node: ts.Node): node is ts.MethodDeclaration | ts.FunctionExpression {
if (ts.TypeGuards.isParameteredNode(node)) {
const thisParam = node.getParameter("this");
if (thisParam) {
return getType(thisParam).getText() !== "void";
} else {
return (
ts.TypeGuards.isMethodDeclaration(node) ||
ts.TypeGuards.isMethodSignature(node) ||
(ts.TypeGuards.isFunctionExpression(node) && isFunctionExpressionMethod(node))
);
}
}
return false;
}
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) && isTupleType(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)) {
checkReserved(nameNode);
names.push(compileExpression(state, nameNode));
}
} else if (ts.TypeGuards.isOmittedExpression(element)) {
names.push("_");
}
}
values.push(compileCallExpression(state, rhs, true));
if (isExported && decKind === ts.VariableDeclarationKind.Let) {
let returnValue: string | undefined;
concatNamesAndValues(state, names, values, false, str => (returnValue = str));
return state.exitPrecedingStatementContextAndJoin() + returnValue || "";
} else {
if (isExported && ts.TypeGuards.isVariableStatement(grandParent)) {
function compileSymbolPropertyCallback(state: CompilerState, expression: ts.Expression) {
const symbol = expression.getSymbolOrThrow();
const name = symbol.getName();
const value = symbol.getValueDeclarationOrThrow();
if (ts.TypeGuards.isFunctionLikeDeclaration(value)) {
if (ts.TypeGuards.isMethodDeclaration(value)) {
throw new CompilerError(
"Do not use Method signatures directly as callbacks for Roact Event, Changed or Ref.\n" +
suggest(
`Change the declaration of \`${name}(...) {...}\` to \`${name} = () => { ... }\`, ` +
` or use an arrow function: \`() => { this.${name}() }\``,
),
expression,
CompilerErrorType.RoactInvalidCallExpression,
);
}
}
return compileExpression(state, expression);
}
function hasContinueDescendant(node: ts.Node) {
for (const child of node.getChildren()) {
if (ts.TypeGuards.isContinueStatement(child)) {
return true;
}
if (
!(
ts.TypeGuards.isForInStatement(child) ||
ts.TypeGuards.isForOfStatement(child) ||
ts.TypeGuards.isForStatement(child) ||
ts.TypeGuards.isWhileStatement(child) ||
ts.TypeGuards.isDoStatement(child)
)
) {
if (hasContinueDescendant(child)) {
return true;
}
}
}
return false;
}