@@ -45,6 +45,36 @@ module.exports = {
45
45
}
46
46
}
47
47
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
+
48
78
// --------------------------------------------------------------------------
49
79
// Public
50
80
// --------------------------------------------------------------------------
@@ -64,19 +94,12 @@ module.exports = {
64
94
} ,
65
95
66
96
AssignmentExpression ( node ) {
67
- let item ;
68
97
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 ) {
70
99
return ;
71
100
}
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 ) ) {
80
103
const mutations = ( component && component . mutations ) || [ ] ;
81
104
mutations . push ( node . left . object ) ;
82
105
components . set ( node , {
@@ -86,6 +109,22 @@ module.exports = {
86
109
}
87
110
} ,
88
111
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
+
89
128
'CallExpression:exit' : function ( node ) {
90
129
components . set ( node , {
91
130
inCallExpression : false
0 commit comments