cairo_lang_syntax/node/
db.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
use std::sync::Arc;

use cairo_lang_filesystem::db::FilesGroup;
use cairo_lang_utils::unordered_hash_map::UnorderedHashMap;
use cairo_lang_utils::{Intern, LookupIntern, Upcast};

use super::green::GreenNode;
use super::ids::{GreenId, SyntaxStablePtrId};
use super::key_fields::get_key_fields;
use super::stable_ptr::SyntaxStablePtr;
use super::{SyntaxNode, SyntaxNodeInner};

// Salsa database interface.
#[salsa::query_group(SyntaxDatabase)]
pub trait SyntaxGroup: FilesGroup + Upcast<dyn FilesGroup> {
    #[salsa::interned]
    fn intern_green(&self, field: Arc<GreenNode>) -> GreenId;
    #[salsa::interned]
    fn intern_stable_ptr(&self, field: SyntaxStablePtr) -> SyntaxStablePtrId;

    /// Returns the children of the given node.
    fn get_children(&self, node: SyntaxNode) -> Arc<[SyntaxNode]>;
}

fn get_children(db: &dyn SyntaxGroup, node: SyntaxNode) -> Arc<[SyntaxNode]> {
    let mut res = Vec::new();

    let mut offset = node.offset();
    let mut key_map = UnorderedHashMap::<_, usize>::default();
    for green_id in node.green_node(db).children() {
        let green = green_id.lookup_intern(db);
        let width = green.width();
        let kind = green.kind;
        let key_fields: Vec<GreenId> = get_key_fields(kind, green.children());
        let key_count = key_map.entry((kind, key_fields.clone())).or_default();
        let stable_ptr = SyntaxStablePtr::Child {
            parent: node.0.stable_ptr,
            kind,
            key_fields,
            index: *key_count,
        }
        .intern(db);
        *key_count += 1;
        // Create the SyntaxNode view for the child.
        res.push(SyntaxNode(Arc::new(SyntaxNodeInner {
            green: *green_id,
            offset,
            parent: Some(node.clone()),
            stable_ptr,
        })));

        offset = offset.add_width(width);
    }
    res.into()
}