@@ -6,6 +6,7 @@ use crate::process::utils::is_valid_identifier;
6
6
use crate :: process:: { NodeProcessor , NodeVisitor } ;
7
7
8
8
use super :: utils:: { identifier_permutator, Permutator } ;
9
+ use super :: { NodePostProcessor , NodePostVisitor } ;
9
10
10
11
/// Defines methods to interact with the concept of lexical scoping. The struct implementing this
11
12
/// trait should be able to keep track of identifiers when used along the ScopeVisitor.
@@ -228,6 +229,226 @@ impl<T: NodeProcessor + Scope> NodeVisitor<T> for ScopeVisitor {
228
229
}
229
230
}
230
231
232
+ /// A visitor that can be used only with a NodeProcessor that also implements the Scope trait.
233
+ pub struct ScopePostVisitor ;
234
+
235
+ impl ScopePostVisitor {
236
+ fn visit_block_without_push < T : NodeProcessor + NodePostProcessor + Scope > (
237
+ block : & mut Block ,
238
+ scope : & mut T ,
239
+ ) {
240
+ scope. process_block ( block) ;
241
+
242
+ block
243
+ . iter_mut_statements ( )
244
+ . for_each ( |statement| Self :: visit_statement ( statement, scope) ) ;
245
+
246
+ if let Some ( last_statement) = block. mutate_last_statement ( ) {
247
+ Self :: visit_last_statement ( last_statement, scope) ;
248
+ } ;
249
+ scope. process_after_block ( block) ;
250
+ }
251
+ }
252
+
253
+ impl < T : NodeProcessor + NodePostProcessor + Scope > NodePostVisitor < T > for ScopePostVisitor {
254
+ fn visit_block ( block : & mut Block , scope : & mut T ) {
255
+ scope. push ( ) ;
256
+ Self :: visit_block_without_push ( block, scope) ;
257
+ scope. pop ( ) ;
258
+ }
259
+
260
+ fn visit_local_assign ( statement : & mut LocalAssignStatement , scope : & mut T ) {
261
+ scope. process_local_assign_statement ( statement) ;
262
+
263
+ statement
264
+ . iter_mut_values ( )
265
+ . for_each ( |value| Self :: visit_expression ( value, scope) ) ;
266
+
267
+ for r#type in statement
268
+ . iter_mut_variables ( )
269
+ . filter_map ( TypedIdentifier :: mutate_type)
270
+ {
271
+ Self :: visit_type ( r#type, scope) ;
272
+ }
273
+
274
+ statement. for_each_assignment ( |variable, expression| {
275
+ scope. insert_local ( variable. mutate_name ( ) , expression)
276
+ } ) ;
277
+
278
+ scope. process_after_local_assign_statement ( statement) ;
279
+ }
280
+
281
+ fn visit_function_expression ( function : & mut FunctionExpression , scope : & mut T ) {
282
+ scope. process_function_expression ( function) ;
283
+
284
+ for r#type in function
285
+ . iter_mut_parameters ( )
286
+ . filter_map ( TypedIdentifier :: mutate_type)
287
+ {
288
+ Self :: visit_type ( r#type, scope) ;
289
+ }
290
+
291
+ if let Some ( variadic_type) = function. mutate_variadic_type ( ) {
292
+ Self :: visit_function_variadic_type ( variadic_type, scope) ;
293
+ }
294
+
295
+ if let Some ( return_type) = function. mutate_return_type ( ) {
296
+ Self :: visit_function_return_type ( return_type, scope) ;
297
+ }
298
+
299
+ scope. push ( ) ;
300
+ function
301
+ . mutate_parameters ( )
302
+ . iter_mut ( )
303
+ . for_each ( |parameter| scope. insert ( parameter. mutate_name ( ) ) ) ;
304
+
305
+ scope. process_scope ( function. mutate_block ( ) , None ) ;
306
+
307
+ Self :: visit_block ( function. mutate_block ( ) , scope) ;
308
+ scope. pop ( ) ;
309
+
310
+ scope. process_after_function_expression ( function) ;
311
+ }
312
+
313
+ fn visit_function_statement ( statement : & mut FunctionStatement , scope : & mut T ) {
314
+ scope. process_function_statement ( statement) ;
315
+ scope. process_variable_expression ( statement. mutate_function_name ( ) . mutate_identifier ( ) ) ;
316
+
317
+ for r#type in statement
318
+ . iter_mut_parameters ( )
319
+ . filter_map ( TypedIdentifier :: mutate_type)
320
+ {
321
+ Self :: visit_type ( r#type, scope) ;
322
+ }
323
+
324
+ if let Some ( variadic_type) = statement. mutate_variadic_type ( ) {
325
+ Self :: visit_function_variadic_type ( variadic_type, scope) ;
326
+ }
327
+
328
+ if let Some ( return_type) = statement. mutate_return_type ( ) {
329
+ Self :: visit_function_return_type ( return_type, scope) ;
330
+ }
331
+
332
+ scope. push ( ) ;
333
+ if statement. get_name ( ) . has_method ( ) {
334
+ scope. insert_self ( ) ;
335
+ }
336
+ statement
337
+ . mutate_parameters ( )
338
+ . iter_mut ( )
339
+ . for_each ( |parameter| scope. insert ( parameter. mutate_name ( ) ) ) ;
340
+
341
+ scope. process_scope ( statement. mutate_block ( ) , None ) ;
342
+
343
+ Self :: visit_block ( statement. mutate_block ( ) , scope) ;
344
+ scope. pop ( ) ;
345
+
346
+ scope. process_after_function_statement ( statement) ;
347
+ }
348
+
349
+ fn visit_local_function ( statement : & mut LocalFunctionStatement , scope : & mut T ) {
350
+ scope. process_local_function_statement ( statement) ;
351
+
352
+ scope. insert_local_function ( statement) ;
353
+
354
+ for r#type in statement
355
+ . iter_mut_parameters ( )
356
+ . filter_map ( TypedIdentifier :: mutate_type)
357
+ {
358
+ Self :: visit_type ( r#type, scope) ;
359
+ }
360
+
361
+ if let Some ( variadic_type) = statement. mutate_variadic_type ( ) {
362
+ Self :: visit_function_variadic_type ( variadic_type, scope) ;
363
+ }
364
+
365
+ if let Some ( return_type) = statement. mutate_return_type ( ) {
366
+ Self :: visit_function_return_type ( return_type, scope) ;
367
+ }
368
+
369
+ scope. push ( ) ;
370
+ statement
371
+ . mutate_parameters ( )
372
+ . iter_mut ( )
373
+ . for_each ( |parameter| scope. insert ( parameter. mutate_name ( ) ) ) ;
374
+
375
+ scope. process_scope ( statement. mutate_block ( ) , None ) ;
376
+
377
+ Self :: visit_block ( statement. mutate_block ( ) , scope) ;
378
+ scope. pop ( ) ;
379
+
380
+ scope. process_after_local_function_statement ( statement) ;
381
+ }
382
+
383
+ fn visit_generic_for ( statement : & mut GenericForStatement , scope : & mut T ) {
384
+ scope. process_generic_for_statement ( statement) ;
385
+
386
+ statement
387
+ . iter_mut_expressions ( )
388
+ . for_each ( |expression| Self :: visit_expression ( expression, scope) ) ;
389
+
390
+ scope. push ( ) ;
391
+ statement
392
+ . iter_mut_identifiers ( )
393
+ . for_each ( |identifier| scope. insert ( identifier. mutate_name ( ) ) ) ;
394
+
395
+ for r#type in statement
396
+ . iter_mut_identifiers ( )
397
+ . filter_map ( TypedIdentifier :: mutate_type)
398
+ {
399
+ Self :: visit_type ( r#type, scope) ;
400
+ }
401
+
402
+ scope. process_scope ( statement. mutate_block ( ) , None ) ;
403
+
404
+ Self :: visit_block ( statement. mutate_block ( ) , scope) ;
405
+ scope. pop ( ) ;
406
+
407
+ scope. process_after_generic_for_statement ( statement) ;
408
+ }
409
+
410
+ fn visit_numeric_for ( statement : & mut NumericForStatement , scope : & mut T ) {
411
+ scope. process_numeric_for_statement ( statement) ;
412
+
413
+ Self :: visit_expression ( statement. mutate_start ( ) , scope) ;
414
+ Self :: visit_expression ( statement. mutate_end ( ) , scope) ;
415
+
416
+ if let Some ( step) = statement. mutate_step ( ) {
417
+ Self :: visit_expression ( step, scope) ;
418
+ } ;
419
+
420
+ if let Some ( r#type) = statement. mutate_identifier ( ) . mutate_type ( ) {
421
+ Self :: visit_type ( r#type, scope) ;
422
+ }
423
+
424
+ scope. push ( ) ;
425
+ scope. insert ( statement. mutate_identifier ( ) . mutate_name ( ) ) ;
426
+
427
+ scope. process_scope ( statement. mutate_block ( ) , None ) ;
428
+
429
+ Self :: visit_block ( statement. mutate_block ( ) , scope) ;
430
+ scope. pop ( ) ;
431
+
432
+ scope. process_after_numeric_for_statement ( statement) ;
433
+ }
434
+
435
+ fn visit_repeat_statement ( statement : & mut RepeatStatement , scope : & mut T ) {
436
+ scope. process_repeat_statement ( statement) ;
437
+
438
+ scope. push ( ) ;
439
+
440
+ let ( block, condition) = statement. mutate_block_and_condition ( ) ;
441
+ scope. process_scope ( block, Some ( condition) ) ;
442
+
443
+ Self :: visit_block_without_push ( statement. mutate_block ( ) , scope) ;
444
+ Self :: visit_expression ( statement. mutate_condition ( ) , scope) ;
445
+
446
+ scope. pop ( ) ;
447
+
448
+ scope. process_after_repeat_statement ( statement) ;
449
+ }
450
+ }
451
+
231
452
#[ derive( Debug , Clone , Default ) ]
232
453
pub ( crate ) struct IdentifierTracker {
233
454
identifiers : Vec < HashSet < String > > ,
0 commit comments