Introduce readonly variant of idx
[hiphop-php.git] / hphp / hack / src / naming / naming_special_names.rs
blob1b045ecd65badb0a0183036978286ee65deab455
1 /*
2  * Copyright (c) 2015, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the MIT license found in the
6  * LICENSE file in the "hack" directory of this source tree.
7  *
8  */
10 /** Module consisting of the special names known to the typechecker */
12 pub mod classes {
13     pub const PARENT: &str = "parent";
15     pub const STATIC: &str = "static";
17     pub const SELF: &str = "self";
19     pub const UNKNOWN: &str = "\\*Unknown*";
21     /* Used for dynamic classnames, e.g. new $foo(); */
23     pub const AWAITABLE: &str = "\\HH\\Awaitable";
25     pub const GENERATOR: &str = "\\Generator";
27     pub const ASYNC_GENERATOR: &str = "\\HH\\AsyncGenerator";
29     pub const HH_FORMAT_STRING: &str = "\\HH\\FormatString";
31     pub fn is_format_string(x: &str) -> bool {
32         match x {
33             HH_FORMAT_STRING => true,
34             _ => false,
35         }
36     }
38     pub const HH_BUILTIN_ENUM: &str = "\\HH\\BuiltinEnum";
40     pub const HH_BUILTIN_ENUM_CLASS: &str = "\\HH\\BuiltinEnumClass";
42     pub const HH_BUILTIN_ABSTRACT_ENUM_CLASS: &str = "\\HH\\BuiltinAbstractEnumClass";
44     pub const THROWABLE: &str = "\\Throwable";
46     pub const STD_CLASS: &str = "\\stdClass";
48     pub const DATE_TIME: &str = "\\DateTime";
50     pub const DATE_TIME_IMMUTABLE: &str = "\\DateTimeImmutable";
52     pub const ASYNC_ITERATOR: &str = "\\HH\\AsyncIterator";
54     pub const ASYNC_KEYED_ITERATOR: &str = "\\HH\\AsyncKeyedIterator";
56     pub const STRINGISH: &str = "\\Stringish";
58     pub const STRINGISH_OBJECT: &str = "\\StringishObject";
60     pub const XHP_CHILD: &str = "\\XHPChild";
62     pub const IMEMOIZE_PARAM: &str = "\\HH\\IMemoizeParam";
64     pub const CLASS_NAME: &str = "\\HH\\classname";
66     pub const TYPE_NAME: &str = "\\HH\\typename";
68     pub const IDISPOSABLE: &str = "\\IDisposable";
70     pub const IASYNC_DISPOSABLE: &str = "\\IAsyncDisposable";
72     pub const MEMBER_OF: &str = "\\HH\\MemberOf";
75 pub mod collections {
76     /* concrete classes */
77     pub const VECTOR: &str = "\\HH\\Vector";
79     pub const IMM_VECTOR: &str = "\\HH\\ImmVector";
81     pub const SET: &str = "\\HH\\Set";
83     pub const IMM_SET: &str = "\\HH\\ImmSet";
85     pub const MAP: &str = "\\HH\\Map";
87     pub const IMM_MAP: &str = "\\HH\\ImmMap";
89     pub const PAIR: &str = "\\HH\\Pair";
91     /* interfaces */
92     pub const CONTAINER: &str = "\\HH\\Container";
94     pub const KEYED_CONTAINER: &str = "\\HH\\KeyedContainer";
96     pub const TRAVERSABLE: &str = "\\HH\\Traversable";
98     pub const KEYED_TRAVERSABLE: &str = "\\HH\\KeyedTraversable";
100     pub const COLLECTION: &str = "\\Collection";
102     pub const CONST_VECTOR: &str = "\\ConstVector";
104     pub const CONST_MAP: &str = "\\ConstMap";
106     pub const CONST_COLLECTION: &str = "\\ConstCollection";
108     pub const DICT: &str = "\\HH\\dict";
110     pub const VEC: &str = "\\HH\\vec";
112     pub const KEYSET: &str = "\\HH\\keyset";
115 pub mod members {
116     use hash::{HashMap, HashSet};
117     use lazy_static::lazy_static;
119     pub const M_CLASS: &str = "class";
121     pub const __CONSTRUCT: &str = "__construct";
123     pub const __DESTRUCT: &str = "__destruct";
125     pub const __CALL: &str = "__call";
127     pub const __CALL_STATIC: &str = "__callStatic";
129     pub const __CLONE: &str = "__clone";
131     pub const __DEBUG_INFO: &str = "__debugInfo";
133     pub const __DISPOSE: &str = "__dispose";
135     pub const __DISPOSE_ASYNC: &str = "__disposeAsync";
137     pub const __GET: &str = "__get";
139     pub const __INVOKE: &str = "__invoke";
141     pub const __ISSET: &str = "__isset";
143     pub const __SET: &str = "__set";
145     pub const __SET_STATE: &str = "__set_state";
147     pub const __SLEEP: &str = "__sleep";
149     pub const __TO_STRING: &str = "__toString";
151     pub const __UNSET: &str = "__unset";
153     pub const __WAKEUP: &str = "__wakeup";
155     lazy_static! {
156         static ref AS_SET: HashSet<&'static str> = vec![
157             __CONSTRUCT,
158             __DESTRUCT,
159             __CALL,
160             __CALL_STATIC,
161             __CLONE,
162             __DEBUG_INFO,
163             __DISPOSE,
164             __DISPOSE_ASYNC,
165             __GET,
166             __INVOKE,
167             __ISSET,
168             __SET,
169             __SET_STATE,
170             __SLEEP,
171             __TO_STRING,
172             __UNSET,
173             __WAKEUP
174         ]
175         .into_iter()
176         .collect();
177         pub static ref AS_LOWERCASE_SET: HashSet<String> = {
178             AS_SET
179                 .iter()
180                 .fold(HashSet::<String>::default(), |mut set, special_name| {
181                     set.insert(special_name.to_ascii_lowercase());
182                     set
183                 })
184         };
185         pub static ref UNSUPPORTED_MAP: HashMap<String, &'static str> = {
186             vec![__CALL, __CALL_STATIC, __GET, __ISSET, __SET, __UNSET]
187                 .iter()
188                 .fold(
189                     HashMap::<String, &'static str>::default(),
190                     |mut set, special_name| {
191                         set.insert(special_name.to_ascii_lowercase(), special_name);
192                         set
193                     },
194                 )
195         };
196     }
198     /* Any data- or aria- attribute is always valid, even if it is not declared
199      * for a given XHP element */
200     pub fn is_special_xhp_attribute(s: &str) -> bool {
201         s.len() >= 6
202             && match &s[..6] {
203                 ":data-" | ":aria-" => true,
204                 _ => false,
205             }
206     }
209 pub mod user_attributes {
210     use lazy_static::lazy_static;
211     use std::collections::HashSet;
213     pub const OVERRIDE: &str = "__Override";
215     pub const CONSISTENT_CONSTRUCT: &str = "__ConsistentConstruct";
217     pub const CONST: &str = "__Const";
219     pub const DEPRECATED: &str = "__Deprecated";
221     pub const ENTRY_POINT: &str = "__EntryPoint";
223     pub const MEMOIZE: &str = "__Memoize";
225     pub const MEMOIZE_LSB: &str = "__MemoizeLSB";
227     pub const POLICY_SHARDED_MEMOIZE: &str = "__PolicyShardedMemoize";
229     pub const POLICY_SHARDED_MEMOIZE_LSB: &str = "__PolicyShardedMemoizeLSB";
231     pub const PHP_STD_LIB: &str = "__PHPStdLib";
233     pub const ACCEPT_DISPOSABLE: &str = "__AcceptDisposable";
235     pub const RETURN_DISPOSABLE: &str = "__ReturnDisposable";
237     pub const LSB: &str = "__LSB";
239     pub const SEALED: &str = "__Sealed";
241     pub const LATE_INIT: &str = "__LateInit";
243     pub const NEWABLE: &str = "__Newable";
245     pub const ENFORCEABLE: &str = "__Enforceable";
247     pub const EXPLICIT: &str = "__Explicit";
249     pub const SOFT: &str = "__Soft";
251     pub const WARN: &str = "__Warn";
253     pub const MOCK_CLASS: &str = "__MockClass";
255     pub const PROVENANCE_SKIP_FRAME: &str = "__ProvenanceSkipFrame";
257     pub const DYNAMICALLY_CALLABLE: &str = "__DynamicallyCallable";
259     pub const DYNAMICALLY_CONSTRUCTIBLE: &str = "__DynamicallyConstructible";
261     pub const REIFIABLE: &str = "__Reifiable";
263     pub const NEVER_INLINE: &str = "__NEVER_INLINE";
265     pub const ENABLE_UNSTABLE_FEATURES: &str = "__EnableUnstableFeatures";
267     pub const ENUM_CLASS: &str = "__EnumClass";
269     pub const VIA_LABEL: &str = "__ViaLabel";
271     pub const POLICIED: &str = "__Policied";
273     pub const INFERFLOWS: &str = "__InferFlows";
275     pub const EXTERNAL: &str = "__External";
277     pub const SUPPORT_DYNAMIC_TYPE: &str = "__SupportDynamicType";
279     pub const MODULE: &str = "__Module";
281     pub const INTERNAL: &str = "__Internal";
283     pub const ENABLE_METHOD_TRAIT_DIAMOND: &str = "__EnableMethodTraitDiamond";
285     lazy_static! {
286         pub static ref AS_SET: HashSet<&'static str> = vec![
287             OVERRIDE,
288             CONSISTENT_CONSTRUCT,
289             CONST,
290             DEPRECATED,
291             ENTRY_POINT,
292             MEMOIZE,
293             MEMOIZE_LSB,
294             POLICY_SHARDED_MEMOIZE,
295             POLICY_SHARDED_MEMOIZE_LSB,
296             PHP_STD_LIB,
297             ACCEPT_DISPOSABLE,
298             RETURN_DISPOSABLE,
299             LSB,
300             SEALED,
301             LATE_INIT,
302             NEWABLE,
303             ENFORCEABLE,
304             EXPLICIT,
305             SOFT,
306             WARN,
307             MOCK_CLASS,
308             PROVENANCE_SKIP_FRAME,
309             DYNAMICALLY_CALLABLE,
310             DYNAMICALLY_CONSTRUCTIBLE,
311             REIFIABLE,
312             NEVER_INLINE,
313             ENABLE_UNSTABLE_FEATURES,
314             ENUM_CLASS,
315             VIA_LABEL,
316             POLICIED,
317             INFERFLOWS,
318             EXTERNAL,
319             SUPPORT_DYNAMIC_TYPE,
320             MODULE,
321         ]
322         .into_iter()
323         .collect();
324     }
326     pub fn is_memoized_regular(name: &str) -> bool {
327         name == MEMOIZE || name == MEMOIZE_LSB
328     }
330     pub fn is_memoized_policy_sharded(name: &str) -> bool {
331         name == POLICY_SHARDED_MEMOIZE || name == POLICY_SHARDED_MEMOIZE_LSB
332     }
334     pub fn is_memoized(name: &str) -> bool {
335         is_memoized_regular(name) || is_memoized_policy_sharded(name)
336     }
338     // TODO(hrust) these should probably be added to the above map/fields, too
340     pub fn is_native(name: &str) -> bool {
341         name == "__Native"
342     }
344     pub fn is_foldable(name: &str) -> bool {
345         name == "__IsFoldable"
346     }
348     pub fn is_meth_caller(name: &str) -> bool {
349         name == "__MethCaller"
350     }
352     pub fn is_reserved(name: &str) -> bool {
353         name.starts_with("__")
354     }
356     pub fn is_soft(name: &str) -> bool {
357         name == SOFT
358     }
361 pub mod attribute_kinds {
362     use hash::HashMap;
363     use lazy_static::lazy_static;
365     pub const CLS: &str = "\\HH\\ClassAttribute";
367     pub const ENUM: &str = "\\HH\\EnumAttribute";
369     pub const TYPE_ALIAS: &str = "\\HH\\TypeAliasAttribute";
371     pub const FN: &str = "\\HH\\FunctionAttribute";
373     pub const MTHD: &str = "\\HH\\MethodAttribute";
375     pub const INST_PROPERTY: &str = "\\HH\\InstancePropertyAttribute";
377     pub const STATIC_PROPERTY: &str = "\\HH\\StaticPropertyAttribute";
379     pub const PARAMETER: &str = "\\HH\\ParameterAttribute";
381     pub const TYPE_PARAM: &str = "\\HH\\TypeParameterAttribute";
383     pub const FILE: &str = "\\HH\\FileAttribute";
385     pub const TYPE_CONST: &str = "\\HH\\TypeConstantAttribute";
387     pub const LAMBDA: &str = "\\HH\\LambdaAttribute";
389     pub const ENUM_CLS: &str = "\\HH\\EnumClassAttribute";
391     pub static PLAIN_ENGLISH: &[(&str, &str)] = &[
392         (CLS, "a class"),
393         (ENUM, "an enum"),
394         (TYPE_ALIAS, "a typealias"),
395         (FN, "a function"),
396         (MTHD, "a method"),
397         (INST_PROPERTY, "an instance property"),
398         (STATIC_PROPERTY, "a static property"),
399         (PARAMETER, "a parameter"),
400         (TYPE_PARAM, "a type parameter"),
401         (FILE, "a file"),
402         (TYPE_CONST, "a type constant"),
403         (LAMBDA, "a lambda expression"),
404         (ENUM_CLS, "an enum class"),
405     ];
407     lazy_static! {
408         pub static ref PLAIN_ENGLISH_MAP: HashMap<&'static str, &'static str> =
409             PLAIN_ENGLISH.iter().copied().collect();
410     }
413 /* Tested before \\-prepending name-canonicalization */
414 pub mod special_functions {
415     use lazy_static::lazy_static;
417     pub const ECHO: &str = "echo"; /* pseudo-function */
419     pub const HHAS_ADATA: &str = "__hhas_adata";
421     pub fn is_special_function(x: &str) -> bool {
422         lazy_static! {
423             static ref ALL_SPECIAL_FUNCTIONS: Vec<&'static str> =
424                 vec![ECHO, HHAS_ADATA,].into_iter().collect();
425         }
426         ALL_SPECIAL_FUNCTIONS.contains(&x)
427     }
430 pub mod autoimported_functions {
431     pub const INVARIANT: &str = "\\HH\\invariant";
433     pub const INVARIANT_VIOLATION: &str = "\\HH\\invariant_violation";
435     pub const FUN_: &str = "\\HH\\fun";
437     pub const INST_METH: &str = "\\HH\\inst_meth";
439     pub const CLASS_METH: &str = "\\HH\\class_meth";
441     pub const METH_CALLER: &str = "\\HH\\meth_caller";
444 pub mod special_idents {
445     pub const THIS: &str = "$this";
447     pub const PLACEHOLDER: &str = "$_";
449     pub const DOLLAR_DOLLAR: &str = "$$";
451     /* Intentionally using an invalid variable name to ensure it's translated */
452     pub const TMP_VAR_PREFIX: &str = "__tmp$";
454     pub fn is_tmp_var(name: &str) -> bool {
455         name.len() > 6 && &name.as_bytes()[..6] == TMP_VAR_PREFIX.as_bytes()
456     }
458     pub fn assert_tmp_var(name: &str) {
459         assert!(is_tmp_var(name))
460     }
463 pub mod pseudo_functions {
464     use lazy_static::lazy_static;
465     use std::collections::HashSet;
467     pub const ISSET: &str = "\\isset";
469     pub const UNSET: &str = "\\unset";
471     pub const HH_SHOW: &str = "\\hh_show";
473     pub const HH_SHOW_ENV: &str = "\\hh_show_env";
475     pub const HH_LOG_LEVEL: &str = "\\hh_log_level";
477     pub const HH_FORCE_SOLVE: &str = "\\hh_force_solve";
479     pub const HH_LOOP_FOREVER: &str = "\\hh_loop_forever";
481     pub const ECHO: &str = "\\echo";
483     pub const ECHO_NO_NS: &str = "echo";
485     pub const EMPTY: &str = "\\empty";
487     pub const EXIT: &str = "\\exit";
489     pub const DIE: &str = "\\die";
491     pub static ALL_PSEUDO_FUNCTIONS: &[&str] = &[
492         ISSET,
493         UNSET,
494         HH_SHOW,
495         HH_SHOW_ENV,
496         HH_LOG_LEVEL,
497         HH_FORCE_SOLVE,
498         HH_LOOP_FOREVER,
499         ECHO,
500         EMPTY,
501         EXIT,
502         DIE,
503     ];
505     lazy_static! {
506         static ref PSEUDO_SET: HashSet<&'static str> =
507             ALL_PSEUDO_FUNCTIONS.iter().copied().collect();
508     }
510     pub fn is_pseudo_function(x: &str) -> bool {
511         PSEUDO_SET.contains(x)
512     }
515 pub mod std_lib_functions {
516     pub const IS_ARRAY: &str = "\\is_array";
518     pub const IS_NULL: &str = "\\is_null";
520     pub const GET_CLASS: &str = "\\get_class";
522     pub const ARRAY_FILTER: &str = "\\array_filter";
524     pub const CALL_USER_FUNC: &str = "\\call_user_func";
526     pub const TYPE_STRUCTURE: &str = "\\HH\\type_structure";
528     pub const ARRAY_MARK_LEGACY: &str = "\\HH\\array_mark_legacy";
530     pub const ARRAY_UNMARK_LEGACY: &str = "\\HH\\array_unmark_legacy";
533 pub mod typehints {
534     use lazy_static::lazy_static;
535     use std::collections::HashSet;
537     pub const NULL: &str = "null";
539     pub const VOID: &str = "void";
541     pub const RESOURCE: &str = "resource";
543     pub const NUM: &str = "num";
545     pub const ARRAYKEY: &str = "arraykey";
547     pub const NORETURN: &str = "noreturn";
549     pub const MIXED: &str = "mixed";
551     pub const NONNULL: &str = "nonnull";
553     pub const THIS: &str = "this";
555     pub const DYNAMIC: &str = "dynamic";
557     pub const NOTHING: &str = "nothing";
559     pub const INT: &str = "int";
561     pub const BOOL: &str = "bool";
563     pub const FLOAT: &str = "float";
565     pub const STRING: &str = "string";
567     pub const DARRAY: &str = "darray";
569     pub const VARRAY: &str = "varray";
571     pub const VARRAY_OR_DARRAY: &str = "varray_or_darray";
573     pub const CALLABLE: &str = "callable";
575     pub const OBJECT_CAST: &str = "object";
577     pub const WILDCARD: &str = "_";
579     pub fn is_reserved_type_hint(x: &str) -> bool {
580         lazy_static! {
581             static ref RESERVED_TYPEHINTS: HashSet<&'static str> = vec![
582                 NULL,
583                 VOID,
584                 RESOURCE,
585                 NUM,
586                 ARRAYKEY,
587                 NORETURN,
588                 MIXED,
589                 NONNULL,
590                 THIS,
591                 DYNAMIC,
592                 NOTHING,
593                 INT,
594                 BOOL,
595                 FLOAT,
596                 STRING,
597                 DARRAY,
598                 VARRAY,
599                 VARRAY_OR_DARRAY,
600                 CALLABLE,
601                 WILDCARD,
602             ]
603             .into_iter()
604             .collect();
605         }
607         RESERVED_TYPEHINTS.contains(x)
608     }
610     lazy_static! {
611         static ref RESERVED_GLOBAL_NAMES: HashSet<&'static str> =
612             vec![CALLABLE, crate::classes::SELF, crate::classes::PARENT]
613                 .into_iter()
614                 .collect();
615     }
617     pub fn is_reserved_global_name(x: &str) -> bool {
618         RESERVED_GLOBAL_NAMES.contains(x)
619     }
621     lazy_static! {
622         static ref RESERVED_HH_NAMES: HashSet<&'static str> = vec![
623             VOID, NORETURN, INT, BOOL, FLOAT, NUM, STRING, RESOURCE, MIXED, ARRAYKEY, DYNAMIC,
624             WILDCARD, NULL, NONNULL, NOTHING, THIS
625         ]
626         .into_iter()
627         .collect();
628     }
630     pub fn is_reserved_hh_name(x: &str) -> bool {
631         RESERVED_HH_NAMES.contains(x)
632     }
634     // This function checks if this is a namespace of the "(not HH)\\(...)*\\(reserved_name)"
635     pub fn is_namespace_with_reserved_hh_name(x: &str) -> bool {
636         // This splits the string into its namespaces
637         fn unqualify(x: &str) -> (Vec<&str>, &str) {
638             let mut as_list = x.split('\\').collect::<Vec<&str>>();
639             // Retain if not empty
640             as_list.retain(|&split| match split {
641                 "" => false,
642                 _ => true,
643             });
644             let last_split = match as_list.pop() {
645                 None => "",
646                 Some(x) => x,
647             };
649             (as_list, last_split)
650         }
652         // This returns a bool whether or not the list is just the string "HH"
653         fn is_hh(qualifier: &[&str]) -> bool {
654             match qualifier.len() {
655                 1 => qualifier[0] == "HH",
656                 _ => false,
657             }
658         }
659         let (qualifier, name) = unqualify(x);
660         !is_hh(&qualifier) && !qualifier.is_empty() && is_reserved_hh_name(name)
661     }
664 pub mod literal {
665     pub const TRUE: &str = "true";
666     pub const FALSE: &str = "false";
667     pub const NULL: &str = "null";
670 pub mod pseudo_consts {
671     use lazy_static::lazy_static;
672     use std::collections::HashSet;
674     pub const G__LINE__: &str = "\\__LINE__";
676     pub const G__CLASS__: &str = "\\__CLASS__";
678     pub const G__TRAIT__: &str = "\\__TRAIT__";
680     pub const G__FILE__: &str = "\\__FILE__";
682     pub const G__DIR__: &str = "\\__DIR__";
684     pub const G__FUNCTION__: &str = "\\__FUNCTION__";
686     pub const G__METHOD__: &str = "\\__METHOD__";
688     pub const G__NAMESPACE__: &str = "\\__NAMESPACE__";
690     pub const G__COMPILER_FRONTEND__: &str = "\\__COMPILER_FRONTEND__";
692     pub const G__FUNCTION_CREDENTIAL__: &str = "\\__FUNCTION_CREDENTIAL__";
694     pub const DIE: &str = "\\die";
696     pub const EXIT: &str = "\\exit";
698     pub static ALL_PSEUDO_CONSTS: &[&str] = &[
699         G__LINE__,
700         G__CLASS__,
701         G__TRAIT__,
702         G__FILE__,
703         G__DIR__,
704         G__FUNCTION__,
705         G__METHOD__,
706         G__NAMESPACE__,
707         G__COMPILER_FRONTEND__,
708         G__FUNCTION_CREDENTIAL__,
709         DIE,
710         EXIT,
711     ];
713     lazy_static! {
714         static ref PSEUDO_SET: HashSet<&'static str> = ALL_PSEUDO_CONSTS.iter().copied().collect();
715     }
717     pub fn is_pseudo_const(x: &str) -> bool {
718         PSEUDO_SET.contains(x)
719     }
722 pub mod fb {
723     pub const ENUM: &str = "\\Enum";
725     pub const IDX: &str = "\\HH\\idx";
727     pub const IDXREADONLY: &str = "\\HH\\idx_readonly";
729     pub const TYPE_STRUCTURE: &str = "\\HH\\TypeStructure";
731     pub const INCORRECT_TYPE: &str = "\\HH\\INCORRECT_TYPE";
733     pub const INCORRECT_TYPE_NO_NS: &str = "HH\\INCORRECT_TYPE";
736 pub mod hh {
737     pub const CONTAINS: &str = "\\HH\\Lib\\C\\contains";
739     pub const CONTAINS_KEY: &str = "\\HH\\Lib\\C\\contains_key";
742 pub mod readonly {
743     pub const AS_MUT: &str = "\\HH\\Readonly\\as_mut";
746 pub mod coeffects {
747     use lazy_static::lazy_static;
748     use std::collections::HashSet;
750     pub const DEFAULTS: &str = "defaults";
752     pub const RX_LOCAL: &str = "rx_local";
754     pub const RX_SHALLOW: &str = "rx_shallow";
756     pub const RX: &str = "rx";
758     pub const WRITE_THIS_PROPS: &str = "write_this_props";
760     pub const WRITE_PROPS: &str = "write_props";
762     pub const CONTROLLED: &str = "controlled";
764     pub const POLICIED_LOCAL: &str = "policied_local";
766     pub const POLICIED_SHALLOW: &str = "policied_shallow";
768     pub const POLICIED: &str = "policied";
770     pub const POLICIED_OF: &str = "policied_of";
772     pub const PURE: &str = "pure";
774     pub const READ_GLOBALS: &str = "read_globals";
776     pub const GLOBALS: &str = "globals";
778     pub const CONTEXTS: &str = "HH\\Contexts";
780     pub const CAPABILITIES: &str = "HH\\Capabilities";
782     pub fn is_any_policied(x: &str) -> bool {
783         lazy_static! {
784             static ref POLICIED_SET: HashSet<&'static str> =
785                 vec![POLICIED, POLICIED_OF,].into_iter().collect();
786         }
787         POLICIED_SET.contains(x)
788     }
791 pub mod shapes {
792     pub const SHAPES: &str = "\\HH\\Shapes";
794     pub const IDX: &str = "idx";
796     pub const AT: &str = "at";
798     pub const KEY_EXISTS: &str = "keyExists";
800     pub const REMOVE_KEY: &str = "removeKey";
802     pub const TO_ARRAY: &str = "toArray";
804     pub const TO_DICT: &str = "toDict";
807 pub mod superglobals {
808     use lazy_static::lazy_static;
809     use std::collections::HashSet;
810     pub const GLOBALS: &str = "$GLOBALS";
812     pub static SUPERGLOBALS: &[&str] = &[
813         "$_SERVER",
814         "$_GET",
815         "$_POST",
816         "$_FILES",
817         "$_COOKIE",
818         "$_REQUEST",
819         "$_ENV",
820     ];
822     lazy_static! {
823         static ref SUPERGLOBALS_SET: HashSet<&'static str> = SUPERGLOBALS.iter().copied().collect();
824     }
825     pub fn is_superglobal(x: &str) -> bool {
826         SUPERGLOBALS_SET.contains(x)
827     }
828     pub fn is_any_global(x: &str) -> bool {
829         is_superglobal(x) || x == GLOBALS
830     }
833 pub mod xhp {
834     pub const PCDATA: &str = "pcdata";
835     pub const ANY: &str = "any";
836     pub const EMPTY: &str = "empty";
837     pub fn is_reserved(x: &str) -> bool {
838         x == PCDATA || x == ANY || x == EMPTY
839     }
840     pub fn is_xhp_category(x: &str) -> bool {
841         x.starts_with('%')
842     }
845 pub mod regex {
846     pub const T_PATTERN: &str = "\\HH\\Lib\\Regex\\Pattern";
849 pub mod emitter_special_functions {
850     pub const EVAL: &str = "\\eval";
851     pub const SET_FRAME_METADATA: &str = "\\HH\\set_frame_metadata";
852     pub const SYSTEMLIB_REIFIED_GENERICS: &str = "\\__systemlib_reified_generics";
855 pub mod math {
856     pub const NAN: &str = "NAN";
857     pub const INF: &str = "INF";
858     pub const NEG_INF: &str = "-INF";
861 pub mod expression_trees {
862     pub const MAKE_TREE: &str = "makeTree";
864     pub const INT_TYPE: &str = "intType";
865     pub const FLOAT_TYPE: &str = "floatType";
866     pub const BOOL_TYPE: &str = "boolType";
867     pub const STRING_TYPE: &str = "stringType";
868     pub const NULL_TYPE: &str = "nullType";
869     pub const VOID_TYPE: &str = "voidType";
870     pub const SYMBOL_TYPE: &str = "symbolType";
872     pub const VISIT_INT: &str = "visitInt";
873     pub const VISIT_FLOAT: &str = "visitFloat";
874     pub const VISIT_BOOL: &str = "visitBool";
875     pub const VISIT_STRING: &str = "visitString";
876     pub const VISIT_NULL: &str = "visitNull";
877     pub const VISIT_BINOP: &str = "visitBinop";
878     pub const VISIT_UNOP: &str = "visitUnop";
879     pub const VISIT_LOCAL: &str = "visitLocal";
880     pub const VISIT_LAMBDA: &str = "visitLambda";
881     pub const VISIT_GLOBAL_FUNCTION: &str = "visitGlobalFunction";
882     pub const VISIT_STATIC_METHOD: &str = "visitStaticMethod";
883     pub const VISIT_CALL: &str = "visitCall";
884     pub const VISIT_ASSIGN: &str = "visitAssign";
885     pub const VISIT_TERNARY: &str = "visitTernary";
886     pub const VISIT_IF: &str = "visitIf";
887     pub const VISIT_WHILE: &str = "visitWhile";
888     pub const VISIT_RETURN: &str = "visitReturn";
889     pub const VISIT_FOR: &str = "visitFor";
890     pub const VISIT_BREAK: &str = "visitBreak";
891     pub const VISIT_CONTINUE: &str = "visitContinue";
892     pub const VISIT_PROPERTY_ACCESS: &str = "visitPropertyAccess";
893     pub const VISIT_XHP: &str = "visitXhp";
894     pub const VISIT_INSTANCE_METHOD: &str = "visitInstanceMethod";
896     pub const SPLICE: &str = "splice";
899 #[cfg(test)]
900 mod test {
901     use crate::members::is_special_xhp_attribute;
902     use crate::members::AS_LOWERCASE_SET;
903     use crate::members::UNSUPPORTED_MAP;
904     use crate::special_idents::is_tmp_var;
905     use crate::typehints::is_namespace_with_reserved_hh_name;
907     #[test]
908     fn test_special_idents_is_tmp_var() {
909         assert!(!is_tmp_var("_tmp$Blah"));
910         assert!(!is_tmp_var("__tmp$"));
911         assert!(!is_tmp_var("О БОЖЕ"));
913         assert!(is_tmp_var("__tmp$Blah"));
914     }
916     #[test]
917     fn test_members_as_lowercase_set() {
918         assert!(AS_LOWERCASE_SET.contains("__tostring"));
919         assert!(!AS_LOWERCASE_SET.contains("__toString"));
920     }
922     #[test]
923     fn test_members_unsupported_map() {
924         assert_eq!(UNSUPPORTED_MAP.get("__callstatic"), Some(&"__callStatic"));
925         assert!(!UNSUPPORTED_MAP.contains_key("__callStatic"));
926     }
928     #[test]
929     fn test_members_is_special_xhp_attribute() {
930         assert!(is_special_xhp_attribute(":data-blahblah"));
931         assert!(is_special_xhp_attribute(":aria-blahblah"));
933         assert!(!is_special_xhp_attribute(":arla-blahblah"));
934         assert!(!is_special_xhp_attribute(":aria"));
935     }
937     #[test]
938     fn test_typehint_is_namespace_with_reserved_hh_name() {
939         assert!(!is_namespace_with_reserved_hh_name("HH\\void"));
940         assert!(!is_namespace_with_reserved_hh_name("void"));
941         assert!(!is_namespace_with_reserved_hh_name("ReturnType\\Lloyd"));
942         assert!(!is_namespace_with_reserved_hh_name("Lloyd"));
944         assert!(is_namespace_with_reserved_hh_name("Anything\\Else\\void"));
945     }