Refactor findref to not use lazy heap
[hiphop-php.git] / hphp / hack / src / server / serverFindRefs.ml
blob095751de3ec31f7dfefdaa6d8121619fd32be1cf
1 (**
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
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.
9 *)
11 open Core
12 open Option.Monad_infix
13 open ServerEnv
14 open Reordered_argument_collections
16 let to_json input =
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
20 Hh_json.JSON_Object [
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_;
27 end in
28 Hh_json.JSON_Array entries
30 let add_ns name =
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
40 strip_ns res
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
58 let target =
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 =
76 match action with
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
92 res
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)
112 | _ -> None
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)