44 */
55'use strict' ;
66
7+ var Components = require ( '../util/Components' ) ;
8+
79// ------------------------------------------------------------------------------
810// Rule Definition
911// ------------------------------------------------------------------------------
@@ -18,7 +20,31 @@ module.exports = {
1820 schema : [ ]
1921 } ,
2022
21- create : function ( context ) {
23+ create : Components . detect ( function ( context , components , utils ) {
24+
25+ /**
26+ * Checks if the component is valid
27+ * @param {Object } component The component to process
28+ * @returns {Boolean } True if the component is valid, false if not.
29+ */
30+ function isValid ( component ) {
31+ return Boolean ( component && ! component . useSetState ) ;
32+ }
33+
34+ /**
35+ * Reports usages of setState for a given component
36+ * @param {Object } component The component to process
37+ */
38+ function reportSetStateUsages ( component ) {
39+ var setStateUsage ;
40+ for ( var i = 0 , j = component . setStateUsages . length ; i < j ; i ++ ) {
41+ setStateUsage = component . setStateUsages [ i ] ;
42+ context . report ( {
43+ node : setStateUsage ,
44+ message : 'Do not use setState'
45+ } ) ;
46+ }
47+ }
2248
2349 // --------------------------------------------------------------------------
2450 // Public
@@ -28,24 +54,31 @@ module.exports = {
2854
2955 CallExpression : function ( node ) {
3056 var callee = node . callee ;
31- if ( callee . type !== 'MemberExpression' ) {
57+ if (
58+ callee . type !== 'MemberExpression' ||
59+ callee . object . type !== 'ThisExpression' ||
60+ callee . property . name !== 'setState'
61+ ) {
3262 return ;
3363 }
34- if ( callee . object . type !== 'ThisExpression' || callee . property . name !== 'setState' ) {
35- return ;
36- }
37- var ancestors = context . getAncestors ( callee ) ;
38- for ( var i = 0 , j = ancestors . length ; i < j ; i ++ ) {
39- if ( ancestors [ i ] . type === 'Property' || ancestors [ i ] . type === 'MethodDefinition' ) {
40- context . report ( {
41- node : callee ,
42- message : 'Do not use setState'
43- } ) ;
44- break ;
64+ var component = components . get ( utils . getParentComponent ( ) ) ;
65+ var setStateUsages = component && component . setStateUsages || [ ] ;
66+ setStateUsages . push ( callee ) ;
67+ components . set ( node , {
68+ useSetState : true ,
69+ setStateUsages : setStateUsages
70+ } ) ;
71+ } ,
72+
73+ 'Program:exit' : function ( ) {
74+ var list = components . list ( ) ;
75+ for ( var component in list ) {
76+ if ( ! list . hasOwnProperty ( component ) || isValid ( list [ component ] ) ) {
77+ continue ;
4578 }
79+ reportSetStateUsages ( list [ component ] ) ;
4680 }
4781 }
4882 } ;
49-
50- }
83+ } )
5184} ;
0 commit comments