mxmlextrema_as3parser/tree/
node_assignment.rs1use crate::ns::*;
2use by_address::ByAddress;
3
4const LARGE_BYTES: usize = 26_000;
5
6pub struct NodeAssignment<S> {
12 common: NodeAssignment1<S>,
13 large_units: RefCell<HashMap<ByAddress<Rc<CompilationUnit>>, NodeAssignment1<S>>>,
14}
15
16impl<S: Clone> NodeAssignment<S> {
17 pub fn new() -> Self {
18 Self {
19 common: NodeAssignment1::new(),
20 large_units: RefCell::new(HashMap::new()),
21 }
22 }
23
24 pub fn clear(&self) {
25 self.common.clear();
26 self.large_units.borrow_mut().clear();
27 }
28}
29
30pub trait NodeAssignmentMethod<T, S: Clone> {
34 fn get(&self, node: &Rc<T>) -> Option<S>;
35 fn set(&self, node: &Rc<T>, symbol: Option<S>);
36 fn delete(&self, node: &Rc<T>) -> bool;
37 fn has(&self, node: &Rc<T>) -> bool;
38}
39
40macro impl_semantics_with_loc_call {
41 (struct $node_assignment_id:ident, $($nodetype:ident),*$(,)?) => {
42 $(
43 impl<S: Clone> NodeAssignmentMethod<$nodetype, S> for $node_assignment_id<S> {
44 fn get(&self, node: &Rc<$nodetype>) -> Option<S> {
45 let cu = node.location().compilation_unit();
46 if cu.text().len() < LARGE_BYTES {
47 self.common.get(node)
48 } else {
49 let large_units = self.large_units.borrow();
50 let m1 = large_units.get(&ByAddress(cu));
51 m1.and_then(|m1| m1.get(node))
52 }
53 }
54 fn set(&self, node: &Rc<$nodetype>, symbol: Option<S>) {
55 let cu = node.location().compilation_unit();
56 if cu.text().len() < LARGE_BYTES {
57 self.common.set(node, symbol);
58 } else {
59 let mut large_units = self.large_units.borrow_mut();
60 let m1 = large_units.get_mut(&ByAddress(cu.clone()));
61 if let Some(m1) = m1 {
62 m1.set(node, symbol);
63 } else {
64 let m1 = NodeAssignment1::new();
65 m1.set(node, symbol);
66 large_units.insert(ByAddress(cu), m1);
67 }
68 }
69 }
70 fn delete(&self, node: &Rc<$nodetype>) -> bool {
71 let cu = node.location().compilation_unit();
72 if cu.text().len() < LARGE_BYTES {
73 self.common.delete(node)
74 } else {
75 let mut large_units = self.large_units.borrow_mut();
76 let m1 = large_units.get_mut(&ByAddress(cu));
77 m1.map(|m1| m1.delete(node)).unwrap_or(false)
78 }
79 }
80 fn has(&self, node: &Rc<$nodetype>) -> bool {
81 let cu = node.location().compilation_unit();
82 if cu.text().len() < LARGE_BYTES {
83 self.common.has(node)
84 } else {
85 let large_units = self.large_units.borrow();
86 let m1 = large_units.get(&ByAddress(cu));
87 m1.map(|m1| m1.has(node)).unwrap_or(false)
88 }
89 }
90 }
91 )*
92 },
93}
94
95macro impl_semantics_with_loc_field {
96 (struct $node_assignment_id:ident, $($nodetype:ident),*$(,)?) => {
97 $(
98 impl<S: Clone> NodeAssignmentMethod<$nodetype, S> for $node_assignment_id<S> {
99 fn get(&self, node: &Rc<$nodetype>) -> Option<S> {
100 let cu = node.location.compilation_unit();
101 if cu.text().len() < LARGE_BYTES {
102 self.common.get(node)
103 } else {
104 let large_units = self.large_units.borrow();
105 let m1 = large_units.get(&ByAddress(cu));
106 m1.and_then(|m1| m1.get(node))
107 }
108 }
109 fn set(&self, node: &Rc<$nodetype>, symbol: Option<S>) {
110 let cu = node.location.compilation_unit();
111 if cu.text().len() < LARGE_BYTES {
112 self.common.set(node, symbol);
113 } else {
114 let mut large_units = self.large_units.borrow_mut();
115 let m1 = large_units.get_mut(&ByAddress(cu.clone()));
116 if let Some(m1) = m1 {
117 m1.set(node, symbol);
118 } else {
119 let m1 = NodeAssignment1::new();
120 m1.set(node, symbol);
121 large_units.insert(ByAddress(cu), m1);
122 }
123 }
124 }
125 fn delete(&self, node: &Rc<$nodetype>) -> bool {
126 let cu = node.location.compilation_unit();
127 if cu.text().len() < LARGE_BYTES {
128 self.common.delete(node)
129 } else {
130 let mut large_units = self.large_units.borrow_mut();
131 let m1 = large_units.get_mut(&ByAddress(cu));
132 m1.map(|m1| m1.delete(node)).unwrap_or(false)
133 }
134 }
135 fn has(&self, node: &Rc<$nodetype>) -> bool {
136 let cu = node.location.compilation_unit();
137 if cu.text().len() < LARGE_BYTES {
138 self.common.has(node)
139 } else {
140 let large_units = self.large_units.borrow();
141 let m1 = large_units.get(&ByAddress(cu));
142 m1.map(|m1| m1.has(node)).unwrap_or(false)
143 }
144 }
145 }
146 )*
147 },
148}
149
150macro impl_semantics_1 {
151 (struct $node_assignment_1_id:ident, fn $new_id:ident, fn $clear_id:ident, $($nodetype:ident),*$(,)?) => {
152 #[allow(non_snake_case)]
153 struct $node_assignment_1_id<S> {
154 $($nodetype: RefCell<HashMap<NodeAsKey<Rc<$nodetype>>, Option<S>>>,)*
155 }
156
157 impl<S: Clone> $node_assignment_1_id<S> {
158 pub fn $new_id() -> Self {
159 Self {
160 $($nodetype: RefCell::new(HashMap::new()),)*
161 }
162 }
163
164 pub fn $clear_id(&self) {
165 $(self.$nodetype.borrow_mut().clear();)*
166 }
167 }
168
169 $(
170 impl<S: Clone> NodeAssignmentMethod<$nodetype, S> for $node_assignment_1_id<S> {
171 fn get(&self, node: &Rc<$nodetype>) -> Option<S> {
172 let m = self.$nodetype.borrow();
173 let v = m.get(&NodeAsKey(node.clone()));
174 if let Some(v) = v {
175 v.clone()
176 } else {
177 None
178 }
179 }
180 fn set(&self, node: &Rc<$nodetype>, symbol: Option<S>) {
181 self.$nodetype.borrow_mut().insert(NodeAsKey(node.clone()), symbol);
182 }
183 fn delete(&self, node: &Rc<$nodetype>) -> bool {
184 self.$nodetype.borrow_mut().remove(&NodeAsKey(node.clone())).is_some()
185 }
186 fn has(&self, node: &Rc<$nodetype>) -> bool {
187 self.$nodetype.borrow().contains_key(&NodeAsKey(node.clone()))
188 }
189 }
190 )*
191 },
192}
193
194impl_semantics_with_loc_call!(
195 struct NodeAssignment,
196 Expression,
197 InitializerField,
198 Directive,
199 MxmlContent,
200 CssDirective,
201 CssMediaQueryCondition,
202 CssSelectorCondition,
203 CssPropertyValue,
204 CssSelector,
205 AsdocReference,
206);
207
208impl_semantics_with_loc_field!(
209 struct NodeAssignment,
210 FunctionCommon,
211 Block,
212 Program,
213 PackageDefinition,
214 SimpleVariableDefinition,
215 Metadata,
216 MetadataEntry,
217 Mxml,
218 MxmlElement,
219 MxmlAttribute,
220 CssProperty,
221 CssRule,
222 CssDocument,
223 QualifiedIdentifier,
224);
225
226impl_semantics_1!(
227 struct NodeAssignment1,
228 fn new,
229 fn clear,
230 Expression,
231 InitializerField,
232 Directive,
233 FunctionCommon,
234 Block,
235 Program,
236 PackageDefinition,
237 SimpleVariableDefinition,
238 QualifiedIdentifier,
239 Metadata,
240 MetadataEntry,
241 AsdocReference,
242 Mxml,
243 MxmlContent,
244 MxmlElement,
245 MxmlAttribute,
246 CssDirective,
247 CssRule,
248 CssMediaQueryCondition,
249 CssSelectorCondition,
250 CssPropertyValue,
251 CssSelector,
252 CssProperty,
253 CssDocument,
254);