@@ -22,6 +22,7 @@ import {
22
22
findAncestor ,
23
23
first ,
24
24
flatMap ,
25
+ forEach ,
25
26
FunctionLikeDeclaration ,
26
27
getAssignmentDeclarationKind ,
27
28
getContainingObjectLiteralElement ,
@@ -41,6 +42,7 @@ import {
41
42
hasEffectiveModifier ,
42
43
hasInitializer ,
43
44
hasStaticModifier ,
45
+ isAnyImportOrBareOrAccessedRequire ,
44
46
isAssignmentDeclaration ,
45
47
isAssignmentExpression ,
46
48
isBinaryExpression ,
@@ -103,6 +105,7 @@ import {
103
105
textRangeContainsPositionInclusive ,
104
106
TextSpan ,
105
107
tryCast ,
108
+ tryGetModuleSpecifierFromDeclaration ,
106
109
TsPlusSymbolTag ,
107
110
Type ,
108
111
TypeChecker ,
@@ -172,13 +175,12 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
172
175
// TSPLUS EXTENSION BEGIN
173
176
let symbol : Symbol | undefined ;
174
177
let failedAliasResolution : boolean | undefined ;
175
- let fallbackNode = node ;
176
178
177
179
const nodeSymbol = typeChecker . getSymbolAtLocation ( node )
178
180
if ( ! nodeSymbol ) {
179
181
if ( isPropertyAccessExpression ( parent ) ) {
180
182
const nodeType = typeChecker . getTypeAtLocation ( node ) ;
181
- if ( nodeType . symbol && isTsPlusSymbol ( nodeType . symbol ) ) {
183
+ if ( nodeType . symbol && isTsPlusSymbol ( nodeType . symbol ) ) {
182
184
if ( parent . parent && isCallExpression ( parent . parent ) && parent . parent . expression === parent ) {
183
185
const declaration = getDeclarationForTsPlus ( typeChecker , parent . parent , nodeType . symbol )
184
186
if ( declaration ) {
@@ -196,14 +198,14 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
196
198
const type = typeChecker . getTypeAtLocation ( parent . expression ) ;
197
199
const extensions = typeChecker . getExtensions ( parent . expression ) ;
198
200
199
- if ( extensions ) {
201
+ if ( extensions ) {
200
202
const name = parent . name . escapedText . toString ( ) ;
201
203
const staticValueSymbol = typeChecker . getStaticExtension ( type , name ) ;
202
- if ( staticValueSymbol ) {
204
+ if ( staticValueSymbol ) {
203
205
// If execution gets here, it means we have a static variable extension,
204
206
// which needs to be treated a little differently
205
207
const declaration = staticValueSymbol . patched . valueDeclaration ;
206
- if ( declaration && declaration . original ) {
208
+ if ( declaration && declaration . original ) {
207
209
symbol = ( declaration . original as Declaration ) . symbol ;
208
210
}
209
211
} else {
@@ -229,22 +231,38 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
229
231
}
230
232
}
231
233
232
- if ( ! symbol && isModuleSpecifierLike ( fallbackNode ) ) {
233
- // We couldn't resolve the module specifier as an external module, but it could
234
- // be that module resolution succeeded but the target was not a module.
235
- const ref = program . getResolvedModule ( sourceFile , fallbackNode . text , getModeForUsageLocation ( sourceFile , fallbackNode ) ) ?. resolvedModule ;
236
- if ( ref ) {
237
- return [ {
238
- name : fallbackNode . text ,
239
- fileName : ref . resolvedFileName ,
240
- containerName : undefined ! ,
241
- containerKind : undefined ! ,
242
- kind : ScriptElementKind . scriptElement ,
243
- textSpan : createTextSpan ( 0 , 0 ) ,
244
- failedAliasResolution,
245
- isAmbient : isDeclarationFileName ( ref . resolvedFileName ) ,
246
- unverified : fallbackNode !== node ,
247
- } ] ;
234
+ if ( ! symbol ) {
235
+ ( { symbol, failedAliasResolution } = getSymbol ( node , typeChecker , stopAtAlias ) ) ;
236
+
237
+ let fallbackNode = node ;
238
+
239
+ if ( searchOtherFilesOnly && failedAliasResolution ) {
240
+ // We couldn't resolve the specific import, try on the module specifier.
241
+ const importDeclaration = forEach ( [ node , ...symbol ?. declarations || emptyArray ] , n => findAncestor ( n , isAnyImportOrBareOrAccessedRequire ) ) ;
242
+ const moduleSpecifier = importDeclaration && tryGetModuleSpecifierFromDeclaration ( importDeclaration ) ;
243
+ if ( moduleSpecifier ) {
244
+ ( { symbol, failedAliasResolution } = getSymbol ( moduleSpecifier , typeChecker , stopAtAlias ) ) ;
245
+ fallbackNode = moduleSpecifier ;
246
+ }
247
+ }
248
+
249
+ if ( ! symbol && isModuleSpecifierLike ( fallbackNode ) ) {
250
+ // We couldn't resolve the module specifier as an external module, but it could
251
+ // be that module resolution succeeded but the target was not a module.
252
+ const ref = program . getResolvedModule ( sourceFile , fallbackNode . text , getModeForUsageLocation ( sourceFile , fallbackNode ) ) ?. resolvedModule ;
253
+ if ( ref ) {
254
+ return [ {
255
+ name : fallbackNode . text ,
256
+ fileName : ref . resolvedFileName ,
257
+ containerName : undefined ! ,
258
+ containerKind : undefined ! ,
259
+ kind : ScriptElementKind . scriptElement ,
260
+ textSpan : createTextSpan ( 0 , 0 ) ,
261
+ failedAliasResolution,
262
+ isAmbient : isDeclarationFileName ( ref . resolvedFileName ) ,
263
+ unverified : fallbackNode !== node ,
264
+ } ] ;
265
+ }
248
266
}
249
267
}
250
268
// TSPLUS EXTENSION END
@@ -512,7 +530,7 @@ export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile
512
530
513
531
return typeDefinitions . length ? [ ...getFirstTypeArgumentDefinitions ( typeChecker , resolvedType , node , failedAliasResolution ) , ...typeDefinitions ]
514
532
: ! ( symbol . flags & SymbolFlags . Value ) && symbol . flags & SymbolFlags . Type ? getDefinitionFromSymbol ( typeChecker , skipAlias ( symbol , typeChecker ) , node , failedAliasResolution )
515
- : undefined ;
533
+ : undefined ;
516
534
}
517
535
518
536
function definitionFromType ( type : Type , checker : TypeChecker , node : Node , failedAliasResolution : boolean | undefined ) : readonly DefinitionInfo [ ] {
0 commit comments