isReference.js
1.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
export default function isReference ( node, parent ) {
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;
if ( /(Function|Class)Expression/.test( parent.type ) ) return false;
if ( parent.type === 'VariableDeclarator' ) return node === parent.init;
// TODO is this right?
if ( parent.type === 'MemberExpression' || parent.type === 'MethodDefinition' ) {
return parent.computed || node === parent.object;
}
if ( parent.type === 'ArrayPattern' ) return false;
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
if ( parent.type === 'Property' ) {
if ( parent.parent.type === 'ObjectPattern' ) return false;
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 false;
return true;
}
}