2 * Copyright (c) 2016, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
11 * This file is an OCaml representation of the Language Server Protocol
12 * https://github.com/Microsoft/language-server-protocol/blob/master/protocol.md
13 * based on the current v3.
15 * Changes to make it more natural in OCaml:
16 * - We don't represent the common base types of Requests/Errors/Notifications
17 * because base types don't naturally mix with abstract data types, and
18 * because code for these things is done more naturally at the JSON layer
19 * - We avoid option types where we can. The idea is to follow the internet
20 * "robustness" rule of being liberal in what we accept, conservative in
21 * what we emit: if we're parsing a message and it lacks a field, and if
22 * the spec tells us how to interpret absence, then we do that interpretation
23 * at the JSON->LSP parsing level (so long as the interpretation is lossless).
24 * On the emitting side, we might as well emit all fields.
25 * - For every request, like Initialize or workspace/Symbol, we've invented
26 * "Initialize.response = (Initialize.result, Initialize.error) Result"
27 * or "Symbol.response = (Symbol.result, Error.error) Result" to show
28 * the two possible return types from this request. Note that each different
29 * request can have its own custom error type, although most don't.
30 * - Most datatypes go in modules since there are so many name-clashes in
31 * the protocol and OCaml doesn't like name-clashes. Only exceptions are
32 * the really primitive types like location and documentUri.
33 * The few places where we still had to rename fields to avoid OCaml name
34 * clashes I've noted in the comments with the word "wire" to indicate the
35 * over-the-wire form of the name.
36 * - Names have been translated from jsonConvention into ocaml convention
37 * only where necessary, e.g. because ocaml uses lowercase for types.
38 * - The spec has space for extra fields like "experimental". It obviously
39 * doesn't make sense to encode them in a type system. I've omitted them
47 type documentUri
= DocumentUri
of string [@@deriving eq
]
49 let uri_of_string (s
: string) : documentUri
= DocumentUri s
51 let string_of_uri (DocumentUri s
) : string = s
53 (* A position is between two characters like an 'insert' cursor in a editor *)
56 (* line position in a document [zero-based] *)
57 character
: int; (* character offset on a line in a document [zero-based] *)
61 (* A range is comparable to a selection in an editor *)
64 (* the range's start position *)
65 end_
: position
; (* the range's end position [exclusive] *)
69 type textDocumentSaveReason
=
71 | AfterDelay
[@value 2]
75 (* Represents a location inside a resource, such as a line inside a text file *)
76 module Location
= struct
84 (* Represents a location inside a resource which also wants to display a
85 friendly name to the user. *)
86 module DefinitionLocation
= struct
93 (* markedString can be used to render human readable text. It is either a
94 * markdown string or a code-block that provides a language and a code snippet.
95 * Note that markdown strings will be sanitized by the client - including
98 | MarkedString
of string
100 | MarkedCode
of string * string
102 (* Represents a reference to a command. Provides a title which will be used to
103 * represent a command in the UI. Commands are identitifed using a string
104 * identifier and the protocol currently doesn't specify a set of well known
105 * commands. So executing a command requires some tool extension code. *)
106 module Command
= struct
109 (* title of the command, like `save` *)
111 (* the identifier of the actual command handler *)
112 arguments
: Hh_json.json list
; (* wire: it can be omitted *)
116 (* A textual edit applicable to a text document. If n textEdits are applied
117 to a text document all text edits describe changes to the initial document
118 version. Execution wise text edits should applied from the bottom to the
119 top of the text document. Overlapping text edits are not supported. *)
120 module TextEdit
= struct
123 (* to insert text, use a range where start = end *)
124 newText
: string; (* for delete operations, use an empty string *)
128 (* Text documents are identified using a URI. *)
129 module TextDocumentIdentifier
= struct
130 type t
= { uri
: documentUri
(* the text document's URI *) }
133 (* An identifier to denote a specific version of a text document. *)
134 module VersionedTextDocumentIdentifier
= struct
137 (* the text document's URI *)
138 version
: int; (* the version number of this document *)
142 (* Describes textual changes on a single text document. The text document is
143 referred to as a VersionedTextDocumentIdentifier to allow clients to check
144 the text document version before an edit is applied. *)
145 module TextDocumentEdit
= struct
147 textDocument
: VersionedTextDocumentIdentifier.t
;
148 edits
: TextEdit.t list
;
152 (* A workspace edit represents changes to many resources managed in the
153 workspace. A workspace edit consists of a mapping from a URI to an
154 array of TextEdits to be applied to the document with that URI. *)
155 module WorkspaceEdit
= struct
157 changes
: TextEdit.t list
SMap.t
; (* holds changes to existing docs *)
161 (* An item to transfer a text document from the client to the server. The
162 version number strictly increases after each change, including undo/redo. *)
163 module TextDocumentItem
= struct
166 (* the text document's URI *)
168 (* the text document's language identifier *)
170 (* the version of the document *)
171 text
: string; (* the content of the opened text document *)
176 * A code lens represents a command that should be shown along with
177 * source text, like the number of references, a way to run tests, etc.
179 * A code lens is _unresolved_ when no command is associated to it. For performance
180 * reasons the creation of a code lens and resolving should be done in two stages.
182 module CodeLens
= struct
186 data
: Hh_json.json
option;
190 (* A parameter literal used in requests to pass a text document and a position
191 inside that document. *)
192 module TextDocumentPositionParams
= struct
194 textDocument
: TextDocumentIdentifier.t
;
195 (* the text document *)
196 position
: position
; (* the position inside the text document *)
200 (* A document filter denotes a document through properties like language,
201 schema or pattern. E.g. language:"typescript",scheme:"file"
202 or language:"json",pattern:"**/package.json" *)
203 module DocumentFilter
= struct
205 language
: string option;
206 (* a language id, like "typescript" *)
207 scheme
: string option;
208 (* a uri scheme, like "file" or "untitled" *)
209 pattern
: string option; (* a glob pattern, like "*.{ts,js}" *)
213 (* A document selector is the combination of one or many document filters. *)
214 module DocumentSelector
= struct
215 type t
= DocumentFilter.t list
218 (* Represents information about programming constructs like variables etc. *)
219 module SymbolInformation
= struct
220 (* These numbers should match
221 * https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#symbolKind
226 | Namespace
[@value 3]
230 | Property
[@value 7]
232 | Constructor
[@value 9]
234 | Interface
[@value 11]
235 | Function
[@value 12]
236 | Variable
[@value 13]
237 | Constant
[@value 14]
240 | Boolean
[@value 17]
245 | EnumMember
[@value 22]
248 | Operator
[@value 25]
249 | TypeParameter
[@value 26]
255 location
: Location.t
;
256 (* the span of the symbol including its contents *)
257 containerName
: string option; (* the symbol containing this symbol *)
261 (* For showing messages (not diagnostics) in the user interface. *)
262 module MessageType
= struct
264 | ErrorMessage
[@value 1]
265 | WarningMessage
[@value 2]
266 | InfoMessage
[@value 3]
267 | LogMessage
[@value 4]
268 [@@deriving eq
, enum
]
271 module CodeActionKind
= struct
272 (* The kind of a code action.
273 * Kinds are a hierarchical list of identifiers separated by `.`, e.g.
274 * `"refactor.extract.function"`.
275 * The set of kinds is open and client needs to announce the kinds it supports
276 * to the server during initialization.
277 * CodeActionKind.t uses a pair to represent a non-empty list and provides utility
278 * functions for creation, membership, printing.
279 * Module CodeAction below also references this module as Kind.
281 type t
= string * string list
283 (* is x of kind k? *)
284 let is_kind : t
-> t
-> bool =
285 let rec is_prefix_of ks xs
=
288 | (k
:: ks
, x
:: xs
) when String.equal k x
-> is_prefix_of ks xs
291 (fun (k
, ks
) (x
, xs
) -> String.equal k x
&& is_prefix_of ks xs
)
293 (* does `ks` contain kind `k` *)
294 let contains_kind k ks
= List.exists
(is_kind k
) ks
296 (* does an optional list of kinds `ks` contain kind `k` *)
297 let contains_kind_opt ~default k ks
=
299 | Some ks
-> contains_kind k ks
302 (* Create a kind from a string that follows the spec *)
303 let kind_of_string : string -> t
=
305 match String.split_on_char '
.' s
with
306 | [] -> failwith
"split_on_char does not return an empty list"
309 (* Create the equivalent string that the spec would have required *)
310 let string_of_kind : t
-> string = (fun (k
, ks
) -> String.concat
"." (k
:: ks
))
312 (* Create a new sub-kind of an existing kind *)
313 let sub_kind : t
-> string -> t
=
314 let cons_to_end (ss
: string list
) (s
: string) =
315 Base.List.(fold_right ss ~f
:cons ~init
:[s
])
317 (fun (k
, ks
) s
-> (k
, cons_to_end ks s
))
319 (* Some of the constants defined by the spec *)
320 let quickfix = kind_of_string "quickfix"
322 let refactor = kind_of_string "refactor"
324 (* Document wide code actions *)
325 let source = kind_of_string "source"
328 (* Cancellation notification, method="$/cancelRequest" *)
329 module CancelRequest
= struct
330 type params
= cancelParams
332 and cancelParams
= { id
: lsp_id
(* the request id to cancel *) }
335 (* SetTraceNotification, method="$/setTraceNotification" *)
336 module SetTraceNotification
= struct
342 (* Initialize request, method="initialize" *)
343 module Initialize
= struct
344 type textDocumentSyncKind
=
345 (* docs should not be synced at all. Wire "None" *)
347 (* synced by always sending full content. Wire "Full" *)
348 | FullSync
[@value 1]
349 | IncrementalSync
[@value 2]
353 processId
: int option;
354 (* pid of parent process *)
355 rootPath
: string option;
357 rootUri
: documentUri
option;
358 (* the root URI of the workspace *)
359 initializationOptions
: initializationOptions
;
360 client_capabilities
: client_capabilities
;
361 (* "capabilities" over wire *)
362 trace
: trace
; (* the initial trace setting, default="off" *)
366 server_capabilities
: server_capabilities
; (* "capabilities" over wire *)
370 retry
: bool; (* should client retry the initialize request *)
378 and initializationOptions
= {
379 useTextEditAutocomplete
: bool;
380 namingTableSavedStatePath
: string option;
381 namingTableSavedStateTestDelay
: float;
384 and client_capabilities
= {
385 workspace
: workspaceClientCapabilities
;
386 textDocument
: textDocumentClientCapabilities
;
387 window
: windowClientCapabilities
;
388 telemetry
: telemetryClientCapabilities
; (* omitted: experimental *)
391 and workspaceClientCapabilities
= {
393 (* client supports appling batch edits *)
394 workspaceEdit
: workspaceEdit
;
395 didChangeWatchedFiles
: dynamicRegistration
;
396 (* omitted: other dynamic-registration fields *)
399 and dynamicRegistration
= {
400 dynamicRegistration
: bool;
401 (* client supports dynamic registration for this capability *)
404 and workspaceEdit
= {
405 documentChanges
: bool; (* client supports versioned doc changes *)
408 and textDocumentClientCapabilities
= {
409 synchronization
: synchronization
;
410 completion
: completion
; (** textDocument/completion *)
411 codeAction
: codeAction
;
412 definition
: definition
;
413 typeDefinition
: typeDefinition
;
414 declaration
: declaration
;
415 implementation
: implementation
;
418 (* synchronization capabilities say what messages the client is capable
419 * of sending, should be be so asked by the server.
420 * We use the "can_" prefix for OCaml naming reasons; it's absent in LSP *)
421 and synchronization
= {
423 (* client can send textDocument/willSave *)
424 can_willSaveWaitUntil
: bool;
425 (* textDoc.../willSaveWaitUntil *)
426 can_didSave
: bool; (* textDocument/didSave *)
429 and completion
= { completionItem
: completionItem
}
431 and completionItem
= {
432 snippetSupport
: bool; (* client can do snippets as insert text *)
436 (* Whether code action supports dynamic registration. *)
437 codeAction_dynamicRegistration
: bool;
438 (* wire: dynamicRegistraction *)
439 (* The client support code action literals as a valid
440 * response of the `textDocument/codeAction` request. *)
441 codeActionLiteralSupport
: codeActionliteralSupport
option;
444 and definition
= { definitionLinkSupport
: bool }
446 and typeDefinition
= { typeDefinitionLinkSupport
: bool }
448 and declaration
= { declarationLinkSupport
: bool }
450 and implementation
= { implementationLinkSupport
: bool }
452 and codeActionliteralSupport
= {
453 (* The code action kind values the client supports. When this
454 * property exists the client also guarantees that it will
455 * handle values outside its set gracefully and falls back
456 * to a default value when unknown. *)
457 codeAction_valueSet
: CodeActionKind.t list
; (* wire: valueSet *)
460 and windowClientCapabilities
= {
462 (* Nuclide-specific: client supports window/showStatusRequest *)
465 and telemetryClientCapabilities
= {
466 connectionStatus
: bool;
467 (* Nuclide-specific: client supports telemetry/connectionStatus *)
470 (* What capabilities the server provides *)
471 and server_capabilities
= {
472 textDocumentSync
: textDocumentSyncOptions
;
475 completionProvider
: completionOptions
option;
476 signatureHelpProvider
: signatureHelpOptions
option;
477 definitionProvider
: bool;
478 typeDefinitionProvider
: bool;
479 referencesProvider
: bool;
480 documentHighlightProvider
: bool;
481 documentSymbolProvider
: bool;
482 (* ie. document outline *)
483 workspaceSymbolProvider
: bool;
484 (* ie. find-symbol-in-project *)
485 codeActionProvider
: bool;
486 codeLensProvider
: codeLensOptions
option;
487 documentFormattingProvider
: bool;
488 documentRangeFormattingProvider
: bool;
489 documentOnTypeFormattingProvider
: documentOnTypeFormattingOptions
option;
490 renameProvider
: bool;
491 documentLinkProvider
: documentLinkOptions
option;
492 executeCommandProvider
: executeCommandOptions
option;
493 implementationProvider
: bool;
494 (* Nuclide-specific features below *)
495 typeCoverageProviderFB
: bool;
496 rageProviderFB
: bool;
499 and completionOptions
= {
500 resolveProvider
: bool;
501 (* server resolves extra info on demand *)
502 completion_triggerCharacters
: string list
; (* wire "triggerCharacters" *)
505 and signatureHelpOptions
= {
506 sighelp_triggerCharacters
: string list
; (* wire "triggerCharacters" *)
509 and codeLensOptions
= {
510 codelens_resolveProvider
: bool; (* wire "resolveProvider" *)
513 and documentOnTypeFormattingOptions
= {
514 firstTriggerCharacter
: string;
516 moreTriggerCharacter
: string list
;
519 and documentLinkOptions
= {
520 doclink_resolveProvider
: bool; (* wire "resolveProvider" *)
523 and executeCommandOptions
= {
524 commands
: string list
; (* the commands to be executed on the server *)
527 (* text document sync options say what messages the server requests the
528 * client to send. We use the "want_" prefix for OCaml naming reasons;
529 * this prefix is absent in LSP. *)
530 and textDocumentSyncOptions
= {
531 want_openClose
: bool;
532 (* textDocument/didOpen+didClose *)
533 want_change
: textDocumentSyncKind
;
535 (* textDocument/willSave *)
536 want_willSaveWaitUntil
: bool;
537 (* textDoc.../willSaveWaitUntil *)
538 want_didSave
: saveOptions
option; (* textDocument/didSave *)
541 (* full only on open. Wire "Incremental" *)
543 includeText
: bool; (* the client should include content on save *)
547 (* Rage request, method="telemetry/rage" *)
548 module RageFB
= struct
549 type result
= rageItem list
552 title
: string option;
557 (* Code Lens resolve request, method="codeLens/resolve" *)
558 module CodeLensResolve
= struct
559 type params
= CodeLens.t
561 and result
= CodeLens.t
564 (* Hover request, method="textDocument/hover" *)
565 module Hover
= struct
566 type params
= TextDocumentPositionParams.t
568 and result
= hoverResult
option
571 contents
: markedString list
;
572 (* wire: either a single one or an array *)
577 (* PublishDiagnostics notification, method="textDocument/PublishDiagnostics" *)
578 module PublishDiagnostics
= struct
579 type diagnosticSeverity
=
582 | Information
[@value 3]
584 [@@deriving eq
, enum
]
586 type params
= publishDiagnosticsParams
588 and publishDiagnosticsParams
= {
590 diagnostics
: diagnostic list
;
596 (* the range at which the message applies *)
597 severity
: diagnosticSeverity
option;
598 (* if omitted, client decides *)
599 code
: diagnosticCode
;
600 (* the diagnostic's code. *)
601 source: string option;
602 (* human-readable string, eg. typescript/lint *)
604 (* the diagnostic's message *)
605 relatedInformation
: diagnosticRelatedInformation list
;
606 relatedLocations
: relatedLocation list
; (* legacy FB extension *)
612 | StringCode
of string
616 and diagnosticRelatedInformation
= {
617 relatedLocation
: Location.t
;
618 (* wire: just "location" *)
619 relatedMessage
: string; (* wire: just "message" *)
623 (* legacy FB extension *)
624 and relatedLocation
= diagnosticRelatedInformation
627 (* DidOpenTextDocument notification, method="textDocument/didOpen" *)
628 module DidOpen
= struct
629 type params
= didOpenTextDocumentParams
631 and didOpenTextDocumentParams
= {
632 textDocument
: TextDocumentItem.t
; (* the document that was opened *)
636 (* DidCloseTextDocument notification, method="textDocument/didClose" *)
637 module DidClose
= struct
638 type params
= didCloseTextDocumentParams
640 and didCloseTextDocumentParams
= {
641 textDocument
: TextDocumentIdentifier.t
; (* the doc that was closed *)
645 (* DidSaveTextDocument notification, method="textDocument/didSave" *)
646 module DidSave
= struct
647 type params
= didSaveTextDocumentParams
649 and didSaveTextDocumentParams
= {
650 textDocument
: TextDocumentIdentifier.t
;
651 (* the doc that was saved *)
652 text
: string option; (* content when saved; depends on includeText *)
656 (* DidChangeTextDocument notification, method="textDocument/didChange" *)
657 module DidChange
= struct
658 type params
= didChangeTextDocumentParams
660 and didChangeTextDocumentParams
= {
661 textDocument
: VersionedTextDocumentIdentifier.t
;
662 contentChanges
: textDocumentContentChangeEvent list
;
665 and textDocumentContentChangeEvent
= {
667 (* the range of the document that changed *)
668 rangeLength
: int option;
669 (* the length that got replaced *)
670 text
: string; (* the new text of the range/document *)
674 (* WillSaveWaitUntilTextDocument request, method="textDocument/willSaveWaitUntil" *)
675 module WillSaveWaitUntil
= struct
676 type params
= willSaveWaitUntilTextDocumentParams
678 and willSaveWaitUntilTextDocumentParams
= {
679 textDocument
: TextDocumentIdentifier.t
;
680 reason
: textDocumentSaveReason
;
683 and result
= TextEdit.t list
686 (* Watched files changed notification, method="workspace/didChangeWatchedFiles" *)
687 module DidChangeWatchedFiles
= struct
688 type registerOptions
= { watchers
: fileSystemWatcher list
}
690 and fileSystemWatcher
= { globPattern
: string }
692 type fileChangeType
=
698 type params
= { changes
: fileEvent list
}
702 type_
: fileChangeType
;
706 (* Goto Definition request, method="textDocument/definition" *)
707 module Definition
= struct
708 type params
= TextDocumentPositionParams.t
710 and result
= DefinitionLocation.t list
712 (* wire: either a single one or an array *)
715 (* Goto TypeDefinition request, method="textDocument/typeDefinition" *)
716 module TypeDefinition
= struct
717 type params
= TextDocumentPositionParams.t
719 and result
= DefinitionLocation.t list
722 (* Go To Implementation request, method="textDocument/implementation" *)
723 module Implementation
= struct
724 type params
= TextDocumentPositionParams.t
726 and result
= Location.t list
729 module CodeAction
= struct
730 (* A code action represents a change that can be performed in code, e.g. to fix a problem or
733 (* A short, human-readable, title for this code action. *)
735 (* The kind of the code action. Used to filter code actions. *)
736 kind
: CodeActionKind.t
;
737 (* The diagnostics that this code action resolves. *)
738 diagnostics
: PublishDiagnostics.diagnostic list
;
739 (* A CodeAction must set either `edit` and/or a `command`.
740 If both are supplied, the `edit` is applied first, then the `command` is executed. *)
741 action
: edit_and_or_command
;
744 and edit_and_or_command
=
745 | EditOnly
of WorkspaceEdit.t
746 | CommandOnly
of Command.t
747 | BothEditThenCommand
of (WorkspaceEdit.t
* Command.t
)
749 type result
= command_or_action list
751 and command_or_action
=
752 | Command
of Command.t
756 (* Code Action Request, method="textDocument/codeAction" *)
757 module CodeActionRequest
= struct
759 (* The document in which the command was invoked. *)
760 textDocument
: TextDocumentIdentifier.t
;
761 (* The range for which the command was invoked. *)
763 (* Context carrying additional information. *)
764 context
: codeActionContext
;
767 (* Contains additional diagnostic information about the context in which
768 a code action is run. *)
769 and codeActionContext
= {
770 diagnostics
: PublishDiagnostics.diagnostic list
;
771 only
: CodeActionKind.t list
option;
775 (* Completion request, method="textDocument/completion" *)
776 module Completion
= struct
777 (* These numbers should match
778 * https://microsoft.github.io/language-server-protocol/specification#textDocument_completion
780 type completionItemKind
=
783 | Function
[@value 3]
784 | Constructor
[@value 4]
786 | Variable
[@value 6]
788 | Interface
[@value 8]
790 | Property
[@value 10]
794 | Keyword
[@value 14]
795 | Snippet
[@value 15]
798 | Reference
[@value 18]
800 | MemberOf
[@value 20]
801 | Constant
[@value 21]
804 | Operator
[@value 24]
805 | TypeParameter
[@value 25]
808 (* These numbers should match
809 * https://microsoft.github.io/language-server-protocol/specification#textDocument_completion
811 type insertTextFormat
=
812 | PlainText
[@value 1] (* the insertText/textEdits are just plain strings *)
813 | SnippetFormat
[@value 2] (* wire: just "Snippet" *)
816 type completionTriggerKind
=
818 | TriggerCharacter
[@value 2]
819 | TriggerForIncompleteCompletions
[@value 3]
822 let is_invoked = function
825 | TriggerForIncompleteCompletions
->
828 type params
= completionParams
830 and completionParams
= {
831 loc
: TextDocumentPositionParams.t
;
832 context
: completionContext
option;
835 and completionContext
= {
836 triggerKind
: completionTriggerKind
;
837 triggerCharacter
: string option;
840 and result
= completionList
842 (* wire: can also be 'completionItem list' *)
843 and completionList
= {
845 (* further typing should result in recomputing *)
846 items
: completionItem list
;
849 and completionDocumentation
=
850 | MarkedStringsDocumentation
of markedString list
851 | UnparsedDocumentation
of Hh_json.json
853 and completionItem
= {
855 (* the label in the UI *)
856 kind
: completionItemKind
option;
857 (* tells editor which icon to use *)
858 detail
: string option;
859 (* human-readable string like type/symbol info *)
860 inlineDetail
: string option;
861 (* nuclide-specific, right column *)
862 itemType
: string option;
863 (* nuclide-specific, left column *)
864 documentation
: completionDocumentation
option;
865 (* human-readable doc-comment *)
866 sortText
: string option;
867 (* used for sorting; if absent, uses label *)
868 filterText
: string option;
869 (* used for filtering; if absent, uses label *)
870 insertText
: string option;
871 (* used for inserting; if absent, uses label *)
872 insertTextFormat
: insertTextFormat
option;
873 textEdits
: TextEdit.t list
;
874 (* wire: split into hd and tl *)
875 command
: Command.t
option;
876 (* if present, is executed after completion *)
877 data
: Hh_json.json
option;
881 (* Completion Item Resolve request, method="completionItem/resolve" *)
882 module CompletionItemResolve
= struct
883 type params
= Completion.completionItem
885 and result
= Completion.completionItem
888 (* Workspace Symbols request, method="workspace/symbol" *)
889 module WorkspaceSymbol
= struct
890 type params
= workspaceSymbolParams
892 and result
= SymbolInformation.t list
894 and workspaceSymbolParams
= { query
: string (* a non-empty query string *) }
897 (* Document Symbols request, method="textDocument/documentSymbol" *)
898 module DocumentSymbol
= struct
899 type params
= documentSymbolParams
901 and result
= SymbolInformation.t list
903 and documentSymbolParams
= { textDocument
: TextDocumentIdentifier.t
}
906 (* Find References request, method="textDocument/references" *)
907 module FindReferences
= struct
908 type params
= referenceParams
910 and result
= Location.t list
912 and referenceParams
= {
913 loc
: TextDocumentPositionParams.t
;
914 (* wire: loc's members are part of referenceParams *)
915 context
: referenceContext
;
918 and referenceContext
= {
919 includeDeclaration
: bool;
920 (* include declaration of current symbol *)
921 includeIndirectReferences
: bool;
925 (* Document Highlights request, method="textDocument/documentHighlight" *)
926 module DocumentHighlight
= struct
927 type params
= TextDocumentPositionParams.t
929 type documentHighlightKind
=
930 (* a textual occurrence *)
932 (* read-access of a symbol, like reading a variable *)
934 (* write-access of a symbol, like writing a variable *)
938 type result
= documentHighlight list
940 and documentHighlight
= {
942 (* the range this highlight applies to *)
943 kind
: documentHighlightKind
option;
947 (* Type Coverage request, method="textDocument/typeCoverage" *)
948 (* THIS IS A NUCLIDE-SPECIFIC EXTENSION TO LSP. *)
949 module TypeCoverageFB
= struct
950 type params
= typeCoverageParams
954 uncoveredRanges
: uncoveredRange list
;
955 defaultMessage
: string;
958 and typeCoverageParams
= { textDocument
: TextDocumentIdentifier.t
}
960 and uncoveredRange
= {
962 message
: string option;
966 (* Document Formatting request, method="textDocument/formatting" *)
967 module DocumentFormatting
= struct
968 type params
= documentFormattingParams
970 and result
= TextEdit.t list
972 and documentFormattingParams
= {
973 textDocument
: TextDocumentIdentifier.t
;
974 options
: formattingOptions
;
977 and formattingOptions
= {
979 (* size of a tab in spaces *)
981 (* prefer spaces over tabs *)
982 (* omitted: signature for further properties *)
986 (* Document Range Formatting request, method="textDocument/rangeFormatting" *)
987 module DocumentRangeFormatting
= struct
988 type params
= documentRangeFormattingParams
990 and result
= TextEdit.t list
992 and documentRangeFormattingParams
= {
993 textDocument
: TextDocumentIdentifier.t
;
995 options
: DocumentFormatting.formattingOptions
;
999 (* Document On Type Formatting req., method="textDocument/onTypeFormatting" *)
1000 module DocumentOnTypeFormatting
= struct
1001 type params
= documentOnTypeFormattingParams
1003 and result
= TextEdit.t list
1005 and documentOnTypeFormattingParams
= {
1006 textDocument
: TextDocumentIdentifier.t
;
1008 (* the position at which this request was sent *)
1010 (* the character that has been typed *)
1011 options
: DocumentFormatting.formattingOptions
;
1015 (* Document Signature Help request, method="textDocument/signatureHelp" *)
1016 module SignatureHelp
= struct
1017 type params
= TextDocumentPositionParams.t
1019 and result
= t
option
1022 signatures
: signature_information list
;
1023 activeSignature
: int;
1024 activeParameter
: int;
1027 and signature_information
= {
1028 siginfo_label
: string;
1029 siginfo_documentation
: string option;
1030 parameters
: parameter_information list
;
1033 and parameter_information
= {
1034 parinfo_label
: string;
1035 parinfo_documentation
: string option;
1039 (* Workspace Rename request, method="textDocument/rename" *)
1040 module Rename
= struct
1041 type params
= renameParams
1043 and result
= WorkspaceEdit.t
1045 and renameParams
= {
1046 textDocument
: TextDocumentIdentifier.t
;
1052 (* Code Lens request, method="textDocument/codeLens" *)
1053 module DocumentCodeLens
= struct
1054 type params
= codelensParams
1056 and result
= CodeLens.t list
1058 and codelensParams
= { textDocument
: TextDocumentIdentifier.t
}
1061 (* LogMessage notification, method="window/logMessage" *)
1062 module LogMessage
= struct
1063 type params
= logMessageParams
1065 and logMessageParams
= {
1066 type_
: MessageType.t
;
1071 (* ShowMessage notification, method="window/showMessage" *)
1072 module ShowMessage
= struct
1073 type params
= showMessageParams
1075 and showMessageParams
= {
1076 type_
: MessageType.t
;
1081 (* ShowMessage request, method="window/showMessageRequest" *)
1082 module ShowMessageRequest
= struct
1084 | Present
of { id
: lsp_id
}
1087 and params
= showMessageRequestParams
1089 and result
= messageActionItem
option
1091 and showMessageRequestParams
= {
1092 type_
: MessageType.t
;
1094 actions
: messageActionItem list
;
1097 and messageActionItem
= { title
: string }
1100 (* ShowStatus request, method="window/showStatus" *)
1101 module ShowStatusFB
= struct
1102 type params
= showStatusParams
1104 and result
= ShowMessageRequest.messageActionItem
option
1106 and showStatusParams
= {
1107 request
: ShowMessageRequest.showMessageRequestParams
;
1108 progress
: int option;
1110 shortMessage
: string option;
1111 telemetry
: Hh_json.json
option;
1115 (* ConnectionStatus notification, method="telemetry/connectionStatus" *)
1116 module ConnectionStatusFB
= struct
1117 type params
= connectionStatusParams
1119 and connectionStatusParams
= { isConnected
: bool }
1122 (* ToggleTypeCoverage notification, method="workspace/toggleTypeCoverage" *)
1123 module ToggleTypeCoverageFB
= struct
1124 type params
= toggleTypeCoverageParams
1126 and toggleTypeCoverageParams
= { toggle
: bool }
1130 module Error
= struct
1132 | ParseError
[@value -32700]
1133 | InvalidRequest
[@value -32600]
1134 | MethodNotFound
[@value -32601]
1135 | InvalidParams
[@value -32602]
1136 | InternalError
[@value -32603]
1137 | ServerErrorStart
[@value -32099]
1138 | ServerErrorEnd
[@value -32000]
1139 | ServerNotInitialized
[@value -32002]
1140 | UnknownErrorCode
[@value -32001]
1141 | RequestCancelled
[@value -32800]
1142 | ContentModified
[@value -32801]
1143 [@@deriving show
, enum
]
1148 data
: Hh_json.json
option;
1151 (** For methods which want to return exceptions, and they also want to decide
1152 how the exception gets serialized over LSP, they should throw this one. *)
1153 exception LspException
of t
1156 type lsp_registration_options
=
1157 | DidChangeWatchedFilesRegistrationOptions
of
1158 DidChangeWatchedFiles.registerOptions
1160 (* Register capability request, method="client/registerCapability" *)
1161 module RegisterCapability
= struct
1162 type params
= { registrations
: registration list
}
1164 and registration
= {
1167 registerOptions
: lsp_registration_options
;
1170 let make_registration (registerOptions
: lsp_registration_options
) :
1172 (* The ID field is arbitrary but unique per type of capability (for future
1173 deregistering, which we don't do). *)
1175 match registerOptions
with
1176 | DidChangeWatchedFilesRegistrationOptions _
->
1177 ("did-change-watched-files", "workspace/didChangeWatchedFiles")
1179 { id
; method_
; registerOptions
}
1183 * Here are gathered-up ADTs for all the messages we handle
1187 | InitializeRequest
of Initialize.params
1188 | RegisterCapabilityRequest
of RegisterCapability.params
1190 | CodeLensResolveRequest
of CodeLensResolve.params
1191 | HoverRequest
of Hover.params
1192 | DefinitionRequest
of Definition.params
1193 | TypeDefinitionRequest
of TypeDefinition.params
1194 | ImplementationRequest
of Implementation.params
1195 | CodeActionRequest
of CodeActionRequest.params
1196 | CompletionRequest
of Completion.params
1197 | CompletionItemResolveRequest
of CompletionItemResolve.params
1198 | WorkspaceSymbolRequest
of WorkspaceSymbol.params
1199 | DocumentSymbolRequest
of DocumentSymbol.params
1200 | FindReferencesRequest
of FindReferences.params
1201 | DocumentHighlightRequest
of DocumentHighlight.params
1202 | TypeCoverageRequestFB
of TypeCoverageFB.params
1203 | DocumentFormattingRequest
of DocumentFormatting.params
1204 | DocumentRangeFormattingRequest
of DocumentRangeFormatting.params
1205 | DocumentOnTypeFormattingRequest
of DocumentOnTypeFormatting.params
1206 | ShowMessageRequestRequest
of ShowMessageRequest.params
1207 | ShowStatusRequestFB
of ShowStatusFB.params
1209 | RenameRequest
of Rename.params
1210 | DocumentCodeLensRequest
of DocumentCodeLens.params
1211 | SignatureHelpRequest
of SignatureHelp.params
1212 | HackTestStartServerRequestFB
1213 | HackTestStopServerRequestFB
1214 | HackTestShutdownServerlessRequestFB
1215 | WillSaveWaitUntilRequest
of WillSaveWaitUntil.params
1216 | UnknownRequest
of string * Hh_json.json
option
1219 | InitializeResult
of Initialize.result
1221 | CodeLensResolveResult
of CodeLensResolve.result
1222 | HoverResult
of Hover.result
1223 | DefinitionResult
of Definition.result
1224 | TypeDefinitionResult
of TypeDefinition.result
1225 | ImplementationResult
of Implementation.result
1226 | CodeActionResult
of CodeAction.result
1227 | CompletionResult
of Completion.result
1228 | CompletionItemResolveResult
of CompletionItemResolve.result
1229 | WorkspaceSymbolResult
of WorkspaceSymbol.result
1230 | DocumentSymbolResult
of DocumentSymbol.result
1231 | FindReferencesResult
of FindReferences.result
1232 | DocumentHighlightResult
of DocumentHighlight.result
1233 | TypeCoverageResultFB
of TypeCoverageFB.result
1234 | DocumentFormattingResult
of DocumentFormatting.result
1235 | DocumentRangeFormattingResult
of DocumentRangeFormatting.result
1236 | DocumentOnTypeFormattingResult
of DocumentOnTypeFormatting.result
1237 | ShowMessageRequestResult
of ShowMessageRequest.result
1238 | ShowStatusResultFB
of ShowStatusFB.result
1239 | RageResultFB
of RageFB.result
1240 | RenameResult
of Rename.result
1241 | DocumentCodeLensResult
of DocumentCodeLens.result
1242 | SignatureHelpResult
of SignatureHelp.result
1243 | HackTestStartServerResultFB
1244 | HackTestStopServerResultFB
1245 | HackTestShutdownServerlessResultFB
1246 | RegisterCapabilityRequestResult
1247 | WillSaveWaitUntilResult
of WillSaveWaitUntil.result
1248 | ErrorResult
of Error.t
1250 type lsp_notification
=
1252 | CancelRequestNotification
of CancelRequest.params
1253 | PublishDiagnosticsNotification
of PublishDiagnostics.params
1254 | DidOpenNotification
of DidOpen.params
1255 | DidCloseNotification
of DidClose.params
1256 | DidSaveNotification
of DidSave.params
1257 | DidChangeNotification
of DidChange.params
1258 | DidChangeWatchedFilesNotification
of DidChangeWatchedFiles.params
1259 | LogMessageNotification
of LogMessage.params
1260 | TelemetryNotification
of LogMessage.params
* (string * Hh_json.json
) list
1261 (** For telemetry, LSP allows 'any', but we're going to send params+list *)
1262 | ShowMessageNotification
of ShowMessage.params
1263 | ConnectionStatusNotificationFB
of ConnectionStatusFB.params
1264 | InitializedNotification
1265 | SetTraceNotification
of SetTraceNotification.params
1266 | LogTraceNotification
(* $/logTraceNotification *)
1267 | ToggleTypeCoverageNotificationFB
of ToggleTypeCoverageFB.params
1268 | UnknownNotification
of string * Hh_json.json
option
1271 | RequestMessage
of lsp_id
* lsp_request
1272 | ResponseMessage
of lsp_id
* lsp_result
1273 | NotificationMessage
of lsp_notification
1275 type 'a lsp_handler
= 'a lsp_result_handler
* 'a lsp_error_handler
1277 and 'a lsp_error_handler
= Error.t
* string -> 'a
-> 'a
1279 and 'a lsp_result_handler
=
1280 | ShowMessageHandler
of (ShowMessageRequest.result
-> 'a
-> 'a
)
1281 | ShowStatusHandler
of (ShowStatusFB.result
-> 'a
-> 'a
)
1283 module IdKey
= struct
1286 let compare (x
: t
) (y
: t
) =
1288 | (NumberId x
, NumberId y
) -> x
- y
1289 | (NumberId _
, StringId _
) -> -1
1290 | (StringId x
, StringId y
) -> String.compare x y
1291 | (StringId _
, NumberId _
) -> 1
1294 module IdSet
= Set.Make
(IdKey
)
1295 module IdMap
= WrappedMap.Make
(IdKey
)
1297 module UriKey
= struct
1298 type t
= documentUri
1300 let compare (DocumentUri x
) (DocumentUri y
) = String.compare x y
1303 module UriSet
= Set.Make
(UriKey
)
1304 module UriMap
= WrappedMap.Make
(UriKey
)