Rip out legacy reactivity from the typechecker and HackC
[hiphop-php.git] / hphp / hack / src / naming / naming_special_names.rs
blob6c1e2fd2e1a08c45436617c80a87a706ae0ff220
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 THROWABLE: &str = "\\Throwable";
44     pub const STD_CLASS: &str = "\\stdClass";
46     pub const DATE_TIME: &str = "\\DateTime";
48     pub const DATE_TIME_IMMUTABLE: &str = "\\DateTimeImmutable";
50     pub const ASYNC_ITERATOR: &str = "\\HH\\AsyncIterator";
52     pub const ASYNC_KEYED_ITERATOR: &str = "\\HH\\AsyncKeyedIterator";
54     pub const STRINGISH: &str = "\\Stringish";
56     pub const XHP_CHILD: &str = "\\XHPChild";
58     pub const IMEMOIZE_PARAM: &str = "\\HH\\IMemoizeParam";
60     pub const CLASS_NAME: &str = "\\HH\\classname";
62     pub const TYPE_NAME: &str = "\\HH\\typename";
64     pub const IDISPOSABLE: &str = "\\IDisposable";
66     pub const IASYNC_DISPOSABLE: &str = "\\IAsyncDisposable";
68     pub const MEMBER_OF: &str = "\\HH\\MemberOf";
71 pub mod collections {
72     /* concrete classes */
73     pub const VECTOR: &str = "\\HH\\Vector";
75     pub const IMM_VECTOR: &str = "\\HH\\ImmVector";
77     pub const SET: &str = "\\HH\\Set";
79     pub const IMM_SET: &str = "\\HH\\ImmSet";
81     pub const MAP: &str = "\\HH\\Map";
83     pub const IMM_MAP: &str = "\\HH\\ImmMap";
85     pub const PAIR: &str = "\\HH\\Pair";
87     /* interfaces */
88     pub const CONTAINER: &str = "\\HH\\Container";
90     pub const KEYED_CONTAINER: &str = "\\HH\\KeyedContainer";
92     pub const TRAVERSABLE: &str = "\\HH\\Traversable";
94     pub const KEYED_TRAVERSABLE: &str = "\\HH\\KeyedTraversable";
96     pub const COLLECTION: &str = "\\Collection";
98     pub const CONST_VECTOR: &str = "\\ConstVector";
100     pub const CONST_MAP: &str = "\\ConstMap";
102     pub const CONST_COLLECTION: &str = "\\ConstCollection";
104     pub const DICT: &str = "\\HH\\dict";
106     pub const VEC: &str = "\\HH\\vec";
108     pub const KEYSET: &str = "\\HH\\keyset";
111 pub mod members {
112     use lazy_static::lazy_static;
113     use std::collections::HashMap;
114     use std::collections::HashSet;
116     pub const M_CLASS: &str = "class";
118     pub const __CONSTRUCT: &str = "__construct";
120     pub const __DESTRUCT: &str = "__destruct";
122     pub const __CALL: &str = "__call";
124     pub const __CALL_STATIC: &str = "__callStatic";
126     pub const __CLONE: &str = "__clone";
128     pub const __DEBUG_INFO: &str = "__debugInfo";
130     pub const __DISPOSE: &str = "__dispose";
132     pub const __DISPOSE_ASYNC: &str = "__disposeAsync";
134     pub const __GET: &str = "__get";
136     pub const __INVOKE: &str = "__invoke";
138     pub const __ISSET: &str = "__isset";
140     pub const __SET: &str = "__set";
142     pub const __SET_STATE: &str = "__set_state";
144     pub const __SLEEP: &str = "__sleep";
146     pub const __TO_STRING: &str = "__toString";
148     pub const __UNSET: &str = "__unset";
150     pub const __WAKEUP: &str = "__wakeup";
152     lazy_static! {
153         static ref AS_SET: HashSet<&'static str> = vec![
154             __CONSTRUCT,
155             __DESTRUCT,
156             __CALL,
157             __CALL_STATIC,
158             __CLONE,
159             __DEBUG_INFO,
160             __DISPOSE,
161             __DISPOSE_ASYNC,
162             __GET,
163             __INVOKE,
164             __ISSET,
165             __SET,
166             __SET_STATE,
167             __SLEEP,
168             __TO_STRING,
169             __UNSET,
170             __WAKEUP
171         ]
172         .into_iter()
173         .collect();
174         pub static ref AS_LOWERCASE_SET: HashSet<String> = {
175             AS_SET
176                 .iter()
177                 .fold(HashSet::<String>::new(), |mut set, special_name| {
178                     set.insert(special_name.to_ascii_lowercase());
179                     set
180                 })
181         };
182         pub static ref UNSUPPORTED_MAP: HashMap<String, &'static str> = {
183             vec![__CALL, __CALL_STATIC, __GET, __ISSET, __SET, __UNSET]
184                 .iter()
185                 .fold(
186                     HashMap::<String, &'static str>::new(),
187                     |mut set, special_name| {
188                         set.insert(special_name.to_ascii_lowercase(), special_name);
189                         set
190                     },
191                 )
192         };
193     }
195     /* Any data- or aria- attribute is always valid, even if it is not declared
196      * for a given XHP element */
197     pub fn is_special_xhp_attribute(s: &str) -> bool {
198         s.len() >= 6
199             && match &s[..6] {
200                 ":data-" | ":aria-" => true,
201                 _ => false,
202             }
203     }
206 pub mod user_attributes {
207     use lazy_static::lazy_static;
208     use std::collections::HashSet;
210     pub const OVERRIDE: &str = "__Override";
212     pub const CONSISTENT_CONSTRUCT: &str = "__ConsistentConstruct";
214     pub const CONST: &str = "__Const";
216     pub const CONST_FUN: &str = "__ConstFun";
218     pub const DEPRECATED: &str = "__Deprecated";
220     pub const ENTRY_POINT: &str = "__EntryPoint";
222     pub const MEMOIZE: &str = "__Memoize";
224     pub const MEMOIZE_LSB: &str = "__MemoizeLSB";
226     pub const PHP_STD_LIB: &str = "__PHPStdLib";
228     pub const HIPHOP_SPECIFIC: &str = "__HipHopSpecific";
230     pub const ACCEPT_DISPOSABLE: &str = "__AcceptDisposable";
232     pub const RETURN_DISPOSABLE: &str = "__ReturnDisposable";
234     pub const LSB: &str = "__LSB";
236     pub const SEALED: &str = "__Sealed";
238     pub const LATE_INIT: &str = "__LateInit";
240     pub const NEWABLE: &str = "__Newable";
242     pub const ENFORCEABLE: &str = "__Enforceable";
244     pub const EXPLICIT: &str = "__Explicit";
246     pub const SOFT: &str = "__Soft";
248     pub const WARN: &str = "__Warn";
250     pub const MOCK_CLASS: &str = "__MockClass";
252     pub const PROVENANCE_SKIP_FRAME: &str = "__ProvenanceSkipFrame";
254     pub const DYNAMICALLY_CALLABLE: &str = "__DynamicallyCallable";
256     pub const DYNAMICALLY_CONSTRUCTIBLE: &str = "__DynamicallyConstructible";
258     pub const REIFIABLE: &str = "__Reifiable";
260     pub const NEVER_INLINE: &str = "__NEVER_INLINE";
262     pub const ENABLE_UNSTABLE_FEATURES: &str = "__EnableUnstableFeatures";
264     pub const ENUM_CLASS: &str = "__EnumClass";
266     pub const ATOM: &str = "__Atom";
268     pub const POLICIED: &str = "__Policied";
270     pub const INFERFLOWS: &str = "__InferFlows";
272     pub const EXTERNAL: &str = "__External";
274     lazy_static! {
275         static ref AS_SET: HashSet<&'static str> = vec![
276             OVERRIDE,
277             CONSISTENT_CONSTRUCT,
278             CONST,
279             DEPRECATED,
280             ENTRY_POINT,
281             MEMOIZE,
282             MEMOIZE_LSB,
283             PHP_STD_LIB,
284             HIPHOP_SPECIFIC,
285             ACCEPT_DISPOSABLE,
286             RETURN_DISPOSABLE,
287             LSB,
288             SEALED,
289             LATE_INIT,
290             NEWABLE,
291             ENFORCEABLE,
292             EXPLICIT,
293             SOFT,
294             WARN,
295             MOCK_CLASS,
296             PROVENANCE_SKIP_FRAME,
297             DYNAMICALLY_CALLABLE,
298             DYNAMICALLY_CONSTRUCTIBLE,
299             REIFIABLE,
300             NEVER_INLINE,
301             ENABLE_UNSTABLE_FEATURES,
302             ENUM_CLASS,
303             ATOM,
304             POLICIED,
305             INFERFLOWS,
306             EXTERNAL,
307         ]
308         .into_iter()
309         .collect();
310     }
312     pub fn is_memoized(name: &str) -> bool {
313         name == MEMOIZE || name == MEMOIZE_LSB
314     }
316     // TODO(hrust) these should probably be added to the above map/fields, too
318     pub fn is_native(name: &str) -> bool {
319         name == "__Native"
320     }
322     pub fn is_foldable(name: &str) -> bool {
323         name == "__IsFoldable"
324     }
326     pub fn is_meth_caller(name: &str) -> bool {
327         name == "__MethCaller"
328     }
330     pub fn is_reserved(name: &str) -> bool {
331         name.starts_with("__")
332     }
334     pub fn is_soft(name: &str) -> bool {
335         name == SOFT
336     }
339 pub mod attribute_kinds {
340     use lazy_static::lazy_static;
341     use std::collections::HashMap;
343     pub const CLS: &str = "\\HH\\ClassAttribute";
345     pub const ENUM: &str = "\\HH\\EnumAttribute";
347     pub const TYPE_ALIAS: &str = "\\HH\\TypeAliasAttribute";
349     pub const FN: &str = "\\HH\\FunctionAttribute";
351     pub const MTHD: &str = "\\HH\\MethodAttribute";
353     pub const INST_PROPERTY: &str = "\\HH\\InstancePropertyAttribute";
355     pub const STATIC_PROPERTY: &str = "\\HH\\StaticPropertyAttribute";
357     pub const PARAMETER: &str = "\\HH\\ParameterAttribute";
359     pub const TYPE_PARAM: &str = "\\HH\\TypeParameterAttribute";
361     pub const FILE: &str = "\\HH\\FileAttribute";
363     pub const TYPE_CONST: &str = "\\HH\\TypeConstantAttribute";
365     pub const LAMBDA: &str = "\\HH\\LambdaAttribute";
367     pub static PLAIN_ENGLISH: &[(&str, &str)] = &[
368         (CLS, "a class"),
369         (ENUM, "an enum"),
370         (TYPE_ALIAS, "a typealias"),
371         (FN, "a function"),
372         (MTHD, "a method"),
373         (INST_PROPERTY, "an instance property"),
374         (STATIC_PROPERTY, "a static property"),
375         (PARAMETER, "a parameter"),
376         (TYPE_PARAM, "a type parameter"),
377         (FILE, "a file"),
378         (TYPE_CONST, "a type constant"),
379         (LAMBDA, "a lambda expression"),
380     ];
382     lazy_static! {
383         pub static ref PLAIN_ENGLISH_MAP: HashMap<&'static str, &'static str> =
384             PLAIN_ENGLISH.iter().copied().collect();
385     }
388 /* Tested before \\-prepending name-canonicalization */
389 pub mod special_functions {
390     use lazy_static::lazy_static;
392     pub const TUPLE: &str = "tuple"; /* pseudo-function */
394     pub const ECHO: &str = "echo"; /* pseudo-function */
396     pub const HHAS_ADATA: &str = "__hhas_adata";
398     pub fn is_special_function(x: &str) -> bool {
399         lazy_static! {
400             static ref ALL_SPECIAL_FUNCTIONS: Vec<&'static str> =
401                 vec![TUPLE, ECHO, HHAS_ADATA,].into_iter().collect();
402         }
403         ALL_SPECIAL_FUNCTIONS.contains(&x)
404     }
407 pub mod autoimported_functions {
408     pub const INVARIANT: &str = "\\HH\\invariant";
410     pub const INVARIANT_VIOLATION: &str = "\\HH\\invariant_violation";
412     pub const FUN_: &str = "\\HH\\fun";
414     pub const INST_METH: &str = "\\HH\\inst_meth";
416     pub const CLASS_METH: &str = "\\HH\\class_meth";
418     pub const METH_CALLER: &str = "\\HH\\meth_caller";
421 pub mod special_idents {
422     pub const THIS: &str = "$this";
424     pub const PLACEHOLDER: &str = "$_";
426     pub const DOLLAR_DOLLAR: &str = "$$";
428     /* Intentionally using an invalid variable name to ensure it's translated */
429     pub const TMP_VAR_PREFIX: &str = "__tmp$";
431     pub fn is_tmp_var(name: &str) -> bool {
432         name.len() > 6 && &name.as_bytes()[..6] == TMP_VAR_PREFIX.as_bytes()
433     }
435     pub fn assert_tmp_var(name: &str) {
436         assert!(is_tmp_var(name))
437     }
440 pub mod pseudo_functions {
441     use lazy_static::lazy_static;
442     use std::collections::HashSet;
444     pub const ISSET: &str = "\\isset";
446     pub const UNSET: &str = "\\unset";
448     pub const HH_SHOW: &str = "\\hh_show";
450     pub const HH_SHOW_ENV: &str = "\\hh_show_env";
452     pub const HH_LOG_LEVEL: &str = "\\hh_log_level";
454     pub const HH_FORCE_SOLVE: &str = "\\hh_force_solve";
456     pub const HH_LOOP_FOREVER: &str = "\\hh_loop_forever";
458     pub const ECHO: &str = "\\echo";
460     pub const ECHO_NO_NS: &str = "echo";
462     pub const EMPTY: &str = "\\empty";
464     pub const EXIT: &str = "\\exit";
466     pub const DIE: &str = "\\die";
468     pub static ALL_PSEUDO_FUNCTIONS: &[&str] = &[
469         ISSET,
470         UNSET,
471         HH_SHOW,
472         HH_SHOW_ENV,
473         HH_LOG_LEVEL,
474         HH_FORCE_SOLVE,
475         HH_LOOP_FOREVER,
476         ECHO,
477         EMPTY,
478         EXIT,
479         DIE,
480     ];
482     lazy_static! {
483         static ref PSEUDO_SET: HashSet<&'static str> =
484             ALL_PSEUDO_FUNCTIONS.iter().copied().collect();
485     }
487     pub fn is_pseudo_function(x: &str) -> bool {
488         PSEUDO_SET.contains(x)
489     }
492 pub mod std_lib_functions {
493     pub const IS_ARRAY: &str = "\\is_array";
495     pub const IS_NULL: &str = "\\is_null";
497     pub const GET_CLASS: &str = "\\get_class";
499     pub const ARRAY_FILTER: &str = "\\array_filter";
501     pub const ARRAY_MAP: &str = "\\array_map";
503     pub const CALL_USER_FUNC: &str = "\\call_user_func";
505     pub const TYPE_STRUCTURE: &str = "\\HH\\type_structure";
507     pub const ARRAY_MARK_LEGACY: &str = "\\HH\\array_mark_legacy";
509     pub const ARRAY_UNMARK_LEGACY: &str = "\\HH\\array_unmark_legacy";
512 pub mod typehints {
513     use lazy_static::lazy_static;
514     use std::collections::HashSet;
516     pub const NULL: &str = "null";
518     pub const VOID: &str = "void";
520     pub const RESOURCE: &str = "resource";
522     pub const NUM: &str = "num";
524     pub const ARRAYKEY: &str = "arraykey";
526     pub const NORETURN: &str = "noreturn";
528     pub const MIXED: &str = "mixed";
530     pub const NONNULL: &str = "nonnull";
532     pub const THIS: &str = "this";
534     pub const DYNAMIC: &str = "dynamic";
536     pub const NOTHING: &str = "nothing";
538     pub const INT: &str = "int";
540     pub const BOOL: &str = "bool";
542     pub const FLOAT: &str = "float";
544     pub const STRING: &str = "string";
546     pub const DARRAY: &str = "darray";
548     pub const VARRAY: &str = "varray";
550     pub const VARRAY_OR_DARRAY: &str = "varray_or_darray";
552     pub const CALLABLE: &str = "callable";
554     pub const OBJECT_CAST: &str = "object";
556     pub const WILDCARD: &str = "_";
558     pub fn is_reserved_type_hint(x: &str) -> bool {
559         lazy_static! {
560             static ref RESERVED_TYPEHINTS: HashSet<&'static str> = vec![
561                 NULL,
562                 VOID,
563                 RESOURCE,
564                 NUM,
565                 ARRAYKEY,
566                 NORETURN,
567                 MIXED,
568                 NONNULL,
569                 THIS,
570                 DYNAMIC,
571                 NOTHING,
572                 INT,
573                 BOOL,
574                 FLOAT,
575                 STRING,
576                 DARRAY,
577                 VARRAY,
578                 VARRAY_OR_DARRAY,
579                 CALLABLE,
580                 WILDCARD,
581             ]
582             .into_iter()
583             .collect();
584         }
586         RESERVED_TYPEHINTS.contains(x)
587     }
589     lazy_static! {
590         static ref RESERVED_GLOBAL_NAMES: HashSet<&'static str> =
591             vec![CALLABLE, crate::classes::SELF, crate::classes::PARENT]
592                 .into_iter()
593                 .collect();
594     }
596     pub fn is_reserved_global_name(x: &str) -> bool {
597         RESERVED_GLOBAL_NAMES.contains(x)
598     }
600     lazy_static! {
601         static ref RESERVED_HH_NAMES: HashSet<&'static str> = vec![
602             VOID, NORETURN, INT, BOOL, FLOAT, NUM, STRING, RESOURCE, MIXED, ARRAYKEY, DYNAMIC,
603             WILDCARD, NULL, NONNULL, NOTHING, THIS
604         ]
605         .into_iter()
606         .collect();
607     }
609     pub fn is_reserved_hh_name(x: &str) -> bool {
610         RESERVED_HH_NAMES.contains(x)
611     }
613     // This function checks if this is a namespace of the "(not HH)\\(...)*\\(reserved_name)"
614     pub fn is_namespace_with_reserved_hh_name(x: &str) -> bool {
615         // This splits the string into its namespaces
616         fn unqualify(x: &str) -> (Vec<&str>, &str) {
617             let mut as_list = x.split('\\').collect::<Vec<&str>>();
618             // Retain if not empty
619             as_list.retain(|&split| match split {
620                 "" => false,
621                 _ => true,
622             });
623             let last_split = match as_list.pop() {
624                 None => "",
625                 Some(x) => x,
626             };
628             (as_list, last_split)
629         }
631         // This returns a bool whether or not the list is just the string "HH"
632         fn is_hh(qualifier: &[&str]) -> bool {
633             match qualifier.len() {
634                 1 => qualifier[0] == "HH",
635                 _ => false,
636             }
637         }
638         let (qualifier, name) = unqualify(x);
639         !is_hh(&qualifier) && !qualifier.is_empty() && is_reserved_hh_name(name)
640     }
643 pub mod literal {
644     pub const TRUE: &str = "true";
645     pub const FALSE: &str = "false";
646     pub const NULL: &str = "null";
649 pub mod pseudo_consts {
650     use lazy_static::lazy_static;
651     use std::collections::HashSet;
653     pub const G__LINE__: &str = "\\__LINE__";
655     pub const G__CLASS__: &str = "\\__CLASS__";
657     pub const G__TRAIT__: &str = "\\__TRAIT__";
659     pub const G__FILE__: &str = "\\__FILE__";
661     pub const G__DIR__: &str = "\\__DIR__";
663     pub const G__FUNCTION__: &str = "\\__FUNCTION__";
665     pub const G__METHOD__: &str = "\\__METHOD__";
667     pub const G__NAMESPACE__: &str = "\\__NAMESPACE__";
669     pub const G__COMPILER_FRONTEND__: &str = "\\__COMPILER_FRONTEND__";
671     pub const G__FUNCTION_CREDENTIAL__: &str = "\\__FUNCTION_CREDENTIAL__";
673     pub const DIE: &str = "\\die";
675     pub const EXIT: &str = "\\exit";
677     pub static ALL_PSEUDO_CONSTS: &[&str] = &[
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         DIE,
689         EXIT,
690     ];
692     lazy_static! {
693         static ref PSEUDO_SET: HashSet<&'static str> = ALL_PSEUDO_CONSTS.iter().copied().collect();
694     }
696     pub fn is_pseudo_const(x: &str) -> bool {
697         PSEUDO_SET.contains(x)
698     }
701 pub mod fb {
702     pub const ENUM: &str = "\\Enum";
704     pub const IDX: &str = "\\HH\\idx";
706     pub const TYPE_STRUCTURE: &str = "\\HH\\TypeStructure";
708     pub const INCORRECT_TYPE: &str = "\\HH\\INCORRECT_TYPE";
710     pub const INCORRECT_TYPE_NO_NS: &str = "HH\\INCORRECT_TYPE";
713 pub mod hh {
714     pub const CONTAINS: &str = "\\HH\\Lib\\C\\contains";
716     pub const CONTAINS_KEY: &str = "\\HH\\Lib\\C\\contains_key";
719 pub mod rx {
720     pub const IS_ENABLED: &str = "\\HH\\Rx\\IS_ENABLED";
722 pub mod coeffects {
723     pub const DEFAULTS: &str = "defaults";
725     pub const RX_LOCAL: &str = "rx_local";
727     pub const RX_SHALLOW: &str = "rx_shallow";
729     pub const RX: &str = "rx";
731     pub const WRITE_PROPS: &str = "write_props";
733     pub const POLICIED_LOCAL: &str = "policied_local";
735     pub const POLICIED_SHALLOW: &str = "policied_shallow";
737     pub const POLICIED: &str = "policied";
739     pub const POLICIED_OF_LOCAL: &str = "policied_of_local";
741     pub const POLICIED_OF_SHALLOW: &str = "policied_of_shallow";
743     pub const POLICIED_OF: &str = "policied_of";
745     pub const PURE: &str = "pure";
748 pub mod shapes {
749     pub const SHAPES: &str = "\\HH\\Shapes";
751     pub const IDX: &str = "idx";
753     pub const AT: &str = "at";
755     pub const KEY_EXISTS: &str = "keyExists";
757     pub const REMOVE_KEY: &str = "removeKey";
759     pub const TO_ARRAY: &str = "toArray";
761     pub const TO_DICT: &str = "toDict";
764 pub mod superglobals {
765     use lazy_static::lazy_static;
766     use std::collections::HashSet;
767     pub const GLOBALS: &str = "$GLOBALS";
769     pub static SUPERGLOBALS: &[&str] = &[
770         "$_SERVER",
771         "$_GET",
772         "$_POST",
773         "$_FILES",
774         "$_COOKIE",
775         "$_REQUEST",
776         "$_ENV",
777     ];
779     lazy_static! {
780         static ref SUPERGLOBALS_SET: HashSet<&'static str> = SUPERGLOBALS.iter().copied().collect();
781     }
782     pub fn is_superglobal(x: &str) -> bool {
783         SUPERGLOBALS_SET.contains(x)
784     }
785     pub fn is_any_global(x: &str) -> bool {
786         is_superglobal(x) || x == GLOBALS
787     }
790 pub mod xhp {
791     pub const PCDATA: &str = "pcdata";
792     pub const ANY: &str = "any";
793     pub const EMPTY: &str = "empty";
794     pub fn is_reserved(x: &str) -> bool {
795         x == PCDATA || x == ANY || x == EMPTY
796     }
797     pub fn is_xhp_category(x: &str) -> bool {
798         x.starts_with('%')
799     }
802 pub mod regex {
803     pub const T_PATTERN: &str = "\\HH\\Lib\\Regex\\Pattern";
806 pub mod emitter_special_functions {
807     pub const EVAL: &str = "\\eval";
808     pub const SET_FRAME_METADATA: &str = "\\HH\\set_frame_metadata";
809     pub const SYSTEMLIB_REIFIED_GENERICS: &str = "\\__systemlib_reified_generics";
812 pub mod math {
813     pub const NAN: &str = "NAN";
814     pub const INF: &str = "INF";
815     pub const NEG_INF: &str = "-INF";
818 #[cfg(test)]
819 mod test {
820     use crate::members::is_special_xhp_attribute;
821     use crate::members::AS_LOWERCASE_SET;
822     use crate::members::UNSUPPORTED_MAP;
823     use crate::special_idents::is_tmp_var;
824     use crate::typehints::is_namespace_with_reserved_hh_name;
826     #[test]
827     fn test_special_idents_is_tmp_var() {
828         assert!(!is_tmp_var("_tmp$Blah"));
829         assert!(!is_tmp_var("__tmp$"));
830         assert!(!is_tmp_var("О БОЖЕ"));
832         assert!(is_tmp_var("__tmp$Blah"));
833     }
835     #[test]
836     fn test_members_as_lowercase_set() {
837         assert!(AS_LOWERCASE_SET.contains("__tostring"));
838         assert!(!AS_LOWERCASE_SET.contains("__toString"));
839     }
841     #[test]
842     fn test_members_unsupported_map() {
843         assert_eq!(UNSUPPORTED_MAP.get("__callstatic"), Some(&"__callStatic"));
844         assert!(!UNSUPPORTED_MAP.contains_key("__callStatic"));
845     }
847     #[test]
848     fn test_members_is_special_xhp_attribute() {
849         assert!(is_special_xhp_attribute(":data-blahblah"));
850         assert!(is_special_xhp_attribute(":aria-blahblah"));
852         assert!(!is_special_xhp_attribute(":arla-blahblah"));
853         assert!(!is_special_xhp_attribute(":aria"));
854     }
856     #[test]
857     fn test_typehint_is_namespace_with_reserved_hh_name() {
858         assert!(!is_namespace_with_reserved_hh_name("HH\\void"));
859         assert!(!is_namespace_with_reserved_hh_name("void"));
860         assert!(!is_namespace_with_reserved_hh_name("ReturnType\\Lloyd"));
861         assert!(!is_namespace_with_reserved_hh_name("Lloyd"));
863         assert!(is_namespace_with_reserved_hh_name("Anything\\Else\\void"));
864     }