2 * Copyright (c) 2015, 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.
11 (*****************************************************************************)
12 (* Code for auto-completion *)
13 (*****************************************************************************)
16 ~
(tcopt
:TypecheckerOptions.t
)
17 ~
(delimit_on_namespaces
:bool)
18 ~
(autocomplete_context
: AutocompleteTypes.legacy_autocomplete_context
)
20 ~
(env
:SearchUtils.local_tracking_env
)
22 (file_info
:FileInfo.t
)
24 : AutocompleteTypes.complete_autocomplete_result list
Utils.With_complete_flag.t
=
26 FileInfo.n_funs
= content_funs
; n_classes
= content_classes
; _
27 } = FileInfo.simplify file_info
in
28 AutocompleteService.go tast
30 ~delimit_on_namespaces
38 ~
(tcopt
:TypecheckerOptions.t
)
39 ~
(delimit_on_namespaces
:bool)
40 ~
(autocomplete_context
: AutocompleteTypes.legacy_autocomplete_context
)
42 ~
(env
:SearchUtils.local_tracking_env
)
44 : AutocompleteTypes.complete_autocomplete_result list
Utils.With_complete_flag.t
=
46 ServerIdeUtils.declare_and_check content
47 ~f
:(get_results ~tcopt ~delimit_on_namespaces ~autocomplete_context ~basic_only ~env
) tcopt
in
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
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.
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;
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
90 is_after_single_colon;
91 is_after_double_right_angle_bracket;
92 is_after_open_square_bracket;
96 let auto_complete_at_position
97 ~
(delimit_on_namespaces
:bool)
98 ~
(is_manually_invoked
: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