@@ -22,6 +22,7 @@ import {
2222 findAncestor ,
2323 first ,
2424 flatMap ,
25+ forEach ,
2526 FunctionLikeDeclaration ,
2627 getAssignmentDeclarationKind ,
2728 getContainingObjectLiteralElement ,
@@ -41,6 +42,7 @@ import {
4142 hasEffectiveModifier ,
4243 hasInitializer ,
4344 hasStaticModifier ,
45+ isAnyImportOrBareOrAccessedRequire ,
4446 isAssignmentDeclaration ,
4547 isAssignmentExpression ,
4648 isBinaryExpression ,
@@ -103,6 +105,7 @@ import {
103105 textRangeContainsPositionInclusive ,
104106 TextSpan ,
105107 tryCast ,
108+ tryGetModuleSpecifierFromDeclaration ,
106109 TsPlusSymbolTag ,
107110 Type ,
108111 TypeChecker ,
@@ -172,13 +175,12 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
172175 // TSPLUS EXTENSION BEGIN
173176 let symbol : Symbol | undefined ;
174177 let failedAliasResolution : boolean | undefined ;
175- let fallbackNode = node ;
176178
177179 const nodeSymbol = typeChecker . getSymbolAtLocation ( node )
178180 if ( ! nodeSymbol ) {
179181 if ( isPropertyAccessExpression ( parent ) ) {
180182 const nodeType = typeChecker . getTypeAtLocation ( node ) ;
181- if ( nodeType . symbol && isTsPlusSymbol ( nodeType . symbol ) ) {
183+ if ( nodeType . symbol && isTsPlusSymbol ( nodeType . symbol ) ) {
182184 if ( parent . parent && isCallExpression ( parent . parent ) && parent . parent . expression === parent ) {
183185 const declaration = getDeclarationForTsPlus ( typeChecker , parent . parent , nodeType . symbol )
184186 if ( declaration ) {
@@ -196,14 +198,14 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
196198 const type = typeChecker . getTypeAtLocation ( parent . expression ) ;
197199 const extensions = typeChecker . getExtensions ( parent . expression ) ;
198200
199- if ( extensions ) {
201+ if ( extensions ) {
200202 const name = parent . name . escapedText . toString ( ) ;
201203 const staticValueSymbol = typeChecker . getStaticExtension ( type , name ) ;
202- if ( staticValueSymbol ) {
204+ if ( staticValueSymbol ) {
203205 // If execution gets here, it means we have a static variable extension,
204206 // which needs to be treated a little differently
205207 const declaration = staticValueSymbol . patched . valueDeclaration ;
206- if ( declaration && declaration . original ) {
208+ if ( declaration && declaration . original ) {
207209 symbol = ( declaration . original as Declaration ) . symbol ;
208210 }
209211 } else {
@@ -229,22 +231,38 @@ export function getDefinitionAtPosition(program: Program, sourceFile: SourceFile
229231 }
230232 }
231233
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+ }
248266 }
249267 }
250268 // TSPLUS EXTENSION END
@@ -512,7 +530,7 @@ export function getTypeDefinitionAtPosition(typeChecker: TypeChecker, sourceFile
512530
513531 return typeDefinitions . length ? [ ...getFirstTypeArgumentDefinitions ( typeChecker , resolvedType , node , failedAliasResolution ) , ...typeDefinitions ]
514532 : ! ( symbol . flags & SymbolFlags . Value ) && symbol . flags & SymbolFlags . Type ? getDefinitionFromSymbol ( typeChecker , skipAlias ( symbol , typeChecker ) , node , failedAliasResolution )
515- : undefined ;
533+ : undefined ;
516534}
517535
518536function definitionFromType ( type : Type , checker : TypeChecker , node : Node , failedAliasResolution : boolean | undefined ) : readonly DefinitionInfo [ ] {
0 commit comments