teo_parser/ast/
source.rs

1use std::collections::{BTreeMap, BTreeSet};
2use std::sync::Arc;
3use maplit::btreeset;
4use crate::availability::Availability;
5use crate::ast::config::Config;
6use crate::ast::decorator::Decorator;
7use crate::ast::empty_decorator::EmptyDecorator;
8use crate::ast::import::Import;
9use crate::ast::namespace::Namespace;
10use crate::ast::node::Node;
11use crate::format::Writer;
12use crate::traits::write::Write;
13
14#[derive(Debug)]
15pub struct Source {
16    pub id: usize,
17    pub builtin: bool,
18    pub file_path: String,
19    pub children: BTreeMap<usize, Node>,
20    pub references: SourceReferences,
21}
22
23impl Source {
24
25    pub fn new(id: usize, builtin: bool, file_path: String, children: BTreeMap<usize, Node>, references: SourceReferences) -> Self {
26        Self {
27            id,
28            builtin,
29            file_path,
30            children,
31            references,
32        }
33    }
34
35    pub fn children(&self) -> Vec<&Node> {
36        self.children.values().collect()
37    }
38
39    pub fn imports(&self) -> Vec<&Import> {
40        self.references.imports.iter().map(|id| self.children.get(id).unwrap().as_import().unwrap()).collect()
41    }
42
43    pub fn namespaces(&self) -> Vec<&Namespace> {
44        self.references.namespaces.iter().map(|m| self.get_namespace(*m).unwrap()).collect()
45    }
46
47    pub fn unattached_decorators(&self) -> Vec<&Decorator> {
48        self.references.unattached_decorators.iter().map(|m| self.get_unattached_decorator(*m).unwrap()).collect()
49    }
50
51    pub fn empty_decorators(&self) -> Vec<&EmptyDecorator> {
52        self.references.empty_decorators.iter().map(|m| self.children.get(m).unwrap().as_empty_decorator().unwrap()).collect()
53    }
54
55    pub fn get_connector(&self) -> Option<&Config> {
56        self.references.connector.map(|id| self.children.get(&id).unwrap().as_config().unwrap())
57    }
58
59    pub fn get_namespace(&self, id: usize) -> Option<&Namespace> {
60        self.children.get(&id).unwrap().as_namespace()
61    }
62
63    pub fn get_unattached_decorator(&self, id: usize) -> Option<&Decorator> {
64        self.children.get(&id).unwrap().as_decorator()
65    }
66
67    pub fn find_top_by_id(&self, id: usize) -> Option<&Node> {
68        self.children.get(&id)
69    }
70
71    pub fn find_top_by_name(&self, name: &str, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
72        self.children().iter().find(|t| {
73            if let Some(n) = t.name() {
74                (n == name) && filter(t) && t.available_test(availability)
75            } else {
76                false
77            }
78        }).map(|t| *t)
79    }
80
81    pub fn find_top_by_path(&self, path: &Vec<usize>) -> Option<&Node> {
82        if *path.first().unwrap() != self.id {
83            return None;
84        }
85        if path.len() < 2 {
86            return None;
87        } else if path.len() == 2 {
88            self.find_top_by_id(*path.get(1).unwrap())
89        } else {
90            let mut path_for_ns = path.clone();
91            path_for_ns.remove(path_for_ns.len() - 1);
92            let child_ns = self.find_child_namespace_by_path(&path_for_ns);
93            if let Some(child_ns) = child_ns {
94                child_ns.find_top_by_id(*path.last().unwrap())
95            } else {
96                None
97            }
98        }
99    }
100
101    pub fn find_node_by_string_path(&self, path: &Vec<&str>, filter: &Arc<dyn Fn(&Node) -> bool>, availability: Availability) -> Option<&Node> {
102        if path.len() == 0 {
103            return None;
104        } else if path.len() == 1 {
105            self.find_top_by_name(path.get(0).unwrap(), filter, availability)
106        } else {
107            let mut path_for_ns = path.clone();
108            path_for_ns.remove(path_for_ns.len() - 1);
109            let child_ns = self.find_child_namespace_by_string_path(&path_for_ns);
110            if let Some(child_ns) = child_ns {
111                child_ns.find_top_by_name(path.last().unwrap(), filter, availability)
112            } else {
113                None
114            }
115        }
116    }
117
118    pub fn parent_namespace_for_namespace(&self, namespace: &Namespace) -> Option<&Namespace> {
119        self.find_child_namespace_by_string_path(&namespace.parent_str_path())
120    }
121
122    pub fn find_child_namespace_by_path(&self, path: &Vec<usize>) -> Option<&Namespace> {
123        if *path.first().unwrap() != self.id {
124            return None;
125        }
126        let mut ns = self.get_namespace(*path.get(1).unwrap());
127        for (index, item) in path.iter().enumerate() {
128            if index > 1 {
129                if let Some(ns_ref) = ns {
130                    ns = ns_ref.get_namespace(*item);
131                } else {
132                    return None;
133                }
134            }
135        }
136        ns
137    }
138
139    pub fn find_child_namespace_by_string_path(&self, path: &Vec<&str>) -> Option<&Namespace> {
140        if path.len() == 0 { return None }
141        let mut ns = self.namespaces().iter().find(|n| n.identifier().name() == *path.get(0).unwrap()).map(|r| *r);
142        for (index, item) in path.iter().enumerate() {
143            if index > 0 {
144                if let Some(ns_ref) = ns {
145                    ns = ns_ref.namespaces().iter().find(|n| n.identifier().name() == *item).map(|r| *r);
146                } else {
147                    return None;
148                }
149            }
150        }
151        ns
152    }
153}
154
155#[derive(Debug)]
156pub struct SourceReferences {
157    pub imports: BTreeSet<usize>,
158    pub connector: Option<usize>,
159    pub constants: BTreeSet<usize>,
160    pub configs: BTreeSet<usize>,
161    pub enums: BTreeSet<usize>,
162    pub models: BTreeSet<usize>,
163    pub data_sets: BTreeSet<usize>,
164    pub interfaces: BTreeSet<usize>,
165    pub namespaces: BTreeSet<usize>,
166    pub config_declarations: BTreeSet<usize>,
167    pub decorator_declarations: BTreeSet<usize>,
168    pub pipeline_item_declarations: BTreeSet<usize>,
169    pub middlewares: BTreeSet<usize>,
170    pub handlers: BTreeSet<usize>,
171    pub handler_groups: BTreeSet<usize>,
172    pub use_middlewares_block: Option<usize>,
173    pub empty_decorators: BTreeSet<usize>,
174    pub unattached_decorators: BTreeSet<usize>,
175    pub synthesized_shape_declarations: BTreeSet<usize>,
176    pub handler_template_declarations: BTreeSet<usize>,
177}
178
179impl SourceReferences {
180
181    pub fn new() -> Self {
182        Self {
183            imports: btreeset!{},
184            connector: None,
185            constants: btreeset!{},
186            configs: btreeset!{},
187            enums: btreeset!{},
188            models: btreeset!{},
189            namespaces: btreeset!{},
190            interfaces: btreeset!{},
191            data_sets: btreeset!{},
192            config_declarations: btreeset!{},
193            decorator_declarations: btreeset!{},
194            pipeline_item_declarations: btreeset!{},
195            middlewares: btreeset!{},
196            handlers: btreeset!{},
197            handler_groups: btreeset!{},
198            use_middlewares_block: None,
199            empty_decorators: btreeset! {},
200            unattached_decorators: btreeset! {},
201            synthesized_shape_declarations: btreeset! {},
202            handler_template_declarations: btreeset! {},
203        }
204    }
205}
206
207impl Write for Source {
208    fn write<'a>(&'a self, writer: &mut Writer<'a>) {
209        writer.write_children(self, self.children.values())
210    }
211}