Canonicalize (HH\)Rx\IS_ENABLED to simplify further changes
[hiphop-php.git] / hphp / hack / src / naming / naming_special_names.ml
blobe459fa90e40f99836c78a62c81d18c376f1a0f95
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 *)
10 open Hh_prelude
12 (** Module consisting of the special names known to the typechecker *)
14 module Classes = struct
15 let cParent = "parent"
17 let cStatic = "static"
19 let cSelf = "self"
21 let cUnknown = "\\*Unknown*"
23 (* Used for dynamic classnames, e.g. new $foo(); *)
25 let cAwaitable = "\\HH\\Awaitable"
27 let cGenerator = "\\Generator"
29 let cAsyncGenerator = "\\HH\\AsyncGenerator"
31 let cHHFormatString = "\\HH\\FormatString"
33 let is_format_string x = String.equal x cHHFormatString
35 let cHH_BuiltinEnum = "\\HH\\BuiltinEnum"
37 let cHH_BuiltinEnumClass = "\\HH\\BuiltinEnumClass"
39 let cThrowable = "\\Throwable"
41 let cStdClass = "\\stdClass"
43 let cDateTime = "\\DateTime"
45 let cDateTimeImmutable = "\\DateTimeImmutable"
47 let cAsyncIterator = "\\HH\\AsyncIterator"
49 let cAsyncKeyedIterator = "\\HH\\AsyncKeyedIterator"
51 let cStringish = "\\Stringish"
53 let cXHPChild = "\\XHPChild"
55 let cIMemoizeParam = "\\HH\\IMemoizeParam"
57 let cClassname = "\\HH\\classname"
59 let cTypename = "\\HH\\typename"
61 let cIDisposable = "\\IDisposable"
63 let cIAsyncDisposable = "\\IAsyncDisposable"
65 let cEnumMember = "\\HH\\EnumMember"
67 (* Classes that can be spliced into ExpressionTrees *)
68 let cSpliceable = "\\Spliceable"
69 end
71 module Collections = struct
72 (* concrete classes *)
73 let cVector = "\\HH\\Vector"
75 let cImmVector = "\\HH\\ImmVector"
77 let cSet = "\\HH\\Set"
79 let cImmSet = "\\HH\\ImmSet"
81 let cMap = "\\HH\\Map"
83 let cImmMap = "\\HH\\ImmMap"
85 let cPair = "\\HH\\Pair"
87 (* interfaces *)
88 let cContainer = "\\HH\\Container"
90 let cKeyedContainer = "\\HH\\KeyedContainer"
92 let cTraversable = "\\HH\\Traversable"
94 let cKeyedTraversable = "\\HH\\KeyedTraversable"
96 let cCollection = "\\Collection"
98 let cConstVector = "\\ConstVector"
100 let cConstMap = "\\ConstMap"
102 let cConstCollection = "\\ConstCollection"
104 let cAnyArray = "\\HH\\AnyArray"
106 let cDict = "\\HH\\dict"
108 let cVec = "\\HH\\vec"
110 let cKeyset = "\\HH\\keyset"
113 module Members = struct
114 let mClass = "class"
116 let __construct = "__construct"
118 let __destruct = "__destruct"
120 let __call = "__call"
122 let __callStatic = "__callStatic"
124 let __clone = "__clone"
126 let __debugInfo = "__debugInfo"
128 let __dispose = "__dispose"
130 let __disposeAsync = "__disposeAsync"
132 let __get = "__get"
134 let __invoke = "__invoke"
136 let __isset = "__isset"
138 let __set = "__set"
140 let __set_state = "__set_state"
142 let __sleep = "__sleep"
144 let __toString = "__toString"
146 let __unset = "__unset"
148 let __wakeup = "__wakeup"
150 let as_set =
151 List.fold_right
152 ~f:SSet.add
153 ~init:SSet.empty
155 __construct;
156 __destruct;
157 __call;
158 __callStatic;
159 __clone;
160 __debugInfo;
161 __dispose;
162 __disposeAsync;
163 __get;
164 __invoke;
165 __isset;
166 __set;
167 __set_state;
168 __sleep;
169 __toString;
170 __unset;
171 __wakeup;
174 let as_lowercase_set = SSet.map String.lowercase as_set
176 (* Any data- or aria- attribute is always valid, even if it is not declared
177 * for a given XHP element *)
178 let is_special_xhp_attribute s =
179 String_utils.string_starts_with s ":data-"
180 || String_utils.string_starts_with s ":aria-"
183 module AttributeKinds = struct
184 let cls = "\\HH\\ClassAttribute"
186 let enum = "\\HH\\EnumAttribute"
188 let typealias = "\\HH\\TypeAliasAttribute"
190 let fn = "\\HH\\FunctionAttribute"
192 let mthd = "\\HH\\MethodAttribute"
194 let instProperty = "\\HH\\InstancePropertyAttribute"
196 let staticProperty = "\\HH\\StaticPropertyAttribute"
198 let parameter = "\\HH\\ParameterAttribute"
200 let typeparam = "\\HH\\TypeParameterAttribute"
202 let file = "\\HH\\FileAttribute"
204 let typeconst = "\\HH\\TypeConstantAttribute"
206 let lambda = "\\HH\\LambdaAttribute"
208 let plain_english_map =
209 List.fold_left
210 ~init:SMap.empty
211 ~f:(fun acc (k, v) -> SMap.add k v acc)
213 (cls, "a class");
214 (enum, "an enum");
215 (typealias, "a typealias");
216 (fn, "a function");
217 (mthd, "a method");
218 (instProperty, "an instance property");
219 (staticProperty, "a static property");
220 (parameter, "a parameter");
221 (typeparam, "a type parameter");
222 (file, "a file");
223 (typeconst, "a type constant");
224 (lambda, "a lambda expression");
228 module UserAttributes = struct
229 let uaOverride = "__Override"
231 let uaConsistentConstruct = "__ConsistentConstruct"
233 let uaConst = "__Const"
235 let uaDeprecated = "__Deprecated"
237 let uaEntryPoint = "__EntryPoint"
239 let uaMemoize = "__Memoize"
241 let uaMemoizeLSB = "__MemoizeLSB"
243 let uaPHPStdLib = "__PHPStdLib"
245 let uaHipHopSpecific = "__HipHopSpecific"
247 let uaAcceptDisposable = "__AcceptDisposable"
249 let uaReturnDisposable = "__ReturnDisposable"
251 let uaPure = "__Pure"
253 let uaCipp = "__Cipp"
255 let uaCippLocal = "__CippLocal"
257 let uaCippGlobal = "__CippGlobal"
259 let uaCippRx = "__CippRx"
261 let uaReactive = "__Rx"
263 let uaLocalReactive = "__RxLocal"
265 let uaShallowReactive = "__RxShallow"
267 let uaMutable = "__Mutable"
269 let uaMutableReturn = "__MutableReturn"
271 let uaOnlyRxIfImpl = "__OnlyRxIfImpl"
273 let uaLSB = "__LSB"
275 let uaAtMostRxAsFunc = "__AtMostRxAsFunc"
277 let uaAtMostRxAsArgs = "__AtMostRxAsArgs"
279 let uaSealed = "__Sealed"
281 let uaReturnsVoidToRx = "__ReturnsVoidToRx"
283 let uaMaybeMutable = "__MaybeMutable"
285 let uaLateInit = "__LateInit"
287 let uaOwnedMutable = "__OwnedMutable"
289 let uaNonRx = "__NonRx"
291 let uaNewable = "__Newable"
293 let uaEnforceable = "__Enforceable"
295 let uaExplicit = "__Explicit"
297 let uaSoft = "__Soft"
299 let uaWarn = "__Warn"
301 let uaMockClass = "__MockClass"
303 let uaProvenanceSkipFrame = "__ProvenanceSkipFrame"
305 let uaDynamicallyCallable = "__DynamicallyCallable"
307 let uaDynamicallyConstructible = "__DynamicallyConstructible"
309 let uaReifiable = "__Reifiable"
311 let uaNeverInline = "__NEVER_INLINE"
313 let uaDisableTypecheckerInternal = "__DisableTypecheckerInternal"
315 let uaHasTopLevelCode = "__HasTopLevelCode"
317 let uaIsFoldable = "__IsFoldable"
319 let uaNative = "__Native"
321 let uaOutOnly = "__OutOnly"
323 let uaAlwaysInline = "__ALWAYS_INLINE"
325 let uaPu = "__Pu"
327 let uaEnableUnstableFeatures = "__EnableUnstableFeatures"
329 let uaEnumClass = "__EnumClass"
331 let uaPolicied = "__Policied"
333 let uaInferFlows = "__InferFlows"
335 let uaExternal = "__External"
337 let uaCanCall = "__CanCall"
339 let uaAtom = "__Atom"
341 let as_map =
342 AttributeKinds.(
343 SMap.of_list
345 (uaOverride, [mthd]);
346 (uaConsistentConstruct, [cls]);
347 (uaConst, [cls; instProperty; parameter; staticProperty]);
348 (uaDeprecated, [fn; mthd]);
349 (uaEntryPoint, [fn]);
350 (uaMemoize, [fn; mthd]);
351 (uaMemoizeLSB, [mthd]);
352 (uaPHPStdLib, [cls; fn; mthd]);
353 (uaHipHopSpecific, [cls; fn; mthd]);
354 (uaAcceptDisposable, [parameter]);
355 (uaReturnDisposable, [fn; mthd; lambda]);
356 (uaPure, [fn; mthd; lambda]);
357 (uaCipp, [fn; mthd; lambda]);
358 (uaCippLocal, [fn; mthd; lambda]);
359 (uaCippGlobal, [fn; mthd; lambda]);
360 (uaCippRx, [fn; mthd; lambda]);
361 (uaReactive, [fn; mthd; lambda]);
362 (uaLocalReactive, [fn; mthd; lambda]);
363 (uaMutable, [mthd; parameter]);
364 (uaMutableReturn, [fn; mthd; lambda]);
365 (uaShallowReactive, [fn; mthd; lambda]);
366 (uaOnlyRxIfImpl, [parameter; mthd]);
367 (uaLSB, [staticProperty]);
368 (uaSealed, [cls]);
369 (uaReturnsVoidToRx, [fn; mthd; lambda]);
370 (uaMaybeMutable, [mthd; parameter]);
371 (uaLateInit, [instProperty; staticProperty]);
372 (uaAtMostRxAsFunc, [parameter]);
373 (uaAtMostRxAsArgs, [fn; mthd; lambda]);
374 (uaOwnedMutable, [parameter]);
375 (uaNonRx, [fn; mthd; lambda]);
376 (uaNewable, [typeparam]);
377 (uaEnforceable, [typeconst; typeparam]);
378 (uaExplicit, [typeparam]);
379 (uaSoft, [instProperty; parameter; staticProperty; typeparam]);
380 (uaWarn, [typeparam]);
381 (uaMockClass, [cls]);
382 (uaProvenanceSkipFrame, [fn; mthd; lambda]);
383 (uaDynamicallyCallable, [fn; mthd]);
384 (uaDynamicallyConstructible, [cls]);
385 (uaReifiable, [typeconst]);
386 (uaNeverInline, [fn; mthd]);
387 (uaDisableTypecheckerInternal, [fn; mthd]);
388 (uaPu, [cls]);
389 (uaEnableUnstableFeatures, [file]);
390 (uaEnumClass, [cls; enum]);
391 (uaPolicied, [fn; mthd; instProperty; parameter]);
392 (uaInferFlows, [fn; mthd]);
393 (uaExternal, [parameter]);
394 (uaCanCall, [parameter]);
395 (uaAtom, [parameter]);
398 (* These are names which are allowed in the systemlib but not in normal programs *)
399 let systemlib_map =
400 AttributeKinds.(
401 SMap.of_list
403 (uaAlwaysInline, [fn; mthd]);
404 (uaIsFoldable, [fn; mthd]);
405 (uaNative, [fn; mthd]);
406 (uaOutOnly, [parameter]);
409 let is_reserved name = String.is_prefix name ~prefix:"__"
412 (* Tested before \\-prepending name-canonicalization *)
413 module SpecialFunctions = struct
414 let tuple = "tuple" (* pseudo-function *)
416 let echo = "echo" (* pseudo-function *)
418 let assert_ = "assert"
420 let hhas_adata = "__hhas_adata"
422 let is_special_function =
423 let all_special_functions =
424 HashSet.of_list [tuple; echo; assert_; hhas_adata]
426 (fun x -> HashSet.mem all_special_functions x)
429 (* There are a number of functions that are automatically imported into the
430 * namespace. The full list can be found in hh_autoimport.ml.
432 module AutoimportedFunctions = struct
433 let invariant_violation = "\\HH\\invariant_violation"
435 let invariant = "\\HH\\invariant"
437 let fun_ = "\\HH\\fun"
439 let inst_meth = "\\HH\\inst_meth"
441 let class_meth = "\\HH\\class_meth"
443 let meth_caller = "\\HH\\meth_caller"
446 module SpecialIdents = struct
447 let this = "$this"
449 let placeholder = "$_"
451 let dollardollar = "$$"
453 (* Intentionally using an invalid variable name to ensure it's translated *)
454 let tmp_var_prefix = "__tmp$"
456 let is_tmp_var name =
457 String.length name > 6 && String.(sub name 0 6 = tmp_var_prefix)
459 let assert_tmp_var name = assert (is_tmp_var name)
462 (* PseudoFunctions are functions (or items that are parsed like functions)
463 * that are treated like builtins that do not have a public HHI or interface.
465 module PseudoFunctions = struct
466 let isset = "\\isset"
468 let unset = "\\unset"
470 let hh_show = "\\hh_show"
472 let hh_show_env = "\\hh_show_env"
474 let hh_log_level = "\\hh_log_level"
476 let hh_force_solve = "\\hh_force_solve"
478 let hh_loop_forever = "\\hh_loop_forever"
480 let assert_ = "\\assert"
482 let echo = "\\echo"
484 let empty = "\\empty"
486 let exit = "\\exit"
488 let die = "\\die"
490 let all_pseudo_functions =
491 HashSet.of_list
493 isset;
494 unset;
495 hh_show;
496 hh_show_env;
497 hh_log_level;
498 hh_force_solve;
499 hh_loop_forever;
500 assert_;
501 echo;
502 empty;
503 exit;
504 die;
507 let is_pseudo_function x = HashSet.mem all_pseudo_functions x
510 module StdlibFunctions = struct
511 let is_null = "\\is_null"
513 let get_class = "\\get_class"
515 let array_filter = "\\array_filter"
517 let array_map = "\\array_map"
519 let call_user_func = "\\call_user_func"
521 let type_structure = "\\HH\\type_structure"
523 let array_mark_legacy = "\\HH\\array_mark_legacy"
525 let array_unmark_legacy = "\\HH\\array_unmark_legacy"
527 let is_php_array = "\\HH\\is_php_array"
529 let is_any_array = "\\HH\\is_any_array"
531 let is_dict_or_darray = "\\HH\\is_dict_or_darray"
533 let is_vec_or_varray = "\\HH\\is_vec_or_varray"
536 module Typehints = struct
537 let null = "null"
539 let void = "void"
541 let resource = "resource"
543 let num = "num"
545 let arraykey = "arraykey"
547 let noreturn = "noreturn"
549 let mixed = "mixed"
551 let nonnull = "nonnull"
553 let this = "this"
555 let dynamic = "dynamic"
557 let nothing = "nothing"
559 let int = "int"
561 let bool = "bool"
563 let float = "float"
565 let string = "string"
567 let darray = "darray"
569 let varray = "varray"
571 let varray_or_darray = "varray_or_darray"
573 let callable = "callable"
575 let wildcard = "_"
577 let is_reserved_type_hint =
578 let reserved_typehints =
579 HashSet.of_list
581 null;
582 void;
583 resource;
584 num;
585 arraykey;
586 noreturn;
587 mixed;
588 nonnull;
589 this;
590 dynamic;
591 nothing;
592 int;
593 bool;
594 float;
595 string;
596 darray;
597 varray;
598 varray_or_darray;
599 callable;
600 wildcard;
603 (fun x -> HashSet.mem reserved_typehints x)
605 let is_reserved_global_name x =
606 String.equal x callable
607 || String.equal x Classes.cSelf
608 || String.equal x Classes.cParent
610 let is_reserved_hh_name x =
611 String.equal x void
612 || String.equal x noreturn
613 || String.equal x int
614 || String.equal x bool
615 || String.equal x float
616 || String.equal x num
617 || String.equal x string
618 || String.equal x resource
619 || String.equal x mixed
620 || String.equal x arraykey
621 || String.equal x dynamic
622 || String.equal x wildcard
623 || String.equal x null
624 || String.equal x nonnull
625 || String.equal x nothing
626 || String.equal x this
628 let is_namespace_with_reserved_hh_name x =
629 let unqualify qualified_name =
630 let as_list = Str.split (Str.regexp "\\") qualified_name in
631 let as_list = List.filter as_list ~f:(fun s -> not (phys_equal s "")) in
632 match List.rev as_list with
633 | name :: qualifiers -> (List.rev qualifiers, name)
634 | [] -> ([], qualified_name)
636 let is_HH qualifier =
637 match qualifier with
638 | [qual] -> String.equal qual "HH"
639 | _ -> false
641 let (qualifier, name) = unqualify x in
642 name |> is_reserved_hh_name
643 && (not (List.is_empty qualifier))
644 && not (qualifier |> is_HH)
647 module PseudoConsts = struct
648 let g__LINE__ = "\\__LINE__"
650 let g__CLASS__ = "\\__CLASS__"
652 let g__TRAIT__ = "\\__TRAIT__"
654 let g__FILE__ = "\\__FILE__"
656 let g__DIR__ = "\\__DIR__"
658 let g__FUNCTION__ = "\\__FUNCTION__"
660 let g__METHOD__ = "\\__METHOD__"
662 let g__NAMESPACE__ = "\\__NAMESPACE__"
664 let g__COMPILER_FRONTEND__ = "\\__COMPILER_FRONTEND__"
666 let g__FUNCTION_CREDENTIAL__ = "\\__FUNCTION_CREDENTIAL__"
668 (* exit and die are not pseudo consts, but they are currently parsed as such.
669 * Would be more correct to parse them as special statements like return
671 let exit = "\\exit"
673 let die = "\\die"
675 let all_pseudo_consts =
676 HashSet.of_list
678 g__LINE__;
679 g__CLASS__;
680 g__TRAIT__;
681 g__FILE__;
682 g__DIR__;
683 g__FUNCTION__;
684 g__METHOD__;
685 g__NAMESPACE__;
686 g__COMPILER_FRONTEND__;
687 g__FUNCTION_CREDENTIAL__;
688 exit;
689 die;
692 let is_pseudo_const x = HashSet.mem all_pseudo_consts x
695 module FB = struct
696 let cEnum = "\\Enum"
698 let tInner = "TInner"
700 let idx = "\\HH\\idx"
702 let cTypeStructure = "\\HH\\TypeStructure"
704 let cIncorrectType = "\\HH\\INCORRECT_TYPE"
707 module HH = struct
708 let contains = "\\HH\\Lib\\C\\contains"
710 let contains_key = "\\HH\\Lib\\C\\contains_key"
713 module Rx = struct
714 let is_enabled = "\\HH\\Rx\\IS_ENABLED"
716 let freeze = "\\HH\\Rx\\freeze"
718 let mutable_ = "\\HH\\Rx\\mutable"
720 let cTraversable = "\\HH\\Rx\\Traversable"
722 let cKeyedTraversable = "\\HH\\Rx\\KeyedTraversable"
724 let cAsyncIterator = "\\HH\\Rx\\AsyncIterator"
726 let move = "\\HH\\Rx\\move"
728 let hPure = "Pure"
730 let hRx = "Rx"
732 let hRxShallow = "RxShallow"
734 let hRxLocal = "RxLocal"
736 let hMutable = "Mutable"
738 let hMaybeMutable = "MaybeMutable"
740 let hOwnedMutable = "OwnedMutable"
742 let is_reactive_typehint =
743 let reactive_typehints =
744 [hPure; hRx; hRxShallow; hRxLocal; hMutable; hMaybeMutable; hOwnedMutable]
746 fun name ->
747 List.exists reactive_typehints ~f:(fun th -> String.equal th name)
750 module Shapes = struct
751 let cShapes = "\\HH\\Shapes"
753 let idx = "idx"
755 let at = "at"
757 let keyExists = "keyExists"
759 let removeKey = "removeKey"
761 let toArray = "toArray"
763 let toDict = "toDict"
766 module Superglobals = struct
767 let globals = "$GLOBALS"
769 let is_superglobal =
770 let superglobals =
771 HashSet.of_list
773 "$_SERVER";
774 "$_GET";
775 "$_POST";
776 "$_FILES";
777 "$_COOKIE";
778 "$_REQUEST";
779 "$_ENV";
782 (fun x -> HashSet.mem superglobals x)
785 module Regex = struct
786 let tPattern = "\\HH\\Lib\\Regex\\Pattern"
789 (* These are functions treated by the emitter specially. They are not
790 * autoimported (see hh_autoimport.ml) nor are they consider PseudoFunctions
791 * so they can be overridden by namespacing (at least currently)
793 module EmitterSpecialFunctions = struct
794 let eval = "\\eval"
796 let set_frame_metadata = "\\HH\\set_frame_metadata"
798 let systemlib_reified_generics = "\\__systemlib_reified_generics"
801 module XHP = struct
802 let pcdata = "pcdata"
804 let any = "any"
806 let empty = "empty"
808 let is_reserved name =
809 String.equal name pcdata || String.equal name any || String.equal name empty
811 let is_xhp_category name = String_utils.string_starts_with name "%"
814 (* This should be a subset of rust_parser_errors::UnstableFeatures that is relevant
815 * to the typechecker *)
816 module UnstableFeatures = struct
817 let coeffects_provisional = "coeffects_provisional"
819 let ifc = "ifc"
822 module Coeffects = struct
823 let capability = "$#capability"
825 let local_capability = "$#local_capability"
827 let contexts = "HH\\Contexts"
829 let unsafe_contexts = contexts ^ "\\Unsafe"
832 module Capabilities = struct
833 let defaults = "\\HH\\Contexts\\defaults"
835 let prefix = "\\HH\\Capabilities\\"
837 let writeProperty = prefix ^ "WriteProperty"
839 let accessStaticVariable = prefix ^ "AccessStaticVariable"
841 let output = prefix ^ "Output"