cairo_lang_syntax/node/
ids.rs

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