2
2
namespace ts . GoToDefinition {
3
3
export function getDefinitionAtPosition ( program : Program , sourceFile : SourceFile , position : number ) : readonly DefinitionInfo [ ] | undefined {
4
4
const resolvedRef = getReferenceAtPosition ( sourceFile , position , program ) ;
5
- if ( resolvedRef ) {
6
- return [ getDefinitionInfoForFileReference ( resolvedRef . reference . fileName , resolvedRef . file . fileName ) ] ;
5
+ const fileReferenceDefinition = resolvedRef && [ getDefinitionInfoForFileReference ( resolvedRef . reference . fileName , resolvedRef . fileName , resolvedRef . unverified ) ] || emptyArray ;
6
+ if ( resolvedRef ?. file ) {
7
+ // If `file` is missing, do a symbol-based lookup as well
8
+ return fileReferenceDefinition ;
7
9
}
8
10
9
11
const node = getTouchingPropertyName ( sourceFile , position ) ;
@@ -25,7 +27,7 @@ namespace ts.GoToDefinition {
25
27
// Could not find a symbol e.g. node is string or number keyword,
26
28
// or the symbol was an internal symbol and does not have a declaration e.g. undefined symbol
27
29
if ( ! symbol ) {
28
- return getDefinitionInfoForIndexSignatures ( node , typeChecker ) ;
30
+ return concatenate ( fileReferenceDefinition , getDefinitionInfoForIndexSignatures ( node , typeChecker ) ) ;
29
31
}
30
32
31
33
const calledDeclaration = tryGetSignatureDeclaration ( typeChecker , node ) ;
@@ -76,7 +78,7 @@ namespace ts.GoToDefinition {
76
78
} ) ;
77
79
}
78
80
79
- return getDefinitionFromObjectLiteralElement ( typeChecker , node ) || getDefinitionFromSymbol ( typeChecker , symbol , node ) ;
81
+ return concatenate ( fileReferenceDefinition , getDefinitionFromObjectLiteralElement ( typeChecker , node ) || getDefinitionFromSymbol ( typeChecker , symbol , node ) ) ;
80
82
}
81
83
82
84
/**
@@ -111,24 +113,42 @@ namespace ts.GoToDefinition {
111
113
}
112
114
}
113
115
114
- export function getReferenceAtPosition ( sourceFile : SourceFile , position : number , program : Program ) : { reference : FileReference , file : SourceFile } | undefined {
116
+ export function getReferenceAtPosition ( sourceFile : SourceFile , position : number , program : Program ) : { reference : FileReference , fileName : string , unverified : boolean , file ? : SourceFile } | undefined {
115
117
const referencePath = findReferenceInPosition ( sourceFile . referencedFiles , position ) ;
116
118
if ( referencePath ) {
117
119
const file = program . getSourceFileFromReference ( sourceFile , referencePath ) ;
118
- return file && { reference : referencePath , file } ;
120
+ return file && { reference : referencePath , fileName : file . fileName , file , unverified : false } ;
119
121
}
120
122
121
123
const typeReferenceDirective = findReferenceInPosition ( sourceFile . typeReferenceDirectives , position ) ;
122
124
if ( typeReferenceDirective ) {
123
125
const reference = program . getResolvedTypeReferenceDirectives ( ) . get ( typeReferenceDirective . fileName ) ;
124
126
const file = reference && program . getSourceFile ( reference . resolvedFileName ! ) ; // TODO:GH#18217
125
- return file && { reference : typeReferenceDirective , file } ;
127
+ return file && { reference : typeReferenceDirective , fileName : file . fileName , file , unverified : false } ;
126
128
}
127
129
128
130
const libReferenceDirective = findReferenceInPosition ( sourceFile . libReferenceDirectives , position ) ;
129
131
if ( libReferenceDirective ) {
130
132
const file = program . getLibFileFromReference ( libReferenceDirective ) ;
131
- return file && { reference : libReferenceDirective , file } ;
133
+ return file && { reference : libReferenceDirective , fileName : file . fileName , file, unverified : false } ;
134
+ }
135
+
136
+ if ( sourceFile . resolvedModules ?. size ) {
137
+ const node = getTokenAtPosition ( sourceFile , position ) ;
138
+ if ( isModuleSpecifierLike ( node ) && isExternalModuleNameRelative ( node . text ) && sourceFile . resolvedModules . has ( node . text ) ) {
139
+ const verifiedFileName = sourceFile . resolvedModules . get ( node . text ) ?. resolvedFileName ;
140
+ const fileName = verifiedFileName || resolvePath ( getDirectoryPath ( sourceFile . fileName ) , node . text ) ;
141
+ return {
142
+ file : program . getSourceFile ( fileName ) ,
143
+ fileName,
144
+ reference : {
145
+ pos : node . getStart ( ) ,
146
+ end : node . getEnd ( ) ,
147
+ fileName : node . text
148
+ } ,
149
+ unverified : ! ! verifiedFileName ,
150
+ } ;
151
+ }
132
152
}
133
153
134
154
return undefined ;
@@ -318,14 +338,15 @@ namespace ts.GoToDefinition {
318
338
return find ( refs , ref => textRangeContainsPositionInclusive ( ref , pos ) ) ;
319
339
}
320
340
321
- function getDefinitionInfoForFileReference ( name : string , targetFileName : string ) : DefinitionInfo {
341
+ function getDefinitionInfoForFileReference ( name : string , targetFileName : string , unverified : boolean ) : DefinitionInfo {
322
342
return {
323
343
fileName : targetFileName ,
324
344
textSpan : createTextSpanFromBounds ( 0 , 0 ) ,
325
345
kind : ScriptElementKind . scriptElement ,
326
346
name,
327
347
containerName : undefined ! ,
328
348
containerKind : undefined ! , // TODO: GH#18217
349
+ unverified,
329
350
} ;
330
351
}
331
352
0 commit comments