@@ -172,22 +172,52 @@ function findVariableInScope(scope, variableName) {
172172 return null
173173}
174174
175- function getRootIdentifier ( node ) {
176- if ( ! node ) return null
175+ function getRootIdentifiers ( node ) {
176+ if ( ! node ) return [ ]
177177
178178 if ( node . type === 'ChainExpression' ) {
179- return getRootIdentifier ( node . expression )
179+ return getRootIdentifiers ( node . expression )
180180 }
181181
182182 if ( node . type === 'Identifier' ) {
183- return node
183+ return [ node ]
184184 }
185185
186186 if ( node . type === 'MemberExpression' ) {
187- return getRootIdentifier ( node . object )
187+ return getRootIdentifiers ( node . object )
188188 }
189189
190- return null
190+ if ( node . type === 'ObjectPattern' ) {
191+ let identifiers = [ ]
192+ for ( const property of node . properties ) {
193+ if ( ! property ) continue
194+ if ( property . type === 'Property' ) {
195+ identifiers = identifiers . concat ( getRootIdentifiers ( property . value ) )
196+ } else if ( property . type === 'RestElement' ) {
197+ identifiers = identifiers . concat ( getRootIdentifiers ( property . argument ) )
198+ }
199+ }
200+ return identifiers
201+ }
202+
203+ if ( node . type === 'ArrayPattern' ) {
204+ let identifiers = [ ]
205+ for ( const element of node . elements ) {
206+ if ( ! element ) continue
207+ identifiers = identifiers . concat ( getRootIdentifiers ( element ) )
208+ }
209+ return identifiers
210+ }
211+
212+ if ( node . type === 'AssignmentPattern' ) {
213+ return getRootIdentifiers ( node . left )
214+ }
215+
216+ if ( node . type === 'RestElement' ) {
217+ return getRootIdentifiers ( node . argument )
218+ }
219+
220+ return [ ]
191221}
192222
193223function writesOuterState ( callbackNode , sourceCode ) {
@@ -204,20 +234,23 @@ function writesOuterState(callbackNode, sourceCode) {
204234 }
205235
206236 if ( ! writeTarget ) return
207- const rootIdentifier = getRootIdentifier ( writeTarget )
208- if ( ! rootIdentifier ) return
237+ const rootIdentifiers = getRootIdentifiers ( writeTarget )
238+ if ( ! rootIdentifiers . length ) return
209239
210- const identifierScope = sourceCode . getScope ( rootIdentifier )
211- const variable = findVariableInScope ( identifierScope , rootIdentifier . name )
240+ for ( const rootIdentifier of rootIdentifiers ) {
241+ const identifierScope = sourceCode . getScope ( rootIdentifier )
242+ const variable = findVariableInScope ( identifierScope , rootIdentifier . name )
212243
213- // If this is an unresolved/global write, treat it as shared mutable state.
214- if ( ! variable ) {
215- writesOuterValue = true
216- return
217- }
244+ // If this is an unresolved/global write, treat it as shared mutable state.
245+ if ( ! variable ) {
246+ writesOuterValue = true
247+ return
248+ }
218249
219- if ( ! isVariableDefinedInNode ( variable , callbackNode ) ) {
220- writesOuterValue = true
250+ if ( ! isVariableDefinedInNode ( variable , callbackNode ) ) {
251+ writesOuterValue = true
252+ return
253+ }
221254 }
222255 } )
223256
0 commit comments