@@ -434,7 +434,7 @@ namespace ts.server {
434434 const memGetDefinition = memoize ( getDefinition ) ;
435435 projectService . forEachEnabledProject ( project => {
436436 if ( ! addToSeen ( seenProjects , project . projectName ) ) return ;
437- const definition = getDefinitionInProject ( memGetDefinition ( ) , defaultProject , project ) ;
437+ const definition = mapDefinitionInProject ( memGetDefinition ( ) , defaultProject , project ) ;
438438 if ( definition ) {
439439 toDo = callbackProjectAndLocation < TLocation > ( { project, location : definition as TLocation } , projectService , toDo , seenProjects , cb ) ;
440440 }
@@ -446,22 +446,46 @@ namespace ts.server {
446446 }
447447 }
448448
449- function getDefinitionInProject ( definition : DocumentPosition | undefined , definingProject : Project , project : Project ) : DocumentPosition | undefined {
450- if ( ! definition || project . containsFile ( toNormalizedPath ( definition . fileName ) ) ) return definition ;
449+ function mapDefinitionInProject ( definition : DocumentPosition | undefined , definingProject : Project , project : Project ) : DocumentPosition | undefined {
450+ // If the definition is actually from the project, definition is correct as is
451+ if ( ! definition ||
452+ project . containsFile ( toNormalizedPath ( definition . fileName ) ) &&
453+ ! isLocationProjectReferenceRedirect ( project , definition ) ) {
454+ return definition ;
455+ }
451456 const mappedDefinition = definingProject . isSourceOfProjectReferenceRedirect ( definition . fileName ) ?
452457 definition :
453458 definingProject . getLanguageService ( ) . getSourceMapper ( ) . tryGetGeneratedPosition ( definition ) ;
454459 return mappedDefinition && project . containsFile ( toNormalizedPath ( mappedDefinition . fileName ) ) ? mappedDefinition : undefined ;
455460 }
456461
462+ function isLocationProjectReferenceRedirect ( project : Project , location : DocumentPosition | undefined ) {
463+ if ( ! location ) return false ;
464+ const program = project . getLanguageService ( ) . getProgram ( ) ;
465+ if ( ! program ) return false ;
466+ const sourceFile = program . getSourceFile ( location . fileName ) ;
467+
468+ // It is possible that location is attached to project but
469+ // the program actually includes its redirect instead.
470+ // This happens when rootFile in project is one of the file from referenced project
471+ // Thus root is attached but program doesnt have the actual .ts file but .d.ts
472+ // If this is not the file we were actually looking, return rest of the toDo
473+ return ! ! sourceFile &&
474+ sourceFile . resolvedPath !== sourceFile . path &&
475+ sourceFile . resolvedPath !== project . toPath ( location . fileName ) ;
476+ }
477+
457478 function callbackProjectAndLocation < TLocation extends DocumentPosition | undefined > (
458479 projectAndLocation : ProjectAndLocation < TLocation > ,
459480 projectService : ProjectService ,
460481 toDo : ProjectAndLocation < TLocation > [ ] | undefined ,
461482 seenProjects : Map < true > ,
462483 cb : CombineProjectOutputCallback < TLocation > ,
463484 ) : ProjectAndLocation < TLocation > [ ] | undefined {
464- if ( projectAndLocation . project . getCancellationToken ( ) . isCancellationRequested ( ) ) return undefined ; // Skip rest of toDo if cancelled
485+ const { project, location } = projectAndLocation ;
486+ if ( project . getCancellationToken ( ) . isCancellationRequested ( ) ) return undefined ; // Skip rest of toDo if cancelled
487+ // If this is not the file we were actually looking, return rest of the toDo
488+ if ( isLocationProjectReferenceRedirect ( project , location ) ) return toDo ;
465489 cb ( projectAndLocation , ( project , location ) => {
466490 seenProjects . set ( projectAndLocation . project . projectName , true ) ;
467491 const originalLocation = projectService . getOriginalLocationEnsuringConfiguredProject ( project , location ) ;
@@ -475,8 +499,8 @@ namespace ts.server {
475499 }
476500 const symlinkedProjectsMap = projectService . getSymlinkedProjects ( originalScriptInfo ) ;
477501 if ( symlinkedProjectsMap ) {
478- symlinkedProjectsMap . forEach ( ( symlinkedProjects ) => {
479- for ( const symlinkedProject of symlinkedProjects ) addToTodo ( { project : symlinkedProject , location : originalLocation as TLocation } , toDo ! , seenProjects ) ;
502+ symlinkedProjectsMap . forEach ( ( symlinkedProjects , symlinkedPath ) => {
503+ for ( const symlinkedProject of symlinkedProjects ) addToTodo ( { project : symlinkedProject , location : { fileName : symlinkedPath , pos : originalLocation . pos } as TLocation } , toDo ! , seenProjects ) ;
480504 } ) ;
481505 }
482506 return originalLocation === location ? undefined : originalLocation ;
0 commit comments