@@ -2284,16 +2284,8 @@ module ts {
2284
2284
}
2285
2285
}
2286
2286
2287
- function getConcreteSymbol ( symbol : Symbol ) : Symbol {
2288
- if ( symbol . flags & SymbolFlags . UnionProperty ) {
2289
- var types = typeInfoResolver . getUnionTypesOfUnionProperty ( symbol ) ;
2290
- symbol = typeInfoResolver . getPropertyOfType ( types [ 0 ] , symbol . name ) ;
2291
- }
2292
- return typeInfoResolver . getRootSymbol ( symbol ) ;
2293
- }
2294
-
2295
2287
function getSymbolKind ( symbol : Symbol ) : string {
2296
- var flags = getConcreteSymbol ( symbol ) . getFlags ( ) ;
2288
+ var flags = typeInfoResolver . getRootSymbols ( symbol ) [ 0 ] . getFlags ( ) ;
2297
2289
2298
2290
if ( flags & SymbolFlags . Module ) return ScriptElementKind . moduleElement ;
2299
2291
if ( flags & SymbolFlags . Class ) return ScriptElementKind . classElement ;
@@ -2352,7 +2344,7 @@ module ts {
2352
2344
}
2353
2345
2354
2346
function getSymbolModifiers ( symbol : Symbol ) : string {
2355
- symbol = getConcreteSymbol ( symbol ) ;
2347
+ symbol = typeInfoResolver . getRootSymbols ( symbol ) [ 0 ] ;
2356
2348
return symbol && symbol . declarations && symbol . declarations . length > 0
2357
2349
? getNodeModifiers ( symbol . declarations [ 0 ] )
2358
2350
: ScriptElementKindModifier . none ;
@@ -3016,18 +3008,28 @@ module ts {
3016
3008
return [ getReferenceEntryFromNode ( node ) ] ;
3017
3009
}
3018
3010
3011
+ var declarations = symbol . getDeclarations ( ) ;
3012
+
3013
+ // Handel union properties
3014
+ if ( symbol . flags & SymbolFlags . UnionProperty ) {
3015
+ declarations = [ ] ;
3016
+ forEach ( typeInfoResolver . getUnionTypesOfUnionProperty ( symbol ) , t => {
3017
+ declarations . push . apply ( declarations , t . getProperty ( symbol . name ) . declarations ) ;
3018
+ } ) ;
3019
+ }
3020
+
3019
3021
// the symbol was an internal symbol and does not have a declaration e.g.undefined symbol
3020
- if ( ! symbol . getDeclarations ( ) ) {
3022
+ if ( ! declarations || ! declarations . length ) {
3021
3023
return undefined ;
3022
3024
}
3023
3025
3024
3026
var result : ReferenceEntry [ ] ;
3025
3027
3026
3028
// Compute the meaning from the location and the symbol it references
3027
- var searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , symbol . getDeclarations ( ) ) ;
3029
+ var searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , declarations ) ;
3028
3030
3029
3031
// Get the text to search for, we need to normalize it as external module names will have quote
3030
- var symbolName = getNormalizedSymbolName ( symbol ) ;
3032
+ var symbolName = getNormalizedSymbolName ( symbol . name , declarations ) ;
3031
3033
3032
3034
// Get syntactic diagnostics
3033
3035
var scope = getSymbolScope ( symbol ) ;
@@ -3049,15 +3051,15 @@ module ts {
3049
3051
3050
3052
return result ;
3051
3053
3052
- function getNormalizedSymbolName ( symbol : Symbol ) : string {
3054
+ function getNormalizedSymbolName ( symbolName : string , declarations : Declaration [ ] ) : string {
3053
3055
// Special case for function expressions, whose names are solely local to their bodies.
3054
- var functionExpression = getDeclarationOfKind ( symbol , SyntaxKind . FunctionExpression ) ;
3056
+ var functionExpression = forEach ( declarations , d => d . kind === SyntaxKind . FunctionExpression ? d : undefined ) ;
3055
3057
3056
3058
if ( functionExpression && functionExpression . name ) {
3057
3059
var name = functionExpression . name . text ;
3058
3060
}
3059
3061
else {
3060
- var name = symbol . name ;
3062
+ var name = symbolName ;
3061
3063
}
3062
3064
3063
3065
var length = name . length ;
@@ -3084,22 +3086,24 @@ module ts {
3084
3086
var scope : Node = undefined ;
3085
3087
3086
3088
var declarations = symbol . getDeclarations ( ) ;
3087
- for ( var i = 0 , n = declarations . length ; i < n ; i ++ ) {
3088
- var container = getContainerNode ( declarations [ i ] ) ;
3089
+ if ( declarations ) {
3090
+ for ( var i = 0 , n = declarations . length ; i < n ; i ++ ) {
3091
+ var container = getContainerNode ( declarations [ i ] ) ;
3089
3092
3090
- if ( scope && scope !== container ) {
3091
- // Different declarations have different containers, bail out
3092
- return undefined ;
3093
- }
3093
+ if ( scope && scope !== container ) {
3094
+ // Different declarations have different containers, bail out
3095
+ return undefined ;
3096
+ }
3094
3097
3095
- if ( container . kind === SyntaxKind . SourceFile && ! isExternalModule ( < SourceFile > container ) ) {
3096
- // This is a global variable and not an external module, any declaration defined
3097
- // within this scope is visible outside the file
3098
- return undefined ;
3099
- }
3098
+ if ( container . kind === SyntaxKind . SourceFile && ! isExternalModule ( < SourceFile > container ) ) {
3099
+ // This is a global variable and not an external module, any declaration defined
3100
+ // within this scope is visible outside the file
3101
+ return undefined ;
3102
+ }
3100
3103
3101
- // The search scope is the container node
3102
- scope = container ;
3104
+ // The search scope is the container node
3105
+ scope = container ;
3106
+ }
3103
3107
}
3104
3108
3105
3109
return scope ;
@@ -3216,14 +3220,7 @@ module ts {
3216
3220
}
3217
3221
3218
3222
var referenceSymbol = typeInfoResolver . getSymbolInfo ( referenceLocation ) ;
3219
-
3220
- // Could not find a symbol e.g. node is string or number keyword,
3221
- // or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
3222
- if ( ! referenceSymbol || ! ( referenceSymbol . getDeclarations ( ) ) ) {
3223
- return ;
3224
- }
3225
-
3226
- if ( isRelatableToSearchSet ( searchSymbols , referenceSymbol , referenceLocation ) ) {
3223
+ if ( referenceSymbol && isRelatableToSearchSet ( searchSymbols , referenceSymbol , referenceLocation ) ) {
3227
3224
result . push ( getReferenceEntryFromNode ( referenceLocation ) ) ;
3228
3225
}
3229
3226
} ) ;
@@ -3359,24 +3356,26 @@ module ts {
3359
3356
// The search set contains at least the current symbol
3360
3357
var result = [ symbol ] ;
3361
3358
3362
- // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
3363
- var rootSymbol = typeInfoResolver . getRootSymbol ( symbol ) ;
3364
- if ( rootSymbol && rootSymbol !== symbol ) {
3365
- result . push ( rootSymbol ) ;
3366
- }
3367
-
3368
3359
// If the location is in a context sensitive location (i.e. in an object literal) try
3369
3360
// to get a contextual type for it, and add the property symbol from the contextual
3370
3361
// type to the search set
3371
3362
if ( isNameOfPropertyAssignment ( location ) ) {
3372
3363
var symbolFromContextualType = getPropertySymbolFromContextualType ( location ) ;
3373
- if ( symbolFromContextualType ) result . push ( typeInfoResolver . getRootSymbol ( symbolFromContextualType ) ) ;
3364
+ if ( symbolFromContextualType ) result . push . apply ( result , typeInfoResolver . getRootSymbols ( symbolFromContextualType ) ) ;
3374
3365
}
3375
3366
3376
- // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
3377
- if ( symbol . parent && symbol . parent . flags & ( SymbolFlags . Class | SymbolFlags . Interface ) ) {
3378
- getPropertySymbolsFromBaseTypes ( symbol . parent , symbol . getName ( ) , result ) ;
3379
- }
3367
+ // If this is a union property, add all the symbols from all its source symbols in all unioned types.
3368
+ // If the symbol is an instantiation from a another symbol (e.g. widened symbol) , add the root the list
3369
+ forEach ( typeInfoResolver . getRootSymbols ( symbol ) , rootSymbol => {
3370
+ if ( rootSymbol !== symbol ) {
3371
+ result . push ( rootSymbol ) ;
3372
+ }
3373
+
3374
+ // Add symbol of properties/methods of the same name in base classes and implemented interfaces definitions
3375
+ if ( rootSymbol . parent && rootSymbol . parent . flags & ( SymbolFlags . Class | SymbolFlags . Interface ) ) {
3376
+ getPropertySymbolsFromBaseTypes ( rootSymbol . parent , rootSymbol . getName ( ) , result ) ;
3377
+ }
3378
+ } ) ;
3380
3379
3381
3380
return result ;
3382
3381
}
@@ -3411,33 +3410,34 @@ module ts {
3411
3410
}
3412
3411
3413
3412
function isRelatableToSearchSet ( searchSymbols : Symbol [ ] , referenceSymbol : Symbol , referenceLocation : Node ) : boolean {
3414
- // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
3415
- var referenceSymbolTarget = typeInfoResolver . getRootSymbol ( referenceSymbol ) ;
3416
-
3417
- // if it is in the list, then we are done
3418
- if ( searchSymbols . indexOf ( referenceSymbolTarget ) >= 0 ) {
3419
- return true ;
3420
- }
3421
-
3422
3413
// If the reference location is in an object literal, try to get the contextual type for the
3423
3414
// object literal, lookup the property symbol in the contextual type, and use this symbol to
3424
3415
// compare to our searchSymbol
3425
3416
if ( isNameOfPropertyAssignment ( referenceLocation ) ) {
3426
3417
var symbolFromContextualType = getPropertySymbolFromContextualType ( referenceLocation ) ;
3427
- if ( symbolFromContextualType && searchSymbols . indexOf ( typeInfoResolver . getRootSymbol ( symbolFromContextualType ) ) >= 0 ) {
3428
- return true ;
3418
+ if ( symbolFromContextualType ) {
3419
+ return forEach ( typeInfoResolver . getRootSymbols ( symbolFromContextualType ) , s => searchSymbols . indexOf ( s ) >= 0 ) ;
3429
3420
}
3430
3421
}
3431
3422
3432
- // Finally, try all properties with the same name in any type the containing type extend or implemented, and
3433
- // see if any is in the list
3434
- if ( referenceSymbol . parent && referenceSymbol . parent . flags & ( SymbolFlags . Class | SymbolFlags . Interface ) ) {
3435
- var result : Symbol [ ] = [ ] ;
3436
- getPropertySymbolsFromBaseTypes ( referenceSymbol . parent , referenceSymbol . getName ( ) , result ) ;
3437
- return forEach ( result , s => searchSymbols . indexOf ( s ) >= 0 ) ;
3438
- }
3423
+ // Unwrap symbols to get to the root (e.g. transient symbols as a result of widening)
3424
+ // Or a union property, use its underlying unioned symbols
3425
+ return forEach ( typeInfoResolver . getRootSymbols ( referenceSymbol ) , rootSymbol => {
3426
+ // if it is in the list, then we are done
3427
+ if ( searchSymbols . indexOf ( rootSymbol ) >= 0 ) {
3428
+ return true ;
3429
+ }
3439
3430
3440
- return false ;
3431
+ // Finally, try all properties with the same name in any type the containing type extended or implemented, and
3432
+ // see if any is in the list
3433
+ if ( rootSymbol . parent && rootSymbol . parent . flags & ( SymbolFlags . Class | SymbolFlags . Interface ) ) {
3434
+ var result : Symbol [ ] = [ ] ;
3435
+ getPropertySymbolsFromBaseTypes ( rootSymbol . parent , rootSymbol . getName ( ) , result ) ;
3436
+ return forEach ( result , s => searchSymbols . indexOf ( s ) >= 0 ) ;
3437
+ }
3438
+
3439
+ return false ;
3440
+ } ) ;
3441
3441
}
3442
3442
3443
3443
function getPropertySymbolFromContextualType ( node : Node ) : Symbol {
0 commit comments