1
1
'use strict' ;
2
2
3
+ /**
4
+ * Walks backwards through a chain of callees to get the original.
5
+ */
6
+ function getOriginalCallee ( callee ) {
7
+ while ( callee . type === 'MemberExpression' && callee . object . type === 'CallExpression' ) {
8
+ callee = callee . object . callee ;
9
+ }
10
+ return callee ;
11
+ }
12
+
13
+ function isLodash ( callee ) {
14
+ // Check for direct calls
15
+ if ( callee . object . name === '_' ) {
16
+ return true ;
17
+ }
18
+
19
+ // Check for _.chain
20
+ const original = getOriginalCallee ( callee ) ;
21
+ if ( original . type === 'MemberExpression'
22
+ && original . object . name === '_'
23
+ && original . property . name === 'chain' ) {
24
+ return true ;
25
+ }
26
+
27
+ return false ;
28
+ }
29
+
30
+ function isJQuery ( callee ) {
31
+ const original = getOriginalCallee ( callee ) ;
32
+
33
+ if ( original . type === 'Identifier' && ( original . name === '$' || original . name === 'jQuery' ) ) {
34
+ return true ;
35
+ }
36
+
37
+ // Support the popular convention of prefixing a variable with $ to show that
38
+ // it refers to a jQuery object: https://stackoverflow.com/a/553734
39
+ if ( original . type === 'MemberExpression' && original . object . type === 'Identifier' && original . object . name [ 0 ] === '$' ) {
40
+ return true ;
41
+ }
42
+
43
+ return false ;
44
+ }
45
+
46
+ function isPermitted ( callee ) {
47
+ return isLodash ( callee ) || isJQuery ( callee ) ;
48
+ }
49
+
3
50
module . exports = {
4
51
meta : {
5
52
docs : {
@@ -10,34 +57,32 @@ module.exports = {
10
57
create ( context ) {
11
58
return {
12
59
CallExpression ( node ) {
13
- const objectExceptions = [ '_' ] ;
14
- if ( node . callee && node . callee . property && objectExceptions . indexOf ( node . callee . object . name ) === - 1 ) {
15
- const functionName = node . callee . property . name ;
16
-
17
- const es6ArrayFunctions = [
18
- 'find' ,
19
- 'findIndex' ,
20
- 'copyWithin' ,
21
- 'values' ,
22
- 'fill'
23
- ] ;
24
- const es6StringFunctions = [
25
- 'startsWith' ,
26
- 'endsWith' ,
27
- 'includes' ,
28
- 'repeat'
29
- ] ;
30
-
31
- const es6Functions = [ ] . concat (
32
- es6ArrayFunctions ,
33
- es6StringFunctions
34
- ) ;
35
- if ( es6Functions . indexOf ( functionName ) > - 1 ) {
36
- context . report ( {
37
- node : node . callee . property ,
38
- message : 'ES6 methods not allowed: ' + functionName
39
- } ) ;
40
- }
60
+ if ( ! node . callee || ! node . callee . property ) {
61
+ return ;
62
+ }
63
+ const functionName = node . callee . property . name ;
64
+ const es6ArrayFunctions = [
65
+ 'find' ,
66
+ 'findIndex' ,
67
+ 'copyWithin' ,
68
+ 'values' ,
69
+ 'fill'
70
+ ] ;
71
+ const es6StringFunctions = [
72
+ 'startsWith' ,
73
+ 'endsWith' ,
74
+ 'includes' ,
75
+ 'repeat'
76
+ ] ;
77
+ const es6Functions = [ ] . concat (
78
+ es6ArrayFunctions ,
79
+ es6StringFunctions
80
+ ) ;
81
+ if ( es6Functions . indexOf ( functionName ) > - 1 && ! isPermitted ( node . callee ) ) {
82
+ context . report ( {
83
+ node : node . callee . property ,
84
+ message : 'ES6 methods not allowed: ' + functionName
85
+ } ) ;
41
86
}
42
87
}
43
88
} ;
0 commit comments