pipeline_script/postprocessor/
module_merger.rs

1use crate::ast::data::Data;
2use crate::ast::NodeTrait;
3use crate::postprocessor::{Stage, VisitResult, Visitor};
4use std::cell::RefCell;
5use std::rc::Rc;
6
7pub struct ModuleMerger {
8    global_variables: Rc<RefCell<Vec<String>>>,
9    local_variables: Rc<RefCell<Vec<String>>>,
10    module_name: Rc<RefCell<Option<String>>>,
11    module_functions: Rc<RefCell<Vec<String>>>,
12}
13
14impl ModuleMerger {
15    pub fn new() -> Self {
16        Self {
17            global_variables: Rc::new(RefCell::new(vec![])),
18            local_variables: Rc::new(RefCell::new(vec![])),
19            module_name: Rc::new(RefCell::new(None)),
20            module_functions: Rc::new(RefCell::new(vec![])),
21        }
22    }
23    pub fn is_module_function(&self, name: &str) -> bool {
24        self.module_functions.borrow().contains(&name.into())
25    }
26}
27
28impl Default for ModuleMerger {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl Visitor for ModuleMerger {
35    fn stage(&self) -> Stage {
36        todo!()
37    }
38
39    fn match_id(&self, id: &str) -> bool {
40        [
41            "Module",
42            "Function",
43            "ValDecl",
44            "VarDecl",
45            "Expr:Variable",
46            "Expr:FnCall",
47        ]
48        .contains(&id)
49    }
50
51    fn visit(&self, node: &mut (impl NodeTrait + ?Sized)) -> VisitResult
52    where
53        Self: Sized,
54    {
55        let id = node.get_id();
56        match id {
57            "Module" => {
58                let data = node.get_data("global_variables").unwrap();
59                let global_variables = data.as_array().unwrap();
60                for i in global_variables {
61                    self.global_variables
62                        .borrow_mut()
63                        .push(i.as_str().unwrap().to_string());
64                }
65                let data = node.get_data("functions").unwrap();
66                let functions = data.as_array().unwrap();
67                for i in functions {
68                    self.module_functions
69                        .borrow_mut()
70                        .push(i.as_str().unwrap().to_string());
71                }
72                let name = node.get_data("name").unwrap();
73                self.module_name
74                    .borrow_mut()
75                    .replace(name.as_str().unwrap().to_string());
76            }
77            "ValDecl" => {
78                let name = node.get_data("name").unwrap();
79                let name = name.as_str().unwrap();
80                let module_name = self.module_name.borrow();
81                let module_name = module_name.as_ref().unwrap();
82                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
83            }
84            "VarDecl" => {
85                let name = node.get_data("name").unwrap();
86                let name = name.as_str().unwrap();
87                let module_name = self.module_name.borrow();
88                let module_name = module_name.as_ref().unwrap();
89                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
90            }
91            "Expr:Variable" => {
92                let name = node.get_data("name").unwrap();
93                let name = name.as_str().unwrap().to_string();
94                // 判断是否是全局block
95                if self.local_variables.borrow().contains(&name) {
96                    return VisitResult::Continue;
97                }
98                if !self.global_variables.borrow().contains(&name) {
99                    return VisitResult::Continue;
100                }
101                let module_name = self.module_name.borrow();
102                let module_name = module_name.as_ref().unwrap();
103                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
104            }
105            "Expr:FnCall" => {
106                let name = node.get_data("name").unwrap();
107                let name = name.as_str().unwrap();
108                if !self.is_module_function(name) {
109                    return VisitResult::Continue;
110                }
111                let module_name = self.module_name.borrow();
112                let module_name = module_name.as_ref().unwrap();
113                node.set_data("name", Data::String(format!("{}:{}", module_name, name)));
114            }
115            t => {
116                dbg!(t);
117            }
118        }
119        VisitResult::Continue
120    }
121}