Move func_num_args() to an opcode
[hiphop-php.git] / hphp / hack / src / hhbc / hhbc_id.ml
blob016fcf86995c334180cbe9d3a5fcb70dc7fcc534
1 (**
2 * Copyright (c) 2017, 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 *)
10 open Core_kernel
12 module SU = Hhbc_string_utils
14 let elaborate_id ns kind id =
15 let autoimport =
16 if List.mem ~equal:(=)
17 Hh_autoimport.autoimport_only_for_typechecker (SU.strip_ns @@ snd id)
18 then false else Emit_env.is_hh_syntax_enabled () in
20 let was_renamed, fully_qualified_id =
21 Namespaces.elaborate_id_impl ~autoimport ns kind (snd id) in
22 let stripped_fully_qualified_id = SU.strip_global_ns fully_qualified_id in
23 let clean_id = SU.strip_ns fully_qualified_id in
24 let need_fallback =
25 stripped_fully_qualified_id <> clean_id &&
26 (String.contains stripped_fully_qualified_id '\\') &&
27 not (String.contains (snd id) '\\')
29 was_renamed, stripped_fully_qualified_id, if need_fallback then Some clean_id else None
31 (* Class identifier, with namespace qualification if not global, but without
32 * initial backslash.
34 module Class = struct
35 type t = string
37 let from_ast_name s =
38 Hh_autoimport.normalize
39 ~is_hack:(Emit_env.is_hh_syntax_enabled ())
40 ~php7_scalar_types:(Hhbc_options.php7_scalar_types !Hhbc_options.compiler_options)
41 (SU.strip_global_ns s)
42 let from_raw_string s = s
43 let to_raw_string s = s
44 let elaborate_id ns ((_, n) as id) =
45 let ns =
46 if SU.Xhp.is_xhp n
47 then Namespace_env.empty ns.Namespace_env.ns_popt
48 else ns in
49 let mangled_name = SU.Xhp.mangle n in
50 let stripped_mangled_name = SU.strip_global_ns mangled_name in
51 let was_renamed, id, fallback_id =
52 elaborate_id ns Namespaces.ElaborateClass (fst id, mangled_name) in
53 if was_renamed || mangled_name.[0] = '\\'
54 then id, fallback_id
55 else
56 match Hh_autoimport.opt_normalize
57 ~is_hack:(Emit_env.is_hh_syntax_enabled ())
58 ~php7_scalar_types:(Hhbc_options.php7_scalar_types !Hhbc_options.compiler_options)
59 stripped_mangled_name with
60 | None -> id, fallback_id
61 | Some s -> s, None
62 let to_unmangled_string s =
63 SU.Xhp.unmangle s
64 end
66 module Prop = struct
67 type t = string
69 let from_raw_string s = s
70 let from_ast_name s = SU.strip_global_ns s
71 let add_suffix s suffix = s ^ suffix
72 let to_raw_string s = s
73 end
75 module Method = struct
76 type t = string
78 let from_raw_string s = s
79 let from_ast_name s = SU.strip_global_ns s
80 let add_suffix s suffix = s ^ suffix
81 let to_raw_string s = s
82 end
84 module Function = struct
85 type t = string
87 (* See hphp/compiler/parser.cpp. *)
88 let builtins_in_hh =
90 "fun";
91 "meth_caller";
92 "class_meth";
93 "inst_meth";
94 "invariant_callback_register";
95 "invariant";
96 "invariant_violation";
97 "idx";
98 "type_structure";
99 "asio_get_current_context_idx";
100 "asio_get_running_in_context";
101 "asio_get_running";
102 "xenon_get_data";
103 "thread_memory_stats";
104 "thread_mark_stack";
105 "objprof_get_strings";
106 "objprof_get_data";
107 "objprof_get_paths";
108 "heapgraph_create";
109 "heapgraph_stats";
110 "heapgraph_foreach_node";
111 "heapgraph_foreach_edge";
112 "heapgraph_foreach_root";
113 "heapgraph_dfs_nodes";
114 "heapgraph_dfs_edges";
115 "heapgraph_node";
116 "heapgraph_edge";
117 "heapgraph_node_in_edges";
118 "heapgraph_node_out_edges";
119 "server_warmup_status";
120 "dict";
121 "vec";
122 "keyset";
123 "varray";
124 "darray";
125 "is_vec";
126 "is_dict";
127 "is_keyset";
128 "is_varray";
129 "is_darray";
132 let builtins_at_top = [
133 "echo";
134 "exit";
135 "die";
136 "func_get_args";
137 "func_get_arg";
140 let has_hh_prefix s =
141 let s = String.lowercase s in
142 String_utils.string_starts_with s "hh\\"
144 let is_hh_builtin s =
145 let s = if has_hh_prefix s then String_utils.lstrip s "hh\\" else s in
146 List.mem ~equal:(=) builtins_in_hh s
148 let from_raw_string s = s
149 let to_raw_string s = s
150 let add_suffix s suffix = s ^ suffix
152 let elaborate_id ns id =
153 let _, x, y = elaborate_id ns Namespaces.ElaborateFun id in
154 x, y
155 let elaborate_id_with_builtins ns id =
156 let fq_id, backoff_id = elaborate_id ns id in
157 match backoff_id with
158 (* OK we are in a namespace so let's look at the backoff ID and see if
159 * it's an HH\ or top-level function with implicit namespace.
161 | Some id ->
162 if List.mem ~equal:(=) builtins_in_hh id && (Emit_env.is_hh_syntax_enabled ())
163 then SU.prefix_namespace "HH" id, Some id
164 else if List.mem ~equal:(=) builtins_at_top (String.lowercase id)
165 then id, None
166 else fq_id, backoff_id
167 (* Likewise for top-level, with no namespace *)
168 | None ->
169 if is_hh_builtin fq_id && (Emit_env.is_hh_syntax_enabled ())
170 then
171 if has_hh_prefix fq_id
172 then fq_id, None
173 else SU.prefix_namespace "HH" fq_id, Some fq_id
174 else fq_id, None
177 module Const = struct
178 type t = string
180 let from_ast_name s = SU.strip_global_ns s
181 let from_raw_string s = s
182 let to_raw_string s = s
183 let elaborate_id ns id =
184 let _was_renamed, fq_id, backoff_id = elaborate_id ns Namespaces.ElaborateConst id in
185 fq_id, backoff_id, String.contains (snd id) '\\'