From e3e57fe7b999c64cb4a62694671d3ec3677c2bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Fri, 5 Apr 2024 09:03:21 +0300 Subject: [PATCH 1/6] CSharpLanguageServer.Handlers.Hover: sync with rework branch Co-authored-by: Adam Tao --- src/CSharpLanguageServer/Handlers/Hover.fs | 4 ++-- src/CSharpLanguageServer/State/ServerRequestScope.fs | 5 +---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/CSharpLanguageServer/Handlers/Hover.fs b/src/CSharpLanguageServer/Handlers/Hover.fs index 4b2f3beb..4c0c2fba 100644 --- a/src/CSharpLanguageServer/Handlers/Hover.fs +++ b/src/CSharpLanguageServer/Handlers/Hover.fs @@ -34,9 +34,9 @@ module Hover = RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { - match! scope.GetSymbolAtPositionOnAnyDocument p.TextDocument.Uri p.Position with + match! scope.FindSymbol' p.TextDocument.Uri p.Position with | None -> return None |> success - | Some (symbol, doc, pos) -> + | Some (symbol, doc) -> let! semanticModel = doc.GetSemanticModelAsync() |> Async.AwaitTask let content = DocumentationUtil.markdownDocForSymbolWithSignature symbol semanticModel |> markdown let hover = diff --git a/src/CSharpLanguageServer/State/ServerRequestScope.fs b/src/CSharpLanguageServer/State/ServerRequestScope.fs index ec9b3342..2037a720 100644 --- a/src/CSharpLanguageServer/State/ServerRequestScope.fs +++ b/src/CSharpLanguageServer/State/ServerRequestScope.fs @@ -45,9 +45,6 @@ type ServerRequestScope (requestId: int, state: ServerState, emitServerEvent, lo return None } - member this.GetSymbolAtPositionOnAnyDocument uri pos = - this.GetSymbolAtPositionOfType AnyDocument uri pos - member this.GetSymbolAtPositionOnUserDocument uri pos = this.GetSymbolAtPositionOfType UserDocument uri pos @@ -62,7 +59,7 @@ type ServerRequestScope (requestId: int, state: ServerState, emitServerEvent, lo member this.EmitMany es = for e in es do this.Emit e - member this.ResolveSymbolLocation + member private this.ResolveSymbolLocation (project: Microsoft.CodeAnalysis.Project option) sym (l: Microsoft.CodeAnalysis.Location) = async { From 7d29d8ad197f3a62476394ba4c1461828812203f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Fri, 5 Apr 2024 09:06:52 +0300 Subject: [PATCH 2/6] CSharpLanguageServer.Handlers.Rename: sync with rework branch Co-authored-by: Adam Tao --- src/CSharpLanguageServer/Handlers/Rename.fs | 11 +++++------ src/CSharpLanguageServer/Lsp/Server.fs | 2 +- .../State/ServerRequestScope.fs | 17 ----------------- 3 files changed, 6 insertions(+), 24 deletions(-) diff --git a/src/CSharpLanguageServer/Handlers/Rename.fs b/src/CSharpLanguageServer/Handlers/Rename.fs index a27a3000..4d3860f7 100644 --- a/src/CSharpLanguageServer/Handlers/Rename.fs +++ b/src/CSharpLanguageServer/Handlers/Rename.fs @@ -87,13 +87,12 @@ module Rename = { PrepareProvider = Some (prepareSupport clientCapabilities) DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let prepare (getDocumentForUriFromCurrentState: ServerDocumentType -> string -> Async) - (_scope: ServerRequestScope) + let prepare (scope: ServerRequestScope) (p: PrepareRenameParams) : AsyncLspResult = async { - match! getDocumentForUriFromCurrentState UserDocument p.TextDocument.Uri with + match scope.GetDocumentForUriOfType UserDocument p.TextDocument.Uri with | None -> return None |> success - | Some doc -> + | Some (doc, _) -> let! docSyntaxTree = doc.GetSyntaxTreeAsync() |> Async.AwaitTask let! docText = doc.GetTextAsync() |> Async.AwaitTask @@ -152,9 +151,9 @@ module Rename = (scope: ServerRequestScope) (p: RenameParams) : AsyncLspResult = async { - match! scope.GetSymbolAtPositionOnUserDocument p.TextDocument.Uri p.Position with + match! scope.FindSymbol' p.TextDocument.Uri p.Position with | None -> return None |> success - | Some (symbol, doc, _) -> + | Some (symbol, doc) -> let originalSolution = doc.Project.Solution let! updatedSolution = diff --git a/src/CSharpLanguageServer/Lsp/Server.fs b/src/CSharpLanguageServer/Lsp/Server.fs index 576f1ed4..67102d3f 100644 --- a/src/CSharpLanguageServer/Lsp/Server.fs +++ b/src/CSharpLanguageServer/Lsp/Server.fs @@ -230,7 +230,7 @@ type CSharpLspServer( override this.CompletionItemResolve(p) = notImplemented override this.TextDocumentPrepareRename(p) = - p |> withReadOnlyScope (Rename.prepare getDocumentForUriFromCurrentState) + p |> withReadOnlyScope Rename.prepare override this.TextDocumentRename(p) = p |> withReadOnlyScope Rename.handle diff --git a/src/CSharpLanguageServer/State/ServerRequestScope.fs b/src/CSharpLanguageServer/State/ServerRequestScope.fs index 2037a720..0e9c87fd 100644 --- a/src/CSharpLanguageServer/State/ServerRequestScope.fs +++ b/src/CSharpLanguageServer/State/ServerRequestScope.fs @@ -1,7 +1,6 @@ namespace CSharpLanguageServer.State open Microsoft.CodeAnalysis -open Microsoft.CodeAnalysis.Text open Microsoft.CodeAnalysis.FindSymbols open Ionide.LanguageServerProtocol.Types open FSharpPlus @@ -32,22 +31,6 @@ type ServerRequestScope (requestId: int, state: ServerState, emitServerEvent, lo member this.GetAnyDocumentForUri (u: string) = this.GetDocumentForUriOfType AnyDocument u |> Option.map fst - member this.GetSymbolAtPositionOfType docType uri pos = async { - match this.GetDocumentForUriOfType docType uri with - | Some (doc, _docType) -> - let! ct = Async.CancellationToken - let! sourceText = doc.GetTextAsync(ct) |> Async.AwaitTask - let position = sourceText.Lines.GetPosition(LinePosition(pos.Line, pos.Character)) - let! symbolRef = SymbolFinder.FindSymbolAtPositionAsync(doc, position, ct) |> Async.AwaitTask - return if isNull symbolRef then None else Some (symbolRef, doc, position) - - | None -> - return None - } - - member this.GetSymbolAtPositionOnUserDocument uri pos = - this.GetSymbolAtPositionOfType UserDocument uri pos - member _.Emit ev = match ev with | SolutionChange newSolution -> From f8bde2c3779194f4501e3ddbb13136478858cb83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Fri, 5 Apr 2024 09:16:35 +0300 Subject: [PATCH 3/6] CSharpLanguageServer.State.ServerRequestScope: GetAnyDocumentForUri -> GetDocument to sync with rework branch --- src/CSharpLanguageServer/Handlers/CodeAction.fs | 4 ++-- src/CSharpLanguageServer/Handlers/CodeLens.fs | 4 ++-- src/CSharpLanguageServer/Handlers/Completion.fs | 2 +- src/CSharpLanguageServer/Handlers/DocumentFormatting.fs | 2 +- src/CSharpLanguageServer/Handlers/DocumentHighlight.fs | 4 ++-- .../Handlers/DocumentOnTypeFormatting.fs | 2 +- .../Handlers/DocumentRangeFormatting.fs | 2 +- src/CSharpLanguageServer/Handlers/DocumentSymbol.fs | 2 +- src/CSharpLanguageServer/Handlers/InlayHint.fs | 2 +- src/CSharpLanguageServer/Handlers/Rename.fs | 4 ++-- src/CSharpLanguageServer/Handlers/SemanticTokens.fs | 2 +- src/CSharpLanguageServer/Handlers/SignatureHelp.fs | 2 +- src/CSharpLanguageServer/Handlers/TextDocumentSync.fs | 4 ++-- src/CSharpLanguageServer/Handlers/Workspace.fs | 8 ++++---- src/CSharpLanguageServer/State/ServerRequestScope.fs | 6 +++--- 15 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/CSharpLanguageServer/Handlers/CodeAction.fs b/src/CSharpLanguageServer/Handlers/CodeAction.fs index facfed56..a6ebb8a0 100644 --- a/src/CSharpLanguageServer/Handlers/CodeAction.fs +++ b/src/CSharpLanguageServer/Handlers/CodeAction.fs @@ -321,7 +321,7 @@ module CodeAction = let handle (wm: ServerRequestScope) (p: CodeActionParams) : AsyncLspResult = async { - match wm.GetAnyDocumentForUri p.TextDocument.Uri with + match wm.GetDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let! docText = doc.GetTextAsync() |> Async.AwaitTask @@ -386,7 +386,7 @@ module CodeAction = p.Data |> Option.map deserialize - match wm.GetAnyDocumentForUri resolutionData.Value.TextDocumentUri with + match wm.GetDocument resolutionData.Value.TextDocumentUri with | None -> return None |> success | Some doc -> let! ct = Async.CancellationToken diff --git a/src/CSharpLanguageServer/Handlers/CodeLens.fs b/src/CSharpLanguageServer/Handlers/CodeLens.fs index c399c873..8e63b9e6 100644 --- a/src/CSharpLanguageServer/Handlers/CodeLens.fs +++ b/src/CSharpLanguageServer/Handlers/CodeLens.fs @@ -133,7 +133,7 @@ module CodeLens = DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: CodeLensParams): AsyncLspResult = async { - let docMaybe = scope.GetAnyDocumentForUri p.TextDocument.Uri + let docMaybe = scope.GetDocument p.TextDocument.Uri match docMaybe with | None -> return None |> success | Some doc -> @@ -170,7 +170,7 @@ module CodeLens = |> Option.map (fun t -> t.ToObject()) |> Option.defaultValue CodeLensData.Default - let docMaybe = scope.GetAnyDocumentForUri lensData.DocumentUri + let docMaybe = scope.GetDocument lensData.DocumentUri let doc = docMaybe.Value let! sourceText = doc.GetTextAsync(ct) |> Async.AwaitTask diff --git a/src/CSharpLanguageServer/Handlers/Completion.fs b/src/CSharpLanguageServer/Handlers/Completion.fs index 8103d6a6..0184b68d 100644 --- a/src/CSharpLanguageServer/Handlers/Completion.fs +++ b/src/CSharpLanguageServer/Handlers/Completion.fs @@ -86,7 +86,7 @@ module Completion = Documentation = description |> Option.map (fun x -> Documentation.String x.Text) } let handle (scope: ServerRequestScope) (p: Types.CompletionParams): AsyncLspResult = async { - let docMaybe = scope.GetUserDocumentForUri p.TextDocument.Uri + let docMaybe = scope.GetUserDocument p.TextDocument.Uri match docMaybe with | None -> return None |> success | Some doc -> diff --git a/src/CSharpLanguageServer/Handlers/DocumentFormatting.fs b/src/CSharpLanguageServer/Handlers/DocumentFormatting.fs index 90392313..9bfd3036 100644 --- a/src/CSharpLanguageServer/Handlers/DocumentFormatting.fs +++ b/src/CSharpLanguageServer/Handlers/DocumentFormatting.fs @@ -35,7 +35,7 @@ module DocumentFormatting = RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: DocumentFormattingParams) : AsyncLspResult = async { - match scope.GetUserDocumentForUri p.TextDocument.Uri with + match scope.GetUserDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let options = FormatUtil.getFormattingOptions doc p.Options diff --git a/src/CSharpLanguageServer/Handlers/DocumentHighlight.fs b/src/CSharpLanguageServer/Handlers/DocumentHighlight.fs index f7b5ba41..d6511ea5 100644 --- a/src/CSharpLanguageServer/Handlers/DocumentHighlight.fs +++ b/src/CSharpLanguageServer/Handlers/DocumentHighlight.fs @@ -66,9 +66,9 @@ module DocumentHighlight = Kind = Some DocumentHighlightKind.Read }) } - match scope.GetDocumentForUriOfType AnyDocument p.TextDocument.Uri with + match scope.GetDocument p.TextDocument.Uri with | None -> return None |> success - | Some (doc, docType) -> + | Some doc -> let! sourceText = doc.GetTextAsync() |> Async.AwaitTask let position = Position.toRoslynPosition sourceText.Lines p.Position let! symbol = SymbolFinder.FindSymbolAtPositionAsync(doc, position) |> Async.AwaitTask diff --git a/src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs b/src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs index b01a35e3..d0a17b5e 100644 --- a/src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs +++ b/src/CSharpLanguageServer/Handlers/DocumentOnTypeFormatting.fs @@ -43,7 +43,7 @@ module DocumentOnTypeFormatting = DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: DocumentOnTypeFormattingParams) : AsyncLspResult = async { - match scope.GetUserDocumentForUri p.TextDocument.Uri with + match scope.GetUserDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let options = FormatUtil.getFormattingOptions doc p.Options diff --git a/src/CSharpLanguageServer/Handlers/DocumentRangeFormatting.fs b/src/CSharpLanguageServer/Handlers/DocumentRangeFormatting.fs index ff068983..27662e9f 100644 --- a/src/CSharpLanguageServer/Handlers/DocumentRangeFormatting.fs +++ b/src/CSharpLanguageServer/Handlers/DocumentRangeFormatting.fs @@ -37,7 +37,7 @@ module DocumentRangeFormatting = RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: DocumentRangeFormattingParams) : AsyncLspResult = async { - match scope.GetUserDocumentForUri p.TextDocument.Uri with + match scope.GetUserDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let options = FormatUtil.getFormattingOptions doc p.Options diff --git a/src/CSharpLanguageServer/Handlers/DocumentSymbol.fs b/src/CSharpLanguageServer/Handlers/DocumentSymbol.fs index 76f01d1e..51edb309 100644 --- a/src/CSharpLanguageServer/Handlers/DocumentSymbol.fs +++ b/src/CSharpLanguageServer/Handlers/DocumentSymbol.fs @@ -316,7 +316,7 @@ module DocumentSymbol = |> Option.bind (fun cc -> cc.HierarchicalDocumentSymbolSupport) |> Option.defaultValue false - match scope.GetAnyDocumentForUri p.TextDocument.Uri with + match scope.GetDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let! semanticModel = doc.GetSemanticModelAsync() |> Async.AwaitTask diff --git a/src/CSharpLanguageServer/Handlers/InlayHint.fs b/src/CSharpLanguageServer/Handlers/InlayHint.fs index a01ae923..e9f0ff3a 100644 --- a/src/CSharpLanguageServer/Handlers/InlayHint.fs +++ b/src/CSharpLanguageServer/Handlers/InlayHint.fs @@ -218,7 +218,7 @@ module InlayHint = DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: InlayHintParams): AsyncLspResult = async { - match scope.GetUserDocumentForUri p.TextDocument.Uri with + match scope.GetUserDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let! semanticModel = doc.GetSemanticModelAsync() |> Async.AwaitTask diff --git a/src/CSharpLanguageServer/Handlers/Rename.fs b/src/CSharpLanguageServer/Handlers/Rename.fs index 4d3860f7..48a090a4 100644 --- a/src/CSharpLanguageServer/Handlers/Rename.fs +++ b/src/CSharpLanguageServer/Handlers/Rename.fs @@ -90,9 +90,9 @@ module Rename = let prepare (scope: ServerRequestScope) (p: PrepareRenameParams) : AsyncLspResult = async { - match scope.GetDocumentForUriOfType UserDocument p.TextDocument.Uri with + match scope.GetUserDocument p.TextDocument.Uri with | None -> return None |> success - | Some (doc, _) -> + | Some doc -> let! docSyntaxTree = doc.GetSyntaxTreeAsync() |> Async.AwaitTask let! docText = doc.GetTextAsync() |> Async.AwaitTask diff --git a/src/CSharpLanguageServer/Handlers/SemanticTokens.fs b/src/CSharpLanguageServer/Handlers/SemanticTokens.fs index 86b66e2a..06592152 100644 --- a/src/CSharpLanguageServer/Handlers/SemanticTokens.fs +++ b/src/CSharpLanguageServer/Handlers/SemanticTokens.fs @@ -111,7 +111,7 @@ module SemanticTokens = (deltaLine, deltaChar, cLen, cToken, cModifiers) let private getSemanticTokensRange (scope: ServerRequestScope) (uri: string) (range: Range option): AsyncLspResult = async { - let docMaybe = scope.GetUserDocumentForUri uri + let docMaybe = scope.GetUserDocument uri match docMaybe with | None -> return None |> success | Some doc -> diff --git a/src/CSharpLanguageServer/Handlers/SignatureHelp.fs b/src/CSharpLanguageServer/Handlers/SignatureHelp.fs index 9e375949..070a03bc 100644 --- a/src/CSharpLanguageServer/Handlers/SignatureHelp.fs +++ b/src/CSharpLanguageServer/Handlers/SignatureHelp.fs @@ -85,7 +85,7 @@ module SignatureHelp = DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } let handle (scope: ServerRequestScope) (p: SignatureHelpParams): AsyncLspResult = async { - let docMaybe = scope.GetUserDocumentForUri p.TextDocument.Uri + let docMaybe = scope.GetUserDocument p.TextDocument.Uri match docMaybe with | None -> return None |> success | Some doc -> diff --git a/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs b/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs index cdc709b5..44326ccf 100644 --- a/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs +++ b/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs @@ -79,7 +79,7 @@ module TextDocumentSync = (changeParams: DidChangeTextDocumentParams) : Async> = async { - let docMaybe = scope.GetUserDocumentForUri changeParams.TextDocument.Uri + let docMaybe = scope.GetUserDocument changeParams.TextDocument.Uri match docMaybe with | Some doc -> let! ct = Async.CancellationToken @@ -119,7 +119,7 @@ module TextDocumentSync = (saveParams: DidSaveTextDocumentParams) : Async> = // we need to add this file to solution if not already - let doc = scope.GetAnyDocumentForUri saveParams.TextDocument.Uri + let doc = scope.GetDocument saveParams.TextDocument.Uri match doc with | Some _ -> diff --git a/src/CSharpLanguageServer/Handlers/Workspace.fs b/src/CSharpLanguageServer/Handlers/Workspace.fs index e43fa9ac..4b86f0f2 100644 --- a/src/CSharpLanguageServer/Handlers/Workspace.fs +++ b/src/CSharpLanguageServer/Handlers/Workspace.fs @@ -35,8 +35,8 @@ module Workspace = RegisterOptions = { Watchers = [| fileSystemWatcher |] } |> serialize |> Some } let private tryReloadDocumentOnUri logMessage diagnosticsPost (scope: ServerRequestScope) uri = async { - match scope.GetDocumentForUriOfType UserDocument uri with - | Some (doc, _) -> + match scope.GetUserDocument uri with + | Some doc -> let fileText = uri |> Util.parseFileUri |> File.ReadAllText let updatedDoc = SourceText.From(fileText) |> doc.WithText @@ -62,8 +62,8 @@ module Workspace = } let private removeDocument diagnosticsPost (scope: ServerRequestScope) uri = - match scope.GetDocumentForUriOfType UserDocument uri with - | Some (existingDoc, _) -> + match scope.GetUserDocument uri with + | Some existingDoc -> let updatedProject = existingDoc.Project.RemoveDocument(existingDoc.Id) scope.Emit(SolutionChange updatedProject.Solution) diff --git a/src/CSharpLanguageServer/State/ServerRequestScope.fs b/src/CSharpLanguageServer/State/ServerRequestScope.fs index 0e9c87fd..7ad8170b 100644 --- a/src/CSharpLanguageServer/State/ServerRequestScope.fs +++ b/src/CSharpLanguageServer/State/ServerRequestScope.fs @@ -25,10 +25,10 @@ type ServerRequestScope (requestId: int, state: ServerState, emitServerEvent, lo member this.GetDocumentForUriOfType = getDocumentForUriOfType this.State - member this.GetUserDocumentForUri (u: string) = + member this.GetUserDocument (u: string) = this.GetDocumentForUriOfType UserDocument u |> Option.map fst - member this.GetAnyDocumentForUri (u: string) = + member this.GetDocument (u: string) = this.GetDocumentForUriOfType AnyDocument u |> Option.map fst member _.Emit ev = @@ -105,7 +105,7 @@ type ServerRequestScope (requestId: int, state: ServerState, emitServerEvent, lo } member this.FindSymbol' (uri: DocumentUri) (pos: Position): Async<(ISymbol * Document) option> = async { - match this.GetAnyDocumentForUri uri with + match this.GetDocument uri with | None -> return None | Some doc -> let! sourceText = doc.GetTextAsync() |> Async.AwaitTask From 3698e834b501c1fd73e1e64a13aad6ed5d566071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Fri, 5 Apr 2024 09:35:19 +0300 Subject: [PATCH 4/6] CSharpLanguageServer.RoslynHelpers: cleanup --- .../Handlers/TextDocumentSync.fs | 19 +++++ src/CSharpLanguageServer/RoslynHelpers.fs | 79 ------------------- 2 files changed, 19 insertions(+), 79 deletions(-) diff --git a/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs b/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs index 44326ccf..5cbf3cd0 100644 --- a/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs +++ b/src/CSharpLanguageServer/Handlers/TextDocumentSync.fs @@ -6,12 +6,31 @@ open Ionide.LanguageServerProtocol.Types open Microsoft.CodeAnalysis.Text open CSharpLanguageServer +open CSharpLanguageServer.Conversions open CSharpLanguageServer.State open CSharpLanguageServer.State.ServerState open CSharpLanguageServer.RoslynHelpers [] module TextDocumentSync = + let private applyLspContentChangesOnRoslynSourceText + (changes: TextDocumentContentChangeEvent[]) + (initialSourceText: SourceText) = + + let applyLspContentChangeOnRoslynSourceText (sourceText: SourceText) (change: TextDocumentContentChangeEvent) = + match change.Range with + | Some changeRange -> + let changeTextSpan = + changeRange |> Range.toLinePositionSpan sourceText.Lines + |> sourceText.Lines.GetTextSpan + + TextChange(changeTextSpan, change.Text) |> sourceText.WithChanges + + | None -> SourceText.From(change.Text) + + changes |> Seq.fold applyLspContentChangeOnRoslynSourceText initialSourceText + + let provider (clientCapabilities: ClientCapabilities option) : TextDocumentSyncOptions option = Some { TextDocumentSyncOptions.Default with diff --git a/src/CSharpLanguageServer/RoslynHelpers.fs b/src/CSharpLanguageServer/RoslynHelpers.fs index a23d0763..9580c5c8 100644 --- a/src/CSharpLanguageServer/RoslynHelpers.fs +++ b/src/CSharpLanguageServer/RoslynHelpers.fs @@ -24,85 +24,6 @@ open Microsoft.CodeAnalysis.Text open CSharpLanguageServer.Util open CSharpLanguageServer.Conversions -let applyLspContentChangesOnRoslynSourceText - (changes: Types.TextDocumentContentChangeEvent[]) - (initialSourceText: SourceText) = - - let applyLspContentChangeOnRoslynSourceText (sourceText: SourceText) (change: Types.TextDocumentContentChangeEvent) = - match change.Range with - | Some changeRange -> - let changeTextSpan = - changeRange |> Range.toLinePositionSpan sourceText.Lines - |> sourceText.Lines.GetTextSpan - - TextChange(changeTextSpan, change.Text) |> sourceText.WithChanges - - | None -> SourceText.From(change.Text) - - changes |> Seq.fold applyLspContentChangeOnRoslynSourceText initialSourceText - -let formatSymbol (sym: ISymbol) - showAttributes - (semanticModelMaybe: SemanticModel option) - (posMaybe: int option) = - match showAttributes, semanticModelMaybe, posMaybe with - | true, Some semanticModel, Some pos -> sym.ToMinimalDisplayString(semanticModel, pos) - | true, _, _ -> sym.ToDisplayString() - | false, _, _ -> sym.Name - -let getSymbolNameAndKind - (semanticModel: SemanticModel option) - (pos: int option) - (symbol: ISymbol) = - let showAttributes = true - - match symbol with - | :? ILocalSymbol as ls -> - (formatSymbol ls showAttributes semanticModel pos, - Types.SymbolKind.Variable) - - | :? IFieldSymbol as fs -> - (formatSymbol fs showAttributes semanticModel pos, - Types.SymbolKind.Field) - - | :? IPropertySymbol as ps -> - (formatSymbol ps showAttributes semanticModel pos, - Types.SymbolKind.Property) - - | :? IMethodSymbol as ms -> - (formatSymbol ms showAttributes semanticModel pos, - match ms.MethodKind with - | MethodKind.Constructor -> Types.SymbolKind.Constructor - | MethodKind.StaticConstructor -> Types.SymbolKind.Constructor - | MethodKind.BuiltinOperator -> Types.SymbolKind.Operator - | MethodKind.UserDefinedOperator -> Types.SymbolKind.Operator - | MethodKind.Conversion -> Types.SymbolKind.Operator - | _ -> Types.SymbolKind.Method) - - | :? ITypeSymbol as ts -> - (formatSymbol ts showAttributes semanticModel pos, - match ts.TypeKind with - | TypeKind.Class -> Types.SymbolKind.Class - | TypeKind.Enum -> Types.SymbolKind.Enum - | TypeKind.Struct -> Types.SymbolKind.Struct - | TypeKind.Interface -> Types.SymbolKind.Interface - | TypeKind.Delegate -> Types.SymbolKind.Class - | TypeKind.Array -> Types.SymbolKind.Array - | TypeKind.TypeParameter -> Types.SymbolKind.TypeParameter - | _ -> Types.SymbolKind.Class) - - | :? IEventSymbol as es -> - (formatSymbol es showAttributes semanticModel pos, - Types.SymbolKind.Event) - - | :? INamespaceSymbol as ns -> - - (formatSymbol ns showAttributes semanticModel pos, - Types.SymbolKind.Namespace) - - | _ -> - (symbol.ToString(), Types.SymbolKind.File) - type DocumentSymbolCollectorForMatchingSymbolName (documentUri, sym: ISymbol) = inherit CSharpSyntaxWalker(SyntaxWalkerDepth.Token) From 8be7cd66b1809304582d035912080e2120dfe13f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Wed, 10 Apr 2024 09:15:20 +0300 Subject: [PATCH 5/6] CSharpLanguageServer.Types: update defaultDocumentSelector with Language=None to unblock vscode (and possibly other clients) --- src/CSharpLanguageServer/Types.fs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CSharpLanguageServer/Types.fs b/src/CSharpLanguageServer/Types.fs index 46117f9f..f7acd345 100644 --- a/src/CSharpLanguageServer/Types.fs +++ b/src/CSharpLanguageServer/Types.fs @@ -82,7 +82,7 @@ type SignatureHelpRegistrationOptions = type DocumentFilter with static member Default: DocumentFilter = - { Language = Some "cs" + { Language = None Scheme = Some "file" Pattern = Some "**/*.cs" } From b0fbe275e9cf6c2a6241ad9cd3d42edef2ddd371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Saulius=20Menkevi=C4=8Dius?= Date: Thu, 11 Apr 2024 08:33:09 +0300 Subject: [PATCH 6/6] CSharpLanguageServer.Handlers: use "scope" for ServerRequestScope --- .../Handlers/CallHierarchy.fs | 14 +++++------ .../Handlers/CodeAction.fs | 14 +++++------ .../Handlers/Definition.fs | 6 ++--- .../Handlers/Implementation.fs | 8 +++---- .../Handlers/TypeDefinition.fs | 6 ++--- .../Handlers/TypeHierarchy.fs | 24 +++++++++---------- 6 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/CSharpLanguageServer/Handlers/CallHierarchy.fs b/src/CSharpLanguageServer/Handlers/CallHierarchy.fs index b27a350c..b245e7e0 100644 --- a/src/CSharpLanguageServer/Handlers/CallHierarchy.fs +++ b/src/CSharpLanguageServer/Handlers/CallHierarchy.fs @@ -47,10 +47,10 @@ module CallHierarchy = RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let prepare (wm: ServerRequestScope) (p: CallHierarchyPrepareParams) : AsyncLspResult = async { - match! wm.FindSymbol p.TextDocument.Uri p.Position with + let prepare (scope: ServerRequestScope) (p: CallHierarchyPrepareParams) : AsyncLspResult = async { + match! scope.FindSymbol p.TextDocument.Uri p.Position with | Some symbol when isCallableSymbol symbol -> - let! itemList = HierarchyItem.fromSymbol wm.ResolveSymbolLocations symbol + let! itemList = HierarchyItem.fromSymbol scope.ResolveSymbolLocations symbol return itemList |> List.toArray @@ -60,7 +60,7 @@ module CallHierarchy = } let incomingCalls - (wm: ServerRequestScope) + (scope: ServerRequestScope) (p: CallHierarchyIncomingCallsParams) : AsyncLspResult = async { let toCallHierarchyIncomingCalls (info: SymbolCallerInfo) : CallHierarchyIncomingCall seq = @@ -73,10 +73,10 @@ module CallHierarchy = { From = HierarchyItem.fromSymbolAndLocation (info.CallingSymbol) (loc |> Location.fromRoslynLocation) FromRanges = fromRanges }) - match! wm.FindSymbol p.Item.Uri p.Item.Range.Start with + match! scope.FindSymbol p.Item.Uri p.Item.Range.Start with | None -> return None |> success | Some symbol -> - let! callers = wm.FindCallers symbol + let! callers = scope.FindCallers symbol // TODO: If we remove info.IsDirect, then we will get lots of false positive. But if we keep it, // we will miss many callers. Maybe it should have some change in LSP protocol. return @@ -89,7 +89,7 @@ module CallHierarchy = } let outgoingCalls - (wm: ServerRequestScope) + (scope: ServerRequestScope) (p: CallHierarchyOutgoingCallsParams) : AsyncLspResult = async { // TODO: There is no memthod of SymbolFinder which can find all outgoing calls of a specific symbol. diff --git a/src/CSharpLanguageServer/Handlers/CodeAction.fs b/src/CSharpLanguageServer/Handlers/CodeAction.fs index a6ebb8a0..4aaee66a 100644 --- a/src/CSharpLanguageServer/Handlers/CodeAction.fs +++ b/src/CSharpLanguageServer/Handlers/CodeAction.fs @@ -318,10 +318,10 @@ module CodeAction = ResolveProvider = Some true DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let handle (wm: ServerRequestScope) + let handle (scope: ServerRequestScope) (p: CodeActionParams) : AsyncLspResult = async { - match wm.GetDocument p.TextDocument.Uri with + match scope.GetDocument p.TextDocument.Uri with | None -> return None |> success | Some doc -> let! docText = doc.GetTextAsync() |> Async.AwaitTask @@ -330,7 +330,7 @@ module CodeAction = let! roslynCodeActions = getRoslynCodeActions doc textSpan let clientSupportsCodeActionEditResolveWithEditAndData = - wm.ClientCapabilities + scope.ClientCapabilities |> Option.bind (fun x -> x.TextDocument) |> Option.bind (fun x -> x.CodeAction) |> Option.bind (fun x -> x.ResolveSupport) @@ -362,7 +362,7 @@ module CodeAction = let! maybeLspCa = roslynCodeActionToResolvedLspCodeAction doc.Project.Solution - wm.GetDocumentVersion + scope.GetDocumentVersion doc ca @@ -381,12 +381,12 @@ module CodeAction = |> success } - let resolve (wm: ServerRequestScope) (p: CodeAction) : AsyncLspResult = async { + let resolve (scope: ServerRequestScope) (p: CodeAction) : AsyncLspResult = async { let resolutionData = p.Data |> Option.map deserialize - match wm.GetDocument resolutionData.Value.TextDocumentUri with + match scope.GetDocument resolutionData.Value.TextDocumentUri with | None -> return None |> success | Some doc -> let! ct = Async.CancellationToken @@ -402,7 +402,7 @@ module CodeAction = let toResolvedLspCodeAction = roslynCodeActionToResolvedLspCodeAction doc.Project.Solution - wm.GetDocumentVersion + scope.GetDocumentVersion doc let! maybeLspCodeAction = diff --git a/src/CSharpLanguageServer/Handlers/Definition.fs b/src/CSharpLanguageServer/Handlers/Definition.fs index 69286f9c..8675363b 100644 --- a/src/CSharpLanguageServer/Handlers/Definition.fs +++ b/src/CSharpLanguageServer/Handlers/Definition.fs @@ -32,11 +32,11 @@ module Definition = Method = "textDocument/definition" RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let handle (wm: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { - match! wm.FindSymbol' p.TextDocument.Uri p.Position with + let handle (scope: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { + match! scope.FindSymbol' p.TextDocument.Uri p.Position with | None -> return None |> success | Some (symbol, doc) -> - let! locations = wm.ResolveSymbolLocations symbol (Some doc.Project) + let! locations = scope.ResolveSymbolLocations symbol (Some doc.Project) return locations |> Array.ofList diff --git a/src/CSharpLanguageServer/Handlers/Implementation.fs b/src/CSharpLanguageServer/Handlers/Implementation.fs index f907488d..ceef72d9 100644 --- a/src/CSharpLanguageServer/Handlers/Implementation.fs +++ b/src/CSharpLanguageServer/Handlers/Implementation.fs @@ -33,12 +33,12 @@ module Implementation = Method = "textDocument/implementation" RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let handle (wm: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { - match! wm.FindSymbol p.TextDocument.Uri p.Position with + let handle (scope: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { + match! scope.FindSymbol p.TextDocument.Uri p.Position with | None -> return None |> success | Some symbol -> - let! impls = wm.FindImplementations symbol - let! locations = impls |> Seq.map (flip wm.ResolveSymbolLocations None) |> Async.Parallel + let! impls = scope.FindImplementations symbol + let! locations = impls |> Seq.map (flip scope.ResolveSymbolLocations None) |> Async.Parallel return locations diff --git a/src/CSharpLanguageServer/Handlers/TypeDefinition.fs b/src/CSharpLanguageServer/Handlers/TypeDefinition.fs index c2748984..795cbbd9 100644 --- a/src/CSharpLanguageServer/Handlers/TypeDefinition.fs +++ b/src/CSharpLanguageServer/Handlers/TypeDefinition.fs @@ -34,8 +34,8 @@ module TypeDefinition = Method = "textDocument/typeDefinition" RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let handle (wm: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { - match! wm.FindSymbol' p.TextDocument.Uri p.Position with + let handle (scope: ServerRequestScope) (p: TextDocumentPositionParams) : AsyncLspResult = async { + match! scope.FindSymbol' p.TextDocument.Uri p.Position with | None -> return None |> success | Some (symbol, doc) -> let typeSymbol = @@ -47,7 +47,7 @@ module TypeDefinition = | _ -> [] let! locations = typeSymbol - |> map (flip wm.ResolveSymbolLocations (Some doc.Project)) + |> map (flip scope.ResolveSymbolLocations (Some doc.Project)) |> Async.Parallel |> map (Seq.collect id >> Seq.toArray) return diff --git a/src/CSharpLanguageServer/Handlers/TypeHierarchy.fs b/src/CSharpLanguageServer/Handlers/TypeHierarchy.fs index 85105adb..02d2d867 100644 --- a/src/CSharpLanguageServer/Handlers/TypeHierarchy.fs +++ b/src/CSharpLanguageServer/Handlers/TypeHierarchy.fs @@ -40,19 +40,19 @@ module TypeHierarchy = Method = "textDocument/prepareTypeHierarchy" RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some } - let prepare (wm: ServerRequestScope) (p: TypeHierarchyPrepareParams) : AsyncLspResult = async { - match! wm.FindSymbol p.TextDocument.Uri p.Position with + let prepare (scope: ServerRequestScope) (p: TypeHierarchyPrepareParams) : AsyncLspResult = async { + match! scope.FindSymbol p.TextDocument.Uri p.Position with | Some symbol when isTypeSymbol symbol -> - let! itemList = HierarchyItem.fromSymbol wm.ResolveSymbolLocations symbol + let! itemList = HierarchyItem.fromSymbol scope.ResolveSymbolLocations symbol return itemList |> List.toArray |> Some |> success | _ -> return None |> success } let supertypes - (wm: ServerRequestScope) + (scope: ServerRequestScope) (p: TypeHierarchySupertypesParams) : AsyncLspResult = async { - match! wm.FindSymbol p.Item.Uri p.Item.Range.Start with + match! scope.FindSymbol p.Item.Uri p.Item.Range.Start with | Some symbol when isTypeSymbol symbol -> let typeSymbol = symbol :?> INamedTypeSymbol let baseType = @@ -62,24 +62,24 @@ module TypeHierarchy = |> Option.toList let interfaces = Seq.toList typeSymbol.Interfaces let supertypes = baseType @ interfaces - let! items = supertypes |> Seq.map (HierarchyItem.fromSymbol wm.ResolveSymbolLocations) |> Async.Parallel + let! items = supertypes |> Seq.map (HierarchyItem.fromSymbol scope.ResolveSymbolLocations) |> Async.Parallel return items |> Seq.collect id |> Seq.toArray |> Some |> success | _ -> return None |> success } - let subtypes (wm: ServerRequestScope) (p: TypeHierarchySubtypesParams) : AsyncLspResult = async { - match! wm.FindSymbol p.Item.Uri p.Item.Range.Start with + let subtypes (scope: ServerRequestScope) (p: TypeHierarchySubtypesParams) : AsyncLspResult = async { + match! scope.FindSymbol p.Item.Uri p.Item.Range.Start with | Some symbol when isTypeSymbol symbol -> let typeSymbol = symbol :?> INamedTypeSymbol // We only want immediately derived classes/interfaces/implementations here (we only need // subclasses not subclasses' subclasses) let! subtypes = - [ wm.FindDerivedClasses' typeSymbol false - wm.FindDerivedInterfaces' typeSymbol false - wm.FindImplementations' typeSymbol false ] + [ scope.FindDerivedClasses' typeSymbol false + scope.FindDerivedInterfaces' typeSymbol false + scope.FindImplementations' typeSymbol false ] |> Async.Parallel |> map (Seq.collect id >> Seq.toList) - let! items = subtypes |> Seq.map (HierarchyItem.fromSymbol wm.ResolveSymbolLocations) |> Async.Parallel + let! items = subtypes |> Seq.map (HierarchyItem.fromSymbol scope.ResolveSymbolLocations) |> Async.Parallel return items |> Seq.collect id |> Seq.toArray |> Some |> success | _ -> return None |> success }