2 * Copyright (c) 2015, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the "hack" directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
12 open Option.Monad_infix
14 open Reordered_argument_collections
17 let entries = List.map input
begin fun (name
, pos
) ->
18 let filename = Pos.filename pos
in
19 let line, start
, end_
= Pos.info_pos pos
in
21 "name", Hh_json.JSON_String name
;
22 "filename", Hh_json.JSON_String
filename;
23 "line", Hh_json.int_
line;
24 "char_start", Hh_json.int_ start
;
25 "char_end", Hh_json.int_ end_
;
28 Hh_json.JSON_Array
entries
31 if name
.[0] = '
\\'
then name
else "\\" ^ name
33 let strip_ns results
=
34 List.map results
(fun (s
, p
) -> ((Utils.strip_ns s
), p
))
36 let search target include_defs files genv env
=
37 (* Get all the references to the provided target in the files *)
38 let res = FindRefsService.find_references env
.tcopt genv
.workers
39 target include_defs env
.files_info files
in
42 let search_function function_name include_defs genv env
=
43 let function_name = add_ns function_name in
44 let files = FindRefsService.get_dependent_files_function
45 genv
.ServerEnv.workers
function_name in
46 search (FindRefsService.IFunction
function_name) include_defs
files genv env
48 let search_member class_name member include_defs genv env
=
49 let class_name = add_ns class_name in
50 (* Find all the classes that extend this one *)
51 let files = FindRefsService.get_child_classes_files
class_name in
52 let all_classes = FindRefsService.find_child_classes env
.tcopt
53 class_name env
.files_info
files in
54 let all_classes = SSet.add
all_classes class_name in
55 (* Get all the files that reference those classes *)
56 let files = FindRefsService.get_dependent_files
57 genv
.ServerEnv.workers
all_classes in
59 FindRefsService.IMember
(FindRefsService.Class_set
all_classes, member
)
61 search target include_defs
files genv env
63 let search_gconst cst_name include_defs genv env
=
64 let cst_name = add_ns cst_name in
65 let files = FindRefsService.get_dependent_files_gconst
66 genv
.ServerEnv.workers
cst_name in
67 search (FindRefsService.IGConst
cst_name) include_defs
files genv env
69 let search_class class_name include_defs genv env
=
70 let class_name = add_ns class_name in
71 let files = FindRefsService.get_dependent_files
72 genv
.ServerEnv.workers
(SSet.singleton
class_name) in
73 search (FindRefsService.IClass
class_name) include_defs
files genv env
75 let get_refs action include_defs genv env
=
77 | FindRefsService.Member
(class_name, member
) ->
78 search_member class_name member include_defs genv env
79 | FindRefsService.Function
function_name ->
80 search_function function_name include_defs genv env
81 | FindRefsService.Class
class_name ->
82 search_class class_name include_defs genv env
83 | FindRefsService.GConst
cst_name ->
84 search_gconst cst_name include_defs genv env
86 let get_refs_with_defs action genv env
=
87 get_refs action
true genv env
89 let go action genv env
=
90 let res = get_refs action
false genv env
in
91 let res = List.map
res (fun (r
, pos
) -> (r
, Pos.to_absolute pos
)) in
94 let get_action symbol
=
95 let name = symbol
.SymbolOccurrence.name in
96 begin match symbol
.SymbolOccurrence.type_
with
97 | SymbolOccurrence.Class
-> Some
(FindRefsService.Class
name)
98 | SymbolOccurrence.Function
-> Some
(FindRefsService.Function
name)
99 | SymbolOccurrence.Method
(class_name, method_name
) ->
100 Some
(FindRefsService.Member
101 (class_name, FindRefsService.Method method_name
))
102 | SymbolOccurrence.Property
(class_name, prop_name
) ->
103 Some
(FindRefsService.Member
104 (class_name, FindRefsService.Property prop_name
))
105 | SymbolOccurrence.ClassConst
(class_name, const_name
) ->
106 Some
(FindRefsService.Member
107 (class_name, FindRefsService.Class_const const_name
))
108 | SymbolOccurrence.Typeconst
(class_name, tconst_name
) ->
109 Some
(FindRefsService.Member
110 (class_name, FindRefsService.Typeconst tconst_name
))
111 | SymbolOccurrence.GConst
-> Some
(FindRefsService.GConst
name)
115 let go_from_file (content
, line, char
) genv env
=
116 (* Find the symbol at given position *)
117 ServerIdentifyFunction.go content
line char env
.ServerEnv.tcopt
|>
118 (* If there are few, arbitrarily pick the first *)
119 List.hd
>>= fun (occurrence
, definition
) ->
120 (* Ignore symbols that lack definitions *)
121 definition
>>= fun definition
->
122 get_action occurrence
>>= fun action
->
123 let results = go action genv env
|> List.map ~f
:snd
in
124 Some
(definition
.SymbolDefinition.full_name
, results)