@@ -124,6 +124,13 @@ function Namespace(name, options) {
124
124
* @protected
125
125
*/
126
126
this . _needsRecursiveFeatureResolution = true ;
127
+
128
+ /**
129
+ * Whether or not objects contained in this namespace need a resolve.
130
+ * @type {boolean }
131
+ * @protected
132
+ */
133
+ this . _needsRecursiveResolve = true ;
127
134
}
128
135
129
136
function clearCache ( namespace ) {
@@ -273,11 +280,13 @@ Namespace.prototype.add = function add(object) {
273
280
}
274
281
275
282
this . _needsRecursiveFeatureResolution = true ;
283
+ this . _needsRecursiveResolve = true ;
276
284
277
285
// Also clear parent caches, since they need to recurse down.
278
286
var parent = this ;
279
287
while ( parent = parent . parent ) {
280
288
parent . _needsRecursiveFeatureResolution = true ;
289
+ parent . _needsRecursiveResolve = true ;
281
290
}
282
291
283
292
object . onAdd ( this ) ;
@@ -341,13 +350,16 @@ Namespace.prototype.define = function define(path, json) {
341
350
* @returns {Namespace } `this`
342
351
*/
343
352
Namespace . prototype . resolveAll = function resolveAll ( ) {
353
+ if ( ! this . _needsRecursiveResolve ) return this ;
354
+
344
355
var nested = this . nestedArray , i = 0 ;
345
356
this . resolve ( ) ;
346
357
while ( i < nested . length )
347
358
if ( nested [ i ] instanceof Namespace )
348
359
nested [ i ++ ] . resolveAll ( ) ;
349
360
else
350
361
nested [ i ++ ] . resolve ( ) ;
362
+ this . _needsRecursiveResolve = false ;
351
363
return this ;
352
364
} ;
353
365
@@ -389,29 +401,47 @@ Namespace.prototype.lookup = function lookup(path, filterTypes, parentAlreadyChe
389
401
} else if ( ! path . length )
390
402
return this ;
391
403
404
+ var flatPath = path . join ( "." ) ;
405
+
392
406
// Start at root if path is absolute
393
407
if ( path [ 0 ] === "" )
394
408
return this . root . lookup ( path . slice ( 1 ) , filterTypes ) ;
395
409
396
- var found = this . _lookupImpl ( path ) ;
410
+ // Early bailout for objects with matching absolute paths
411
+ var found = this . root . _fullyQualifiedObjects [ "." + flatPath ] ;
412
+ if ( found && ( ! filterTypes || filterTypes . indexOf ( found . constructor ) > - 1 ) ) {
413
+ return found ;
414
+ }
415
+
416
+ // Do a regular lookup at this namespace and below
417
+ found = this . _lookupImpl ( path , flatPath ) ;
397
418
if ( found && ( ! filterTypes || filterTypes . indexOf ( found . constructor ) > - 1 ) ) {
398
419
return found ;
399
420
}
400
421
401
- // If there hasn't been a match, try again at the parent
402
- if ( this . parent === null || parentAlreadyChecked )
422
+ if ( parentAlreadyChecked )
403
423
return null ;
404
- return this . parent . lookup ( path , filterTypes ) ;
424
+
425
+ // If there hasn't been a match, walk up the tree and look more broadly
426
+ var current = this ;
427
+ while ( current . parent ) {
428
+ found = current . parent . _lookupImpl ( path , flatPath ) ;
429
+ if ( found && ( ! filterTypes || filterTypes . indexOf ( found . constructor ) > - 1 ) ) {
430
+ return found ;
431
+ }
432
+ current = current . parent ;
433
+ }
434
+ return null ;
405
435
} ;
406
436
407
437
/**
408
438
* Internal helper for lookup that handles searching just at this namespace and below along with caching.
409
439
* @param {string[] } path Path to look up
440
+ * @param {string } flatPath Flattened version of the path to use as a cache key
410
441
* @returns {ReflectionObject|null } Looked up object or `null` if none could be found
411
442
* @private
412
443
*/
413
- Namespace . prototype . _lookupImpl = function lookup ( path ) {
414
- var flatPath = path . join ( "." ) ;
444
+ Namespace . prototype . _lookupImpl = function lookup ( path , flatPath ) {
415
445
if ( Object . prototype . hasOwnProperty . call ( this . _lookupCache , flatPath ) ) {
416
446
return this . _lookupCache [ flatPath ] ;
417
447
}
@@ -422,13 +452,15 @@ Namespace.prototype._lookupImpl = function lookup(path) {
422
452
if ( found ) {
423
453
if ( path . length === 1 ) {
424
454
exact = found ;
425
- } else if ( found instanceof Namespace && ( found = found . _lookupImpl ( path . slice ( 1 ) ) ) )
426
- exact = found ;
455
+ } else if ( found instanceof Namespace ) {
456
+ path = path . slice ( 1 ) ;
457
+ exact = found . _lookupImpl ( path , path . join ( "." ) ) ;
458
+ }
427
459
428
460
// Otherwise try each nested namespace
429
461
} else {
430
462
for ( var i = 0 ; i < this . nestedArray . length ; ++ i )
431
- if ( this . _nestedArray [ i ] instanceof Namespace && ( found = this . _nestedArray [ i ] . _lookupImpl ( path ) ) )
463
+ if ( this . _nestedArray [ i ] instanceof Namespace && ( found = this . _nestedArray [ i ] . _lookupImpl ( path , flatPath ) ) )
432
464
exact = found ;
433
465
}
434
466
0 commit comments