Unified symbol-to-docblock server command
[hiphop-php.git] / hphp / hack / src / server / serverAutoComplete.ml
blobb185f6cb28099476cee5ae878ebbc8c598141426
1 (**
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
11 (*****************************************************************************)
12 (* Code for auto-completion *)
13 (*****************************************************************************)
15 let get_results
16 ~(tcopt:TypecheckerOptions.t)
17 ~(delimit_on_namespaces:bool)
18 ~(autocomplete_context: AutocompleteTypes.legacy_autocomplete_context)
19 ~(basic_only:bool)
20 ~(env:SearchUtils.local_tracking_env)
21 (_:Relative_path.t)
22 (file_info:FileInfo.t)
23 (tast:Tast.program)
24 : AutocompleteTypes.complete_autocomplete_result list Utils.With_complete_flag.t =
25 let {
26 FileInfo.n_funs = content_funs; n_classes = content_classes; _
27 } = FileInfo.simplify file_info in
28 AutocompleteService.go tast
29 ~tcopt
30 ~delimit_on_namespaces
31 ~content_funs
32 ~content_classes
33 ~autocomplete_context
34 ~basic_only
35 ~env
37 let auto_complete
38 ~(tcopt:TypecheckerOptions.t)
39 ~(delimit_on_namespaces:bool)
40 ~(autocomplete_context: AutocompleteTypes.legacy_autocomplete_context)
41 ~(basic_only:bool)
42 ~(env:SearchUtils.local_tracking_env)
43 (content:string)
44 : AutocompleteTypes.complete_autocomplete_result list Utils.With_complete_flag.t =
45 let result =
46 ServerIdeUtils.declare_and_check content
47 ~f:(get_results ~tcopt ~delimit_on_namespaces ~autocomplete_context ~basic_only ~env) tcopt in
48 result
50 let context_xhp_classname_regex = Str.regexp ".*<[a-zA-Z_0-9:]*$"
51 let context_xhp_member_regex = Str.regexp ".*->[a-zA-Z_0-9:]*$"
52 (* For identifying case statements from text context *)
53 let context_after_single_colon_regex = Str.regexp ".*[a-zA-Z_0-9\"']:$"
54 (* For identifying user attributes *)
55 let context_after_double_right_angle_bracket_regex = Str.regexp ".*[a-zA-z_0-9\"' ,)]>>$"
56 (* For identifying shape keys *)
57 let context_after_quote = Str.regexp ".*['\"]$"
59 let get_autocomplete_context
60 (content:string)
61 (pos:File_content.position)
62 ~(is_manually_invoked:bool)
63 : AutocompleteTypes.legacy_autocomplete_context =
64 (* This function retrieves the current line of text up to the position, *)
65 (* and determines whether it's something like "<nt:te" or "->:attr". *)
66 (* This is a dumb implementation. Would be better to replace it with FFP. *)
67 if pos.File_content.column = 1 then { AutocompleteTypes.
68 is_manually_invoked;
69 is_xhp_classname = false;
70 is_instance_member = false;
71 is_after_single_colon = false;
72 is_after_double_right_angle_bracket = false;
73 is_after_open_square_bracket = false;
74 is_after_quote = false;
75 } else
76 let pos_start = { pos with File_content.column = 1; } in
77 let (offset_start, offset) = File_content.get_offsets content (pos_start, pos) in
78 let text = String.sub content offset_start (offset - offset_start) in
79 (* text is the text from the start of the line up to the caret position *)
80 let is_xhp_classname = Str.string_match context_xhp_classname_regex text 0 in
81 let is_instance_member = Str.string_match context_xhp_member_regex text 0 in
82 let is_after_single_colon = Str.string_match context_after_single_colon_regex text 0 in
83 let is_after_double_right_angle_bracket = Str.string_match context_after_double_right_angle_bracket_regex text 0 in
84 let is_after_open_square_bracket = ((String.length text) >= 1) && ((Str.last_chars text 1) = "[") in
85 let is_after_quote = Str.string_match context_after_quote text 0 in
86 { AutocompleteTypes.
87 is_manually_invoked;
88 is_xhp_classname;
89 is_instance_member;
90 is_after_single_colon;
91 is_after_double_right_angle_bracket;
92 is_after_open_square_bracket;
93 is_after_quote;
96 let auto_complete_at_position
97 ~(delimit_on_namespaces:bool)
98 ~(is_manually_invoked:bool)
99 ~(basic_only:bool)
100 ~(file_content:string)
101 ~(pos:File_content.position)
102 ~(tcopt:TypecheckerOptions.t)
103 ~(env:SearchUtils.local_tracking_env)
104 : AutocompleteTypes.complete_autocomplete_result list Utils.With_complete_flag.t=
105 let open File_content in
106 (* TODO: Avoid doing the "AUTO332" thing by modifying autocomplete service to accept a position *)
107 let autocomplete_context = get_autocomplete_context file_content pos ~is_manually_invoked in
108 let edits = [{range = Some {st = pos; ed = pos}; text = "AUTO332"}] in
109 let content = File_content.edit_file_unsafe file_content edits in
110 auto_complete ~tcopt ~delimit_on_namespaces ~autocomplete_context ~basic_only ~env content