cairo_lang_syntax/node/
ids.rs

1use cairo_lang_filesystem::ids::FileId;
2use cairo_lang_filesystem::span::TextWidth;
3use cairo_lang_utils::define_short_id;
4use salsa::Database;
5
6use super::SyntaxNode;
7use super::green::GreenNode;
8use super::kind::SyntaxKind;
9use crate::node::stable_ptr::SyntaxStablePtr;
10
11define_short_id!(GreenId, GreenNode<'db>);
12impl<'a> GreenId<'a> {
13    /// Returns the width of the node of this green id.
14    pub fn width(&self, db: &dyn Database) -> TextWidth {
15        match &self.long(db).details {
16            super::green::GreenNodeDetails::Token(text) => TextWidth::from_str(text.long(db)),
17            super::green::GreenNodeDetails::Node { width, .. } => *width,
18        }
19    }
20}
21
22define_short_id!(SyntaxStablePtrId, SyntaxStablePtr<'db>);
23impl<'a> SyntaxStablePtrId<'a> {
24    /// Lookups a syntax node using a stable syntax pointer.
25    /// Should only be called on the root from which the stable pointer was generated.
26    pub fn lookup(&self, db: &'a dyn Database) -> SyntaxNode<'a> {
27        let ptr = self.long(db).clone();
28        match ptr {
29            SyntaxStablePtr::Root(file_id, green) => SyntaxNode::new_root(db, file_id, green),
30            SyntaxStablePtr::Child { parent, .. } => {
31                let parent = parent.lookup(db);
32                for child in parent.get_children(db).iter() {
33                    if child.stable_ptr(db) == *self {
34                        return *child;
35                    }
36                }
37                unreachable!();
38            }
39        }
40    }
41    pub fn file_id(&self, db: &'a dyn Database) -> FileId<'a> {
42        let ptr = self.long(db);
43        match ptr {
44            SyntaxStablePtr::Root(file_id, _) => *file_id,
45            SyntaxStablePtr::Child { parent, .. } => parent.file_id(db),
46        }
47    }
48    /// Returns the stable pointer of the parent of this stable pointer.
49    /// Assumes that the parent exists (that is, `self` is not the root). Panics otherwise.
50    pub fn parent<'r: 'a>(&self, db: &'r dyn Database) -> SyntaxStablePtrId<'a> {
51        let SyntaxStablePtr::Child { parent, .. } = self.long(db).clone() else { panic!() };
52        parent
53    }
54    /// Returns the stable pointer of the `n`th parent of this stable pointer.
55    /// n = 0: returns itself.
56    /// n = 1: return the parent.
57    /// n = 2: return the grandparent.
58    /// And so on...
59    /// Assumes that the `n`th parent exists. Panics otherwise.
60    pub fn nth_parent<'r: 'a>(&self, db: &'r dyn Database, n: usize) -> SyntaxStablePtrId<'a> {
61        let mut ptr = *self;
62        for _ in 0..n {
63            ptr = ptr.parent(db);
64        }
65        ptr
66    }
67    /// Returns the kind of this stable pointer.
68    /// Assumes that `self` is not the root. Panics otherwise.
69    pub fn kind(&self, db: &'a dyn Database) -> SyntaxKind {
70        let SyntaxStablePtr::Child { kind, .. } = self.long(db).clone() else { panic!() };
71        kind
72    }
73}