@@ -802,6 +802,11 @@ module ts {
802
802
case SyntaxKind . EnumDeclaration :
803
803
case SyntaxKind . ModuleDeclaration :
804
804
case SyntaxKind . ImportEqualsDeclaration :
805
+ case SyntaxKind . ExportSpecifier :
806
+ case SyntaxKind . ImportSpecifier :
807
+ case SyntaxKind . ImportEqualsDeclaration :
808
+ case SyntaxKind . ImportClause :
809
+ case SyntaxKind . NamespaceImport :
805
810
case SyntaxKind . GetAccessor :
806
811
case SyntaxKind . SetAccessor :
807
812
case SyntaxKind . TypeLiteral :
@@ -841,6 +846,37 @@ module ts {
841
846
case SyntaxKind . PropertySignature :
842
847
namedDeclarations . push ( < Declaration > node ) ;
843
848
break ;
849
+
850
+ case SyntaxKind . ExportDeclaration :
851
+ // Handle named exports case e.g.:
852
+ // export {a, b as B} from "mod";
853
+ if ( ( < ExportDeclaration > node ) . exportClause ) {
854
+ forEach ( ( < ExportDeclaration > node ) . exportClause . elements , visit ) ;
855
+ }
856
+ break ;
857
+
858
+ case SyntaxKind . ImportDeclaration :
859
+ var importClause = ( < ImportDeclaration > node ) . importClause ;
860
+ if ( importClause ) {
861
+ // Handle default import case e.g.:
862
+ // import d from "mod";
863
+ if ( importClause . name ) {
864
+ namedDeclarations . push ( importClause ) ;
865
+ }
866
+
867
+ // Handle named bindings in imports e.g.:
868
+ // import * as NS from "mod";
869
+ // import {a, b as B} from "mod";
870
+ if ( importClause . namedBindings ) {
871
+ if ( importClause . namedBindings . kind === SyntaxKind . NamespaceImport ) {
872
+ namedDeclarations . push ( < NamespaceImport > importClause . namedBindings ) ;
873
+ }
874
+ else {
875
+ forEach ( ( < NamedImports > importClause . namedBindings ) . elements , visit ) ;
876
+ }
877
+ }
878
+ }
879
+ break ;
844
880
}
845
881
} ) ;
846
882
@@ -2010,6 +2046,12 @@ module ts {
2010
2046
case SyntaxKind . TypeParameter : return ScriptElementKind . typeParameterElement ;
2011
2047
case SyntaxKind . EnumMember : return ScriptElementKind . variableElement ;
2012
2048
case SyntaxKind . Parameter : return ( node . flags & NodeFlags . AccessibilityModifier ) ? ScriptElementKind . memberVariableElement : ScriptElementKind . parameterElement ;
2049
+ case SyntaxKind . ImportEqualsDeclaration :
2050
+ case SyntaxKind . ImportSpecifier :
2051
+ case SyntaxKind . ImportClause :
2052
+ case SyntaxKind . ExportSpecifier :
2053
+ case SyntaxKind . NamespaceImport :
2054
+ return ScriptElementKind . alias ;
2013
2055
}
2014
2056
return ScriptElementKind . unknown ;
2015
2057
}
@@ -3986,7 +4028,7 @@ module ts {
3986
4028
var searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , declarations ) ;
3987
4029
3988
4030
// Get the text to search for, we need to normalize it as external module names will have quote
3989
- var declaredName = getDeclaredName ( symbol ) ;
4031
+ var declaredName = getDeclaredName ( symbol , node ) ;
3990
4032
3991
4033
// Try to get the smallest valid scope that we can limit our search to;
3992
4034
// otherwise we'll need to search globally (i.e. include each file).
@@ -4003,7 +4045,7 @@ module ts {
4003
4045
getReferencesInNode ( sourceFiles [ 0 ] , symbol , declaredName , node , searchMeaning , findInStrings , findInComments , result ) ;
4004
4046
}
4005
4047
else {
4006
- var internedName = getInternedName ( symbol , declarations )
4048
+ var internedName = getInternedName ( symbol , node , declarations )
4007
4049
forEach ( sourceFiles , sourceFile => {
4008
4050
cancellationToken . throwIfCancellationRequested ( ) ;
4009
4051
@@ -4023,13 +4065,51 @@ module ts {
4023
4065
4024
4066
return result ;
4025
4067
4026
- function getDeclaredName ( symbol : Symbol ) {
4068
+ function isImportOrExportSpecifierName ( location : Node ) : boolean {
4069
+ return location . parent &&
4070
+ ( location . parent . kind === SyntaxKind . ImportSpecifier || location . parent . kind === SyntaxKind . ExportSpecifier ) &&
4071
+ ( < ImportOrExportSpecifier > location . parent ) . propertyName === location ;
4072
+ }
4073
+
4074
+ function isImportOrExportSpecifierImportSymbol ( symbol : Symbol ) {
4075
+ return ( symbol . flags & SymbolFlags . Import ) && forEach ( symbol . declarations , declaration => {
4076
+ return declaration . kind === SyntaxKind . ImportSpecifier || declaration . kind === SyntaxKind . ExportSpecifier ;
4077
+ } ) ;
4078
+ }
4079
+
4080
+ function getDeclaredName ( symbol : Symbol , location : Node ) {
4081
+ // Special case for function expressions, whose names are solely local to their bodies.
4082
+ var functionExpression = forEach ( symbol . declarations , d => d . kind === SyntaxKind . FunctionExpression ? < FunctionExpression > d : undefined ) ;
4083
+
4084
+ // When a name gets interned into a SourceFile's 'identifiers' Map,
4085
+ // its name is escaped and stored in the same way its symbol name/identifier
4086
+ // name should be stored. Function expressions, however, are a special case,
4087
+ // because despite sometimes having a name, the binder unconditionally binds them
4088
+ // to a symbol with the name "__function".
4089
+ if ( functionExpression && functionExpression . name ) {
4090
+ var name = functionExpression . name . text ;
4091
+ }
4092
+
4093
+ // If this is an export or import specifier it could have been renamed using the as syntax.
4094
+ // if so we want to search for whatever under the cursor, the symbol is pointing to the alias (name)
4095
+ // so check for the propertyName.
4096
+ if ( isImportOrExportSpecifierName ( location ) ) {
4097
+ return location . getText ( ) ;
4098
+ }
4099
+
4027
4100
var name = typeInfoResolver . symbolToString ( symbol ) ;
4028
4101
4029
4102
return stripQuotes ( name ) ;
4030
4103
}
4031
4104
4032
- function getInternedName ( symbol : Symbol , declarations : Declaration [ ] ) : string {
4105
+ function getInternedName ( symbol : Symbol , location : Node , declarations : Declaration [ ] ) : string {
4106
+ // If this is an export or import specifier it could have been renamed using the as syntax.
4107
+ // if so we want to search for whatever under the cursor, the symbol is pointing to the alias (name)
4108
+ // so check for the propertyName.
4109
+ if ( isImportOrExportSpecifierName ( location ) ) {
4110
+ return location . getText ( ) ;
4111
+ }
4112
+
4033
4113
// Special case for function expressions, whose names are solely local to their bodies.
4034
4114
var functionExpression = forEach ( declarations , d => d . kind === SyntaxKind . FunctionExpression ? < FunctionExpression > d : undefined ) ;
4035
4115
@@ -4058,16 +4138,22 @@ module ts {
4058
4138
4059
4139
function getSymbolScope ( symbol : Symbol ) : Node {
4060
4140
// If this is private property or method, the scope is the containing class
4061
- if ( symbol . getFlags ( ) & & ( SymbolFlags . Property | SymbolFlags . Method ) ) {
4141
+ if ( symbol . flags & ( SymbolFlags . Property | SymbolFlags . Method ) ) {
4062
4142
var privateDeclaration = forEach ( symbol . getDeclarations ( ) , d => ( d . flags & NodeFlags . Private ) ? d : undefined ) ;
4063
4143
if ( privateDeclaration ) {
4064
4144
return getAncestor ( privateDeclaration , SyntaxKind . ClassDeclaration ) ;
4065
4145
}
4066
4146
}
4067
4147
4148
+ // If the symbol is an import we would like to find it if we are looking for what it imports.
4149
+ // So consider it visibile outside its declaration scope.
4150
+ if ( symbol . flags & SymbolFlags . Import ) {
4151
+ return undefined ;
4152
+ }
4153
+
4068
4154
// if this symbol is visible from its parent container, e.g. exported, then bail out
4069
4155
// if symbol correspond to the union property - bail out
4070
- if ( symbol . parent || ( symbol . getFlags ( ) & SymbolFlags . UnionProperty ) ) {
4156
+ if ( symbol . parent || ( symbol . flags & SymbolFlags . UnionProperty ) ) {
4071
4157
return undefined ;
4072
4158
}
4073
4159
@@ -4422,6 +4508,11 @@ module ts {
4422
4508
// The search set contains at least the current symbol
4423
4509
var result = [ symbol ] ;
4424
4510
4511
+ // If the symbol is an alias, add what it alaises to the list
4512
+ if ( isImportOrExportSpecifierImportSymbol ( symbol ) ) {
4513
+ result . push ( typeInfoResolver . getAliasedSymbol ( symbol ) ) ;
4514
+ }
4515
+
4425
4516
// If the location is in a context sensitive location (i.e. in an object literal) try
4426
4517
// to get a contextual type for it, and add the property symbol from the contextual
4427
4518
// type to the search set
@@ -4498,6 +4589,13 @@ module ts {
4498
4589
return true ;
4499
4590
}
4500
4591
4592
+ // If the reference symbol is an alias, check if what it is aliasing is one of the search
4593
+ // symbols.
4594
+ if ( isImportOrExportSpecifierImportSymbol ( referenceSymbol ) &&
4595
+ searchSymbols . indexOf ( typeInfoResolver . getAliasedSymbol ( referenceSymbol ) ) >= 0 ) {
4596
+ return true ;
4597
+ }
4598
+
4501
4599
// If the reference location is in an object literal, try to get the contextual type for the
4502
4600
// object literal, lookup the property symbol in the contextual type, and use this symbol to
4503
4601
// compare to our searchSymbol
0 commit comments