From 43c13deb3dfb53524563264c0d590df967cd64a2 Mon Sep 17 00:00:00 2001 From: Kasper Kopec Date: Tue, 3 Jan 2017 15:51:00 -0800 Subject: [PATCH] JSON RPC version of autocomplete / didOpenFile messages Summary: The whole point of versions is to be able to make changes, while giving existing users time to adjust. Here is an example of introducing some changes to commands that are already in use: - rename "contents" of DidOpenFileParams to "text" (for consistency with "text" field of TextEdit) - remove deprecated fields ("variadic", "min_arity", "pos", "expected_ty") from autocomplete response - rename func_details to callable_details in autocomplete reposnes (because "func" suggests only a function, and those can also be methods) - rename getCompletions to autocomplete (consistency with naming in other places) Reviewed By: jopamer Differential Revision: D4315591 fbshipit-source-id: aa67c88ba68103add39120adbaba0b9f7b910ccf --- .../hack/src/ide_rpc/ide_rpc_V0_message_printer.ml | 27 ++++++++++ hphp/hack/src/ide_rpc/ide_rpc_V0_method_parser.ml | 15 ++++++ .../src/ide_rpc/ide_rpc_method_parser_utils.ml | 21 ++++++++ ..._printer.ml => ide_rpc_method_parser_utils.mli} | 15 ++++-- hphp/hack/src/ide_rpc/nuclide_rpc_method_parser.ml | 10 +--- hphp/hack/src/ide_rpc/protocol.md | 63 +++++++++++++++++++++- .../test/unit/ide/ide_message_parser_test_utils.ml | 7 +++ .../unit/ide/ide_rpc_V0_message_printer_test.ml | 39 +++++++++++++- .../test/unit/ide/ide_rpc_V0_method_parser_test.ml | 62 +++++++++++++++++++++ .../unit/ide/nuclide_rpc_method_parser_test.ml | 7 --- 10 files changed, 243 insertions(+), 23 deletions(-) create mode 100644 hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.ml copy hphp/hack/src/ide_rpc/{ide_rpc_V0_message_printer.ml => ide_rpc_method_parser_utils.mli} (55%) create mode 100644 hphp/hack/test/unit/ide/ide_rpc_V0_method_parser_test.ml diff --git a/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml b/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml index 50564f72024..c8d2a8ae65b 100644 --- a/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml +++ b/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml @@ -8,7 +8,34 @@ * *) +open Core +open Ide_message +open Hh_json + +let autocomplete_response_to_json x = + let param_to_json x = JSON_Object [ + ("name", JSON_String x.name); + ("type", JSON_String x.type_); + ] in + + let callable_details_to_json x = JSON_Object [ + ("return_type", JSON_String x.return_type); + ("params", JSON_Array (List.map x.params ~f:param_to_json)); + ] in + + let callable_details_to_json = function + | None -> [] + | Some x -> [("callable_details", callable_details_to_json x)] in + + let autocomplete_response_to_json x = JSON_Object ([ + ("name", JSON_String x.autocomplete_item_text); + ("type", JSON_String x.autocomplete_item_type); + ] @ (callable_details_to_json x.callable_details)) in + + JSON_Array (List.map x ~f:autocomplete_response_to_json) + let to_json ~id:_ ~response = match response with + | Autocomplete_response x -> autocomplete_response_to_json x (* Delegate unhandled messages to previous version of API *) | _ -> Nuclide_rpc_message_printer.to_json ~response diff --git a/hphp/hack/src/ide_rpc/ide_rpc_V0_method_parser.ml b/hphp/hack/src/ide_rpc/ide_rpc_V0_method_parser.ml index 06998785777..12ba2831d35 100644 --- a/hphp/hack/src/ide_rpc/ide_rpc_V0_method_parser.ml +++ b/hphp/hack/src/ide_rpc/ide_rpc_V0_method_parser.ml @@ -8,14 +8,29 @@ * *) +open Ide_message +open Ide_rpc_method_parser_utils open Ide_rpc_protocol_parser_types +open Result.Monad_infix let delegate_to_previous_version method_name params = Nuclide_rpc_method_parser.parse ~method_name:(Method_name method_name) ~params +let parse_did_open_file_params params = + get_filename_filed params >>= fun did_open_file_filename -> + get_text_field params >>= fun did_open_file_text -> + Result.Ok { did_open_file_filename; did_open_file_text; } + +let parse_did_open_file method_name params = + assert_params_required method_name params >>= + parse_did_open_file_params >>= fun params -> + Result.Ok (Did_open_file params) + let parse_method method_name params = match method_name with + | "didOpenFile" -> parse_did_open_file method_name params + | "autocomplete" -> delegate_to_previous_version "getCompletions" params | _ -> delegate_to_previous_version method_name params let parse ~method_name ~params = diff --git a/hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.ml b/hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.ml new file mode 100644 index 00000000000..a088dfcdbca --- /dev/null +++ b/hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.ml @@ -0,0 +1,21 @@ +(** + * Copyright (c) 2016, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +open Ide_parser_utils +open Ide_rpc_protocol_parser_types + +let assert_params_required method_name params = + Result.of_option params + ~error:(Invalid_params + (Printf.sprintf "%s request requires params" method_name)) + +let get_text_field = get_string_field "text" + +let get_filename_filed = get_string_field "filename" diff --git a/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml b/hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.mli similarity index 55% copy from hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml copy to hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.mli index 50564f72024..1a90e0173b1 100644 --- a/hphp/hack/src/ide_rpc/ide_rpc_V0_message_printer.ml +++ b/hphp/hack/src/ide_rpc/ide_rpc_method_parser_utils.mli @@ -8,7 +8,14 @@ * *) -let to_json ~id:_ ~response = - match response with - (* Delegate unhandled messages to previous version of API *) - | _ -> Nuclide_rpc_message_printer.to_json ~response +open Ide_rpc_protocol_parser_types +open Hh_json + +val assert_params_required : + string -> 'a option -> ('a, error_t) Result.t + +val get_text_field : + json -> (string, error_t) Result.t + +val get_filename_filed : + json -> (string, error_t) Result.t diff --git a/hphp/hack/src/ide_rpc/nuclide_rpc_method_parser.ml b/hphp/hack/src/ide_rpc/nuclide_rpc_method_parser.ml index bb1f0d4b6f5..7a8ec2f9f6d 100644 --- a/hphp/hack/src/ide_rpc/nuclide_rpc_method_parser.ml +++ b/hphp/hack/src/ide_rpc/nuclide_rpc_method_parser.ml @@ -11,16 +11,10 @@ open Core open Ide_message open Ide_parser_utils +open Ide_rpc_method_parser_utils open Ide_rpc_protocol_parser_types open Result.Monad_infix -let assert_params_required method_name params = - Result.of_option params - ~error:(Invalid_params - (Printf.sprintf "%s request requires params" method_name)) - -let get_filename_filed = get_string_field "filename" - let get_position_filed = get_obj_field "position" let get_line_field = get_int_field "line" @@ -29,8 +23,6 @@ let get_column_field = get_int_field "column" let get_contents_field = get_string_field "contents" -let get_text_field = get_string_field "text" - let get_start_field = get_obj_field "start" let get_end_field = get_obj_field "end" diff --git a/hphp/hack/src/ide_rpc/protocol.md b/hphp/hack/src/ide_rpc/protocol.md index 03a5526912d..37512503a33 100644 --- a/hphp/hack/src/ide_rpc/protocol.md +++ b/hphp/hack/src/ide_rpc/protocol.md @@ -88,7 +88,7 @@ where `DidOpenFileParams` is defined as: /** * Contents of opened file. */ - contents : string; + text : string; } #### Change file notification @@ -174,3 +174,64 @@ where DiagnosticsParams is defined as: message : string; position : FilePosition; } + +### Autocomplete request + +*Client request:* + + method : "autocomplete" + params : FilePosition + +*Server response:* + + AutocompleteItem[] + +`AutocompleteItem:` + + { + /** + * The text to be inserted when selecting this completion item. + * + * The text includes the prefix which is already typed out in the + * file. For example: + * + * $x = new Fo + * + * can include "Foo" as text to complete. + */ + text : string; + + /** + * Additional information about completion type, e.g: + * "abstract class", "function" + */ + type : string; + + /** + * For callable completions (functions, methods), additional + * information about it. + */ + callable_details? : { + /** + * Callable return type. + */ + return_type : string; + /** + * Informations about all of the callable parameters. + */ + params: CallableParam[] + } + } + +`CallableParam:` + + { + /** + * Argument name, as specified in callable declaration. + */ + name : string; + /** + * Expected type of callable argument. + */ + type : string; + } diff --git a/hphp/hack/test/unit/ide/ide_message_parser_test_utils.ml b/hphp/hack/test/unit/ide/ide_message_parser_test_utils.ml index 01679806a05..de4229844e1 100644 --- a/hphp/hack/test/unit/ide/ide_message_parser_test_utils.ml +++ b/hphp/hack/test/unit/ide/ide_message_parser_test_utils.ml @@ -44,6 +44,13 @@ let assert_json_equal expected got = let got = json_to_string got in assert_equal expected got +let expect_api_message expected got = expect_value + (fun got -> got) expected got + +let test message check_function = + check_function (Ide_message_parser.parse ~version:V0 ~message); + true + let test_response protocol version response expected = let response = Ide_message_printer.to_json ~id:(Some 4) diff --git a/hphp/hack/test/unit/ide/ide_rpc_V0_message_printer_test.ml b/hphp/hack/test/unit/ide/ide_rpc_V0_message_printer_test.ml index 9c2bb3b04fa..6efa985e7e1 100644 --- a/hphp/hack/test/unit/ide/ide_rpc_V0_message_printer_test.ml +++ b/hphp/hack/test/unit/ide/ide_rpc_V0_message_printer_test.ml @@ -8,8 +8,9 @@ * *) - open Ide_message_parser_test_utils - open Ide_rpc_protocol_parser_types +open Ide_message +open Ide_message_parser_test_utils +open Ide_rpc_protocol_parser_types (* Test suite for V0 version of the API responses *) @@ -35,8 +36,42 @@ let test_method_not_found () = } }|} +let test_autocomplete_response () = + let response = Autocomplete_response [{ + autocomplete_item_text = "aaa"; + autocomplete_item_type = "bbb"; + callable_details = Some { + return_type = "ccc"; + Ide_message.params = [{ + name = "ddd"; + type_ = "eee"; + }] + } + }] in + test_response response + {|{ + "jsonrpc": "2.0", + "id": 4, + "result": [ + { + "name": "aaa", + "type": "bbb", + "callable_details": { + "return_type": "ccc", + "params": [ + { + "name": "ddd", + "type": "eee" + } + ] + } + } + ] + }|} + let tests = [ "test_method_not_found", test_method_not_found; + "test_autocomplete_response", test_autocomplete_response; ] let () = diff --git a/hphp/hack/test/unit/ide/ide_rpc_V0_method_parser_test.ml b/hphp/hack/test/unit/ide/ide_rpc_V0_method_parser_test.ml new file mode 100644 index 00000000000..13f76ef979e --- /dev/null +++ b/hphp/hack/test/unit/ide/ide_rpc_V0_method_parser_test.ml @@ -0,0 +1,62 @@ +(** + * Copyright (c) 2016, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the "hack" directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + *) + +(* Test suite for V0 version of the API methods *) + +open File_content +open Ide_message +open Ide_message_parser_test_utils + +let build_request_message = Printf.sprintf + {|{ + "jsonrpc" : "2.0", + "id" : 4, + "method" : "%s" , + "params" : {%s} + }|} + +let test_did_open_file () = + let msg = build_request_message "didOpenFile" + {| + "filename" : "test.php", + "text" : " got) expected got - -let test message check_function = - check_function (Ide_message_parser.parse ~version:V0 ~message); - true - let build_call_message = Printf.sprintf {|{ "protocol" : "service_framework3_rpc", -- 2.11.4.GIT