cairo_lang_syntax/node/
db.rs1use 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::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 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 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}