UNPKG

2.49 kBJavaScriptView Raw
1export function isReference ( node, parent ) {
2 if ( parent.type === 'MemberExpression' ) return parent.computed || node === parent.object;
3
4 // disregard the `bar` in { bar: foo }
5 if ( parent.type === 'Property' && node !== parent.value ) return false;
6
7 // disregard the `bar` in `class Foo { bar () {...} }`
8 if ( parent.type === 'MethodDefinition' ) return false;
9
10 // disregard the `bar` in `export { foo as bar }`
11 if ( parent.type === 'ExportSpecifier' && node !== parent.local ) return false;
12
13 return true;
14}
15
16export function flatten ( node ) {
17 const parts = [];
18
19 while ( node.type === 'MemberExpression' ) {
20 if ( node.computed ) return null;
21
22 parts.unshift( node.property.name );
23 node = node.object;
24 }
25
26 if ( node.type !== 'Identifier' ) return null;
27
28 const name = node.name;
29 parts.unshift( name );
30
31 return { name, keypath: parts.join( '.' ) };
32}
33
34export function extractNames ( node ) {
35 const names = [];
36 extractors[ node.type ]( names, node );
37 return names;
38}
39
40const extractors = {
41 Identifier ( names, node ) {
42 names.push( node.name );
43 },
44
45 ObjectPattern ( names, node ) {
46 node.properties.forEach( prop => {
47 extractors[ prop.value.type ]( names, prop.value );
48 });
49 },
50
51 ArrayPattern ( names, node ) {
52 node.elements.forEach( element => {
53 if ( element ) extractors[ element.type ]( names, element );
54 });
55 },
56
57 RestElement ( names, node ) {
58 extractors[ node.argument.type ]( names, node.argument );
59 },
60
61 AssignmentPattern ( names, node ) {
62 extractors[ node.left.type ]( names, node.left );
63 }
64};
65
66
67export function isTruthy ( node ) {
68 if ( node.type === 'Literal' ) return !!node.value;
69 if ( node.type === 'ParenthesizedExpression' ) return isTruthy( node.expression );
70 if ( node.operator in operators ) return operators[ node.operator ]( node );
71}
72
73export function isFalsy ( node ) {
74 return not( isTruthy( node ) );
75}
76
77function not ( value ) {
78 return value === undefined ? value : !value;
79}
80
81function equals ( a, b, strict ) {
82 if ( a.type !== b.type ) return undefined;
83 if ( a.type === 'Literal' ) return strict ? a.value === b.value : a.value == b.value;
84}
85
86const operators = {
87 '==': x => {
88 return equals( x.left, x.right, false );
89 },
90
91 '!=': x => not( operators['==']( x ) ),
92
93 '===': x => {
94 return equals( x.left, x.right, true );
95 },
96
97 '!==': x => not( operators['===']( x ) ),
98
99 '!': x => isFalsy( x.argument ),
100
101 '&&': x => isTruthy( x.left ) && isTruthy( x.right ),
102
103 '||': x => isTruthy( x.left ) || isTruthy( x.right )
104};