|
| 1 | +(* |
| 2 | + * Copyright (c) 2018, Facebook, Inc. |
| 3 | + * All rights reserved. |
| 4 | + * |
| 5 | + * This source code is licensed under the MIT license found in the |
| 6 | + * LICENSE file in the "hack" directory of this source tree. |
| 7 | + * |
| 8 | + *) |
| 9 | +open Hh_prelude |
| 10 | +open Option.Monad_infix |
| 11 | + |
| 12 | +let go |
| 13 | + (workers : MultiWorker.worker list option) |
| 14 | + (env : ServerEnv.env) |
| 15 | + (files : string list) |
| 16 | + (error_filter : Filter_errors.Filter.t) |
| 17 | + (preexisting_warnings : bool) : Telemetry.t = |
| 18 | + let file_names = |
| 19 | + List.map files ~f:(fun filename -> ServerCommandTypes.FileName filename) |
| 20 | + in |
| 21 | + |
| 22 | + let ctx = Provider_utils.ctx_from_server_env env in |
| 23 | + |
| 24 | + let tast_error_filter = |
| 25 | + { |
| 26 | + Tast_provider.ErrorFilter.error_filter; |
| 27 | + warnings_saved_state = |
| 28 | + ServerEnv.(env.init_env.mergebase_warning_hashes) |
| 29 | + >>= Option.some_if (not preexisting_warnings); |
| 30 | + } |
| 31 | + in |
| 32 | + |
| 33 | + let (errors, _tasts) = |
| 34 | + ServerStatusSingle.go |
| 35 | + workers |
| 36 | + file_names |
| 37 | + ctx |
| 38 | + ~return_expanded_tast:false |
| 39 | + ~error_filter:tast_error_filter |
| 40 | + in |
| 41 | + |
| 42 | + (* Define error JSON serialization function. |
| 43 | + This differs from `hh --json` to align with the information sent to VSCode |
| 44 | + (similar structure, though not identical). The `hh --json` format includes |
| 45 | + unnecessary extra fields that aren't needed for this use case. *) |
| 46 | + let error_to_json : Errors.error -> Hh_json.json = |
| 47 | + fun err -> |
| 48 | + let { |
| 49 | + User_error.severity; |
| 50 | + code = _; |
| 51 | + claim = (pos, claim_msg); |
| 52 | + reasons; |
| 53 | + explanation = _; |
| 54 | + custom_msgs; |
| 55 | + quickfixes = _; |
| 56 | + is_fixmed = _; |
| 57 | + function_pos = _; |
| 58 | + } = |
| 59 | + User_error.to_absolute err |
| 60 | + in |
| 61 | + let msg_to_json msg = |
| 62 | + Hh_json.string_ @@ Markdown_lite.render ~add_bold:false msg |
| 63 | + in |
| 64 | + let reason_to_json (pos, msg) = |
| 65 | + Hh_json.JSON_Object |
| 66 | + [("location", Pos.multiline_json pos); ("message", msg_to_json msg)] |
| 67 | + in |
| 68 | + Hh_json.JSON_Object |
| 69 | + [ |
| 70 | + ( "severity", |
| 71 | + Hh_json.string_ @@ User_error.Severity.to_all_caps_string severity ); |
| 72 | + ("range", Pos.multiline_json_no_filename pos); |
| 73 | + ("message", msg_to_json claim_msg); |
| 74 | + ("relatedInformation", Hh_json.array_ reason_to_json reasons); |
| 75 | + ("customErrors", Hh_json.array_ msg_to_json custom_msgs); |
| 76 | + ( "lineAgnosticHash", |
| 77 | + Hh_json.string_ |
| 78 | + @@ Printf.sprintf "%x" (User_error.hash_error_for_saved_state err) ); |
| 79 | + ] |
| 80 | + in |
| 81 | + let errors = Errors.drop_fixmed_errors_in_files errors in |
| 82 | + let file_to_errors = Errors.as_map errors in |
| 83 | + let file_to_error_json = |
| 84 | + Relative_path.Map.map ~f:(List.map ~f:error_to_json) file_to_errors |
| 85 | + in |
| 86 | + let compute_file_telemetry fn = |
| 87 | + let relpath = Relative_path.create_detect_prefix fn in |
| 88 | + Telemetry.create () |
| 89 | + |> Telemetry.string_ |
| 90 | + ~key:"filename" |
| 91 | + ~value:(Relative_path.to_absolute relpath) |
| 92 | + |> Telemetry.json_ |
| 93 | + ~key:"diagnostics" |
| 94 | + ~value: |
| 95 | + (Hh_json.JSON_Array |
| 96 | + (Relative_path.Map.find_opt file_to_error_json relpath |
| 97 | + |> Option.value ~default:[])) |
| 98 | + in |
| 99 | + Telemetry.create () |
| 100 | + |> Telemetry.object_list |
| 101 | + ~key:"errors" |
| 102 | + ~value:(List.map files ~f:compute_file_telemetry) |
0 commit comments