export function matchesCallExpression( expression: babel.MemberExpression, path: string[]): boolean { if (!expression.property || !expression.object) { return false; } assert(path.length >= 2); if (!babel.isIdentifier(expression.property)) { return false; } // Unravel backwards, make sure properties match each step of the way. if (expression.property.name !== path[path.length - 1]) { return false; } // We've got ourselves a final member expression. if (path.length === 2 && babel.isIdentifier(expression.object)) { return expression.object.name === path[0]; } // Nested expressions. if (path.length > 2 && babel.isMemberExpression(expression.object)) { return matchesCallExpression( expression.object, path.slice(0, path.length - 1)); } return false; }
export function isVariableCall(node: Expression): node is VariableCallAST { return ( isCallExpression(node) && isMemberExpression(node.callee, { computed: false }) && isVariable(node.callee.object) && isIdentifier(node.callee.property) ); }
export function isVariable(node: Expression): node is VariableAST { return ( isCallExpression(node) && isMemberExpression(node.callee, { computed: false }) && isIdentifier(node.callee.object, { name: 'Variable' }) && isIdentifier(node.callee.property, { name: 'find' }) && isIdentifier(node.arguments[0], { name: 'gameModel' }) && isStringLiteral(node.arguments[1]) ); }
export function extractGlobalMethod(node: CallExpression) { let ret: Identifier[] = []; let depth = node.callee; while (isMemberExpression(depth)) { if (!isIdentifier(depth.property)) { throw Error('Unhandled'); } ret.push(depth.property); depth = depth.object; } if (!isIdentifier(depth)) { throw Error('Unhandled'); } ret.push(depth); return ret .reverse() .map(i => i.name) .join('.'); }