arrow_parser/
lifetime_analysis.rs1use crate::ast::Expression;
2use crate::ast::LiteralTemplatePart;
3use crate::ast::Module;
4use crate::ast::ModuleItem;
5use crate::ast::Node;
6use crate::ast::Statement;
7use crate::symbol::Scope;
8use crate::symbol::ScopeType;
9
10pub struct LifetimeAnalyser {}
14
15impl LifetimeAnalyser {
16 fn process_variable(&mut self, scope: &Scope, name: &str) {
17 if let Some((decl_scope, symbol)) = scope.find_symbol_declaration(name) {
18 if let Some(decl_closure) = decl_scope.find_nearest_closure() {
20 if let Some(usage_closure) = scope.find_nearest_closure() {
22 if decl_closure != usage_closure {
24 decl_scope.borrow_mut().boxed_var_decls.insert(symbol);
26 let mut cur = usage_closure;
27 while cur != decl_scope {
28 if cur.typ == ScopeType::Closure {
29 cur.borrow_mut().boxed_var_captures.insert(symbol);
30 };
31 cur = cur.parent().unwrap();
32 }
33 };
34 };
35 };
36 };
37 }
38
39 fn analyse_expression(&mut self, expr: &Node<Expression>) {
40 match expr.stx.as_ref() {
41 Expression::Binary { left, right, .. } => {
42 self.analyse_expression(left);
43 self.analyse_expression(right);
44 }
45 Expression::BindMethod { arguments, .. } => {
46 for arg in arguments {
47 self.analyse_expression(arg);
48 }
49 }
50 Expression::Block { statements, result } => {
51 for stmt in statements {
52 self.analyse_statement(stmt);
53 }
54 if let Some(result) = result {
55 self.analyse_expression(result);
56 };
57 }
58 Expression::CallMethod {
59 object, arguments, ..
60 } => {
61 self.analyse_expression(object);
62 for arg in arguments {
63 self.analyse_expression(arg);
64 }
65 }
66 Expression::CallValue {
67 callee, arguments, ..
68 } => {
69 self.analyse_expression(callee);
70 for arg in arguments {
71 self.analyse_expression(arg);
72 }
73 }
74 Expression::Cast { value, .. } => {
75 self.analyse_expression(value);
76 }
77 Expression::Field { object, .. } => {
78 self.analyse_expression(object);
79 }
80 Expression::Index { object, index, .. } => {
81 self.analyse_expression(object);
82 self.analyse_expression(index);
83 }
84 Expression::If {
85 condition,
86 consequent,
87 alternate,
88 } => {
89 self.analyse_expression(condition);
90 self.analyse_expression(consequent);
91 if let Some(alternate) = alternate {
92 self.analyse_expression(alternate);
93 };
94 }
95 Expression::Closure { body, .. } => {
96 self.analyse_expression(body);
97 }
98 Expression::LiteralArray { entries } => {
99 for ent in entries {
100 self.analyse_expression(ent);
101 }
102 }
103 Expression::LiteralBoolean { .. } => {}
104 Expression::LiteralFloat { .. } => {}
105 Expression::LiteralInt { .. } => {}
106 Expression::LiteralNone { .. } => {}
107 Expression::LiteralObject { fields } => {
108 for (_, value) in fields {
109 self.analyse_expression(value);
110 }
111 }
112 Expression::LiteralTemplateExpr { parts } => {
113 for part in parts {
114 match part {
115 LiteralTemplatePart::Substitution(v) => {
116 self.analyse_expression(v);
117 }
118 LiteralTemplatePart::String(_) => {}
119 };
120 }
121 }
122 Expression::Unary { operand, .. } => {
123 self.analyse_expression(operand);
124 }
125 Expression::Var { name } => {
126 self.process_variable(&expr.scope, name);
127 }
128 }
129 }
130
131 fn analyse_statement(&mut self, stmt: &Node<Statement>) {
132 match stmt.stx.as_ref() {
133 Statement::Break => {}
134 Statement::Continue => {}
135 Statement::Expression { expression } => {
136 self.analyse_expression(expression);
137 }
138 Statement::FieldAssign { object, value, .. } => {
139 self.analyse_expression(object);
140 self.analyse_expression(value);
141 }
142 Statement::For { iterable, body, .. } => {
143 self.analyse_expression(iterable);
144 self.analyse_expression(body);
145 }
146 Statement::IndexAssign {
147 object,
148 index,
149 value,
150 ..
151 } => {
152 self.analyse_expression(object);
153 self.analyse_expression(index);
154 self.analyse_expression(value);
155 }
156 Statement::Let { value, .. } => {
157 self.analyse_expression(value);
158 }
159 Statement::Loop { body } => {
160 self.analyse_expression(body);
161 }
162 Statement::Return { value } => {
163 if let Some(value) = value {
164 self.analyse_expression(value);
165 };
166 }
167 Statement::VarAssign { variable, value } => {
168 self.analyse_expression(value);
169 self.process_variable(&stmt.scope, &variable);
170 }
171 };
172 }
173
174 fn analyse_module_item(&mut self, item: &Node<ModuleItem>) {
175 match item.stx.as_ref() {
176 ModuleItem::Impl { methods, .. } => {
177 for (_, method) in methods {
178 self.analyse_expression(method);
179 }
180 }
181 ModuleItem::Statement { statement } => {
182 self.analyse_statement(statement);
183 }
184 };
185 }
186
187 pub fn analyse_lifetimes(&mut self, module: &Module) {
188 for item in module.items.iter() {
189 self.analyse_module_item(item);
190 }
191 }
192}