1use std::{
2 borrow::Cow,
3 fmt::Display,
4 ops::{Deref, DerefMut},
5};
6
7use once_cell::sync::Lazy;
8use phf::phf_set;
9use rustc_hash::FxHashSet;
10use swc_atoms::{atom, Atom, UnsafeAtom};
11use swc_common::{
12 ast_node, util::take::Take, BytePos, EqIgnoreSpan, Mark, Span, Spanned, SyntaxContext, DUMMY_SP,
13};
14
15use crate::{typescript::TsTypeAnn, Expr};
16
17#[derive(Clone, Debug, PartialEq, Eq, Hash, EqIgnoreSpan, Default)]
19#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
20#[cfg_attr(
21 any(feature = "rkyv-impl"),
22 derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
23)]
24#[cfg_attr(
25 feature = "rkyv-impl",
26 rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
27 __S::Error: rkyv::rancor::Source))
28)]
29#[cfg_attr(
30 feature = "rkyv-impl",
31 rkyv(deserialize_bounds(__D::Error: rkyv::rancor::Source))
32)]
33#[cfg_attr(
34 feature = "rkyv-impl",
35 rkyv(bytecheck(bounds(
36 __C: rkyv::validation::ArchiveContext,
37 __C::Error: rkyv::rancor::Source
38 )))
39)]
40#[cfg_attr(feature = "rkyv-impl", repr(C))]
41#[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))]
42#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
43#[cfg_attr(
44 feature = "encoding-impl",
45 derive(::swc_common::Encode, ::swc_common::Decode)
46)]
47pub struct BindingIdent {
48 #[cfg_attr(feature = "serde-impl", serde(flatten))]
49 #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
50 pub id: Ident,
51
52 #[cfg_attr(feature = "serde-impl", serde(default, rename = "typeAnnotation"))]
53 #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
54 #[cfg_attr(
55 feature = "encoding-impl",
56 encoding(with = "cbor4ii::core::types::Maybe")
57 )]
58 pub type_ann: Option<Box<TsTypeAnn>>,
59}
60
61impl Spanned for BindingIdent {
62 fn span(&self) -> Span {
63 match &self.type_ann {
64 Some(ann) => Span::new(self.id.span.lo(), ann.span().hi()),
65 None => self.id.span,
66 }
67 }
68}
69
70impl Deref for BindingIdent {
71 type Target = Ident;
72
73 fn deref(&self) -> &Self::Target {
74 &self.id
75 }
76}
77
78impl DerefMut for BindingIdent {
79 fn deref_mut(&mut self) -> &mut Self::Target {
80 &mut self.id
81 }
82}
83
84impl AsRef<str> for BindingIdent {
85 fn as_ref(&self) -> &str {
86 &self.sym
87 }
88}
89
90impl From<BindingIdent> for Box<Expr> {
91 fn from(bi: BindingIdent) -> Self {
92 Box::new(Expr::Ident(bi.into()))
93 }
94}
95impl From<&'_ BindingIdent> for Ident {
96 fn from(bi: &'_ BindingIdent) -> Self {
97 Ident {
98 span: bi.span,
99 ctxt: bi.ctxt,
100 sym: bi.sym.clone(),
101 optional: bi.optional,
102 }
103 }
104}
105
106impl BindingIdent {
107 pub fn to_id(&self) -> Id {
109 (self.sym.clone(), self.ctxt)
110 }
111}
112
113impl Take for BindingIdent {
114 fn dummy() -> Self {
115 Default::default()
116 }
117}
118
119impl From<Ident> for BindingIdent {
120 fn from(id: Ident) -> Self {
121 BindingIdent {
122 id,
123 ..Default::default()
124 }
125 }
126}
127
128bridge_from!(BindingIdent, Ident, Id);
129
130#[ast_node("Identifier")]
181#[derive(Eq, Hash, Default)]
182#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
183pub struct Ident {
184 #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
185 pub span: Span,
186
187 #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
188 pub ctxt: SyntaxContext,
189
190 #[cfg_attr(feature = "serde-impl", serde(rename = "value"))]
191 pub sym: Atom,
192
193 #[cfg_attr(feature = "serde-impl", serde(default))]
195 pub optional: bool,
196}
197
198impl From<BindingIdent> for Ident {
199 fn from(bi: BindingIdent) -> Self {
200 bi.id
201 }
202}
203
204impl From<Atom> for Ident {
205 fn from(bi: Atom) -> Self {
206 Ident::new_no_ctxt(bi, DUMMY_SP)
207 }
208}
209bridge_from!(Ident, Atom, &'_ str);
210bridge_from!(Ident, Atom, Cow<'_, str>);
211bridge_from!(Ident, Atom, String);
212
213impl From<(Atom, Span)> for Ident {
214 fn from((sym, span): (Atom, Span)) -> Self {
215 Ident {
216 span,
217 sym,
218 ..Default::default()
219 }
220 }
221}
222
223impl EqIgnoreSpan for Ident {
224 fn eq_ignore_span(&self, other: &Self) -> bool {
225 if self.sym != other.sym {
226 return false;
227 }
228
229 self.ctxt.eq_ignore_span(&other.ctxt)
230 }
231}
232
233impl From<Id> for Ident {
234 fn from(id: Id) -> Self {
235 Ident::new(id.0, DUMMY_SP, id.1)
236 }
237}
238
239impl From<Ident> for Id {
240 fn from(i: Ident) -> Self {
241 (i.sym, i.ctxt)
242 }
243}
244
245#[repr(C, align(64))]
246struct Align64<T>(pub(crate) T);
247
248const T: bool = true;
249const F: bool = false;
250
251impl Ident {
252 pub fn within_ignored_ctxt<F, Ret>(op: F) -> Ret
254 where
255 F: FnOnce() -> Ret,
256 {
257 SyntaxContext::within_ignored_ctxt(op)
258 }
259
260 pub fn without_loc(mut self) -> Ident {
262 self.span.lo = BytePos::DUMMY;
263 self.span.hi = BytePos::DUMMY;
264 self
265 }
266
267 pub fn to_id(&self) -> Id {
269 (self.sym.clone(), self.ctxt)
270 }
271
272 #[inline]
273 pub fn is_valid_ascii_start(c: u8) -> bool {
274 debug_assert!(c.is_ascii());
275 const ASCII_START: Align64<[bool; 128]> = Align64([
277 F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
278 F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
279 F, F, F, F, F, F, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
280 T, T, T, T, F, F, F, F, T, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
281 T, T, T, T, T, T, T, F, F, F, F, F,
282 ]);
283 ASCII_START.0[c as usize]
284 }
285
286 pub fn is_valid_non_ascii_start(c: char) -> bool {
287 debug_assert!(!c.is_ascii());
288 unicode_id_start::is_id_start_unicode(c)
289 }
290
291 #[inline]
293 pub fn is_valid_start(c: char) -> bool {
294 if c.is_ascii() {
295 Self::is_valid_ascii_start(c as u8)
296 } else {
297 Self::is_valid_non_ascii_start(c)
298 }
299 }
300
301 #[inline]
302 pub fn is_valid_non_ascii_continue(c: char) -> bool {
303 debug_assert!(!c.is_ascii());
304 unicode_id_start::is_id_continue_unicode(c)
305 }
306
307 #[inline]
308 pub fn is_valid_ascii_continue(c: u8) -> bool {
309 debug_assert!(c.is_ascii());
310 const ASCII_CONTINUE: Align64<[bool; 128]> = Align64([
312 F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F,
313 F, F, F, F, F, F, F, T, F, F, F, F, F, F, F, F, F, F, F, T, T, T, T, T, T, T, T, T, T,
314 F, F, F, F, F, F, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
315 T, T, T, T, F, F, F, F, T, F, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T,
316 T, T, T, T, T, T, T, F, F, F, F, F,
317 ]);
318 ASCII_CONTINUE.0[c as usize]
319 }
320
321 #[inline]
324 pub fn is_valid_continue(c: char) -> bool {
325 if c.is_ascii() {
326 Self::is_valid_ascii_continue(c as u8)
327 } else {
328 Self::is_valid_non_ascii_continue(c)
329 }
330 }
331
332 pub fn verify_symbol(s: &str) -> Result<(), String> {
337 fn is_reserved_symbol(s: &str) -> bool {
338 s.is_reserved() || s.is_reserved_in_strict_mode(true) || s.is_reserved_in_strict_bind()
339 }
340
341 if is_reserved_symbol(s) {
342 let mut buf = String::with_capacity(s.len() + 1);
343 buf.push('_');
344 buf.push_str(s);
345 return Err(buf);
346 }
347
348 {
349 let mut chars = s.chars();
350
351 if let Some(first) = chars.next() {
352 if Self::is_valid_start(first) && chars.all(Self::is_valid_continue) {
353 return Ok(());
354 }
355 }
356 }
357
358 let mut buf = String::with_capacity(s.len() + 2);
359 let mut has_start = false;
360
361 for c in s.chars() {
362 if !has_start && Self::is_valid_start(c) {
363 has_start = true;
364 buf.push(c);
365 continue;
366 }
367
368 if Self::is_valid_continue(c) {
369 buf.push(c);
370 }
371 }
372
373 if buf.is_empty() {
374 buf.push('_');
375 }
376
377 if is_reserved_symbol(&buf) {
378 let mut new_buf = String::with_capacity(buf.len() + 1);
379 new_buf.push('_');
380 new_buf.push_str(&buf);
381 buf = new_buf;
382 }
383
384 Err(buf)
385 }
386
387 pub fn with_prefix(&self, prefix: &str) -> Ident {
389 Ident::new(
390 format!("{}{}", prefix, self.sym).into(),
391 self.span,
392 self.ctxt,
393 )
394 }
395
396 pub fn into_private(self) -> Ident {
399 Self::new(
400 self.sym,
401 self.span,
402 SyntaxContext::empty().apply_mark(Mark::new()),
403 )
404 }
405
406 #[inline]
407 pub fn is_dummy(&self) -> bool {
408 self.sym == atom!("") && self.span.is_dummy()
409 }
410
411 pub fn with_pos(mut self, lo: BytePos, hi: BytePos) -> Ident {
413 self.span = Span::new(lo, hi);
414 self
415 }
416}
417
418#[ast_node("Identifier")]
419#[derive(Eq, Hash, Default, EqIgnoreSpan)]
420#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
421#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
422pub struct IdentName {
423 #[cfg_attr(feature = "__rkyv", rkyv(omit_bounds))]
424 pub span: Span,
425
426 #[cfg_attr(feature = "serde-impl", serde(rename = "value"))]
427 pub sym: Atom,
428}
429
430impl From<Atom> for IdentName {
431 fn from(sym: Atom) -> Self {
432 IdentName {
433 span: DUMMY_SP,
434 sym,
435 }
436 }
437}
438
439impl From<(Atom, Span)> for IdentName {
440 fn from((sym, span): (Atom, Span)) -> Self {
441 IdentName { span, sym }
442 }
443}
444
445bridge_from!(IdentName, Atom, &'_ str);
446bridge_from!(IdentName, Atom, Cow<'_, str>);
447bridge_from!(IdentName, Atom, String);
448bridge_from!(IdentName, Ident, &'_ BindingIdent);
449bridge_from!(IdentName, Ident, BindingIdent);
450
451impl AsRef<str> for IdentName {
452 fn as_ref(&self) -> &str {
453 &self.sym
454 }
455}
456
457impl IdentName {
458 pub const fn new(sym: Atom, span: Span) -> Self {
459 Self { span, sym }
460 }
461}
462
463impl Take for IdentName {
464 fn dummy() -> Self {
465 Default::default()
466 }
467}
468
469impl From<Ident> for IdentName {
470 fn from(i: Ident) -> Self {
471 IdentName {
472 span: i.span,
473 sym: i.sym,
474 }
475 }
476}
477
478impl From<IdentName> for Ident {
479 fn from(i: IdentName) -> Self {
480 Ident {
481 span: i.span,
482 sym: i.sym,
483 ..Default::default()
484 }
485 }
486}
487
488bridge_from!(BindingIdent, Ident, Atom);
489bridge_from!(BindingIdent, Atom, &'_ str);
490bridge_from!(BindingIdent, Atom, Cow<'_, str>);
491bridge_from!(BindingIdent, Atom, String);
492
493impl From<IdentName> for BindingIdent {
494 fn from(i: IdentName) -> Self {
495 BindingIdent {
496 id: i.into(),
497 ..Default::default()
498 }
499 }
500}
501
502pub type UnsafeId = (UnsafeAtom, SyntaxContext);
510
511pub unsafe fn unsafe_id(id: &Id) -> UnsafeId {
520 (UnsafeAtom::new(&id.0), id.1)
521}
522
523pub unsafe fn unsafe_id_from_ident(id: &Ident) -> UnsafeId {
532 (UnsafeAtom::new(&id.sym), id.ctxt)
533}
534
535pub type Id = (Atom, SyntaxContext);
537
538impl Take for Ident {
539 fn dummy() -> Self {
540 Ident::new_no_ctxt(atom!(""), DUMMY_SP)
541 }
542}
543
544impl Display for Ident {
545 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
546 write!(f, "{}{:?}", self.sym, self.ctxt)
547 }
548}
549
550impl Display for IdentName {
551 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
552 write!(f, "{}", self.sym)
553 }
554}
555
556impl Display for BindingIdent {
557 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
558 write!(f, "{}{:?}", self.sym, self.ctxt)
559 }
560}
561
562#[cfg(feature = "arbitrary")]
563#[cfg_attr(docsrs, doc(cfg(feature = "arbitrary")))]
564impl<'a> arbitrary::Arbitrary<'a> for Ident {
565 fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
566 let span = u.arbitrary()?;
567 let sym = u.arbitrary::<Atom>()?;
568
569 let optional = u.arbitrary()?;
570
571 Ok(Self {
572 span,
573 sym,
574 optional,
575 ctxt: Default::default(),
576 })
577 }
578}
579
580#[ast_node("PrivateName")]
581#[derive(Eq, Hash, EqIgnoreSpan, Default)]
582#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
583#[cfg_attr(feature = "shrink-to-fit", derive(shrink_to_fit::ShrinkToFit))]
584pub struct PrivateName {
585 pub span: Span,
586 #[cfg_attr(feature = "serde-impl", serde(rename = "value"))]
587 pub name: Atom,
588}
589
590impl AsRef<str> for Ident {
591 fn as_ref(&self) -> &str {
592 &self.sym
593 }
594}
595
596impl Ident {
597 pub const fn new(sym: Atom, span: Span, ctxt: SyntaxContext) -> Self {
598 Ident {
599 span,
600 ctxt,
601 sym,
602 optional: false,
603 }
604 }
605
606 #[inline(never)]
615 pub fn new_private(sym: Atom, span: Span) -> Self {
616 Self::new(sym, span, SyntaxContext::empty().apply_mark(Mark::new()))
617 }
618
619 pub const fn new_no_ctxt(sym: Atom, span: Span) -> Self {
620 Self::new(sym, span, SyntaxContext::empty())
621 }
622}
623
624macro_rules! gen_reserved_set {
625 ($set: ident, $set_atoms: ident, [$($item: expr),*]) => {
626 static $set: phf::Set<&str> = phf_set!($($item),*);
627 static $set_atoms: Lazy<FxHashSet<Atom>> = Lazy::new(|| {
628 let mut set = FxHashSet::with_capacity_and_hasher($set.len(), rustc_hash::FxBuildHasher);
629 $(
630 set.insert(atom!($item));
631 )*
632 set
633 });
634 };
635}
636
637gen_reserved_set!(
638 RESERVED,
639 RESERVED_ATOMS,
640 [
641 "break",
642 "case",
643 "catch",
644 "class",
645 "const",
646 "continue",
647 "debugger",
648 "default",
649 "delete",
650 "do",
651 "else",
652 "enum",
653 "export",
654 "extends",
655 "false",
656 "finally",
657 "for",
658 "function",
659 "if",
660 "import",
661 "in",
662 "instanceof",
663 "new",
664 "null",
665 "package",
666 "return",
667 "super",
668 "switch",
669 "this",
670 "throw",
671 "true",
672 "try",
673 "typeof",
674 "var",
675 "void",
676 "while",
677 "with"
678 ]
679);
680
681gen_reserved_set!(
682 RESSERVED_IN_STRICT_MODE,
683 RESSERVED_IN_STRICT_MODE_ATOMS,
684 [
685 "implements",
686 "interface",
687 "let",
688 "package",
689 "private",
690 "protected",
691 "public",
692 "static",
693 "yield"
694 ]
695);
696
697gen_reserved_set!(
698 RESSERVED_IN_STRICT_BIND,
699 RESSERVED_IN_STRICT_BIND_ATOMS,
700 ["eval", "arguments"]
701);
702
703gen_reserved_set!(
704 RESERVED_IN_ES3,
705 RESERVED_IN_ES3_ATOMS,
706 [
707 "abstract",
708 "boolean",
709 "byte",
710 "char",
711 "double",
712 "final",
713 "float",
714 "goto",
715 "int",
716 "long",
717 "native",
718 "short",
719 "synchronized",
720 "throws",
721 "transient",
722 "volatile"
723 ]
724);
725
726pub trait EsReserved {
727 fn is_reserved(&self) -> bool;
728 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool;
729 fn is_reserved_in_strict_bind(&self) -> bool;
730 fn is_reserved_in_es3(&self) -> bool;
731 fn is_reserved_in_any(&self) -> bool;
732}
733
734impl EsReserved for Atom {
735 fn is_reserved(&self) -> bool {
736 is_reserved_for_atom(self)
737 }
738
739 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
740 is_reserved_in_strict_mode_for_atom(self, is_module)
741 }
742
743 fn is_reserved_in_strict_bind(&self) -> bool {
744 is_reserved_in_strict_bind_for_atom(self)
745 }
746
747 fn is_reserved_in_es3(&self) -> bool {
748 is_reserved_in_es3_for_atom(self)
749 }
750
751 fn is_reserved_in_any(&self) -> bool {
752 is_reserved_in_any_for_atom(self)
753 }
754}
755impl EsReserved for IdentName {
756 fn is_reserved(&self) -> bool {
757 is_reserved_for_atom(&self.sym)
758 }
759
760 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
761 is_reserved_in_strict_mode_for_atom(&self.sym, is_module)
762 }
763
764 fn is_reserved_in_strict_bind(&self) -> bool {
765 is_reserved_in_strict_bind_for_atom(&self.sym)
766 }
767
768 fn is_reserved_in_es3(&self) -> bool {
769 is_reserved_in_es3_for_atom(&self.sym)
770 }
771
772 fn is_reserved_in_any(&self) -> bool {
773 is_reserved_in_any_for_atom(&self.sym)
774 }
775}
776impl EsReserved for Ident {
777 fn is_reserved(&self) -> bool {
778 is_reserved_for_atom(&self.sym)
779 }
780
781 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
782 is_reserved_in_strict_mode_for_atom(&self.sym, is_module)
783 }
784
785 fn is_reserved_in_strict_bind(&self) -> bool {
786 is_reserved_in_strict_bind_for_atom(&self.sym)
787 }
788
789 fn is_reserved_in_es3(&self) -> bool {
790 is_reserved_in_es3_for_atom(&self.sym)
791 }
792
793 fn is_reserved_in_any(&self) -> bool {
794 is_reserved_in_any_for_atom(&self.sym)
795 }
796}
797impl EsReserved for BindingIdent {
798 fn is_reserved(&self) -> bool {
799 is_reserved_for_atom(&self.sym)
800 }
801
802 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
803 is_reserved_in_strict_mode_for_atom(&self.sym, is_module)
804 }
805
806 fn is_reserved_in_strict_bind(&self) -> bool {
807 is_reserved_in_strict_bind_for_atom(&self.sym)
808 }
809
810 fn is_reserved_in_es3(&self) -> bool {
811 is_reserved_in_es3_for_atom(&self.sym)
812 }
813
814 fn is_reserved_in_any(&self) -> bool {
815 is_reserved_in_any_for_atom(&self.sym)
816 }
817}
818impl EsReserved for &'_ str {
819 fn is_reserved(&self) -> bool {
820 is_reserved_for_str(self)
821 }
822
823 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
824 is_reserved_in_strict_mode_for_str(self, is_module)
825 }
826
827 fn is_reserved_in_strict_bind(&self) -> bool {
828 is_reserved_in_strict_bind_for_str(self)
829 }
830
831 fn is_reserved_in_es3(&self) -> bool {
832 is_reserved_in_es3_for_str(self)
833 }
834
835 fn is_reserved_in_any(&self) -> bool {
836 is_reserved_in_any_for_str(self)
837 }
838}
839impl EsReserved for String {
840 fn is_reserved(&self) -> bool {
841 is_reserved_for_str(self)
842 }
843
844 fn is_reserved_in_strict_mode(&self, is_module: bool) -> bool {
845 is_reserved_in_strict_mode_for_str(self, is_module)
846 }
847
848 fn is_reserved_in_strict_bind(&self) -> bool {
849 is_reserved_in_strict_bind_for_str(self)
850 }
851
852 fn is_reserved_in_es3(&self) -> bool {
853 is_reserved_in_es3_for_str(self)
854 }
855
856 fn is_reserved_in_any(&self) -> bool {
857 is_reserved_in_any_for_str(self)
858 }
859}
860
861fn is_reserved_for_str(n: impl AsRef<str>) -> bool {
862 RESERVED.contains(n.as_ref())
863}
864
865fn is_reserved_in_strict_mode_for_str(n: impl AsRef<str>, is_module: bool) -> bool {
866 if is_module && n.as_ref() == "await" {
867 return true;
868 }
869 RESSERVED_IN_STRICT_MODE.contains(n.as_ref())
870}
871
872fn is_reserved_in_strict_bind_for_str(n: impl AsRef<str>) -> bool {
873 RESSERVED_IN_STRICT_BIND.contains(n.as_ref())
874}
875
876fn is_reserved_in_es3_for_str(n: impl AsRef<str>) -> bool {
877 RESERVED_IN_ES3.contains(n.as_ref())
878}
879
880fn is_reserved_in_any_for_str(n: impl AsRef<str>) -> bool {
881 RESERVED.contains(n.as_ref())
882 || RESSERVED_IN_STRICT_MODE.contains(n.as_ref())
883 || RESSERVED_IN_STRICT_BIND.contains(n.as_ref())
884 || RESERVED_IN_ES3.contains(n.as_ref())
885}
886
887fn is_reserved_for_atom(n: &Atom) -> bool {
888 RESERVED_ATOMS.contains(n)
889}
890
891fn is_reserved_in_strict_mode_for_atom(n: &Atom, is_module: bool) -> bool {
892 if is_module && *n == atom!("await") {
893 return true;
894 }
895 RESSERVED_IN_STRICT_MODE_ATOMS.contains(n)
896}
897
898fn is_reserved_in_strict_bind_for_atom(n: &Atom) -> bool {
899 RESSERVED_IN_STRICT_BIND_ATOMS.contains(n)
900}
901
902fn is_reserved_in_es3_for_atom(n: &Atom) -> bool {
903 RESERVED_IN_ES3_ATOMS.contains(n)
904}
905
906fn is_reserved_in_any_for_atom(n: &Atom) -> bool {
907 RESERVED_ATOMS.contains(n)
908 || RESSERVED_IN_STRICT_MODE_ATOMS.contains(n)
909 || RESSERVED_IN_STRICT_BIND_ATOMS.contains(n)
910 || RESERVED_IN_ES3_ATOMS.contains(n)
911}