@@ -27,10 +27,14 @@ function checkFuncLen(path) {
27
27
if ( obj . node . properties [ 0 ] ?. key ?. name !== 'value' ) {
28
28
return null
29
29
}
30
- if ( obj . listKey !== 'arguments' || obj . key !== 2 ) {
30
+ if ( obj . listKey !== 'arguments' ) {
31
31
return null
32
32
}
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
34
38
const warp = obj . getFunctionParent ( )
35
39
if ( warp . node . params ?. [ 0 ] ?. name !== func_name ) {
36
40
return null
@@ -149,10 +153,9 @@ function processReplace(cache, path, prop_name) {
149
153
return false
150
154
}
151
155
152
- function checkStackInvalid ( path ) {
156
+ function checkStackInvalid ( path , invalid ) {
153
157
const stk_name = path . node . params [ 0 ] . argument . name
154
158
const body_path = path . get ( 'body' )
155
- const obj = { }
156
159
body_path . traverse ( {
157
160
MemberExpression : {
158
161
exit ( path ) {
@@ -163,7 +166,7 @@ function checkStackInvalid(path) {
163
166
const prop = path . get ( 'property' )
164
167
const prop_name = safeGetName ( prop )
165
168
if ( father . isUpdateExpression ( ) ) {
166
- obj [ prop_name ] = 1
169
+ invalid [ prop_name ] = 1
167
170
return
168
171
}
169
172
if ( body_path . scope == father . scope ) {
@@ -172,14 +175,24 @@ function checkStackInvalid(path) {
172
175
if ( ! father . isAssignmentExpression ( ) || path . key !== 'left' ) {
173
176
return
174
177
}
175
- obj [ prop_name ] = 1
178
+ invalid [ prop_name ] = 1
176
179
} ,
177
180
} ,
178
181
} )
179
- return obj
182
+ return invalid
180
183
}
181
184
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 ) {
183
196
const stk_name = path . node . params [ 0 ] . argument . name
184
197
const body_path = path . get ( 'body' )
185
198
const cache = initStackCache ( len )
@@ -212,6 +225,7 @@ function tryStackReplace(path, len, invalid) {
212
225
if ( father . isAssignmentExpression ( ) && path . key === 'left' ) {
213
226
processAssignLeft ( vm , cache , path , prop_name , stk_name )
214
227
} else if ( exist ) {
228
+ used [ prop_name ] = 1
215
229
changed |= processReplace ( cache , path , prop_name )
216
230
}
217
231
} ,
@@ -264,16 +278,23 @@ function getStackParamLen(path) {
264
278
265
279
function processStackParam ( path , len ) {
266
280
if ( path . isArrowFunctionExpression ( ) ) {
267
- console . log ( `Process arrowFunctionExpression, len: ${ len } ` )
281
+ console . log ( `[Stack] Process arrowFunctionExpression, len: ${ len } ` )
268
282
} else if ( path . isFunctionExpression ( ) ) {
269
- console . log ( `Process functionExpression, len: ${ len } ` )
283
+ console . log ( `[Stack] Process functionExpression, len: ${ len } ` )
270
284
} else {
271
- console . log ( `Process Function ${ path . node . id . name } , len: ${ len } ` )
285
+ console . log ( `[Stack] Process Function ${ path . node . id . name } , len: ${ len } ` )
272
286
}
287
+ const orig_code = generator ( path . node ) . code
273
288
let changed = true
274
- const invalid = checkStackInvalid ( path )
289
+ const invalid = { }
290
+ let used = { }
275
291
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 )
277
298
path . traverse ( calculateConstantExp )
278
299
}
279
300
}
@@ -284,11 +305,11 @@ const deStackFuncLen = {
284
305
if ( ! obj ) {
285
306
return
286
307
}
287
- console . log ( `Find functionLengthName: ${ obj . name } ` )
308
+ console . log ( `[Stack] Find functionLengthName: ${ obj . name } ` )
288
309
let binding = obj . path . parentPath . scope . bindings [ obj . name ]
289
310
for ( const ref of binding . referencePaths ) {
290
311
if ( ref . key !== 'callee' ) {
291
- console . warn ( `Unexpected ref of functionLengthName: ${ obj . name } ` )
312
+ console . warn ( `[Stack] Unexpected ref of functionLengthName: ${ obj . name } ` )
292
313
continue
293
314
}
294
315
const repl_path = ref . parentPath
0 commit comments