@@ -802,6 +802,11 @@ module ts {
802802 case SyntaxKind . EnumDeclaration :
803803 case SyntaxKind . ModuleDeclaration :
804804 case SyntaxKind . ImportEqualsDeclaration :
805+ case SyntaxKind . ExportSpecifier :
806+ case SyntaxKind . ImportSpecifier :
807+ case SyntaxKind . ImportEqualsDeclaration :
808+ case SyntaxKind . ImportClause :
809+ case SyntaxKind . NamespaceImport :
805810 case SyntaxKind . GetAccessor :
806811 case SyntaxKind . SetAccessor :
807812 case SyntaxKind . TypeLiteral :
@@ -841,6 +846,37 @@ module ts {
841846 case SyntaxKind . PropertySignature :
842847 namedDeclarations . push ( < Declaration > node ) ;
843848 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 ;
844880 }
845881 } ) ;
846882
@@ -2010,6 +2046,12 @@ module ts {
20102046 case SyntaxKind . TypeParameter : return ScriptElementKind . typeParameterElement ;
20112047 case SyntaxKind . EnumMember : return ScriptElementKind . variableElement ;
20122048 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 ;
20132055 }
20142056 return ScriptElementKind . unknown ;
20152057 }
@@ -3986,7 +4028,7 @@ module ts {
39864028 var searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , declarations ) ;
39874029
39884030 // 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 ) ;
39904032
39914033 // Try to get the smallest valid scope that we can limit our search to;
39924034 // otherwise we'll need to search globally (i.e. include each file).
@@ -4003,7 +4045,7 @@ module ts {
40034045 getReferencesInNode ( sourceFiles [ 0 ] , symbol , declaredName , node , searchMeaning , findInStrings , findInComments , result ) ;
40044046 }
40054047 else {
4006- var internedName = getInternedName ( symbol , declarations )
4048+ var internedName = getInternedName ( symbol , node , declarations )
40074049 forEach ( sourceFiles , sourceFile => {
40084050 cancellationToken . throwIfCancellationRequested ( ) ;
40094051
@@ -4023,13 +4065,51 @@ module ts {
40234065
40244066 return result ;
40254067
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+
40274100 var name = typeInfoResolver . symbolToString ( symbol ) ;
40284101
40294102 return stripQuotes ( name ) ;
40304103 }
40314104
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+
40334113 // Special case for function expressions, whose names are solely local to their bodies.
40344114 var functionExpression = forEach ( declarations , d => d . kind === SyntaxKind . FunctionExpression ? < FunctionExpression > d : undefined ) ;
40354115
@@ -4058,16 +4138,22 @@ module ts {
40584138
40594139 function getSymbolScope ( symbol : Symbol ) : Node {
40604140 // 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 ) ) {
40624142 var privateDeclaration = forEach ( symbol . getDeclarations ( ) , d => ( d . flags & NodeFlags . Private ) ? d : undefined ) ;
40634143 if ( privateDeclaration ) {
40644144 return getAncestor ( privateDeclaration , SyntaxKind . ClassDeclaration ) ;
40654145 }
40664146 }
40674147
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+
40684154 // if this symbol is visible from its parent container, e.g. exported, then bail out
40694155 // 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 ) ) {
40714157 return undefined ;
40724158 }
40734159
@@ -4422,6 +4508,11 @@ module ts {
44224508 // The search set contains at least the current symbol
44234509 var result = [ symbol ] ;
44244510
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+
44254516 // If the location is in a context sensitive location (i.e. in an object literal) try
44264517 // to get a contextual type for it, and add the property symbol from the contextual
44274518 // type to the search set
@@ -4498,6 +4589,13 @@ module ts {
44984589 return true ;
44994590 }
45004591
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+
45014599 // If the reference location is in an object literal, try to get the contextual type for the
45024600 // object literal, lookup the property symbol in the contextual type, and use this symbol to
45034601 // compare to our searchSymbol
0 commit comments