@@ -27,10 +27,14 @@ function checkFuncLen(path) {
2727 if ( obj . node . properties [ 0 ] ?. key ?. name !== 'value' ) {
2828 return null
2929 }
30- if ( obj . listKey !== 'arguments' || obj . key !== 2 ) {
30+ if ( obj . listKey !== 'arguments' ) {
3131 return null
3232 }
33- const func_name = obj . container [ 0 ] ?. name
33+ const arg_num = obj . container . length
34+ if ( obj . key !== arg_num - 1 ) {
35+ return null
36+ }
37+ const func_name = obj . container [ arg_num - 3 ] ?. name
3438 const warp = obj . getFunctionParent ( )
3539 if ( warp . node . params ?. [ 0 ] ?. name !== func_name ) {
3640 return null
@@ -149,10 +153,9 @@ function processReplace(cache, path, prop_name) {
149153 return false
150154}
151155
152- function checkStackInvalid ( path ) {
156+ function checkStackInvalid ( path , invalid ) {
153157 const stk_name = path . node . params [ 0 ] . argument . name
154158 const body_path = path . get ( 'body' )
155- const obj = { }
156159 body_path . traverse ( {
157160 MemberExpression : {
158161 exit ( path ) {
@@ -163,7 +166,7 @@ function checkStackInvalid(path) {
163166 const prop = path . get ( 'property' )
164167 const prop_name = safeGetName ( prop )
165168 if ( father . isUpdateExpression ( ) ) {
166- obj [ prop_name ] = 1
169+ invalid [ prop_name ] = 1
167170 return
168171 }
169172 if ( body_path . scope == father . scope ) {
@@ -172,14 +175,24 @@ function checkStackInvalid(path) {
172175 if ( ! father . isAssignmentExpression ( ) || path . key !== 'left' ) {
173176 return
174177 }
175- obj [ prop_name ] = 1
178+ invalid [ prop_name ] = 1
176179 } ,
177180 } ,
178181 } )
179- return obj
182+ return invalid
180183}
181184
182- function tryStackReplace ( path , len , invalid ) {
185+ function checkChangeValid ( invalid , used ) {
186+ let valid = true
187+ Object . keys ( used ) . forEach ( function ( key ) {
188+ if ( Object . prototype . hasOwnProperty . call ( invalid , key ) ) {
189+ valid = false
190+ }
191+ } )
192+ return valid
193+ }
194+
195+ function tryStackReplace ( path , len , invalid , used ) {
183196 const stk_name = path . node . params [ 0 ] . argument . name
184197 const body_path = path . get ( 'body' )
185198 const cache = initStackCache ( len )
@@ -212,6 +225,7 @@ function tryStackReplace(path, len, invalid) {
212225 if ( father . isAssignmentExpression ( ) && path . key === 'left' ) {
213226 processAssignLeft ( vm , cache , path , prop_name , stk_name )
214227 } else if ( exist ) {
228+ used [ prop_name ] = 1
215229 changed |= processReplace ( cache , path , prop_name )
216230 }
217231 } ,
@@ -264,16 +278,23 @@ function getStackParamLen(path) {
264278
265279function processStackParam ( path , len ) {
266280 if ( path . isArrowFunctionExpression ( ) ) {
267- console . log ( `Process arrowFunctionExpression, len: ${ len } ` )
281+ console . log ( `[Stack] Process arrowFunctionExpression, len: ${ len } ` )
268282 } else if ( path . isFunctionExpression ( ) ) {
269- console . log ( `Process functionExpression, len: ${ len } ` )
283+ console . log ( `[Stack] Process functionExpression, len: ${ len } ` )
270284 } else {
271- console . log ( `Process Function ${ path . node . id . name } , len: ${ len } ` )
285+ console . log ( `[Stack] Process Function ${ path . node . id . name } , len: ${ len } ` )
272286 }
287+ const orig_code = generator ( path . node ) . code
273288 let changed = true
274- const invalid = checkStackInvalid ( path )
289+ const invalid = { }
290+ let used = { }
275291 while ( changed ) {
276- changed = tryStackReplace ( path , len , invalid )
292+ checkStackInvalid ( path , invalid )
293+ if ( ! checkChangeValid ( invalid , used ) ) {
294+ path . replaceWith ( prase ( orig_code ) )
295+ used = { }
296+ }
297+ changed = tryStackReplace ( path , len , invalid , used )
277298 path . traverse ( calculateConstantExp )
278299 }
279300}
@@ -284,11 +305,11 @@ const deStackFuncLen = {
284305 if ( ! obj ) {
285306 return
286307 }
287- console . log ( `Find functionLengthName: ${ obj . name } ` )
308+ console . log ( `[Stack] Find functionLengthName: ${ obj . name } ` )
288309 let binding = obj . path . parentPath . scope . bindings [ obj . name ]
289310 for ( const ref of binding . referencePaths ) {
290311 if ( ref . key !== 'callee' ) {
291- console . warn ( `Unexpected ref of functionLengthName: ${ obj . name } ` )
312+ console . warn ( `[Stack] Unexpected ref of functionLengthName: ${ obj . name } ` )
292313 continue
293314 }
294315 const repl_path = ref . parentPath
0 commit comments