Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 64 additions & 61 deletions src/server/command_handler/commandHandler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1715,6 +1715,62 @@ let handle_persistent_document_highlight
Lwt.return ((), LspProt.LspFromServer (Some response), metadata)
| Error reason -> mk_lsp_error_response ~ret:() ~id:(Some id) ~reason metadata

(* This tries to simulate the logic from elsewhere which determines whether we would report
* errors for a given file. The criteria are
*
* 1) The file must be either implicitly included (be in the same dir structure as .flowconfig)
* or explicitly included
* 2) The file must not be ignored
* 3) The file path must be a Flow file (e.g foo.js and not foo.php or foo/)
* 4) The file must either have `// @flow` or all=true must be set in the .flowconfig or CLI
*)
let check_that_we_care_about_this_file =
let check_file_not_ignored ~file_options ~env ~file_path () =
if Files.wanted ~options:file_options env.ServerEnv.libs file_path then
Ok ()
else
Error "File is ignored"
in
let check_file_included ~options ~file_options ~file_path () =
let file_is_implicitly_included =
let root_str = spf "%s%s" (Path.to_string (Options.root options)) Filename.dir_sep in
String_utils.string_starts_with file_path root_str
in
if file_is_implicitly_included then
Ok ()
else if Files.is_included file_options file_path then
Ok ()
else
Error "File is not implicitly or explicitly included"
in
let check_is_flow_file ~file_options ~file_path () =
if Files.is_flow_file ~options:file_options file_path then
Ok ()
else
Error "File is not a Flow file"
in
let check_flow_pragma ~options ~content ~file_path () =
if Options.all options then
Ok ()
else
let (_, docblock) =
Parsing_service_js.(
parse_docblock docblock_max_tokens (File_key.SourceFile file_path) content)
in
if Docblock.is_flow docblock then
Ok ()
else
Error "File is missing @flow pragma and `all` is not set to `true`"
in
fun ~options ~env ~file_path ~content ->
let file_path = Files.imaginary_realpath file_path in
let file_options = Options.file_options options in
Ok ()
>>= check_file_not_ignored ~file_options ~env ~file_path
>>= check_file_included ~options ~file_options ~file_path
>>= check_is_flow_file ~file_options ~file_path
>>= check_flow_pragma ~options ~content ~file_path

let handle_persistent_coverage ~options ~id ~params ~file ~metadata ~client ~profiling ~env =
let textDocument = params.TypeCoverage.textDocument in
let file =
Expand All @@ -1726,20 +1782,23 @@ let handle_persistent_coverage ~options ~id ~params ~file ~metadata ~client ~pro
Flow_lsp_conversions.lsp_DocumentIdentifier_to_flow textDocument ~client
in
(* if it isn't a flow file (i.e. lacks a @flow directive) then we won't do anything *)
let fkey = File_key.SourceFile (File_input.filename_of_file_input file) in
let content = File_input.content_of_file_input file in
let file_path = File_input.filename_of_file_input file in
let is_flow =
match content with
| Ok content ->
let (_, docblock) = Parsing_service_js.(parse_docblock docblock_max_tokens fkey content) in
Docblock.is_flow docblock
begin
match check_that_we_care_about_this_file ~options ~env ~file_path ~content with
| Ok () -> true
| Error _ -> false
end
| Error _ -> false
in
let%lwt result =
if is_flow then
let force = false in
let type_contents_cache = Some (Persistent_connection.type_contents_cache client) in
(* 'true' makes it report "unknown" for all exprs in non-flow files *)
let force = Options.all options in
let type_contents_cache = Some (Persistent_connection.type_contents_cache client) in
coverage ~options ~env ~profiling ~type_contents_cache ~force ~trust:false file
else
Lwt.return (Ok [])
Expand Down Expand Up @@ -1955,62 +2014,6 @@ let handle_persistent_unsupported ?id ~unhandled ~metadata ~client:_ ~profiling:
let reason = Printf.sprintf "not implemented: %s" (Lsp_fmt.message_name_to_string unhandled) in
mk_lsp_error_response ~ret:() ~id ~reason metadata

(* This tries to simulate the logic from elsewhere which determines whether we would report
* errors for a given file. The criteria are
*
* 1) The file must be either implicitly included (be in the same dir structure as .flowconfig)
* or explicitly included
* 2) The file must not be ignored
* 3) The file path must be a Flow file (e.g foo.js and not foo.php or foo/)
* 4) The file must either have `// @flow` or all=true must be set in the .flowconfig or CLI
*)
let check_that_we_care_about_this_file =
let check_file_not_ignored ~file_options ~env ~file_path () =
if Files.wanted ~options:file_options env.ServerEnv.libs file_path then
Ok ()
else
Error "File is ignored"
in
let check_file_included ~options ~file_options ~file_path () =
let file_is_implicitly_included =
let root_str = spf "%s%s" (Path.to_string (Options.root options)) Filename.dir_sep in
String_utils.string_starts_with file_path root_str
in
if file_is_implicitly_included then
Ok ()
else if Files.is_included file_options file_path then
Ok ()
else
Error "File is not implicitly or explicitly included"
in
let check_is_flow_file ~file_options ~file_path () =
if Files.is_flow_file ~options:file_options file_path then
Ok ()
else
Error "File is not a Flow file"
in
let check_flow_pragma ~options ~content ~file_path () =
if Options.all options then
Ok ()
else
let (_, docblock) =
Parsing_service_js.(
parse_docblock docblock_max_tokens (File_key.SourceFile file_path) content)
in
if Docblock.is_flow docblock then
Ok ()
else
Error "File is missing @flow pragma and `all` is not set to `true`"
in
fun ~options ~env ~file_path ~content ->
let file_path = Files.imaginary_realpath file_path in
let file_options = Options.file_options options in
Ok ()
>>= check_file_not_ignored ~file_options ~env ~file_path
>>= check_file_included ~options ~file_options ~file_path
>>= check_is_flow_file ~file_options ~file_path
>>= check_flow_pragma ~options ~content ~file_path

(* What should we do if we get multiple requests for the same URI? Each request wants the most
* up-to-date live errors, so if we have 10 pending requests then we would want to send the same
* response to each. And we could do that, but it might have some weird side effects:
Expand Down