Skip to main content

oxc_syntax/
node.rs

1//! AST Node ID and flags.
2
3use bitflags::bitflags;
4
5use oxc_allocator::{Allocator, CloneIn, Dummy};
6use oxc_ast_macros::ast;
7use oxc_index::define_nonmax_u32_index_type;
8
9define_nonmax_u32_index_type! {
10    /// AST Node ID
11    #[ast]
12    #[clone_in(default)]
13    #[content_eq(skip)]
14    #[estree(skip)]
15    pub struct NodeId;
16}
17
18impl NodeId {
19    /// Mock node id.
20    ///
21    /// This is used for synthetically-created AST nodes, among other things.
22    pub const DUMMY: Self = NodeId::new(0);
23
24    /// Node id of the Program node.
25    pub const ROOT: Self = NodeId::new(0);
26}
27
28impl Default for NodeId {
29    #[inline]
30    fn default() -> Self {
31        Self::DUMMY
32    }
33}
34
35impl<'a> Dummy<'a> for NodeId {
36    #[inline]
37    fn dummy(_: &'a Allocator) -> Self {
38        Self::DUMMY
39    }
40}
41
42impl<'alloc> CloneIn<'alloc> for NodeId {
43    type Cloned = Self;
44
45    fn clone_in(&self, _: &'alloc Allocator) -> Self {
46        // `clone_in` should never reach this, because `CloneIn` skips `node_id` field
47        unreachable!();
48    }
49
50    #[inline]
51    fn clone_in_with_semantic_ids(&self, _: &'alloc Allocator) -> Self {
52        *self
53    }
54}
55
56bitflags! {
57    /// Contains additional information about an AST node.
58    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
59    pub struct NodeFlags: u8 {
60        /// Set if the Node has a JSDoc comment attached
61        const JSDoc     = 1 << 0;
62        /// Set on Nodes inside classes
63        const Class     = 1 << 1;
64        /// Set functions containing yield statements
65        const HasYield  = 1 << 2;
66        /// Set for `export { specifier }`
67        const ExportSpecifier  = 1 << 3;
68    }
69}
70
71impl NodeFlags {
72    /// Returns `true` if this node has a JSDoc comment attached to it.
73    #[inline]
74    pub fn has_jsdoc(self) -> bool {
75        self.contains(Self::JSDoc)
76    }
77
78    /// Returns `true` if this node is inside a class.
79    #[inline]
80    pub fn has_class(self) -> bool {
81        self.contains(Self::Class)
82    }
83
84    /// Returns `true` if this function has a yield statement.
85    #[inline]
86    pub fn has_yield(self) -> bool {
87        self.contains(Self::HasYield)
88    }
89
90    /// Returns `true` if this function has an export specifier.
91    #[inline]
92    pub fn has_export_specifier(self) -> bool {
93        self.contains(Self::ExportSpecifier)
94    }
95}