import { Node } from '../interfaces'; export default function isReference(node: Node, parent: Node): boolean { if (node.type === 'MemberExpression') { return !node.computed && isReference(node.object, node); } if (node.type === 'Identifier') { // the only time we could have an identifier node without a parent is // if it's the entire body of a function without a block statement – // i.e. an arrow function expression like `a => a` if (!parent) return true; // TODO is this right? if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) { return parent.computed || node === parent.object; } // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` if (parent.type === 'Property') return parent.computed || node === parent.value; // disregard the `bar` in `class Foo { bar () {...} }` if (parent.type === 'MethodDefinition') return false; // disregard the `bar` in `export { foo as bar }` if (parent.type === 'ExportSpecifier' && node !== parent.local) return; return true; } }