Skip to content

Commit f51cd9d

Browse files
authored
Enable LSP features in razor (.cshtml) files (I) (#274)
* tests/CSharpLanguageServer.Tests: re-enable testReferenceWorksToAspNetRazorPageReferencedValue * Use Seq.choose * Update how $/progress is logged in Tooling.fs * Add razorCsharpDocumentFilter in src/CSharpLanguageServer/Types.fs * src/CSharpLanguageServer/RoslynHelpers.fs: extract getProjectForPathOnSolution fn * ServerRequestContext: update FindSymbol' to return Project and optional Document 'Document' may not be available when operating on a razor document * src/CSharpLanguageServer/Conversions.fs: update fromRoslynDiagnostic to return a mapped line span + mapped uri * src/CSharpLanguageServer/Conversions.fs: drop module Path
1 parent f2bf9ab commit f51cd9d

File tree

18 files changed

+79
-76
lines changed

18 files changed

+79
-76
lines changed

src/CSharpLanguageServer/Conversions.fs

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,6 @@ module Uri =
3333
Name = Uri.UnescapeDataString(Uri(unescape uri).Segments |> Array.last) }
3434

3535

36-
module Path =
37-
let toUri = Uri.fromPath
38-
39-
let fromUri = Uri.toPath
40-
41-
let toWorkspaceFolder = toUri >> Uri.toWorkspaceFolder
42-
43-
4436
module Position =
4537
let fromLinePosition (pos: LinePosition) : Position =
4638
{ Line = uint32 pos.Line
@@ -74,7 +66,7 @@ module Range =
7466
module Location =
7567
let fromRoslynLocation (loc: Microsoft.CodeAnalysis.Location) : option<Location> =
7668
let toLspLocation (path: string) span : Location =
77-
{ Uri = path |> Path.toUri
69+
{ Uri = path |> Uri.fromPath
7870
Range = span |> Range.fromLinePositionSpan }
7971

8072
match loc.Kind with
@@ -237,9 +229,7 @@ module SymbolInformation =
237229
Tags = None }
238230

239231
symbol.Locations
240-
|> Seq.map Location.fromRoslynLocation
241-
|> Seq.filter _.IsSome
242-
|> Seq.map _.Value
232+
|> Seq.choose Location.fromRoslynLocation
243233
|> Seq.map toSymbolInformation
244234
|> Seq.toList
245235

@@ -254,19 +244,24 @@ module DiagnosticSeverity =
254244

255245

256246
module Diagnostic =
257-
let fromRoslynDiagnostic (diagnostic: Microsoft.CodeAnalysis.Diagnostic) : Diagnostic =
247+
let fromRoslynDiagnostic (diagnostic: Microsoft.CodeAnalysis.Diagnostic) : Diagnostic * string =
258248
let diagnosticCodeUrl = diagnostic.Descriptor.HelpLinkUri |> Option.ofObj
259249

260-
{ Range = diagnostic.Location.GetLineSpan().Span |> Range.fromLinePositionSpan
261-
Severity = Some(diagnostic.Severity |> DiagnosticSeverity.fromRoslynDiagnosticSeverity)
262-
Code = Some(U2.C2 diagnostic.Id)
263-
CodeDescription = diagnosticCodeUrl |> Option.map (fun x -> { Href = x |> URI })
264-
Source = Some "lsp"
265-
Message = diagnostic.GetMessage()
266-
RelatedInformation = None
267-
// TODO: Convert diagnostic.Descriptor.CustomTags to Tags
268-
Tags = None
269-
Data = None }
250+
let mappedLineSpan = diagnostic.Location.GetMappedLineSpan()
251+
252+
let diagnostic =
253+
{ Range = mappedLineSpan.Span |> Range.fromLinePositionSpan
254+
Severity = Some(diagnostic.Severity |> DiagnosticSeverity.fromRoslynDiagnosticSeverity)
255+
Code = Some(U2.C2 diagnostic.Id)
256+
CodeDescription = diagnosticCodeUrl |> Option.map (fun x -> { Href = x |> URI })
257+
Source = Some "lsp"
258+
Message = diagnostic.GetMessage()
259+
RelatedInformation = None
260+
// TODO: Convert diagnostic.Descriptor.CustomTags to Tags
261+
Tags = None
262+
Data = None }
263+
264+
(diagnostic, mappedLineSpan.Path |> Uri.fromPath)
270265

271266

272267
module CompletionContext =

src/CSharpLanguageServer/Handlers/CallHierarchy.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,7 @@ module CallHierarchy =
4747
|> Seq.toArray
4848

4949
info.CallingSymbol.Locations
50-
|> Seq.map Location.fromRoslynLocation
51-
|> Seq.filter _.IsSome
52-
|> Seq.map _.Value
50+
|> Seq.choose Location.fromRoslynLocation
5351
|> Seq.map (fun loc ->
5452
{ From = CallHierarchyItem.fromSymbolAndLocation (info.CallingSymbol) loc
5553
FromRanges = fromRanges })

src/CSharpLanguageServer/Handlers/CodeAction.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,8 +226,8 @@ module CodeAction =
226226
match newDocFilePathMaybe with
227227
| Some newDocFilePath ->
228228
let textEditDocument =
229-
{ Uri = newDocFilePath |> Path.toUri
230-
Version = newDocFilePath |> Path.toUri |> tryGetDocVersionByUri }
229+
{ Uri = Uri.fromPath newDocFilePath
230+
Version = newDocFilePath |> Uri.fromPath |> tryGetDocVersionByUri }
231231

232232
docTextEdits.Add(
233233
{ TextDocument = textEditDocument
@@ -255,8 +255,8 @@ module CodeAction =
255255
|> Array.ofSeq
256256

257257
let textEditDocument =
258-
{ Uri = originalDoc.FilePath |> Path.toUri
259-
Version = originalDoc.FilePath |> Path.toUri |> tryGetDocVersionByUri }
258+
{ Uri = originalDoc.FilePath |> Uri.fromPath
259+
Version = originalDoc.FilePath |> Uri.fromPath |> tryGetDocVersionByUri }
260260

261261
docTextEdits.Add(
262262
{ TextDocument = textEditDocument

src/CSharpLanguageServer/Handlers/Definition.fs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ open CSharpLanguageServer.State
77

88
[<RequireQualifiedAccess>]
99
module Definition =
10-
let provider (clientCapabilities: ClientCapabilities) : U2<bool, DefinitionOptions> option = Some(U2.C1 true)
10+
let provider (_cc: ClientCapabilities) : U2<bool, DefinitionOptions> option = Some(U2.C1 true)
1111

1212
let handle
1313
(context: ServerRequestContext)
@@ -16,7 +16,7 @@ module Definition =
1616
async {
1717
match! context.FindSymbol' p.TextDocument.Uri p.Position with
1818
| None -> return None |> LspResult.success
19-
| Some(symbol, doc) ->
20-
let! locations = context.ResolveSymbolLocations symbol (Some doc.Project)
19+
| Some(symbol, project, _) ->
20+
let! locations = context.ResolveSymbolLocations symbol (Some project)
2121
return locations |> Array.ofList |> Definition.C2 |> U2.C1 |> Some |> LspResult.success
2222
}

src/CSharpLanguageServer/Handlers/Diagnostic.fs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ module Diagnostic =
4747
let diagnostics =
4848
semanticModel.GetDiagnostics()
4949
|> Seq.map Diagnostic.fromRoslynDiagnostic
50+
|> Seq.map fst
5051
|> Array.ofSeq
5152

5253
return { emptyReport with Items = diagnostics } |> U2.C1 |> LspResult.success
@@ -70,7 +71,7 @@ module Diagnostic =
7071
d.Location.SourceTree
7172
|> Option.ofObj
7273
|> Option.map _.FilePath
73-
|> Option.map Path.toUri
74+
|> Option.map Uri.fromPath
7475

7576
let diagnosticsByDocument =
7677
compilation.GetDiagnostics(ct)
@@ -79,11 +80,17 @@ module Diagnostic =
7980
|> Seq.map (fun (uri, ds) -> (uri.Value, ds))
8081

8182
for (uri, docDiagnostics) in diagnosticsByDocument do
83+
let items =
84+
docDiagnostics
85+
|> Seq.map Diagnostic.fromRoslynDiagnostic
86+
|> Seq.map fst
87+
|> Array.ofSeq
88+
8289
let fullDocumentReport: WorkspaceFullDocumentDiagnosticReport =
8390
{ Kind = "full"
8491
ResultId = None
8592
Uri = uri
86-
Items = docDiagnostics |> Seq.map Diagnostic.fromRoslynDiagnostic |> Array.ofSeq
93+
Items = items
8794
Version = None }
8895

8996
let documentReport: WorkspaceDocumentDiagnosticReport = U2.C1 fullDocumentReport

src/CSharpLanguageServer/Handlers/DocumentHighlight.fs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,20 +49,19 @@ module DocumentHighlight =
4949

5050
return
5151
locations
52-
|> Seq.map Location.fromRoslynLocation
53-
|> Seq.filter _.IsSome
54-
|> Seq.map _.Value
52+
|> Seq.choose Location.fromRoslynLocation
5553
|> Seq.map (fun l ->
5654
{ Range = l.Range
5755
Kind = Some DocumentHighlightKind.Read })
5856
}
5957

6058
match! context.FindSymbol' p.TextDocument.Uri p.Position with
61-
| None -> return None |> LspResult.success
62-
| Some(symbol, doc) ->
59+
| Some(symbol, _, Some doc) ->
6360
if shouldHighlight symbol then
6461
let! highlights = getHighlights symbol doc
6562
return highlights |> Seq.toArray |> Some |> LspResult.success
6663
else
6764
return None |> LspResult.success
65+
66+
| _ -> return None |> LspResult.success
6867
}

src/CSharpLanguageServer/Handlers/Hover.fs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module Hover =
1313
let handle (context: ServerRequestContext) (p: HoverParams) : AsyncLspResult<Hover option> = async {
1414
match! context.FindSymbol' p.TextDocument.Uri p.Position with
1515
| None -> return None |> LspResult.success
16-
| Some(symbol, _) ->
16+
| Some(symbol, _, _) ->
1717
let content = DocumentationUtil.markdownDocForSymbolWithSignature symbol
1818

1919
let hover =

src/CSharpLanguageServer/Handlers/InlayHint.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,9 +250,7 @@ module InlayHint =
250250

251251
let inlayHints =
252252
root.DescendantNodes(textSpan, fun node -> node.Span.IntersectsWith(textSpan))
253-
|> Seq.map (toInlayHint semanticModel sourceText.Lines)
254-
|> Seq.filter Option.isSome
255-
|> Seq.map Option.get
253+
|> Seq.choose (toInlayHint semanticModel sourceText.Lines)
256254

257255
return inlayHints |> Seq.toArray |> Some |> LspResult.success
258256
}

src/CSharpLanguageServer/Handlers/References.fs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ module References =
1818

1919
return
2020
locations
21-
|> Seq.map Location.fromRoslynLocation
22-
|> Seq.filter _.IsSome
23-
|> Seq.map _.Value
21+
|> Seq.choose Location.fromRoslynLocation
2422
|> Seq.distinct
2523
|> Seq.toArray
2624
|> Some

src/CSharpLanguageServer/Handlers/Rename.fs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ module Rename =
5252
|> Seq.map U2.C1
5353
|> Array.ofSeq
5454

55-
let uri = originalDoc.FilePath |> Path.toUri
55+
let uri = originalDoc.FilePath |> Uri.fromPath
5656

5757
let textEditDocument =
5858
{ Uri = uri
@@ -144,13 +144,13 @@ module Rename =
144144
let handle (context: ServerRequestContext) (p: RenameParams) : AsyncLspResult<WorkspaceEdit option> = async {
145145
match! context.FindSymbol' p.TextDocument.Uri p.Position with
146146
| None -> return None |> LspResult.success
147-
| Some(symbol, doc) ->
147+
| Some(symbol, project, _) ->
148148
let! ct = Async.CancellationToken
149-
let originalSolution = doc.Project.Solution
149+
let originalSolution = project.Solution
150150

151151
let! updatedSolution =
152152
Renamer.RenameSymbolAsync(
153-
doc.Project.Solution,
153+
project.Solution,
154154
symbol,
155155
SymbolRenameOptions(RenameOverloads = true, RenameFile = true),
156156
p.NewName,

0 commit comments

Comments
 (0)