2 * Copyright (c) 2019, 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.
12 module Initialize_from_saved_state
= struct
15 naming_table_saved_state_path
: Path.t
option;
16 use_ranked_autocomplete
: bool;
17 config
: (string * string) list
;
18 open_files
: Path.t list
;
21 type result
= { num_changed_files_to_process
: int }
24 type document_location
= {
26 file_contents
: string option;
27 (* if absent, should read from file on disk *)
32 type document_and_path
= {
34 file_contents
: string;
37 (** Denotes a location of the cursor in a document at which an IDE request is
38 being executed (e.g. hover). *)
40 module Ide_file_opened
= struct
41 type request
= document_and_path
44 module Ide_file_changed
= struct
45 type request
= { file_path
: Path.t
}
49 type request
= document_location
51 type result
= HoverService.result
54 module Definition
= struct
55 type request
= document_location
57 type result
= ServerCommandTypes.Go_to_definition.result
60 (* Handles "textDocument/typeDefinition" LSP messages *)
61 module Type_definition
= struct
62 type request
= document_location
64 type result
= ServerCommandTypes.Go_to_type_definition.result
67 (* Handles "textDocument/completion" LSP messages *)
68 module Completion
= struct
70 document_location
: document_location
;
71 is_manually_invoked
: bool;
74 type result
= AutocompleteTypes.ide_result
77 (* "completionItem/resolve" LSP messages - if we have symbol name *)
78 module Completion_resolve
= struct
81 kind
: SearchUtils.si_kind
;
84 type result
= DocblockService.result
87 (* "completionItem/resolve" LSP messages - if we have file/line/column *)
88 module Completion_resolve_location
= struct
90 kind
: SearchUtils.si_kind
;
91 document_location
: document_location
;
94 type result
= DocblockService.result
97 (* Handles "textDocument/documentHighlight" LSP messages *)
98 module Document_highlight
= struct
99 type request
= document_location
101 type result
= Ide_api_types.range list
104 (* Handles "textDocument/signatureHelp" LSP messages *)
105 module Signature_help
= struct
106 type request
= document_location
108 type result
= Lsp.SignatureHelp.result
111 (* Handles "textDocument/documentSymbol" LSP messages *)
112 module Document_symbol
= struct
113 type request
= document_location
115 type result
= FileOutline.outline
118 module Type_coverage
= struct
119 type request
= document_and_path
121 type result
= Coverage_level_defs.result
124 (* GADT for request/response types. See [ServerCommandTypes] for a discussion on
125 using GADTs in this way. *)
127 | Initialize_from_saved_state
:
128 Initialize_from_saved_state.t
129 -> Initialize_from_saved_state.result t
130 | Shutdown
: unit -> unit t
131 | Disk_files_changed
: Path.t list
-> unit t
132 | Ide_file_opened
: Ide_file_opened.request
-> unit t
133 | Ide_file_changed
: Ide_file_changed.request
-> unit t
134 | Ide_file_closed
: Path.t
-> unit t
135 | Verbose
: bool -> unit t
136 | Hover
: Hover.request
-> Hover.result t
137 | Definition
: Definition.request
-> Definition.result t
138 | Completion
: Completion.request
-> Completion.result t
139 | Completion_resolve
:
140 Completion_resolve.request
141 -> Completion_resolve.result t
142 | Completion_resolve_location
:
143 Completion_resolve_location.request
144 -> Completion_resolve_location.result t
145 | Document_highlight
:
146 Document_highlight.request
147 -> Document_highlight.result t
148 | Document_symbol
: Document_symbol.request
-> Document_symbol.result t
149 | Type_definition
: Type_definition.request
-> Type_definition.result t
150 | Type_coverage
: Type_coverage.request
-> Type_coverage.result t
151 | Signature_help
: Signature_help.request
-> Signature_help.result t
153 let t_to_string : type a
. a t
-> string = function
154 | Initialize_from_saved_state _
-> "Initialize_from_saved_state"
155 | Shutdown
() -> "Shutdown"
156 | Disk_files_changed files
->
157 let files = List.map
files ~f
:Path.to_string
in
158 let (files, remainder
) = List.split_n
files 10 in
160 if List.is_empty
remainder then
165 Printf.sprintf
"Disk_file_changed(%s%s)" (String.concat
files) remainder
166 | Ide_file_opened
{ file_path
; _
} ->
167 Printf.sprintf
"Ide_file_opened(%s)" (Path.to_string file_path
)
168 | Ide_file_changed
{ Ide_file_changed.file_path
; _
} ->
169 Printf.sprintf
"Ide_file_changed(%s)" (Path.to_string file_path
)
170 | Ide_file_closed file_path
->
171 Printf.sprintf
"Ide_file_closed(%s)" (Path.to_string file_path
)
172 | Verbose verbose
-> Printf.sprintf
"Verbose(%b)" verbose
173 | Hover
{ file_path
; _
} ->
174 Printf.sprintf
"Hover(%s)" (Path.to_string file_path
)
175 | Definition
{ file_path
; _
} ->
176 Printf.sprintf
"Definition(%s)" (Path.to_string file_path
)
177 | Completion
{ Completion.document_location
= { file_path
; _
}; _
} ->
178 Printf.sprintf
"Completion(%s)" (Path.to_string file_path
)
179 | Completion_resolve
{ Completion_resolve.symbol
; _
} ->
180 Printf.sprintf
"Completion_resolve(%s)" symbol
181 | Completion_resolve_location
182 { Completion_resolve_location.document_location
= { file_path
; _
}; _
} ->
183 Printf.sprintf
"Completion_resolve_location(%s)" (Path.to_string file_path
)
184 | Document_highlight
{ file_path
; _
} ->
185 Printf.sprintf
"Document_highlight(%s)" (Path.to_string file_path
)
186 | Document_symbol
{ file_path
; _
} ->
187 Printf.sprintf
"Document_symbol(%s)" (Path.to_string file_path
)
188 | Type_definition
{ file_path
; _
} ->
189 Printf.sprintf
"Type_definition(%s)" (Path.to_string file_path
)
190 | Type_coverage
{ file_path
; _
} ->
191 Printf.sprintf
"Type_coverage(%s)" (Path.to_string file_path
)
192 | Signature_help
{ file_path
; _
} ->
193 Printf.sprintf
"Signature_help(%s)" (Path.to_string file_path
)
195 type 'a tracked_t
= {
200 let tracked_t_to_string : type a
. a tracked_t
-> string =
201 fun { tracking_id
; message
} ->
202 Printf.sprintf
"#%s: %s" tracking_id
(t_to_string message
)
204 module Processing_files
= struct
210 let to_string (t
: t
) : string = Printf.sprintf
"%d/%d" t
.processed t
.total
215 | Processing_files
of Processing_files.t
218 let notification_to_string (n
: notification
) : string =
220 | Initializing
-> "Initializing"
221 | Processing_files p
->
222 Printf.sprintf
"Processing_file(%s)" (Processing_files.to_string p
)
223 | Done_processing
-> "Done_processing"
226 (* max 20 chars, for status bar. Will be prepended by "Hack:" *)
227 short_user_message
: string;
228 (* max 10 words, for tooltip and alert. Will be postpended by " See <log>" *)
229 medium_user_message
: string;
230 (* should we have window/showMessage, i.e. an alert? *)
232 (* max 5 lines, for window/logMessage, i.e. Output>Hack window. Will be postpended by "\nDetails: <url>" *)
233 long_user_message
: string;
234 (* for experts. Will go in Hh_logger.log, and will be uploaded *)
235 debug_details
: string;
238 (** make_error_data is for reporting internal bugs, invariant
239 violations, unexpected exceptions, ... *)
240 let make_error_data (debug_details
: string) ~
(stack
: string) : error_data
=
242 short_user_message
= "failed";
243 medium_user_message
= "Hack IDE has failed.";
245 "Hack IDE has failed.\nThis is unexpected.\nPlease file a bug within your IDE.";
246 debug_details
= debug_details ^
"\nSTACK:\n" ^ stack
;
247 is_actionable
= false;
250 type 'a timed_response
= {
251 unblocked_time
: float;
252 response
: ('a
, error_data
) result
;
255 type message_from_daemon
=
256 | Notification
of notification
257 | Response
: 'a timed_response
-> message_from_daemon
259 let message_from_daemon_to_string (m
: message_from_daemon
) : string =
261 | Notification n
-> notification_to_string n
262 | Response
{ response
= Error
{ short_user_message
; _
}; _
} ->
263 Printf.sprintf
"Response_error(%s)" short_user_message
264 | Response
{ response
= Ok _
; _
} -> Printf.sprintf
"Response_ok"