@@ -118,11 +118,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
118
118
descend ( ) ;
119
119
scope = save_scope ;
120
120
defun = save_defun ;
121
- return true ; // don't descend again in TreeWalker
121
+ return true ;
122
122
}
123
123
if ( node instanceof AST_With ) {
124
- for ( var s = scope ; s ; s = s . parent_scope )
125
- s . uses_with = true ;
124
+ for ( var s = scope ; s ; s = s . parent_scope ) s . uses_with = true ;
126
125
return ;
127
126
}
128
127
if ( node instanceof AST_Symbol ) {
@@ -132,18 +131,13 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
132
131
node . thedef = node ;
133
132
node . references = [ ] ;
134
133
}
135
- if ( node instanceof AST_SymbolDefun || options . ie8 && node instanceof AST_SymbolLambda ) {
136
- // Careful here, the scope where this should be defined is
137
- // the parent scope. The reason is that we enter a new
138
- // scope when we encounter the AST_Defun node (which is
139
- // instanceof AST_Scope) but we get to the symbol a bit
140
- // later.
141
- ( node . scope = defun . parent_scope ) . def_function ( node , defun ) ;
142
- }
143
- else if ( node instanceof AST_SymbolLambda ) {
134
+ if ( node instanceof AST_SymbolDefun ) {
135
+ // This should be defined in the parent scope, as we encounter the
136
+ // AST_Defun node before getting to its AST_Symbol.
137
+ ( node . scope = defun . parent_scope . resolve ( ) ) . def_function ( node , defun ) ;
138
+ } else if ( node instanceof AST_SymbolLambda ) {
144
139
defun . def_function ( node , node . name == "arguments" ? undefined : defun ) ;
145
- }
146
- else if ( node instanceof AST_SymbolVar ) {
140
+ } else if ( node instanceof AST_SymbolVar ) {
147
141
defun . def_variable ( node , node . TYPE == "SymbolVar" ? null : undefined ) ;
148
142
if ( defun !== scope ) {
149
143
node . mark_enclosed ( options ) ;
@@ -153,18 +147,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
153
147
}
154
148
node . reference ( options ) ;
155
149
}
156
- }
157
- else if ( node instanceof AST_SymbolCatch ) {
150
+ } else if ( node instanceof AST_SymbolCatch ) {
158
151
scope . def_variable ( node ) . defun = defun ;
159
152
}
160
153
} ) ;
161
154
self . walk ( tw ) ;
162
155
163
156
// pass 2: find back references and eval
164
157
self . globals = new Dictionary ( ) ;
165
- var tw = new TreeWalker ( function ( node , descend ) {
166
- if ( node instanceof AST_LoopControl && node . label ) {
167
- node . label . thedef . references . push ( node ) ;
158
+ var tw = new TreeWalker ( function ( node ) {
159
+ if ( node instanceof AST_LoopControl ) {
160
+ if ( node . label ) node . label . thedef . references . push ( node ) ;
168
161
return true ;
169
162
}
170
163
if ( node instanceof AST_SymbolRef ) {
@@ -185,35 +178,43 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options) {
185
178
return true ;
186
179
}
187
180
// ensure mangling works if catch reuses a scope variable
188
- var def ;
189
- if ( node instanceof AST_SymbolCatch && ( def = node . definition ( ) . redefined ( ) ) ) {
190
- var s = node . scope ;
191
- while ( s ) {
181
+ if ( node instanceof AST_SymbolCatch ) {
182
+ var def = node . definition ( ) . redefined ( ) ;
183
+ if ( def ) for ( var s = node . scope ; s ; s = s . parent_scope ) {
192
184
push_uniq ( s . enclosed , def ) ;
193
185
if ( s === def . scope ) break ;
194
- s = s . parent_scope ;
195
186
}
187
+ return true ;
196
188
}
197
189
} ) ;
198
190
self . walk ( tw ) ;
199
191
200
192
// pass 3: fix up any scoping issue with IE8
201
- if ( options . ie8 ) {
202
- self . walk ( new TreeWalker ( function ( node , descend ) {
203
- if ( node instanceof AST_SymbolCatch ) {
204
- var name = node . name ;
205
- var refs = node . thedef . references ;
206
- var scope = node . thedef . defun ;
207
- var def = scope . find_variable ( name ) || self . globals . get ( name ) || scope . def_variable ( node ) ;
208
- refs . forEach ( function ( ref ) {
209
- ref . thedef = def ;
210
- ref . reference ( options ) ;
211
- } ) ;
212
- node . thedef = def ;
213
- node . reference ( options ) ;
214
- return true ;
193
+ if ( options . ie8 ) self . walk ( new TreeWalker ( function ( node ) {
194
+ if ( node instanceof AST_SymbolCatch ) {
195
+ redefine ( node , node . thedef . defun ) ;
196
+ return true ;
197
+ }
198
+ if ( node instanceof AST_SymbolLambda ) {
199
+ var def = node . thedef ;
200
+ if ( def . orig . length == 1 ) {
201
+ redefine ( node , node . scope . parent_scope ) ;
202
+ node . thedef . init = def . init ;
215
203
}
216
- } ) ) ;
204
+ return true ;
205
+ }
206
+ } ) ) ;
207
+
208
+ function redefine ( node , scope ) {
209
+ var name = node . name ;
210
+ var refs = node . thedef . references ;
211
+ var def = scope . find_variable ( name ) || self . globals . get ( name ) || scope . def_variable ( node ) ;
212
+ refs . forEach ( function ( ref ) {
213
+ ref . thedef = def ;
214
+ ref . reference ( options ) ;
215
+ } ) ;
216
+ node . thedef = def ;
217
+ node . reference ( options ) ;
217
218
}
218
219
} ) ;
219
220
@@ -252,16 +253,14 @@ AST_Lambda.DEFMETHOD("init_scope_vars", function() {
252
253
253
254
AST_Symbol . DEFMETHOD ( "mark_enclosed" , function ( options ) {
254
255
var def = this . definition ( ) ;
255
- var s = this . scope ;
256
- while ( s ) {
256
+ for ( var s = this . scope ; s ; s = s . parent_scope ) {
257
257
push_uniq ( s . enclosed , def ) ;
258
258
if ( options . keep_fnames ) {
259
259
s . functions . each ( function ( d ) {
260
260
push_uniq ( def . scope . enclosed , d ) ;
261
261
} ) ;
262
262
}
263
263
if ( s === def . scope ) break ;
264
- s = s . parent_scope ;
265
264
}
266
265
} ) ;
267
266
@@ -298,6 +297,12 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol, init) {
298
297
return symbol . thedef = def ;
299
298
} ) ;
300
299
300
+ AST_Lambda . DEFMETHOD ( "resolve" , return_this ) ;
301
+ AST_Scope . DEFMETHOD ( "resolve" , function ( ) {
302
+ return this . parent_scope ;
303
+ } ) ;
304
+ AST_Toplevel . DEFMETHOD ( "resolve" , return_this ) ;
305
+
301
306
function names_in_use ( scope , options ) {
302
307
var names = scope . names_in_use ;
303
308
if ( ! names ) {
@@ -410,7 +415,7 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
410
415
var save_nesting = lname ;
411
416
descend ( ) ;
412
417
lname = save_nesting ;
413
- return true ; // don't descend again in TreeWalker
418
+ return true ;
414
419
}
415
420
if ( node instanceof AST_Scope ) {
416
421
descend ( ) ;
@@ -422,7 +427,9 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options) {
422
427
}
423
428
if ( node instanceof AST_Label ) {
424
429
var name ;
425
- do name = base54 ( ++ lname ) ; while ( ! is_identifier ( name ) ) ;
430
+ do {
431
+ name = base54 ( ++ lname ) ;
432
+ } while ( ! is_identifier ( name ) ) ;
426
433
node . mangled_name = name ;
427
434
return true ;
428
435
}
0 commit comments