@@ -45,6 +45,36 @@ module.exports = {
4545 }
4646 }
4747
48+ /**
49+ * Walks throughs the MemberExpression to the top-most property.
50+ * @param {Object } node The node to process
51+ * @returns {Object } The outer-most MemberExpression
52+ */
53+ function getOuterMemberExpression ( node ) {
54+ while ( node . object && node . object . property ) {
55+ node = node . object ;
56+ }
57+ return node ;
58+ }
59+
60+ /**
61+ * Determine if this MemberExpression is for `this.state`
62+ * @param {Object } node The node to process
63+ * @returns {Boolean }
64+ */
65+ function isStateMemberExpression ( node ) {
66+ return node . object . type === 'ThisExpression' && node . property . name === 'state' ;
67+ }
68+
69+ /**
70+ * Determine if we should currently ignore assignments in this component.
71+ * @param {?Object } component The component to process
72+ * @returns {Boolean } True if we should skip assignment checks.
73+ */
74+ function shouldIgnoreComponent ( component ) {
75+ return ! component || ( component . inConstructor && ! component . inCallExpression ) ;
76+ }
77+
4878 // --------------------------------------------------------------------------
4979 // Public
5080 // --------------------------------------------------------------------------
@@ -64,19 +94,12 @@ module.exports = {
6494 } ,
6595
6696 AssignmentExpression ( node ) {
67- let item ;
6897 const component = components . get ( utils . getParentComponent ( ) ) ;
69- if ( ! component || ( component . inConstructor && ! component . inCallExpression ) || ! node . left || ! node . left . object ) {
98+ if ( shouldIgnoreComponent ( component ) || ! node . left || ! node . left . object ) {
7099 return ;
71100 }
72- item = node . left ;
73- while ( item . object && item . object . property ) {
74- item = item . object ;
75- }
76- if (
77- item . object . type === 'ThisExpression' &&
78- item . property . name === 'state'
79- ) {
101+ const item = getOuterMemberExpression ( node . left ) ;
102+ if ( isStateMemberExpression ( item ) ) {
80103 const mutations = ( component && component . mutations ) || [ ] ;
81104 mutations . push ( node . left . object ) ;
82105 components . set ( node , {
@@ -86,6 +109,22 @@ module.exports = {
86109 }
87110 } ,
88111
112+ UpdateExpression ( node ) {
113+ const component = components . get ( utils . getParentComponent ( ) ) ;
114+ if ( shouldIgnoreComponent ( component ) || node . argument . type !== 'MemberExpression' ) {
115+ return ;
116+ }
117+ const item = getOuterMemberExpression ( node . argument ) ;
118+ if ( isStateMemberExpression ( item ) ) {
119+ const mutations = ( component && component . mutations ) || [ ] ;
120+ mutations . push ( item ) ;
121+ components . set ( node , {
122+ mutateSetState : true ,
123+ mutations
124+ } ) ;
125+ }
126+ } ,
127+
89128 'CallExpression:exit' : function ( node ) {
90129 components . set ( node , {
91130 inCallExpression : false
0 commit comments