1use crate::{
2 concurrent_slab::ConcurrentSlab,
3 language::parsed::{
4 AbiDeclaration, ConfigurableDeclaration, ConstGenericDeclaration, ConstantDeclaration,
5 EnumDeclaration, EnumVariant, FunctionDeclaration, ImplSelfOrTrait, StorageDeclaration,
6 StructDeclaration, TraitDeclaration, TraitFn, TraitTypeDeclaration, TypeAliasDeclaration,
7 VariableDeclaration,
8 },
9};
10
11use std::sync::Arc;
12use sway_types::{ProgramId, SourceId, Spanned};
13
14use super::parsed_id::ParsedDeclId;
15
16#[derive(Clone, Debug, Default)]
18pub struct ParsedDeclEngine {
19 variable_slab: ConcurrentSlab<VariableDeclaration>,
20 function_slab: ConcurrentSlab<FunctionDeclaration>,
21 trait_slab: ConcurrentSlab<TraitDeclaration>,
22 trait_fn_slab: ConcurrentSlab<TraitFn>,
23 trait_type_slab: ConcurrentSlab<TraitTypeDeclaration>,
24 impl_self_or_trait_slab: ConcurrentSlab<ImplSelfOrTrait>,
25 struct_slab: ConcurrentSlab<StructDeclaration>,
26 storage_slab: ConcurrentSlab<StorageDeclaration>,
27 abi_slab: ConcurrentSlab<AbiDeclaration>,
28 constant_slab: ConcurrentSlab<ConstantDeclaration>,
29 configurable_slab: ConcurrentSlab<ConfigurableDeclaration>,
30 const_generic_slab: ConcurrentSlab<ConstGenericDeclaration>,
31 enum_slab: ConcurrentSlab<EnumDeclaration>,
32 enum_variant_slab: ConcurrentSlab<EnumVariant>,
33 type_alias_slab: ConcurrentSlab<TypeAliasDeclaration>,
34}
35
36pub trait ParsedDeclEngineGet<I, U> {
37 fn get(&self, index: &I) -> Arc<U>;
38}
39
40pub trait ParsedDeclEngineInsert<T> {
41 fn insert(&self, decl: T) -> ParsedDeclId<T>;
42}
43
44#[allow(unused)]
45pub trait ParsedDeclEngineReplace<T> {
46 fn replace(&self, index: ParsedDeclId<T>, decl: T);
47}
48
49#[allow(unused)]
50pub trait ParsedDeclEngineIndex<T>:
51 ParsedDeclEngineGet<ParsedDeclId<T>, T> + ParsedDeclEngineInsert<T> + ParsedDeclEngineReplace<T>
52{
53}
54
55macro_rules! decl_engine_get {
56 ($slab:ident, $decl:ty) => {
57 impl ParsedDeclEngineGet<ParsedDeclId<$decl>, $decl> for ParsedDeclEngine {
58 fn get(&self, index: &ParsedDeclId<$decl>) -> Arc<$decl> {
59 self.$slab.get(index.inner())
60 }
61 }
62 };
63}
64decl_engine_get!(variable_slab, VariableDeclaration);
65decl_engine_get!(function_slab, FunctionDeclaration);
66decl_engine_get!(trait_slab, TraitDeclaration);
67decl_engine_get!(trait_fn_slab, TraitFn);
68decl_engine_get!(trait_type_slab, TraitTypeDeclaration);
69decl_engine_get!(impl_self_or_trait_slab, ImplSelfOrTrait);
70decl_engine_get!(struct_slab, StructDeclaration);
71decl_engine_get!(storage_slab, StorageDeclaration);
72decl_engine_get!(abi_slab, AbiDeclaration);
73decl_engine_get!(constant_slab, ConstantDeclaration);
74decl_engine_get!(configurable_slab, ConfigurableDeclaration);
75decl_engine_get!(const_generic_slab, ConstGenericDeclaration);
76decl_engine_get!(enum_slab, EnumDeclaration);
77decl_engine_get!(enum_variant_slab, EnumVariant);
78decl_engine_get!(type_alias_slab, TypeAliasDeclaration);
79
80macro_rules! decl_engine_insert {
81 ($slab:ident, $decl:ty) => {
82 impl ParsedDeclEngineInsert<$decl> for ParsedDeclEngine {
83 fn insert(&self, decl: $decl) -> ParsedDeclId<$decl> {
84 ParsedDeclId::new(self.$slab.insert(decl))
85 }
86 }
87 };
88}
89
90decl_engine_insert!(variable_slab, VariableDeclaration);
91decl_engine_insert!(function_slab, FunctionDeclaration);
92decl_engine_insert!(trait_slab, TraitDeclaration);
93decl_engine_insert!(trait_fn_slab, TraitFn);
94decl_engine_insert!(trait_type_slab, TraitTypeDeclaration);
95decl_engine_insert!(impl_self_or_trait_slab, ImplSelfOrTrait);
96decl_engine_insert!(struct_slab, StructDeclaration);
97decl_engine_insert!(storage_slab, StorageDeclaration);
98decl_engine_insert!(abi_slab, AbiDeclaration);
99decl_engine_insert!(constant_slab, ConstantDeclaration);
100decl_engine_insert!(configurable_slab, ConfigurableDeclaration);
101decl_engine_insert!(const_generic_slab, ConstGenericDeclaration);
102decl_engine_insert!(enum_slab, EnumDeclaration);
103decl_engine_insert!(enum_variant_slab, EnumVariant);
104decl_engine_insert!(type_alias_slab, TypeAliasDeclaration);
105
106macro_rules! decl_engine_replace {
107 ($slab:ident, $decl:ty) => {
108 impl ParsedDeclEngineReplace<$decl> for ParsedDeclEngine {
109 fn replace(&self, index: ParsedDeclId<$decl>, decl: $decl) {
110 self.$slab.replace(index.inner(), decl);
111 }
112 }
113 };
114}
115
116decl_engine_replace!(variable_slab, VariableDeclaration);
117decl_engine_replace!(function_slab, FunctionDeclaration);
118decl_engine_replace!(trait_slab, TraitDeclaration);
119decl_engine_replace!(trait_fn_slab, TraitFn);
120decl_engine_replace!(trait_type_slab, TraitTypeDeclaration);
121decl_engine_replace!(impl_self_or_trait_slab, ImplSelfOrTrait);
122decl_engine_replace!(struct_slab, StructDeclaration);
123decl_engine_replace!(storage_slab, StorageDeclaration);
124decl_engine_replace!(abi_slab, AbiDeclaration);
125decl_engine_replace!(configurable_slab, ConfigurableDeclaration);
126decl_engine_replace!(constant_slab, ConstantDeclaration);
127decl_engine_replace!(enum_slab, EnumDeclaration);
128decl_engine_replace!(type_alias_slab, TypeAliasDeclaration);
129
130macro_rules! decl_engine_clear {
131 ($($slab:ident, $decl:ty);* $(;)?) => {
132 impl ParsedDeclEngine {
133 pub fn clear(&self) {
134 $(
135 self.$slab.clear();
136 )*
137 }
138 }
139 };
140}
141
142macro_rules! decl_engine_index {
143 ($slab:ident, $decl:ty) => {
144 impl ParsedDeclEngineIndex<$decl> for ParsedDeclEngine {}
145 };
146}
147decl_engine_index!(variable_slab, VariableDeclaration);
148decl_engine_index!(function_slab, FunctionDeclaration);
149decl_engine_index!(trait_slab, TraitDeclaration);
150decl_engine_index!(trait_fn_slab, TraitFn);
151decl_engine_index!(trait_type_slab, TraitTypeDeclaration);
152decl_engine_index!(impl_self_or_trait_slab, ImplSelfOrTrait);
153decl_engine_index!(struct_slab, StructDeclaration);
154decl_engine_index!(storage_slab, StorageDeclaration);
155decl_engine_index!(abi_slab, AbiDeclaration);
156decl_engine_index!(configurable_slab, ConfigurableDeclaration);
157decl_engine_index!(constant_slab, ConstantDeclaration);
158decl_engine_index!(enum_slab, EnumDeclaration);
159decl_engine_index!(type_alias_slab, TypeAliasDeclaration);
160
161decl_engine_clear!(
162 variable_slab, VariableDeclaration;
163 function_slab, FunctionDeclaration;
164 trait_slab, TraitDeclaration;
165 trait_fn_slab, TraitFn;
166 trait_type_slab, TraitTypeDeclaration;
167 impl_self_or_trait_slab, ImplTrait;
168 struct_slab, StructDeclaration;
169 storage_slab, StorageDeclaration;
170 abi_slab, AbiDeclaration;
171 constant_slab, ConstantDeclaration;
172 enum_slab, EnumDeclaration;
173 type_alias_slab, TypeAliasDeclaration;
174);
175
176macro_rules! decl_engine_clear_program {
177 ($(($slab:ident, $getter:expr)),* $(,)?) => {
178 impl ParsedDeclEngine {
179 pub fn clear_program(&mut self, program_id: &ProgramId) {
180 $(
181 self.$slab.retain(|_k, item| {
182 #[allow(clippy::redundant_closure_call)]
183 let span = $getter(item);
184 match span.source_id() {
185 Some(source_id) => &source_id.program_id() != program_id,
186 None => true,
187 }
188 });
189 )*
190 }
191 }
192 };
193}
194
195decl_engine_clear_program!(
196 (variable_slab, |item: &VariableDeclaration| item.name.span()),
197 (function_slab, |item: &FunctionDeclaration| item.name.span()),
198 (trait_slab, |item: &TraitDeclaration| item.name.span()),
199 (trait_fn_slab, |item: &TraitFn| item.name.span()),
200 (trait_type_slab, |item: &TraitTypeDeclaration| item
201 .name
202 .span()),
203 (impl_self_or_trait_slab, |item: &ImplSelfOrTrait| item
204 .block_span
205 .clone()),
206 (struct_slab, |item: &StructDeclaration| item.name.span()),
207 (storage_slab, |item: &StorageDeclaration| item.span.clone()),
208 (abi_slab, |item: &AbiDeclaration| item.name.span()),
209 (constant_slab, |item: &ConstantDeclaration| item.name.span()),
210 (enum_slab, |item: &EnumDeclaration| item.name.span()),
211 (type_alias_slab, |item: &TypeAliasDeclaration| item
212 .name
213 .span()),
214);
215
216macro_rules! decl_engine_clear_module {
217 ($(($slab:ident, $getter:expr)),* $(,)?) => {
218 impl ParsedDeclEngine {
219 pub fn clear_module(&mut self, program_id: &SourceId) {
220 $(
221 self.$slab.retain(|_k, item| {
222 #[allow(clippy::redundant_closure_call)]
223 let span = $getter(item);
224 match span.source_id() {
225 Some(src_id) => src_id != program_id,
226 None => true,
227 }
228 });
229 )*
230 }
231 }
232 };
233}
234
235decl_engine_clear_module!(
236 (variable_slab, |item: &VariableDeclaration| item.name.span()),
237 (function_slab, |item: &FunctionDeclaration| item.name.span()),
238 (trait_slab, |item: &TraitDeclaration| item.name.span()),
239 (trait_fn_slab, |item: &TraitFn| item.name.span()),
240 (trait_type_slab, |item: &TraitTypeDeclaration| item
241 .name
242 .span()),
243 (impl_self_or_trait_slab, |item: &ImplSelfOrTrait| item
244 .block_span
245 .clone()),
246 (struct_slab, |item: &StructDeclaration| item.name.span()),
247 (storage_slab, |item: &StorageDeclaration| item.span.clone()),
248 (abi_slab, |item: &AbiDeclaration| item.name.span()),
249 (constant_slab, |item: &ConstantDeclaration| item.name.span()),
250 (enum_slab, |item: &EnumDeclaration| item.name.span()),
251 (type_alias_slab, |item: &TypeAliasDeclaration| item
252 .name
253 .span()),
254);
255
256impl ParsedDeclEngine {
257 pub fn get_function<I>(&self, index: &I) -> Arc<FunctionDeclaration>
263 where
264 ParsedDeclEngine: ParsedDeclEngineGet<I, FunctionDeclaration>,
265 {
266 self.get(index)
267 }
268
269 pub fn get_trait<I>(&self, index: &I) -> Arc<TraitDeclaration>
275 where
276 ParsedDeclEngine: ParsedDeclEngineGet<I, TraitDeclaration>,
277 {
278 self.get(index)
279 }
280
281 pub fn get_trait_fn<I>(&self, index: &I) -> Arc<TraitFn>
287 where
288 ParsedDeclEngine: ParsedDeclEngineGet<I, TraitFn>,
289 {
290 self.get(index)
291 }
292
293 pub fn get_impl_self_or_trait<I>(&self, index: &I) -> Arc<ImplSelfOrTrait>
299 where
300 ParsedDeclEngine: ParsedDeclEngineGet<I, ImplSelfOrTrait>,
301 {
302 self.get(index)
303 }
304
305 pub fn get_struct<I>(&self, index: &I) -> Arc<StructDeclaration>
311 where
312 ParsedDeclEngine: ParsedDeclEngineGet<I, StructDeclaration>,
313 {
314 self.get(index)
315 }
316
317 pub fn get_storage<I>(&self, index: &I) -> Arc<StorageDeclaration>
323 where
324 ParsedDeclEngine: ParsedDeclEngineGet<I, StorageDeclaration>,
325 {
326 self.get(index)
327 }
328
329 pub fn get_abi<I>(&self, index: &I) -> Arc<AbiDeclaration>
335 where
336 ParsedDeclEngine: ParsedDeclEngineGet<I, AbiDeclaration>,
337 {
338 self.get(index)
339 }
340
341 pub fn get_constant<I>(&self, index: &I) -> Arc<ConstantDeclaration>
347 where
348 ParsedDeclEngine: ParsedDeclEngineGet<I, ConstantDeclaration>,
349 {
350 self.get(index)
351 }
352
353 pub fn get_configurable<I>(&self, index: &I) -> Arc<ConfigurableDeclaration>
359 where
360 ParsedDeclEngine: ParsedDeclEngineGet<I, ConfigurableDeclaration>,
361 {
362 self.get(index)
363 }
364
365 pub fn get_const_generic<I>(&self, index: &I) -> Arc<ConstGenericDeclaration>
371 where
372 ParsedDeclEngine: ParsedDeclEngineGet<I, ConstGenericDeclaration>,
373 {
374 self.get(index)
375 }
376
377 pub fn get_trait_type<I>(&self, index: &I) -> Arc<TraitTypeDeclaration>
383 where
384 ParsedDeclEngine: ParsedDeclEngineGet<I, TraitTypeDeclaration>,
385 {
386 self.get(index)
387 }
388
389 pub fn get_enum<I>(&self, index: &I) -> Arc<EnumDeclaration>
395 where
396 ParsedDeclEngine: ParsedDeclEngineGet<I, EnumDeclaration>,
397 {
398 self.get(index)
399 }
400
401 pub fn get_enum_variant<I>(&self, index: &I) -> Arc<EnumVariant>
407 where
408 ParsedDeclEngine: ParsedDeclEngineGet<I, EnumVariant>,
409 {
410 self.get(index)
411 }
412
413 pub fn get_type_alias<I>(&self, index: &I) -> Arc<TypeAliasDeclaration>
419 where
420 ParsedDeclEngine: ParsedDeclEngineGet<I, TypeAliasDeclaration>,
421 {
422 self.get(index)
423 }
424
425 pub fn get_variable<I>(&self, index: &I) -> Arc<VariableDeclaration>
431 where
432 ParsedDeclEngine: ParsedDeclEngineGet<I, VariableDeclaration>,
433 {
434 self.get(index)
435 }
436
437 pub fn pretty_print(&self) -> String {
438 use std::fmt::Write;
439 let mut s = String::new();
440 let _ = write!(
441 &mut s,
442 "Function Count: {}",
443 self.function_slab.values().len()
444 );
445 for f in self.function_slab.values() {
446 let _ = write!(&mut s, "Function: {}", f.name);
447 for node in f.body.contents.iter() {
448 let _ = write!(&mut s, " Node: {:#?}", node);
449 }
450 }
451
452 s
453 }
454}