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
= string
49 (* A position is between two characters like an 'insert' cursor in a editor *)
51 line
: int; (* line position in a document [zero-based] *)
52 character
: int; (* character offset on a line in a document [zero-based] *)
55 (* A range is comparable to a selection in an editor *)
57 start
: position
; (* the range's start position *)
58 end_
: position
; (* the range's end position [exclusive] *)
61 (* Represents a location inside a resource, such as a line inside a text file *)
62 module Location
= struct
69 (* Represents a location inside a resource which also wants to display a
70 friendly name to the user. *)
71 module DefinitionLocation
= struct
78 (* markedString can be used to render human readable text. It is either a
79 * markdown string or a code-block that provides a language and a code snippet.
80 * Note that markdown strings will be sanitized by the client - including
83 | MarkedString
of string
84 | MarkedCode
of string * string (* lang, value *)
86 (* Represents a reference to a command. Provides a title which will be used to
87 * represent a command in the UI. Commands are identitifed using a string
88 * identifier and the protocol currently doesn't specify a set of well known
89 * commands. So executing a command requires some tool extension code. *)
90 module Command
= struct
92 title
: string; (* title of the command, like `save` *)
93 command
: string; (* the identifier of the actual command handler *)
94 arguments
: Hh_json.json list
; (* wire: it can be omitted *)
98 (* A textual edit applicable to a text document. If n textEdits are applied
99 to a text document all text edits describe changes to the initial document
100 version. Execution wise text edits should applied from the bottom to the
101 top of the text document. Overlapping text edits are not supported. *)
102 module TextEdit
= struct
104 range
: range
; (* to insert text, use a range where start = end *)
105 newText
: string; (* for delete operations, use an empty string *)
109 (* Text documents are identified using a URI. *)
110 module TextDocumentIdentifier
= struct
112 uri
: documentUri
; (* the text document's URI *)
116 (* An identifier to denote a specific version of a text document. *)
117 module VersionedTextDocumentIdentifier
= struct
119 uri
: documentUri
; (* the text document's URI *)
120 version
: int; (* the version number of this document *)
124 (* Describes textual changes on a single text document. The text document is
125 referred to as a VersionedTextDocumentIdentifier to allow clients to check
126 the text document version before an edit is applied. *)
127 module TextDocumentEdit
= struct
129 textDocument
: VersionedTextDocumentIdentifier.t
;
130 edits
: TextEdit.t list
;
134 (* A workspace edit represents changes to many resources managed in the
135 workspace. A workspace edit consists of a mapping from a URI to an
136 array of TextEdits to be applied to the document with that URI. *)
137 module WorkspaceEdit
= struct
139 changes
: TextEdit.t list
SMap.t
; (* holds changes to existing docs *)
143 (* An item to transfer a text document from the client to the server. The
144 version number strictly increases after each change, including undo/redo. *)
145 module TextDocumentItem
= struct
147 uri
: documentUri
; (* the text document's URI *)
148 languageId
: string; (* the text document's language identifier *)
149 version
: int; (* the version of the document *)
150 text
: string; (* the content of the opened text document *)
155 * A code lens represents a command that should be shown along with
156 * source text, like the number of references, a way to run tests, etc.
158 * A code lens is _unresolved_ when no command is associated to it. For performance
159 * reasons the creation of a code lens and resolving should be done in two stages.
161 module CodeLens
= struct
165 data
: Hh_json.json
option;
169 (* A parameter literal used in requests to pass a text document and a position
170 inside that document. *)
171 module TextDocumentPositionParams
= struct
173 textDocument
: TextDocumentIdentifier.t
; (* the text document *)
174 position
: position
; (* the position inside the text document *)
178 (* A document filter denotes a document through properties like language,
179 schema or pattern. E.g. language:"typescript",scheme:"file"
180 or language:"json",pattern:"**/package.json" *)
181 module DocumentFilter
= struct
183 language
: string option; (* a language id, like "typescript" *)
184 scheme
: string option; (* a uri scheme, like "file" or "untitled" *)
185 pattern
: string option; (* a glob pattern, like "*.{ts,js}" *)
189 (* A document selector is the combination of one or many document filters. *)
190 module DocumentSelector
= struct
191 type t
= DocumentFilter.t list
195 (* Represents information about programming constructs like variables etc. *)
196 module SymbolInformation
= struct
200 location
: Location.t
; (* the span of the symbol including its contents *)
201 containerName
: string option; (* the symbol containing this symbol *)
213 | Constructor
(* 9 *)
226 (* For showing messages (not diagnostics) in the user interface. *)
227 module MessageType
= struct
229 | ErrorMessage
(* 1 *)
230 | WarningMessage
(* 2 *)
231 | InfoMessage
(* 3 *)
235 module CodeActionKind
= struct
236 (* The kind of a code action.
237 * Kinds are a hierarchical list of identifiers separated by `.`, e.g.
238 * `"refactor.extract.function"`.
239 * The set of kinds is open and client needs to announce the kinds it supports
240 * to the server during initialization.
241 * CodeActionKind.t uses a pair to represent a non-empty list and provides utility
242 * functions for creation, membership, printing.
243 * Module CodeAction below also references this module as Kind.
245 type t
= (string * string list
)
247 (* is x of kind k? *)
248 let is_kind : t
-> t
-> bool =
249 let rec is_prefix_of ks xs
=
252 | (k
:: ks
), (x
:: xs
) when String.equal k x
-> is_prefix_of ks xs
254 fun (k
, ks
) (x
, xs
) -> String.equal k x
&& is_prefix_of ks xs
256 (* does `ks` contain kind `k` *)
257 let contains_kind k ks
= List.exists
(is_kind k
) ks
259 (* does an optional list of kinds `ks` contain kind `k` *)
260 let contains_kind_opt ~default k ks
=
262 | Some ks
-> contains_kind k ks
265 (* Create a kind from a string that follows the spec *)
266 let kind_of_string : string -> t
=
268 match String.split_on_char '
.' s
with
269 | [] -> failwith
"split_on_char does not return an empty list"
270 | (k
:: ks
) -> (k
, ks
)
272 (* Create the equivalent string that the spec would have required *)
273 let string_of_kind : t
-> string =
274 fun (k
, ks
) -> String.concat
"." (k
:: ks
)
276 (* Create a new sub-kind of an existing kind *)
277 let sub_kind : t
-> string -> t
=
278 let cons_to_end (ss
: string list
) (s
: string) =
279 Core_list.(fold_right ss ~f
:cons ~init
:[s
]) in
280 fun (k
, ks
) s
-> (k
, cons_to_end ks s
)
282 (* Some of the constants defined by the spec *)
283 let quickfix = kind_of_string "quickfix"
285 (* Document wide code actions *)
286 let source = kind_of_string "source"
289 (* Cancellation notification, method="$/cancelRequest" *)
290 module CancelRequest
= struct
291 type params
= cancelParams
294 id
: lsp_id
; (* the request id to cancel *)
298 (* Initialize request, method="initialize" *)
299 module Initialize
= struct
301 processId
: int option; (* pid of parent process *)
302 rootPath
: string option; (* deprecated *)
303 rootUri
: documentUri
option; (* the root URI of the workspace *)
304 initializationOptions
: initializationOptions
;
305 client_capabilities
: client_capabilities
; (* "capabilities" over wire *)
306 trace
: trace
; (* the initial trace setting, default="off" *)
310 server_capabilities
: server_capabilities
; (* "capabilities" over wire *)
314 retry
: bool; (* should client retry the initialize request *)
322 (* Following initialization options are unfortunately a mix of Hack
323 * and Flow. We should find a way to separate them.
324 * Anyway, they're all optional in the source json, but we pick
325 * a default if necessary while parsing. *)
326 and initializationOptions
= {
327 useTextEditAutocomplete
: bool; (* only supported for Hack so far *)
328 liveSyntaxErrors
: bool; (* implicitly true for Hack; supported in Flow *)
329 namingTableSavedStatePath
: string option; (* only supported for Hack *)
330 sendServerStatusEvents
: bool; (* only supported for Hack *)
333 and client_capabilities
= {
334 workspace
: workspaceClientCapabilities
;
335 textDocument
: textDocumentClientCapabilities
;
336 window
: windowClientCapabilities
;
337 telemetry
: telemetryClientCapabilities
;
338 (* omitted: experimental *)
341 and workspaceClientCapabilities
= {
342 applyEdit
: bool; (* client supports appling batch edits *)
343 workspaceEdit
: workspaceEdit
;
345 didChangeWatchedFiles
: dynamicRegistration
;
346 (* omitted: other dynamic-registration fields *)
349 and dynamicRegistration
= {
350 dynamicRegistration
: bool; (* client supports dynamic registration for this capability *)
353 and workspaceEdit
= {
354 documentChanges
: bool; (* client supports versioned doc changes *)
357 and textDocumentClientCapabilities
= {
358 synchronization
: synchronization
;
359 completion
: completion
; (* textDocument/completion *)
360 codeAction
: codeAction
;
361 (* omitted: dynamic-registration fields *)
364 (* synchronization capabilities say what messages the client is capable
365 * of sending, should be be so asked by the server.
366 * We use the "can_" prefix for OCaml naming reasons; it's absent in LSP *)
367 and synchronization
= {
368 can_willSave
: bool; (* client can send textDocument/willSave *)
369 can_willSaveWaitUntil
: bool; (* textDoc.../willSaveWaitUntil *)
370 can_didSave
: bool; (* textDocument/didSave *)
374 completionItem
: completionItem
;
377 and completionItem
= {
378 snippetSupport
: bool; (* client can do snippets as insert text *)
382 (* Whether code action supports dynamic registration. *)
383 codeAction_dynamicRegistration
: bool; (* wire: dynamicRegistraction *)
384 (* The client support code action literals as a valid
385 * response of the `textDocument/codeAction` request. *)
386 codeActionLiteralSupport
: codeActionliteralSupport
option;
389 and codeActionliteralSupport
= {
390 (* The code action kind values the client supports. When this
391 * property exists the client also guarantees that it will
392 * handle values outside its set gracefully and falls back
393 * to a default value when unknown. *)
394 codeAction_valueSet
: CodeActionKind.t list
(* wire: valueSet *)
397 and windowClientCapabilities
= {
398 status
: bool; (* Nuclide-specific: client supports window/showStatusRequest *)
399 progress
: bool; (* Nuclide-specific: client supports window/progress *)
400 actionRequired
: bool; (* Nuclide-specific: client supports window/actionRequired *)
403 and telemetryClientCapabilities
= {
404 connectionStatus
: bool; (* Nuclide-specific: client supports telemetry/connectionStatus *)
407 (* What capabilities the server provides *)
408 and server_capabilities
= {
409 textDocumentSync
: textDocumentSyncOptions
; (* how to sync *)
411 completionProvider
: completionOptions
option;
412 signatureHelpProvider
: signatureHelpOptions
option;
413 definitionProvider
: bool;
414 typeDefinitionProvider
: bool;
415 referencesProvider
: bool;
416 documentHighlightProvider
: bool;
417 documentSymbolProvider
: bool; (* ie. document outline *)
418 workspaceSymbolProvider
: bool; (* ie. find-symbol-in-project *)
419 codeActionProvider
: bool;
420 codeLensProvider
: codeLensOptions
option;
421 documentFormattingProvider
: bool;
422 documentRangeFormattingProvider
: bool;
423 documentOnTypeFormattingProvider
: documentOnTypeFormattingOptions
option;
424 renameProvider
: bool;
425 documentLinkProvider
: documentLinkOptions
option;
426 executeCommandProvider
: executeCommandOptions
option;
427 typeCoverageProvider
: bool; (* Nuclide-specific feature *)
429 (* omitted: experimental *)
432 and completionOptions
= {
433 resolveProvider
: bool; (* server resolves extra info on demand *)
434 completion_triggerCharacters
: string list
; (* wire "triggerCharacters" *)
437 and signatureHelpOptions
= {
438 sighelp_triggerCharacters
: string list
; (* wire "triggerCharacters" *)
441 and codeLensOptions
= {
442 codelens_resolveProvider
: bool; (* wire "resolveProvider" *)
445 and documentOnTypeFormattingOptions
= {
446 firstTriggerCharacter
: string; (* e.g. "}" *)
447 moreTriggerCharacter
: string list
;
450 and documentLinkOptions
= {
451 doclink_resolveProvider
: bool; (* wire "resolveProvider" *)
454 and executeCommandOptions
= {
455 commands
: string list
; (* the commands to be executed on the server *)
458 (* text document sync options say what messages the server requests the
459 * client to send. We use the "want_" prefix for OCaml naming reasons;
460 * this prefix is absent in LSP. *)
461 and textDocumentSyncOptions
= {
462 want_openClose
: bool; (* textDocument/didOpen+didClose *)
463 want_change
: textDocumentSyncKind
;
464 want_willSave
: bool; (* textDocument/willSave *)
465 want_willSaveWaitUntil
: bool; (* textDoc.../willSaveWaitUntil *)
466 want_didSave
: saveOptions
option; (* textDocument/didSave *)
469 and textDocumentSyncKind
=
470 | NoSync
(* 0 *) (* docs should not be synced at all. Wire "None" *)
471 | FullSync
(* 1 *) (* synced by always sending full content. Wire "Full" *)
472 | IncrementalSync
(* 2 *) (* full only on open. Wire "Incremental" *)
475 includeText
: bool; (* the client should include content on save *)
479 (* Shutdown request, method="shutdown" *)
480 module Shutdown
= struct
483 (* Exit notification, method="exit" *)
487 (* Rage request, method="telemetry/rage" *)
489 type result
= rageItem list
492 title
: string option;
497 (* Code Lens resolve request, method="codeLens/resolve" *)
498 module CodeLensResolve
= struct
499 type params
= CodeLens.t
501 and result
= CodeLens.t
504 (* Hover request, method="textDocument/hover" *)
505 module Hover
= struct
506 type params
= TextDocumentPositionParams.t
508 and result
= hoverResult
option
511 contents
: markedString list
; (* wire: either a single one or an array *)
516 (* PublishDiagnostics notification, method="textDocument/PublishDiagnostics" *)
517 module PublishDiagnostics
= struct
519 type diagnosticSeverity
=
522 | Information
[@value 3]
526 type params
= publishDiagnosticsParams
528 and publishDiagnosticsParams
= {
530 diagnostics
: diagnostic list
;
534 range
: range
; (* the range at which the message applies *)
535 severity
: diagnosticSeverity
option; (* if omitted, client decides *)
536 code
: diagnosticCode
; (* the diagnostic's code. *)
537 source: string option; (* human-readable string, eg. typescript/lint *)
538 message
: string; (* the diagnostic's message *)
539 relatedInformation
: diagnosticRelatedInformation list
;
540 relatedLocations
: relatedLocation list
; (* legacy FB extension *)
545 | StringCode
of string
549 and diagnosticRelatedInformation
= {
550 relatedLocation
: Location.t
; (* wire: just "location" *)
551 relatedMessage
: string; (* wire: just "message" *)
554 (* legacy FB extension *)
555 and relatedLocation
= diagnosticRelatedInformation
558 (* DidOpenTextDocument notification, method="textDocument/didOpen" *)
559 module DidOpen
= struct
560 type params
= didOpenTextDocumentParams
562 and didOpenTextDocumentParams
= {
563 textDocument
: TextDocumentItem.t
; (* the document that was opened *)
567 (* DidCloseTextDocument notification, method="textDocument/didClose" *)
568 module DidClose
= struct
569 type params
= didCloseTextDocumentParams
571 and didCloseTextDocumentParams
= {
572 textDocument
: TextDocumentIdentifier.t
; (* the doc that was closed *)
576 (* DidSaveTextDocument notification, method="textDocument/didSave" *)
577 module DidSave
= struct
578 type params
= didSaveTextDocumentParams
580 and didSaveTextDocumentParams
= {
581 textDocument
: TextDocumentIdentifier.t
; (* the doc that was saved *)
582 text
: string option; (* content when saved; depends on includeText *)
586 (* DidChangeTextDocument notification, method="textDocument/didChange" *)
587 module DidChange
= struct
588 type params
= didChangeTextDocumentParams
590 and didChangeTextDocumentParams
= {
591 textDocument
: VersionedTextDocumentIdentifier.t
;
592 contentChanges
: textDocumentContentChangeEvent list
;
595 and textDocumentContentChangeEvent
= {
596 range
: range
option; (* the range of the document that changed *)
597 rangeLength
: int option; (* the length that got replaced *)
598 text
: string; (* the new text of the range/document *)
602 (* Watched files changed notification, method="workspace/didChangeWatchedFiles" *)
603 module DidChangeWatchedFiles
= struct
604 type registerOptions
= {
605 watchers
: fileSystemWatcher list
;
608 and fileSystemWatcher
= {
612 type fileChangeType
=
619 changes
: fileEvent list
;
624 type_
: fileChangeType
;
628 (* Goto Definition request, method="textDocument/definition" *)
629 module Definition
= struct
630 type params
= TextDocumentPositionParams.t
632 and result
= DefinitionLocation.t list
(* wire: either a single one or an array *)
635 (* Goto TypeDefinition request, method="textDocument/typeDefinition" *)
636 module TypeDefinition
= struct
637 type params
= TextDocumentPositionParams.t
639 and result
= DefinitionLocation.t list
642 module CodeAction
= struct
643 (* A code action represents a change that can be performed in code, e.g. to fix a problem or
646 (* A short, human-readable, title for this code action. *)
648 (* The kind of the code action. Used to filter code actions. *)
649 kind
: CodeActionKind.t
;
650 (* The diagnostics that this code action resolves. *)
651 diagnostics
: PublishDiagnostics.diagnostic list
;
652 (* A CodeAction must set either `edit` and/or a `command`.
653 If both are supplied, the `edit` is applied first, then the `command` is executed. *)
654 action
: edit_and_or_command
;
657 and edit_and_or_command
=
658 | EditOnly
of WorkspaceEdit.t
659 | CommandOnly
of Command.t
660 | BothEditThenCommand
of (WorkspaceEdit.t
* Command.t
)
662 type result
= command_or_action list
664 and command_or_action
=
665 | Command
of Command.t
669 (* Code Action Request, method="textDocument/codeAction" *)
670 module CodeActionRequest
= struct
672 (* The document in which the command was invoked. *)
673 textDocument
: TextDocumentIdentifier.t
;
674 (* The range for which the command was invoked. *)
676 (* Context carrying additional information. *)
677 context
: codeActionContext
;
680 (* Contains additional diagnostic information about the context in which
681 a code action is run. *)
682 and codeActionContext
= {
683 diagnostics
: PublishDiagnostics.diagnostic list
;
684 only
: CodeActionKind.t list
option
688 (* Completion request, method="textDocument/completion" *)
689 module Completion
= struct
690 (* These numbers should match
691 * https://microsoft.github.io/language-server-protocol/specification#textDocument_completion
693 type completionItemKind
=
696 | Function
[@value 3]
697 | Constructor
[@value 4]
699 | Variable
[@value 6]
701 | Interface
[@value 8]
703 | Property
[@value 10]
707 | Keyword
[@value 14]
708 | Snippet
[@value 15]
711 | Reference
[@value 18]
713 | EnumMember
[@value 20]
714 | Constant
[@value 21]
717 | Operator
[@value 24]
718 | TypeParameter
[@value 25]
721 (* These numbers should match
722 * https://microsoft.github.io/language-server-protocol/specification#textDocument_completion
724 type insertTextFormat
=
725 | PlainText
[@value 1] (* the insertText/textEdits are just plain strings *)
726 | SnippetFormat
[@value 2] (* wire: just "Snippet" *)
729 type params
= completionParams
731 and completionParams
= {
732 loc
: TextDocumentPositionParams.t
;
733 context
: completionContext
option;
736 and completionContext
= {
737 triggerKind
: completionTriggerKind
;
740 and completionTriggerKind
=
742 | TriggerCharacter
(* 2 *)
743 | TriggerForIncompleteCompletions
(* 3 *)
745 and result
= completionList
(* wire: can also be 'completionItem list' *)
747 and completionList
= {
748 isIncomplete
: bool; (* further typing should result in recomputing *)
749 items
: completionItem list
;
752 and completionItem
= {
753 label
: string; (* the label in the UI *)
754 kind
: completionItemKind
option; (* tells editor which icon to use *)
755 detail
: string option; (* human-readable string like type/symbol info *)
756 inlineDetail
: string option; (* nuclide-specific, right column *)
757 itemType
: string option; (* nuclide-specific, left column *)
758 documentation
: markedString list
option; (* human-readable doc-comment *)
759 sortText
: string option; (* used for sorting; if absent, uses label *)
760 filterText
: string option; (* used for filtering; if absent, uses label *)
761 insertText
: string option; (* used for inserting; if absent, uses label *)
762 insertTextFormat
: insertTextFormat
option;
763 textEdits
: TextEdit.t list
; (* wire: split into hd and tl *)
764 command
: Command.t
option; (* if present, is executed after completion *)
765 data
: Hh_json.json
option;
771 (* Completion Item Resolve request, method="completionItem/resolve" *)
772 module CompletionItemResolve
= struct
773 type params
= Completion.completionItem
775 and result
= Completion.completionItem
779 (* Workspace Symbols request, method="workspace/symbol" *)
780 module WorkspaceSymbol
= struct
781 type params
= workspaceSymbolParams
783 and result
= SymbolInformation.t list
785 and workspaceSymbolParams
= {
786 query
: string; (* a non-empty query string *)
791 (* Document Symbols request, method="textDocument/documentSymbols" *)
792 module DocumentSymbol
= struct
793 type params
= documentSymbolParams
795 and result
= SymbolInformation.t list
797 and documentSymbolParams
= {
798 textDocument
: TextDocumentIdentifier.t
;
803 (* Find References request, method="textDocument/references" *)
804 module FindReferences
= struct
805 type params
= referenceParams
807 and result
= Location.t list
809 and referenceParams
= {
810 loc
: TextDocumentPositionParams.t
; (* wire: loc's members are part of referenceParams *)
811 context
: referenceContext
;
814 and referenceContext
= {
815 includeDeclaration
: bool; (* include declaration of current symbol *)
816 includeIndirectReferences
: bool;
821 (* Document Highlights request, method="textDocument/documentHighlight" *)
822 module DocumentHighlight
= struct
823 type params
= TextDocumentPositionParams.t
825 and result
= documentHighlight list
827 and documentHighlight
= {
828 range
: range
; (* the range this highlight applies to *)
829 kind
: documentHighlightKind
option;
832 and documentHighlightKind
=
833 | Text
(* 1 *) (* a textual occurrence *)
834 | Read
(* 2 *) (* read-access of a symbol, like reading a variable *)
835 | Write
(* 3 *) (* write-access of a symbol, like writing a variable *)
839 (* Type Coverage request, method="textDocument/typeCoverage" *)
840 (* THIS IS A NUCLIDE-SPECIFIC EXTENSION TO LSP. *)
841 module TypeCoverage
= struct
842 type params
= typeCoverageParams
846 uncoveredRanges
: uncoveredRange list
;
847 defaultMessage
: string;
850 and typeCoverageParams
= {
851 textDocument
: TextDocumentIdentifier.t
;
854 and uncoveredRange
= {
856 message
: string option;
861 (* Document Formatting request, method="textDocument/formatting" *)
862 module DocumentFormatting
= struct
863 type params
= documentFormattingParams
865 and result
= TextEdit.t list
867 and documentFormattingParams
= {
868 textDocument
: TextDocumentIdentifier.t
;
869 options
: formattingOptions
;
872 and formattingOptions
= {
873 tabSize
: int; (* size of a tab in spaces *)
874 insertSpaces
: bool; (* prefer spaces over tabs *)
875 (* omitted: signature for further properties *)
880 (* Document Range Formatting request, method="textDocument/rangeFormatting" *)
881 module DocumentRangeFormatting
= struct
882 type params
= documentRangeFormattingParams
884 and result
= TextEdit.t list
886 and documentRangeFormattingParams
= {
887 textDocument
: TextDocumentIdentifier.t
;
889 options
: DocumentFormatting.formattingOptions
;
894 (* Document On Type Formatting req., method="textDocument/onTypeFormatting" *)
895 module DocumentOnTypeFormatting
= struct
896 type params
= documentOnTypeFormattingParams
898 and result
= TextEdit.t list
900 and documentOnTypeFormattingParams
= {
901 textDocument
: TextDocumentIdentifier.t
;
902 position
: position
; (* the position at which this request was sent *)
903 ch
: string; (* the character that has been typed *)
904 options
: DocumentFormatting.formattingOptions
;
909 (* Document Signature Help request, method="textDocument/signatureHelp" *)
910 module SignatureHelp
= struct
911 type params
= TextDocumentPositionParams.t
913 and result
= t
option
916 signatures
: signature_information list
;
917 activeSignature
: int;
918 activeParameter
: int;
921 and signature_information
= {
922 siginfo_label
: string;
923 siginfo_documentation
: string option;
924 parameters
: parameter_information list
;
927 and parameter_information
= {
928 parinfo_label
: string;
929 parinfo_documentation
: string option;
933 (* Workspace Rename request, method="textDocument/rename" *)
934 module Rename
= struct
935 type params
= renameParams
937 and result
= WorkspaceEdit.t
940 textDocument
: TextDocumentIdentifier.t
;
946 (* Code Lens request, method="textDocument/codeLens" *)
947 module DocumentCodeLens
= struct
948 type params
= codelensParams
950 and result
= CodeLens.t list
952 and codelensParams
= {
953 textDocument
: TextDocumentIdentifier.t
;
957 (* LogMessage notification, method="window/logMessage" *)
958 module LogMessage
= struct
959 type params
= logMessageParams
961 and logMessageParams
= {
962 type_
: MessageType.t
;
968 (* ShowMessage notification, method="window/showMessage" *)
969 module ShowMessage
= struct
970 type params
= showMessageParams
972 and showMessageParams
= {
973 type_
: MessageType.t
;
979 (* ShowMessage request, method="window/showMessageRequest" *)
980 module ShowMessageRequest
= struct
981 type t
= Present
of {id
: lsp_id
;} | Absent
983 and params
= showMessageRequestParams
985 and result
= messageActionItem
option
987 and showMessageRequestParams
= {
988 type_
: MessageType.t
;
990 actions
: messageActionItem list
;
993 and messageActionItem
= {
999 (* ShowStatus request, method="window/showStatus" *)
1000 module ShowStatus
= struct
1001 type params
= showStatusParams
1003 and result
= ShowMessageRequest.messageActionItem
option
1005 and showStatusParams
= {
1006 request
: ShowMessageRequest.showMessageRequestParams
;
1007 progress
: int option;
1009 shortMessage
: string option;
1014 (* Progress notification, method="window/progress" *)
1015 module Progress
= struct
1016 type t
= Present
of {id
: int; label
: string;} | Absent
1018 and params
= progressParams
1020 and progressParams
= {
1021 (* LSP progress notifications have a lifetime that starts with their 1st *)
1022 (* window/progress update message and ends with an update message with *)
1023 (* label = None. They use an ID number (not JsonRPC id) to associate *)
1024 (* multiple messages to a single lifetime stream. *)
1026 label
: string option;
1031 (* ActionRequired notification, method="window/actionRequired" *)
1032 module ActionRequired
= struct
1033 type t
= Present
of {id
: int; label
: string;} | Absent
1035 and params
= actionRequiredParams
1037 and actionRequiredParams
= {
1038 (* See progressParams.id for an explanation of this field. *)
1040 label
: string option;
1045 (* ConnectionStatus notification, method="telemetry/connectionStatus" *)
1046 module ConnectionStatus
= struct
1047 type params
= connectionStatusParams
1049 and connectionStatusParams
= {
1055 (* Module for dynamic view, method="workspace/toggleTypeCoverage" *)
1056 module ToggleTypeCoverage
= struct
1057 type params
= toggleTypeCoverageParams
1058 and toggleTypeCoverageParams
= {
1064 module Error
= struct
1065 type t
= {code
: int; message
: string; data
: Hh_json.json
option}
1067 (* Legacy: some code uses exceptions instead of Error.t. *)
1068 (* Be careful with that since if you unmarshal one then you can't pattern-match it. *)
1070 (* Defined by JSON-RPC. *)
1071 exception Parse
of string (* -32700 *)
1072 exception InvalidRequest
of string (* -32600 *)
1073 exception MethodNotFound
of string (* -32601 *)
1074 exception InvalidParams
of string (* -32602 *)
1075 exception InternalError
of string (* -32603 *)
1076 exception ServerErrorStart
of string * Initialize.errorData
(* -32099 *)
1077 exception ServerErrorEnd
of string (* -32000 *)
1078 exception ServerNotInitialized
of string (* -32002 *)
1079 exception Unknown
of string (* -32001 *)
1081 (* Defined by the protocol. *)
1082 exception RequestCancelled
of string (* -32800 *)
1084 module Code
= struct
1085 (* Defined by JSON RPC *)
1086 let parseError = -32700
1087 let invalidRequest = -32600
1088 let methodNotFound = -32601
1089 let invalidParams = -32602
1090 let internalError = -32603
1091 let serverErrorStart = -32099
1092 let serverErrorEnd = -32000
1093 let serverNotInitialized = -32002
1094 let unknownErrorCode = -32001
1096 (* Defined by the protocol. *)
1097 let requestCancelled = -32800
1098 let contentModified = -32801
1102 type lsp_registration_options
=
1103 | DidChangeWatchedFilesRegistrationOptions
of
1104 DidChangeWatchedFiles.registerOptions
1106 (* Register capability request, method="client/registerCapability" *)
1107 module RegisterCapability
= struct
1109 registrations
: registration list
;
1112 and registration
= {
1115 registerOptions
: lsp_registration_options
;
1118 let make_registration
1119 (registerOptions
: lsp_registration_options
)
1121 (* The ID field is arbitrary but unique per type of capability (for future
1122 deregistering, which we don't do). *)
1124 match registerOptions
with
1125 | DidChangeWatchedFilesRegistrationOptions _
->
1126 ("did-change-watched-files", "workspace/didChangeWatchedFiles")
1128 { id
; method_
; registerOptions
}
1133 * Here are gathered-up ADTs for all the messages we handle
1137 | InitializeRequest
of Initialize.params
1138 | RegisterCapabilityRequest
of RegisterCapability.params
1140 | CodeLensResolveRequest
of CodeLensResolve.params
1141 | HoverRequest
of Hover.params
1142 | DefinitionRequest
of Definition.params
1143 | TypeDefinitionRequest
of TypeDefinition.params
1144 | CodeActionRequest
of CodeActionRequest.params
1145 | CompletionRequest
of Completion.params
1146 | CompletionItemResolveRequest
of CompletionItemResolve.params
1147 | WorkspaceSymbolRequest
of WorkspaceSymbol.params
1148 | DocumentSymbolRequest
of DocumentSymbol.params
1149 | FindReferencesRequest
of FindReferences.params
1150 | DocumentHighlightRequest
of DocumentHighlight.params
1151 | TypeCoverageRequest
of TypeCoverage.params
1152 | DocumentFormattingRequest
of DocumentFormatting.params
1153 | DocumentRangeFormattingRequest
of DocumentRangeFormatting.params
1154 | DocumentOnTypeFormattingRequest
of DocumentOnTypeFormatting.params
1155 | ShowMessageRequestRequest
of ShowMessageRequest.params
1156 | ShowStatusRequest
of ShowStatus.params
1158 | RenameRequest
of Rename.params
1159 | DocumentCodeLensRequest
of DocumentCodeLens.params
1160 | UnknownRequest
of string * Hh_json.json
option
1163 | InitializeResult
of Initialize.result
1165 | CodeLensResolveResult
of CodeLensResolve.result
1166 | HoverResult
of Hover.result
1167 | DefinitionResult
of Definition.result
1168 | TypeDefinitionResult
of TypeDefinition.result
1169 | CodeActionResult
of CodeAction.result
1170 | CompletionResult
of Completion.result
1171 | CompletionItemResolveResult
of CompletionItemResolve.result
1172 | WorkspaceSymbolResult
of WorkspaceSymbol.result
1173 | DocumentSymbolResult
of DocumentSymbol.result
1174 | FindReferencesResult
of FindReferences.result
1175 | DocumentHighlightResult
of DocumentHighlight.result
1176 | TypeCoverageResult
of TypeCoverage.result
1177 | DocumentFormattingResult
of DocumentFormatting.result
1178 | DocumentRangeFormattingResult
of DocumentRangeFormatting.result
1179 | DocumentOnTypeFormattingResult
of DocumentOnTypeFormatting.result
1180 | ShowMessageRequestResult
of ShowMessageRequest.result
1181 | ShowStatusResult
of ShowStatus.result
1182 | RageResult
of Rage.result
1183 | RenameResult
of Rename.result
1184 | DocumentCodeLensResult
of DocumentCodeLens.result
1185 | ErrorResult
of Error.t
* string (* the string is a stacktrace *)
1187 type lsp_notification
=
1189 | CancelRequestNotification
of CancelRequest.params
1190 | PublishDiagnosticsNotification
of PublishDiagnostics.params
1191 | DidOpenNotification
of DidOpen.params
1192 | DidCloseNotification
of DidClose.params
1193 | DidSaveNotification
of DidSave.params
1194 | DidChangeNotification
of DidChange.params
1195 | DidChangeWatchedFilesNotification
of DidChangeWatchedFiles.params
1196 | LogMessageNotification
of LogMessage.params
1197 | TelemetryNotification
of LogMessage.params
(* LSP allows 'any' but we only send these *)
1198 | ShowMessageNotification
of ShowMessage.params
1199 | ProgressNotification
of Progress.params
1200 | ActionRequiredNotification
of ActionRequired.params
1201 | ConnectionStatusNotification
of ConnectionStatus.params
1202 | InitializedNotification
1203 | SetTraceNotification
(* $/setTraceNotification *)
1204 | LogTraceNotification
(* $/logTraceNotification *)
1205 | UnknownNotification
of string * Hh_json.json
option
1208 | RequestMessage
of lsp_id
* lsp_request
1209 | ResponseMessage
of lsp_id
* lsp_result
1210 | NotificationMessage
of lsp_notification
1212 type 'a lsp_handler
= 'a lsp_result_handler
* 'a lsp_error_handler
1214 and 'a lsp_error_handler
= (Error.t
* string) -> 'a
-> 'a
1216 and 'a lsp_result_handler
=
1217 | ShowMessageHandler
of (ShowMessageRequest.result
-> 'a
-> 'a
)
1218 | ShowStatusHandler
of (ShowStatus.result
-> 'a
-> 'a
)
1220 module IdKey
= struct
1223 let compare (x
: t
) (y
:t
) =
1225 | NumberId x
, NumberId y
-> x
- y
1226 | NumberId _
, StringId _
-> -1
1227 | StringId x
, StringId y
-> String.compare x y
1228 | StringId _
, NumberId _
-> 1
1231 module IdSet
= Set.Make
(IdKey
)
1232 module IdMap
= MyMap.Make
(IdKey
)