44 */
55'use strict' ;
66
7+ var componentUtil = require ( '../util/component' ) ;
8+ var ComponentList = componentUtil . List ;
9+
710// ------------------------------------------------------------------------------
811// Rule Definition
912// ------------------------------------------------------------------------------
1013
1114module . exports = function ( context ) {
1215
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+
1342 // --------------------------------------------------------------------------
1443 // Public
1544 // --------------------------------------------------------------------------
@@ -29,8 +58,33 @@ module.exports = function(context) {
2958 item . object . type === 'ThisExpression' &&
3059 item . property . name === 'state'
3160 ) {
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 ;
3384 }
85+ componentList . set ( context , node , {
86+ isReactComponent : true
87+ } ) ;
3488 }
3589 } ;
3690
0 commit comments