Skip to content

Commit

Permalink
feat: Implement Diagnostic Pull for TextDocument
Browse files Browse the repository at this point in the history
  • Loading branch information
razzmatazz committed Jul 3, 2024
1 parent 38d254a commit 5c0a072
Showing 1 changed file with 74 additions and 4 deletions.
78 changes: 74 additions & 4 deletions src/CSharpLanguageServer/Handlers/Diagnostic.fs
Original file line number Diff line number Diff line change
@@ -1,14 +1,84 @@
namespace CSharpLanguageServer.Handlers

open System

open Ionide.LanguageServerProtocol.Server
open Ionide.LanguageServerProtocol.Types

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

[<RequireQualifiedAccess>]
module Diagnostic =
let provider (clientCapabilities: ClientCapabilities) = None
let private logger = LogProvider.getLoggerByName "Diagnostic"

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

let provider (clientCapabilities: ClientCapabilities): U2<DiagnosticOptions, DiagnosticRegistrationOptions> option =
match dynamicRegistration clientCapabilities with
| true -> None
| false ->
let diagnosticOptions: DiagnosticRegistrationOptions =
{ DocumentSelector = Some defaultDocumentSelector
WorkDoneProgress = None
Identifier = None
InterFileDependencies = false
WorkspaceDiagnostics = false
Id = None
}

Some (U2.C2 diagnosticOptions)

let registration (clientCapabilities: ClientCapabilities) : Registration option =
match dynamicRegistration clientCapabilities with
| false -> None
| true ->
let registerOptions: DiagnosticRegistrationOptions =
{ DocumentSelector = Some defaultDocumentSelector
WorkDoneProgress = None
Identifier = None
InterFileDependencies = false
WorkspaceDiagnostics = false
Id = None }

Some
{ Id = Guid.NewGuid().ToString()
Method = "textDocument/diagnostic"
RegisterOptions = registerOptions |> serialize |> Some }

let handle (context: ServerRequestContext) (p: DocumentDiagnosticParams) : AsyncLspResult<DocumentDiagnosticReport> = async {
let emptyReport: RelatedFullDocumentDiagnosticReport =
{
Kind = "full"
ResultId = None
Items = [| |]
RelatedDocuments = None
}

match context.GetDocument p.TextDocument.Uri with
| None ->
return emptyReport |> U2.C1 |> LspResult.success

| Some doc ->
let! ct = Async.CancellationToken
let! semanticModelMaybe = doc.GetSemanticModelAsync(ct) |> Async.AwaitTask
match semanticModelMaybe |> Option.ofObj with
| Some semanticModel ->
let diagnostics =
semanticModel.GetDiagnostics()
|> Seq.map Diagnostic.fromRoslynDiagnostic
|> Array.ofSeq

let registration (clientCapabilities: ClientCapabilities) : Registration option = None
return { emptyReport with Items = diagnostics }
|> U2.C1
|> LspResult.success

let handle (context: ServerRequestContext) (def: DocumentDiagnosticParams) : AsyncLspResult<DocumentDiagnosticReport> =
LspResult.notImplemented<DocumentDiagnosticReport> |> async.Return
| None ->
return emptyReport |> U2.C1 |> LspResult.success
}

0 comments on commit 5c0a072

Please sign in to comment.