cairo_lang_syntax/node/
db.rs

1use std::sync::Arc;
2
3use cairo_lang_filesystem::db::FilesGroup;
4use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
5use cairo_lang_utils::{Intern, LookupIntern, Upcast};
6
7use super::green::GreenNode;
8use super::ids::{GreenId, SyntaxStablePtrId};
9use super::key_fields::get_key_fields;
10use super::stable_ptr::SyntaxStablePtr;
11use super::{SyntaxNode, SyntaxNodeInner};
12
13// Salsa database interface.
14#[salsa::query_group(SyntaxDatabase)]
15pub trait SyntaxGroup: FilesGroup + Upcast<dyn FilesGroup> {
16    #[salsa::interned]
17    fn intern_green(&self, field: Arc<GreenNode>) -> GreenId;
18    #[salsa::interned]
19    fn intern_stable_ptr(&self, field: SyntaxStablePtr) -> SyntaxStablePtrId;
20
21    /// Returns the children of the given node.
22    fn get_children(&self, node: SyntaxNode) -> Arc<[SyntaxNode]>;
23}
24
25fn get_children(db: &dyn SyntaxGroup, node: SyntaxNode) -> Arc<[SyntaxNode]> {
26    let mut res = Vec::new();
27
28    let mut offset = node.offset();
29    let mut key_map = UnorderedHashMap::<_, usize>::default();
30    for green_id in node.green_node(db).children() {
31        let green = green_id.lookup_intern(db);
32        let width = green.width();
33        let kind = green.kind;
34        let key_fields: Vec<GreenId> = get_key_fields(kind, green.children());
35        let key_count = key_map.entry((kind, key_fields.clone())).or_default();
36        let stable_ptr = SyntaxStablePtr::Child {
37            parent: node.0.stable_ptr,
38            kind,
39            key_fields,
40            index: *key_count,
41        }
42        .intern(db);
43        *key_count += 1;
44        // Create the SyntaxNode view for the child.
45        res.push(SyntaxNode(Arc::new(SyntaxNodeInner {
46            green: *green_id,
47            offset,
48            parent: Some(node.clone()),
49            stable_ptr,
50        })));
51
52        offset = offset.add_width(width);
53    }
54    res.into()
55}