@@ -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
}
@@ -3292,6 +3334,17 @@ module ts {
3292
3334
return undefined ;
3293
3335
}
3294
3336
3337
+ // If this is an alias, and the request came at the declaration location
3338
+ // get the aliased symbol instead. This allows for goto def on an import e.g.
3339
+ // import {A, B} from "mod";
3340
+ // to jump to the implementation directelly.
3341
+ if ( symbol . flags & SymbolFlags . Import ) {
3342
+ var declaration = symbol . declarations [ 0 ] ;
3343
+ if ( node . kind === SyntaxKind . Identifier && node . parent === declaration ) {
3344
+ symbol = typeInfoResolver . getAliasedSymbol ( symbol ) ;
3345
+ }
3346
+ }
3347
+
3295
3348
var result : DefinitionInfo [ ] = [ ] ;
3296
3349
3297
3350
// Because name in short-hand property assignment has two different meanings: property name and property value,
@@ -4022,7 +4075,7 @@ module ts {
4022
4075
var searchMeaning = getIntersectingMeaningFromDeclarations ( getMeaningFromLocation ( node ) , declarations ) ;
4023
4076
4024
4077
// Get the text to search for, we need to normalize it as external module names will have quote
4025
- var declaredName = getDeclaredName ( symbol ) ;
4078
+ var declaredName = getDeclaredName ( symbol , node ) ;
4026
4079
4027
4080
// Try to get the smallest valid scope that we can limit our search to;
4028
4081
// otherwise we'll need to search globally (i.e. include each file).
@@ -4039,7 +4092,7 @@ module ts {
4039
4092
getReferencesInNode ( sourceFiles [ 0 ] , symbol , declaredName , node , searchMeaning , findInStrings , findInComments , result ) ;
4040
4093
}
4041
4094
else {
4042
- var internedName = getInternedName ( symbol , declarations )
4095
+ var internedName = getInternedName ( symbol , node , declarations )
4043
4096
forEach ( sourceFiles , sourceFile => {
4044
4097
cancellationToken . throwIfCancellationRequested ( ) ;
4045
4098
@@ -4059,13 +4112,51 @@ module ts {
4059
4112
4060
4113
return result ;
4061
4114
4062
- function getDeclaredName ( symbol : Symbol ) {
4115
+ function isImportOrExportSpecifierName ( location : Node ) : boolean {
4116
+ return location . parent &&
4117
+ ( location . parent . kind === SyntaxKind . ImportSpecifier || location . parent . kind === SyntaxKind . ExportSpecifier ) &&
4118
+ ( < ImportOrExportSpecifier > location . parent ) . propertyName === location ;
4119
+ }
4120
+
4121
+ function isImportOrExportSpecifierImportSymbol ( symbol : Symbol ) {
4122
+ return ( symbol . flags & SymbolFlags . Import ) && forEach ( symbol . declarations , declaration => {
4123
+ return declaration . kind === SyntaxKind . ImportSpecifier || declaration . kind === SyntaxKind . ExportSpecifier ;
4124
+ } ) ;
4125
+ }
4126
+
4127
+ function getDeclaredName ( symbol : Symbol , location : Node ) {
4128
+ // Special case for function expressions, whose names are solely local to their bodies.
4129
+ var functionExpression = forEach ( symbol . declarations , d => d . kind === SyntaxKind . FunctionExpression ? < FunctionExpression > d : undefined ) ;
4130
+
4131
+ // When a name gets interned into a SourceFile's 'identifiers' Map,
4132
+ // its name is escaped and stored in the same way its symbol name/identifier
4133
+ // name should be stored. Function expressions, however, are a special case,
4134
+ // because despite sometimes having a name, the binder unconditionally binds them
4135
+ // to a symbol with the name "__function".
4136
+ if ( functionExpression && functionExpression . name ) {
4137
+ var name = functionExpression . name . text ;
4138
+ }
4139
+
4140
+ // If this is an export or import specifier it could have been renamed using the as syntax.
4141
+ // if so we want to search for whatever under the cursor, the symbol is pointing to the alias (name)
4142
+ // so check for the propertyName.
4143
+ if ( isImportOrExportSpecifierName ( location ) ) {
4144
+ return location . getText ( ) ;
4145
+ }
4146
+
4063
4147
var name = typeInfoResolver . symbolToString ( symbol ) ;
4064
4148
4065
4149
return stripQuotes ( name ) ;
4066
4150
}
4067
4151
4068
- function getInternedName ( symbol : Symbol , declarations : Declaration [ ] ) : string {
4152
+ function getInternedName ( symbol : Symbol , location : Node , declarations : Declaration [ ] ) : string {
4153
+ // If this is an export or import specifier it could have been renamed using the as syntax.
4154
+ // if so we want to search for whatever under the cursor, the symbol is pointing to the alias (name)
4155
+ // so check for the propertyName.
4156
+ if ( isImportOrExportSpecifierName ( location ) ) {
4157
+ return location . getText ( ) ;
4158
+ }
4159
+
4069
4160
// Special case for function expressions, whose names are solely local to their bodies.
4070
4161
var functionExpression = forEach ( declarations , d => d . kind === SyntaxKind . FunctionExpression ? < FunctionExpression > d : undefined ) ;
4071
4162
@@ -4094,16 +4185,22 @@ module ts {
4094
4185
4095
4186
function getSymbolScope ( symbol : Symbol ) : Node {
4096
4187
// If this is private property or method, the scope is the containing class
4097
- if ( symbol . getFlags ( ) & & ( SymbolFlags . Property | SymbolFlags . Method ) ) {
4188
+ if ( symbol . flags & ( SymbolFlags . Property | SymbolFlags . Method ) ) {
4098
4189
var privateDeclaration = forEach ( symbol . getDeclarations ( ) , d => ( d . flags & NodeFlags . Private ) ? d : undefined ) ;
4099
4190
if ( privateDeclaration ) {
4100
4191
return getAncestor ( privateDeclaration , SyntaxKind . ClassDeclaration ) ;
4101
4192
}
4102
4193
}
4103
4194
4195
+ // If the symbol is an import we would like to find it if we are looking for what it imports.
4196
+ // So consider it visibile outside its declaration scope.
4197
+ if ( symbol . flags & SymbolFlags . Import ) {
4198
+ return undefined ;
4199
+ }
4200
+
4104
4201
// if this symbol is visible from its parent container, e.g. exported, then bail out
4105
4202
// if symbol correspond to the union property - bail out
4106
- if ( symbol . parent || ( symbol . getFlags ( ) & SymbolFlags . UnionProperty ) ) {
4203
+ if ( symbol . parent || ( symbol . flags & SymbolFlags . UnionProperty ) ) {
4107
4204
return undefined ;
4108
4205
}
4109
4206
@@ -4458,6 +4555,11 @@ module ts {
4458
4555
// The search set contains at least the current symbol
4459
4556
var result = [ symbol ] ;
4460
4557
4558
+ // If the symbol is an alias, add what it alaises to the list
4559
+ if ( isImportOrExportSpecifierImportSymbol ( symbol ) ) {
4560
+ result . push ( typeInfoResolver . getAliasedSymbol ( symbol ) ) ;
4561
+ }
4562
+
4461
4563
// If the location is in a context sensitive location (i.e. in an object literal) try
4462
4564
// to get a contextual type for it, and add the property symbol from the contextual
4463
4565
// type to the search set
@@ -4534,6 +4636,13 @@ module ts {
4534
4636
return true ;
4535
4637
}
4536
4638
4639
+ // If the reference symbol is an alias, check if what it is aliasing is one of the search
4640
+ // symbols.
4641
+ if ( isImportOrExportSpecifierImportSymbol ( referenceSymbol ) &&
4642
+ searchSymbols . indexOf ( typeInfoResolver . getAliasedSymbol ( referenceSymbol ) ) >= 0 ) {
4643
+ return true ;
4644
+ }
4645
+
4537
4646
// If the reference location is in an object literal, try to get the contextual type for the
4538
4647
// object literal, lookup the property symbol in the contextual type, and use this symbol to
4539
4648
// compare to our searchSymbol
@@ -4744,12 +4853,18 @@ module ts {
4744
4853
case SyntaxKind . NamedImports :
4745
4854
case SyntaxKind . ImportSpecifier :
4746
4855
case SyntaxKind . ImportEqualsDeclaration :
4856
+ case SyntaxKind . ImportDeclaration :
4857
+ case SyntaxKind . ExportAssignment :
4858
+ case SyntaxKind . ExportDeclaration :
4747
4859
return SemanticMeaning . Value | SemanticMeaning . Type | SemanticMeaning . Namespace ;
4748
4860
4749
4861
// An external module can be a Value
4750
4862
case SyntaxKind . SourceFile :
4751
4863
return SemanticMeaning . Namespace | SemanticMeaning . Value ;
4752
4864
}
4865
+
4866
+ return SemanticMeaning . Value | SemanticMeaning . Type | SemanticMeaning . Namespace ;
4867
+
4753
4868
Debug . fail ( "Unknown declaration type" ) ;
4754
4869
}
4755
4870
0 commit comments