4
4
*/
5
5
'use strict' ;
6
6
7
+ var componentUtil = require ( '../util/component' ) ;
8
+ var ComponentList = componentUtil . List ;
9
+
7
10
// ------------------------------------------------------------------------------
8
11
// Rule Definition
9
12
// ------------------------------------------------------------------------------
10
13
11
14
module . exports = function ( context ) {
12
15
16
+ var componentList = new ComponentList ( ) ;
17
+
18
+ /**
19
+ * Checks if the component is valid
20
+ * @param {Object } component The component to process
21
+ * @returns {Boolean } True if the component is valid, false if not.
22
+ */
23
+ function isValid ( component ) {
24
+ var isNotReactComponent = Boolean ( component && ! component . isReactComponent ) ;
25
+ var doNotMutateSetState = Boolean ( component && ! component . mutateSetState ) ;
26
+
27
+ return isNotReactComponent || doNotMutateSetState ;
28
+ }
29
+
30
+ /**
31
+ * Reports undeclared proptypes for a given component
32
+ * @param {Object } component The component to process
33
+ */
34
+ function reportMutations ( component ) {
35
+ var mutation ;
36
+ for ( var i = 0 , j = component . mutations . length ; i < j ; i ++ ) {
37
+ mutation = component . mutations [ i ] ;
38
+ context . report ( mutation , 'Do not mutate state directly. Use setState().' ) ;
39
+ }
40
+ }
41
+
13
42
// --------------------------------------------------------------------------
14
43
// Public
15
44
// --------------------------------------------------------------------------
@@ -29,8 +58,33 @@ module.exports = function(context) {
29
58
item . object . type === 'ThisExpression' &&
30
59
item . property . name === 'state'
31
60
) {
32
- context . report ( node . left . object , 'Do not mutate state directly. Use setState().' ) ;
61
+ var component = componentList . getByNode ( context , node ) ;
62
+ var mutations = component && component . mutations || [ ] ;
63
+ mutations . push ( node . left . object ) ;
64
+ componentList . set ( context , node , {
65
+ mutateSetState : true ,
66
+ mutations : mutations
67
+ } ) ;
68
+ }
69
+ } ,
70
+
71
+ 'Program:exit' : function ( ) {
72
+ var list = componentList . getList ( ) ;
73
+ for ( var component in list ) {
74
+ if ( ! list . hasOwnProperty ( component ) || isValid ( list [ component ] ) ) {
75
+ continue ;
76
+ }
77
+ reportMutations ( list [ component ] ) ;
78
+ }
79
+ } ,
80
+
81
+ ReturnStatement : function ( node ) {
82
+ if ( ! componentUtil . isReactComponent ( context , node ) ) {
83
+ return ;
33
84
}
85
+ componentList . set ( context , node , {
86
+ isReactComponent : true
87
+ } ) ;
34
88
}
35
89
} ;
36
90
0 commit comments