Skip to content

Commit

Permalink
Merge pull request #142 from razzmatazz/integration-from-rework-iv
Browse files Browse the repository at this point in the history
Integrate refactoring changes (pt. V)
  • Loading branch information
razzmatazz authored Mar 13, 2024
2 parents a5963c9 + 5bafab9 commit 4732130
Show file tree
Hide file tree
Showing 38 changed files with 824 additions and 137 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

## [Unreleased]
* Register server capabilities with the client lazily to improve startup performance
- PR by @tcx4c70 in https://github.com/razzmatazz/csharp-language-server/pull/102
* Rework logging to be based on Serilog
- PR by @tcx4c70 in https://github.com/razzmatazz/csharp-language-server/pull/134
* More refactoring by @tcx4c70
Expand Down
9 changes: 9 additions & 0 deletions src/CSharpLanguageServer/CSharpLanguageServer.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,29 @@
<Compile Include="Handlers/CallHierarchy.fs" />
<Compile Include="Handlers/CodeAction.fs" />
<Compile Include="Handlers/CodeLens.fs" />
<Compile Include="Handlers/Color.fs" />
<Compile Include="Handlers/Completion.fs" />
<Compile Include="Handlers/Declaration.fs" />
<Compile Include="Handlers/Definition.fs" />
<Compile Include="Handlers/Diagnostic.fs" />
<Compile Include="Handlers/DocumentFormatting.fs" />
<Compile Include="Handlers/DocumentHighlight.fs" />
<Compile Include="Handlers/DocumentLink.fs" />
<Compile Include="Handlers/DocumentOnTypeFormatting.fs" />
<Compile Include="Handlers/DocumentRangeFormatting.fs" />
<Compile Include="Handlers/DocumentSymbol.fs" />
<Compile Include="Handlers/ExecuteCommand.fs" />
<Compile Include="Handlers/FoldingRange.fs" />
<Compile Include="Handlers/Hover.fs" />
<Compile Include="Handlers/Implementation.fs" />
<Compile Include="Handlers/Initialization.fs" />
<Compile Include="Handlers/InlayHint.fs" />
<Compile Include="Handlers/InlineValue.fs" />
<Compile Include="Handlers/LinkedEditingRange.fs" />
<Compile Include="Handlers/Moniker.fs" />
<Compile Include="Handlers/References.fs" />
<Compile Include="Handlers/Rename.fs" />
<Compile Include="Handlers/SelectionRange.fs" />
<Compile Include="Handlers/SemanticTokens.fs" />
<Compile Include="Handlers/SignatureHelp.fs" />
<Compile Include="Handlers/TextDocumentSync.fs" />
Expand Down
5 changes: 3 additions & 2 deletions src/CSharpLanguageServer/Handlers/CallHierarchy.fs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ module CallHierarchy =
Microsoft.CodeAnalysis.SymbolKind.Event
Microsoft.CodeAnalysis.SymbolKind.Property ]

let provider (clientCapabilities: ClientCapabilities option) : bool option =
Some true
let provider (clientCapabilities: ClientCapabilities option) : bool option = Some true

let registration (clientCapabilities: ClientCapabilities option) : Registration option = None

let prepare (scope: ServerRequestScope) (prepareParams: CallHierarchyPrepareParams): AsyncLspResult<CallHierarchyItem[] option> = async {
match scope.GetUserDocumentForUri prepareParams.TextDocument.Uri with
Expand Down
41 changes: 35 additions & 6 deletions src/CSharpLanguageServer/Handlers/CodeAction.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ open CSharpLanguageServer.State
open CSharpLanguageServer.RoslynHelpers
open CSharpLanguageServer.Logging
open CSharpLanguageServer.Conversions
open CSharpLanguageServer.Types

type CSharpCodeActionResolutionData =
{ TextDocumentUri: string
Expand Down Expand Up @@ -289,12 +290,40 @@ module CodeAction =
}
}

let provider (clientCapabilities: ClientCapabilities option) : U2<bool,CodeActionOptions> option =
{ CodeActionKinds = None
ResolveProvider = Some true
}
|> U2.Second
|> Some
let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.CodeAction)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let private literalSupport (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.CodeAction)
|> Option.bind (fun x -> x.CodeActionLiteralSupport)

let provider (clientCapabilities: ClientCapabilities option) : U2<bool, CodeActionOptions> option =
match dynamicRegistration clientCapabilities, literalSupport clientCapabilities with
| true, _ -> None
| false, _ ->
// TODO: Server can only return CodeActionOptions if literalSupport is not None
U2.Second
{ CodeActionKinds = None
ResolveProvider = Some true }
|> Some

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/codeAction"
RegisterOptions =
{ CodeActionKinds = None
ResolveProvider = Some true
DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some }

let handle (logMessage: Util.AsyncLogFn)
(scope: ServerRequestScope)
Expand Down
30 changes: 26 additions & 4 deletions src/CSharpLanguageServer/Handlers/CodeLens.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,20 @@ namespace CSharpLanguageServer.Handlers

open System

open Ionide.LanguageServerProtocol.Types
open Ionide.LanguageServerProtocol.Types.LspResult
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.CSharp
open Microsoft.CodeAnalysis.CSharp.Syntax
open Microsoft.CodeAnalysis.FindSymbols
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.FindSymbols
open Ionide.LanguageServerProtocol.Server
open Ionide.LanguageServerProtocol.Types
open Ionide.LanguageServerProtocol.Types.LspResult
open Newtonsoft.Json.Linq

open CSharpLanguageServer
open CSharpLanguageServer.State
open CSharpLanguageServer.Conversions
open CSharpLanguageServer.Types

type private DocumentSymbolCollectorForCodeLens(semanticModel: SemanticModel) =
inherit CSharpSyntaxWalker(SyntaxWalkerDepth.Token)
Expand Down Expand Up @@ -108,8 +110,28 @@ module CodeLens =
{ DocumentUri = ""
Position = { Line = 0; Character = 0 } }

let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.CodeLens)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let provider (clientCapabilities: ClientCapabilities option) : CodeLensOptions option =
Some { ResolveProvider = Some true }
match dynamicRegistration clientCapabilities with
| true -> None
| false -> Some { ResolveProvider = Some true }

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/codeLens"
RegisterOptions =
{ ResolveProvider = Some true
DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some }

let handle (scope: ServerRequestScope) (p: CodeLensParams): AsyncLspResult<CodeLens[] option> = async {
let docMaybe = scope.GetAnyDocumentForUri p.TextDocument.Uri
Expand Down
17 changes: 17 additions & 0 deletions src/CSharpLanguageServer/Handlers/Color.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace CSharpLanguageServer.Handlers

open Ionide.LanguageServerProtocol.Types

open CSharpLanguageServer.State

[<RequireQualifiedAccess>]
module Color =
let provider (clientCapabilities: ClientCapabilities option) = None

let registration (clientCapabilities: ClientCapabilities option) : Registration option = None

let handle (scope: ServerRequestScope) (p: DocumentColorParams) : AsyncLspResult<ColorInformation[]> =
LspResult.notImplemented<ColorInformation[]> |> async.Return

let present (scope: ServerRequestScope) (p: ColorPresentationParams) : AsyncLspResult<ColorPresentation[]> =
LspResult.notImplemented<ColorPresentation[]> |> async.Return
44 changes: 36 additions & 8 deletions src/CSharpLanguageServer/Handlers/Completion.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,54 @@ namespace CSharpLanguageServer.Handlers

open System

open Microsoft.CodeAnalysis.Completion
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Completion
open Ionide.LanguageServerProtocol
open Ionide.LanguageServerProtocol.Types
open Ionide.LanguageServerProtocol.Types.LspResult
open Ionide.LanguageServerProtocol.Server
open Microsoft.CodeAnalysis
open Microsoft.CodeAnalysis.Text
open Microsoft.CodeAnalysis.Completion

open CSharpLanguageServer
open CSharpLanguageServer.State
open CSharpLanguageServer.RoslynHelpers
open CSharpLanguageServer.Types

[<RequireQualifiedAccess>]
module Completion =
let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.Completion)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let provider (clientCapabilities: ClientCapabilities option) : CompletionOptions option =
Some { ResolveProvider = None
TriggerCharacters = Some ([| '.'; '''; |])
AllCommitCharacters = None
CompletionItem = None
}
match dynamicRegistration clientCapabilities with
| true -> None
| false ->
Some { ResolveProvider = None
TriggerCharacters = Some ([| '.'; '''; |])
AllCommitCharacters = None
CompletionItem = None
}

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/completion"
RegisterOptions =
{ ResolveProvider = None
TriggerCharacters = Some ([| '.'; '''; |])
AllCommitCharacters = None
DocumentSelector = Some defaultDocumentSelector }
|> serialize
|> Some }

let private roslynTagToLspCompletion tag =
match tag with
Expand Down
14 changes: 14 additions & 0 deletions src/CSharpLanguageServer/Handlers/Declaration.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace CSharpLanguageServer.Handlers

open Ionide.LanguageServerProtocol.Types

open CSharpLanguageServer.State

[<RequireQualifiedAccess>]
module Declaration =
let provider (clientCapabilities: ClientCapabilities option) : bool option = None

let registration (clientCapabilities: ClientCapabilities option) : Registration option = None

let handle (scope: ServerRequestScope) (def: TextDocumentPositionParams) : AsyncLspResult<GotoResult option> =
LspResult.notImplemented<GotoResult option> |> async.Return
21 changes: 20 additions & 1 deletion src/CSharpLanguageServer/Handlers/Definition.fs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,30 @@ open Microsoft.CodeAnalysis.FindSymbols
open Microsoft.CodeAnalysis.Text

open CSharpLanguageServer.State
open CSharpLanguageServer.Types

[<RequireQualifiedAccess>]
module Definition =
let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.Definition)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let provider (clientCapabilities: ClientCapabilities option) : bool option =
Some true
match dynamicRegistration clientCapabilities with
| true -> None
| false -> Some true

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/definition"
RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some }

let handle (scope: ServerRequestScope) (def: TextDocumentPositionParams) : AsyncLspResult<GotoResult option> = async {
let docMaybe = scope.GetAnyDocumentForUri def.TextDocument.Uri
Expand Down
14 changes: 14 additions & 0 deletions src/CSharpLanguageServer/Handlers/Diagnostic.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace CSharpLanguageServer.Handlers

open Ionide.LanguageServerProtocol.Types

open CSharpLanguageServer.State

[<RequireQualifiedAccess>]
module Diagnostic =
let provider (clientCapabilities: ClientCapabilities option) = None

let registration (clientCapabilities: ClientCapabilities option) : Registration option = None

let handle (scope: ServerRequestScope) (def: DocumentDiagnosticParams) : AsyncLspResult<DocumentDiagnosticReport option> =
LspResult.notImplemented<DocumentDiagnosticReport option> |> async.Return
22 changes: 21 additions & 1 deletion src/CSharpLanguageServer/Handlers/DocumentFormatting.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace CSharpLanguageServer.Handlers
open System
open System.Collections.Immutable

open Microsoft.CodeAnalysis.Formatting
open Ionide.LanguageServerProtocol.Server
open Ionide.LanguageServerProtocol.Types
open Ionide.LanguageServerProtocol.Types.LspResult
Expand All @@ -14,11 +15,30 @@ open Microsoft.CodeAnalysis.Formatting
open CSharpLanguageServer
open CSharpLanguageServer.State
open CSharpLanguageServer.RoslynHelpers
open CSharpLanguageServer.Types

[<RequireQualifiedAccess>]
module DocumentFormatting =
let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.Formatting)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let provider (clientCapabilities: ClientCapabilities option) : bool option =
Some true
match dynamicRegistration clientCapabilities with
| true -> None
| false -> Some true

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/formatting"
RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some }

let handle (scope: ServerRequestScope) (p: DocumentFormattingParams) : AsyncLspResult<TextEdit [] option> = async {
match scope.GetUserDocumentForUri p.TextDocument.Uri with
Expand Down
20 changes: 19 additions & 1 deletion src/CSharpLanguageServer/Handlers/DocumentHighlight.fs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,26 @@ open CSharpLanguageServer.Conversions

[<RequireQualifiedAccess>]
module DocumentHighlight =
let private dynamicRegistration (clientCapabilities: ClientCapabilities option) =
clientCapabilities
|> Option.bind (fun x -> x.TextDocument)
|> Option.bind (fun x -> x.DocumentHighlight)
|> Option.bind (fun x -> x.DynamicRegistration)
|> Option.defaultValue false

let provider (clientCapabilities: ClientCapabilities option) : bool option =
Some true
match dynamicRegistration clientCapabilities with
| true -> None
| false -> Some true

let registration (clientCapabilities: ClientCapabilities option) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/documentHighlight"
RegisterOptions = { DocumentSelector = Some defaultDocumentSelector } |> serialize |> Some }

let private shouldHighlight (symbol: ISymbol) =
match symbol with
Expand Down
17 changes: 17 additions & 0 deletions src/CSharpLanguageServer/Handlers/DocumentLink.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace CSharpLanguageServer.Handlers

open Ionide.LanguageServerProtocol.Types

open CSharpLanguageServer.State

[<RequireQualifiedAccess>]
module DocumentLink =
let provider (clientCapabilities: ClientCapabilities option) : DocumentLinkOptions option = None

let registration (clientCapabilities: ClientCapabilities option) : Registration option = None

let handle (scope: ServerRequestScope) (p: DocumentLinkParams) : AsyncLspResult<DocumentLink[] option> =
LspResult.notImplemented<DocumentLink[] option> |> async.Return

let resolve (scope: ServerRequestScope) (p: DocumentLink) : AsyncLspResult<DocumentLink> =
LspResult.notImplemented<DocumentLink> |> async.Return
Loading

0 comments on commit 4732130

Please sign in to comment.