Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7fce39f

Browse files
cartermpTIHan
authored andcommitted
Navigable symbols (ctrl+click to go to definition) (dotnet#4906)
* First cut* fix* Order in the court* Rename* get rid of unused gtdservice* wut* Add file* Remove unused opens* do it right (marolf)* Cleanup* unused value* Make the navigable URL the decl symbol* refactor* IT WAS A DIFFERENT MEF* clean up a bit
1 parent23350be commit7fce39f

File tree

6 files changed

+544
-420
lines changed

6 files changed

+544
-420
lines changed

‎vsintegration/src/FSharp.Editor/FSharp.Editor.fsproj‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@
7373
<CompileInclude="Completion\SignatureHelp.fs" />
7474
<CompileInclude="InlineRename\InlineRenameService.fs" />
7575
<CompileInclude="DocumentHighlights\DocumentHighlightsService.fs" />
76+
<CompileInclude="Navigation\GoToDefinition.fs" />
77+
<CompileInclude="Navigation\NavigableSymbolsService.fs" />
7678
<CompileInclude="Navigation\GoToDefinitionService.fs" />
7779
<CompileInclude="Navigation\NavigationBarItemService.fs" />
7880
<CompileInclude="Navigation\NavigateToSearchService.fs" />

‎vsintegration/src/FSharp.Editor/Navigation/GoToDefinition.fs‎

Lines changed: 383 additions & 0 deletions
Large diffs are not rendered by default.

‎vsintegration/src/FSharp.Editor/Navigation/GoToDefinitionService.fs‎

Lines changed: 30 additions & 405 deletions
Large diffs are not rendered by default.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information.
2+
3+
namespaceMicrosoft.VisualStudio.FSharp.Editor
4+
5+
openSystem
6+
openSystem.Threading
7+
openSystem.Threading.Tasks
8+
openSystem.ComponentModel.Composition
9+
10+
openMicrosoft.CodeAnalysis.Text
11+
openMicrosoft.CodeAnalysis.Navigation
12+
13+
openMicrosoft.VisualStudio.Language.Intellisense
14+
openMicrosoft.VisualStudio.Text
15+
openMicrosoft.VisualStudio.Text.Editor
16+
openMicrosoft.VisualStudio.Shell.Interop
17+
openMicrosoft.VisualStudio.Utilities
18+
openMicrosoft.VisualStudio.Shell
19+
20+
[<AllowNullLiteral>]
21+
typeinternalFSharpNavigableSymbol(item: INavigableItem,span: SnapshotSpan,gtd: GoToDefinition,statusBar: StatusBar)=
22+
interface INavigableSymbolwith
23+
member__.Navigate(_:INavigableRelationship)=
24+
gtd.NavigateToItem(item, statusBar)
25+
26+
member__.Relationships=seq{yield PredefinedNavigableRelationships.Definition}
27+
28+
member__.SymbolSpan= span
29+
30+
typeinternalFSharpNavigableSymbolSource(checkerProvider: FSharpCheckerProvider,projectInfoManager: FSharpProjectOptionsManager,serviceProvider: IServiceProvider)=
31+
32+
let mutabledisposed=false
33+
letgtd= GoToDefinition(checkerProvider.Checker, projectInfoManager)
34+
letstatusBar= StatusBar(serviceProvider.GetService<SVsStatusbar,IVsStatusbar>())
35+
36+
interface INavigableSymbolSourcewith
37+
member__.GetNavigableSymbolAsync(triggerSpan:SnapshotSpan,cancellationToken:CancellationToken)=
38+
// Yes, this is a code smell. But this is how the editor API accepts what we would treat as None.
39+
if disposedthennull
40+
else
41+
asyncMaybe{
42+
letsnapshot= triggerSpan.Snapshot
43+
letposition= triggerSpan.Start.Position
44+
letdocument= snapshot.GetOpenDocumentInCurrentContextWithChanges()
45+
let!sourceText= document.GetTextAsync()|> liftTaskAsync
46+
47+
statusBar.Message(SR.LocatingSymbol())
48+
use _= statusBar.Animate()
49+
50+
letgtdTask= gtd.FindDefinitionTask(document, position, cancellationToken)
51+
52+
// Wrap this in a try/with as if the user clicks "Cancel" on the thread dialog, we'll be cancelled
53+
// Task.Wait throws an exception if the task is cancelled, so be sure to catch it.
54+
letgtdCompletedOrError=
55+
try
56+
// This call to Wait() is fine because we want to be able to provide the error message in the status bar.
57+
gtdTask.Wait()
58+
Ok gtdTask
59+
with exc->
60+
Error(Exception.flattenMessage exc)
61+
62+
match gtdCompletedOrErrorwith
63+
| Ok task->
64+
if task.Status= TaskStatus.RanToCompletion&& task.Result.IsSomethen
65+
let(navigableItem,range)= task.Result.Value
66+
67+
letdeclarationTextSpan= RoslynHelpers.FSharpRangeToTextSpan(sourceText, range)
68+
letdeclarationSpan= Span(declarationTextSpan.Start, declarationTextSpan.Length)
69+
letsymbolSpan= SnapshotSpan(snapshot, declarationSpan)
70+
71+
return FSharpNavigableSymbol(navigableItem, symbolSpan, gtd, statusBar):> INavigableSymbol
72+
else
73+
statusBar.TempMessage(SR.CannotDetermineSymbol())
74+
75+
// The NavigableSymbols API accepts 'null' when there's nothing to navigate to.
76+
returnnull
77+
| Error message->
78+
statusBar.TempMessage(String.Format(SR.NavigateToFailed(), message))
79+
80+
// The NavigableSymbols API accepts 'null' when there's nothing to navigate to.
81+
returnnull
82+
}
83+
|> Async.map Option.toObj
84+
|> RoslynHelpers.StartAsyncAsTask cancellationToken
85+
86+
member__.Dispose()=
87+
disposed<-true
88+
89+
[<Export(typeof<INavigableSymbolSourceProvider>)>]
90+
[<Name("F# Navigable Symbol Service")>]
91+
[<ContentType(Constants.FSharpContentType)>]
92+
[<Order>]
93+
typeinternalFSharpNavigableSymbolService
94+
[<ImportingConstructor>]
95+
(
96+
[<Import(typeof<SVsServiceProvider>)>] serviceProvider: IServiceProvider,
97+
checkerProvider: FSharpCheckerProvider,
98+
projectInfoManager: FSharpProjectOptionsManager
99+
)=
100+
101+
interface INavigableSymbolSourceProviderwith
102+
member__.TryCreateNavigableSymbolSource(_:ITextView,_:ITextBuffer)=
103+
new FSharpNavigableSymbolSource(checkerProvider, projectInfoManager, serviceProvider):> INavigableSymbolSource

‎vsintegration/src/FSharp.Editor/QuickInfo/Navigation.fs‎

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,26 @@
33
namespaceMicrosoft.VisualStudio.FSharp.Editor
44

55
openSystem
6+
67
openMicrosoft.CodeAnalysis
8+
9+
openMicrosoft.FSharp.Compiler.SourceCodeServices
10+
711
openMicrosoft.FSharp.Compiler.Range
12+
openMicrosoft.VisualStudio.Shell.Interop
813

914
typeinternalQuickInfoNavigation
1015
(
11-
gotoDefinitionService: FSharpGoToDefinitionService,
16+
serviceProvider: IServiceProvider,
17+
checker: FSharpChecker,
18+
projectInfoManager: FSharpProjectOptionsManager,
1219
initialDoc: Document,
1320
thisSymbolUseRange: range
1421
)=
1522

1623
letworkspace= initialDoc.Project.Solution.Workspace
1724
letsolution= workspace.CurrentSolution
25+
letstatusBar= StatusBar(serviceProvider.GetService<SVsStatusbar,IVsStatusbar>())
1826

1927
member__.IsTargetValid(range:range)=
2028
range<> rangeStartup&&
@@ -36,8 +44,10 @@ type internal QuickInfoNavigation
3644
let!targetDoc= solution.TryGetDocumentFromFSharpRange(range, initialDoc.Project.Id)
3745
let!targetSource= targetDoc.GetTextAsync()
3846
let!targetTextSpan= RoslynHelpers.TryFSharpRangeToTextSpan(targetSource, range)
39-
// to ensure proper navigation decsions we need to check the type of document the navigation call
40-
// is originating from and the target we're provided by default
47+
letgtd= GoToDefinition(checker, projectInfoManager)
48+
49+
// To ensure proper navigation decsions, we need to check the type of document the navigation call
50+
// is originating from and the target we're provided by default:
4151
// - signature files (.fsi) should navigate to other signature files
4252
// - implementation files (.fs) should navigate to other implementation files
4353
let(|Signature|Implementation|)filepath=
@@ -46,11 +56,13 @@ type internal QuickInfoNavigation
4656
match initialDoc.FilePath, targetPathwith
4757
| Signature, Signature
4858
| Implementation, Implementation->
49-
return gotoDefinitionService.TryNavigateToTextSpan(targetDoc, targetTextSpan)
50-
// adjust the target from signature to implementation
59+
return gtd.TryNavigateToTextSpan(targetDoc, targetTextSpan, statusBar)
60+
61+
// Adjust the target from signature to implementation.
5162
| Implementation, Signature->
52-
return! gotoDefinitionService.NavigateToSymbolDefinitionAsync(targetDoc, targetSource, range)|> liftAsync
53-
// adjust the target from implmentation to signature
63+
return! gtd.NavigateToSymbolDefinitionAsync(targetDoc, targetSource, range, statusBar)
64+
65+
// Adjust the target from implmentation to signature.
5466
| Signature, Implementation->
55-
return!gotoDefinitionService.NavigateToSymbolDeclarationAsync(targetDoc, targetSource, range)|> liftAsync
67+
return!gtd.NavigateToSymbolDeclarationAsync(targetDoc, targetSource, range, statusBar)
5668
}|> Async.Ignore|> Async.StartImmediate

‎vsintegration/src/FSharp.Editor/QuickInfo/QuickInfoProvider.fs‎

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -159,10 +159,10 @@ module private FSharpQuickInfo =
159159

160160
typeinternalFSharpAsyncQuickInfoSource
161161
(
162+
serviceProvider: IServiceProvider,
162163
xmlMemberIndexService: IVsXMLMemberIndexService,
163164
checkerProvider:FSharpCheckerProvider,
164165
projectInfoManager:FSharpProjectOptionsManager,
165-
gotoDefinitionService:FSharpGoToDefinitionService,
166166
textBuffer:ITextBuffer
167167
)=
168168

@@ -211,7 +211,7 @@ type internal FSharpAsyncQuickInfoSource
211211
letmainDescription,documentation,typeParameterMap,usage,exceptions= ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray(), ResizeArray()
212212
XmlDocumentation.BuildDataTipText(documentationBuilder, mainDescription.Add, documentation.Add, typeParameterMap.Add, usage.Add, exceptions.Add, quickInfo.StructuredText)
213213
letimageId= Tokenizer.GetImageIdForSymbol(quickInfo.Symbol, quickInfo.SymbolKind)
214-
letnavigation= QuickInfoNavigation(gotoDefinitionService, document, symbolUse.RangeAlternate)
214+
letnavigation= QuickInfoNavigation(serviceProvider, checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
215215
letdocs= joinWithLineBreaks[documentation; typeParameterMap; usage; exceptions]
216216
letcontent= QuickInfoViewProvider.provideContent(imageId, mainDescription, docs, navigation)
217217
letspan= getTrackingSpan quickInfo.Span
@@ -242,7 +242,7 @@ type internal FSharpAsyncQuickInfoSource
242242
]|> ResizeArray
243243
letdocs= joinWithLineBreaks[documentation; typeParameterMap; usage; exceptions]
244244
letimageId= Tokenizer.GetImageIdForSymbol(targetQuickInfo.Symbol, targetQuickInfo.SymbolKind)
245-
letnavigation= QuickInfoNavigation(gotoDefinitionService, document, symbolUse.RangeAlternate)
245+
letnavigation= QuickInfoNavigation(serviceProvider, checkerProvider.Checker, projectInfoManager, document, symbolUse.RangeAlternate)
246246
letcontent= QuickInfoViewProvider.provideContent(imageId, mainDescription, docs, navigation)
247247
letspan= getTrackingSpan targetQuickInfo.Span
248248
return QuickInfoItem(span, content)
@@ -256,11 +256,10 @@ type internal FSharpAsyncQuickInfoSource
256256
typeinternalFSharpAsyncQuickInfoSourceProvider
257257
[<ImportingConstructor>]
258258
(
259-
[<Import(typeof<SVsServiceProvider>)>] serviceProvider:IServiceProvider,
259+
[<Import(typeof<SVsServiceProvider>)>] serviceProvider:IServiceProvider,
260260
checkerProvider:FSharpCheckerProvider,
261-
projectInfoManager:FSharpProjectOptionsManager,
262-
gotoDefinitionService:FSharpGoToDefinitionService
261+
projectInfoManager:FSharpProjectOptionsManager
263262
)=
264263
interface IAsyncQuickInfoSourceProviderwith
265264
override__.TryCreateQuickInfoSource(textBuffer:ITextBuffer):IAsyncQuickInfoSource=
266-
new FSharpAsyncQuickInfoSource(serviceProvider.XMLMemberIndexService, checkerProvider, projectInfoManager, gotoDefinitionService, textBuffer):> IAsyncQuickInfoSource
265+
new FSharpAsyncQuickInfoSource(serviceProvider, serviceProvider.XMLMemberIndexService, checkerProvider, projectInfoManager, textBuffer):> IAsyncQuickInfoSource

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp