@@ -565,17 +565,77 @@ type internal GoToDefinition(metadataAsSource: FSharpMetadataAsSourceService) =
565565                return  this.NavigateToItem( item,  cancellationToken) 
566566        } 
567567
568-     member  this.NavigateToExternalDeclarationAsync 
569-         ( 
570-             targetSymbolUse :  FSharpSymbolUse , 
571-             metadataReferences :  seq < MetadataReference > 
572-         )  = 
573-         foregroundCancellableTask
574-             { 
575-                 let!  cancellationToken  =  CancellableTask.getCancellationToken() 
576-                 do !  ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync( cancellationToken) 
577-                 return  this.NavigateToExternalDeclaration( targetSymbolUse,  metadataReferences,  cancellationToken) 
578-             } 
568+     member  this.NavigateToExternalDeclarationAsync   ( targetSymbolUse :  FSharpSymbolUse ,  metadataReferences :  seq < MetadataReference >)  = 
569+         let  textOpt  = 
570+             match  targetSymbolUse.Symbol with 
571+             |  :?  FSharpEntity as  symbol ->  symbol.TryGetMetadataText()  |>  Option.map ( fun  text  ->  text,  symbol.DisplayName) 
572+             |  :?  FSharpMemberOrFunctionOrValue as  symbol -> 
573+                 symbol.ApparentEnclosingEntity.TryGetMetadataText() 
574+                 |>  Option.map ( fun  text  ->  text,  symbol.ApparentEnclosingEntity.DisplayName) 
575+             |  :?  FSharpField as  symbol -> 
576+                 match  symbol.DeclaringEntity with 
577+                 |  Some entity -> 
578+                     let  text  =  entity.TryGetMetadataText() 
579+ 
580+                     match  text with 
581+                     |  Some text ->  Some( text,  entity.DisplayName) 
582+                     |  None ->  None
583+                 |  None ->  None
584+             |  :?  FSharpUnionCase as  symbol -> 
585+                 symbol.DeclaringEntity.TryGetMetadataText() 
586+                 |>  Option.map ( fun  text  ->  text,  symbol.DisplayName) 
587+             |  _  ->  None
588+ 
589+         match  textOpt with 
590+         |  None ->  CancellableTask.singleton false 
591+         |  Some ( text,  fileName)  -> 
592+             foregroundCancellableTask
593+                 { 
594+                     let!  cancellationToken  =  CancellableTask.getCancellationToken() 
595+                     do !  ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync( cancellationToken) 
596+ 
597+                     let  tmpProjInfo ,  tmpDocInfo  = 
598+                         MetadataAsSource.generateTemporaryDocument ( 
599+                             AssemblyIdentity( targetSymbolUse.Symbol.Assembly.QualifiedName), 
600+                             fileName, 
601+                             metadataReferences
602+                         ) 
603+                     let  tmpShownDocOpt  = 
604+                         metadataAsSource.ShowDocument( tmpProjInfo,  tmpDocInfo.FilePath,  SourceText.From( text.ToString())) 
605+ 
606+                     match  tmpShownDocOpt with 
607+                     |  ValueNone -> 
608+                         return  false 
609+                     |  ValueSome tmpShownDoc -> 
610+                         let!  _ ,  checkResults  =  tmpShownDoc.GetFSharpParseAndCheckResultsAsync( " NavigateToExternalDeclaration" ) 
611+ 
612+                         let  r  = 
613+                             // This tries to find the best possible location of the target symbol's location in the metadata source. 
614+                             // We really should rely on symbol equality within FCS instead of doing it here, 
615+                             //     but the generated metadata as source isn't perfect for symbol equality. 
616+                             let  symbols  =  checkResults.GetAllUsesOfAllSymbolsInFile( cancellationToken) 
617+ 
618+                             symbols
619+                             |>  Seq.tryFindV ( tryFindExternalSymbolUse targetSymbolUse) 
620+                             |>  ValueOption.map ( fun  x  ->  x.Range) 
621+                         
622+                         let!  span  = 
623+                             cancellableTask { 
624+                                 let!  cancellationToken  =  CancellableTask.getCancellationToken() 
625+ 
626+                                 match  r with 
627+                                 |  ValueNone ->  return  TextSpan.empty
628+                                 |  ValueSome r -> 
629+                                     let!  text  =  tmpShownDoc.GetTextAsync( cancellationToken) 
630+ 
631+                                     match  RoslynHelpers.TryFSharpRangeToTextSpan( text,  r)  with 
632+                                     |  ValueSome span ->  return  span
633+                                     |  _  ->  return  TextSpan.empty
634+                             } 
635+ 
636+                         let  navItem  =  FSharpGoToDefinitionNavigableItem( tmpShownDoc,  span) 
637+                         return  this.NavigateToItem( navItem,  cancellationToken) 
638+                 } 
579639
580640    member  this.NavigateToExternalDeclaration 
581641        ( 
@@ -718,17 +778,12 @@ type internal FSharpNavigation(metadataAsSource: FSharpMetadataAsSourceService,
718778            let  gtd  =  GoToDefinition( metadataAsSource) 
719779            let!  result  =  gtd.FindDefinitionAtPosition( initialDoc,  position) 
720780
721-             
722781            match  result with 
723782            |  ValueSome( FSharpGoToDefinitionResult.NavigableItem( navItem),  _)  -> 
724783                return  ImmutableArray.create navItem
725784            |  ValueSome( FSharpGoToDefinitionResult.ExternalAssembly( targetSymbolUse,  metadataReferences),  _)  -> 
726-                 let!  res  =  gtd.NavigateToExternalDeclarationAsync( targetSymbolUse,  metadataReferences) 
727-                 if  not  res then 
728-                     return  ImmutableArray.empty
729-                 else 
730-                     // TODO: return something? Maybe cancelled task? 
731-                     return  ImmutableArray.empty
785+                 do !  gtd.NavigateToExternalDeclarationAsync( targetSymbolUse,  metadataReferences)  |>  CancellableTask.ignore    
786+                 return  ImmutableArray.empty
732787            |  _  -> 
733788                return  ImmutableArray.empty
734789        } 
0 commit comments