@@ -7,6 +7,7 @@ import { convert } from '../../generator'
7
7
import { redex } from '../..'
8
8
import { StepperArrowFunctionExpression } from '../Expression/ArrowFunctionExpression'
9
9
import { getFreshName } from '../../utils'
10
+ import { StepperVariableDeclaration } from './VariableDeclaration'
10
11
11
12
export class StepperFunctionDeclaration implements FunctionDeclaration , StepperBaseNode {
12
13
type : 'FunctionDeclaration'
@@ -33,16 +34,23 @@ export class StepperFunctionDeclaration implements FunctionDeclaration, StepperB
33
34
) {
34
35
this . type = 'FunctionDeclaration'
35
36
this . id = id
36
- this . body = body
37
37
this . params = params
38
38
this . generator = generator
39
39
this . async = async
40
40
this . leadingComments = leadingComments
41
41
this . trailingComments = trailingComments
42
42
this . loc = loc
43
43
this . range = range
44
- }
45
44
45
+
46
+ const repeatedNames = body . scanAllDeclarationNames ( ) . filter ( name => name === this . id . name ) ;
47
+ const newNames = getFreshName ( [ this . id . name ] , repeatedNames )
48
+ let currentBlockStatement = body
49
+ for ( var index in newNames ) {
50
+ currentBlockStatement = currentBlockStatement . rename ( repeatedNames [ index ] , newNames [ index ] )
51
+ }
52
+ this . body = currentBlockStatement ;
53
+ }
46
54
static create ( node : FunctionDeclaration ) {
47
55
return new StepperFunctionDeclaration (
48
56
convert ( node . id ) as StepperIdentifier ,
@@ -94,25 +102,37 @@ export class StepperFunctionDeclaration implements FunctionDeclaration, StepperB
94
102
scanAllDeclarationNames ( ) : string [ ] {
95
103
const paramNames = this . params . map ( param => param . name )
96
104
const bodyDeclarations = this . body . body
97
- . filter ( stmt => stmt . type === 'VariableDeclaration' )
98
- . flatMap ( decl => ( decl as any ) . declarations . map ( ( d : any ) => d . id . name ) )
99
-
105
+ . filter ( ast => ast . type === 'VariableDeclaration' || ast . type === 'FunctionDeclaration' )
106
+ . flatMap ( ( ast : StepperVariableDeclaration | StepperFunctionDeclaration ) => {
107
+ if ( ast . type === 'VariableDeclaration' ) {
108
+ return ast . declarations . map ( ast => ast . id . name )
109
+ } else {
110
+ // Function Declaration
111
+ return [ ( ast as StepperFunctionDeclaration ) . id . name ]
112
+ }
113
+ } )
100
114
return [ ...paramNames , ...bodyDeclarations ]
101
115
}
102
116
103
- substitute ( id : StepperPattern , value : StepperExpression , upperBoundName ?: string [ ] ) : StepperBaseNode {
117
+ substitute (
118
+ id : StepperPattern ,
119
+ value : StepperExpression ,
120
+ upperBoundName ?: string [ ]
121
+ ) : StepperBaseNode {
104
122
const valueFreeNames = value . freeNames ( )
105
123
const scopeNames = this . scanAllDeclarationNames ( )
106
124
const repeatedNames = valueFreeNames . filter ( name => scopeNames . includes ( name ) )
107
125
108
- var currentFunction : StepperFunctionDeclaration = this ;
109
- let protectedNamesSet = new Set ( [ this . allNames ( ) , upperBoundName ?? [ ] ] . flat ( ) ) ;
110
- repeatedNames . forEach ( name => protectedNamesSet . delete ( name ) ) ;
111
- const protectedNames = Array . from ( protectedNamesSet ) ;
112
- const newNames = getFreshName ( repeatedNames , protectedNames ) ;
126
+ var currentFunction : StepperFunctionDeclaration = this
127
+ let protectedNamesSet = new Set ( [ this . allNames ( ) , upperBoundName ?? [ ] ] . flat ( ) )
128
+ repeatedNames . forEach ( name => protectedNamesSet . delete ( name ) )
129
+ const protectedNames = Array . from ( protectedNamesSet )
130
+ const newNames = getFreshName ( repeatedNames , protectedNames )
113
131
for ( var index in newNames ) {
114
- currentFunction = currentFunction
115
- . rename ( repeatedNames [ index ] , newNames [ index ] ) as StepperFunctionDeclaration
132
+ currentFunction = currentFunction . rename (
133
+ repeatedNames [ index ] ,
134
+ newNames [ index ]
135
+ ) as StepperFunctionDeclaration
116
136
}
117
137
118
138
if ( currentFunction . scanAllDeclarationNames ( ) . includes ( id . name ) ) {
@@ -141,12 +161,12 @@ export class StepperFunctionDeclaration implements FunctionDeclaration, StepperB
141
161
const paramNames = this . params
142
162
. filter ( param => param . type === 'Identifier' )
143
163
. map ( param => param . name )
144
- return Array . from ( new Set ( [ paramNames , this . body . allNames ( ) ] . flat ( ) ) ) ;
164
+ return Array . from ( new Set ( [ paramNames , this . body . allNames ( ) ] . flat ( ) ) )
145
165
}
146
166
147
167
rename ( before : string , after : string ) : StepperFunctionDeclaration {
148
168
return new StepperFunctionDeclaration (
149
- this . id ,
169
+ this . id . rename ( before , after ) ,
150
170
this . body . rename ( before , after ) as unknown as StepperBlockStatement ,
151
171
this . params . map ( param => param . rename ( before , after ) )
152
172
)
0 commit comments