cairo_lang_semantic/
lookup_item.rs

1use std::sync::Arc;
2
3use cairo_lang_defs::ids::{
4    ConstantId, EnumId, ExternFunctionId, ExternTypeId, FileIndex, FreeFunctionId,
5    FunctionWithBodyId, ImplAliasId, ImplConstantDefId, ImplDefId, ImplFunctionId, ImplImplDefId,
6    ImplItemId, ImplTypeDefId, LanguageElementId, LookupItemId, ModuleFileId, ModuleId,
7    ModuleItemId, ModuleTypeAliasId, StructId, SubmoduleId, TraitConstantId, TraitFunctionId,
8    TraitId, TraitImplId, TraitItemId, TraitTypeId, UseId,
9};
10use cairo_lang_diagnostics::Maybe;
11
12use crate::db::SemanticGroup;
13use crate::expr::inference::InferenceId;
14use crate::resolve::ResolverData;
15
16pub trait HasResolverData {
17    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>>;
18}
19
20pub trait LookupItemEx: HasResolverData {
21    fn function_with_body(&self) -> Option<FunctionWithBodyId>;
22
23    /// Returns the resolver data of the parent generic item if exist.
24    fn resolver_context(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>>;
25}
26
27impl LookupItemEx for LookupItemId {
28    fn function_with_body(&self) -> Option<FunctionWithBodyId> {
29        match self {
30            LookupItemId::ModuleItem(ModuleItemId::FreeFunction(free_function_id)) => {
31                Some(FunctionWithBodyId::Free(*free_function_id))
32            }
33            LookupItemId::TraitItem(TraitItemId::Function(trait_function_id)) => {
34                Some(FunctionWithBodyId::Trait(*trait_function_id))
35            }
36            LookupItemId::ImplItem(ImplItemId::Function(impl_function_id)) => {
37                Some(FunctionWithBodyId::Impl(*impl_function_id))
38            }
39            _ => None,
40        }
41    }
42
43    fn resolver_context(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
44        match self {
45            LookupItemId::ImplItem(impl_item_id) => {
46                let impl_def_id = impl_item_id.impl_def_id(db.upcast());
47                let resolver_data = impl_def_id.resolver_data(db.upcast())?;
48                Ok(resolver_data)
49            }
50            LookupItemId::TraitItem(item) => {
51                let trait_id = item.trait_id(db.upcast());
52                let resolver_data = trait_id.resolver_data(db.upcast())?;
53                Ok(resolver_data)
54            }
55            LookupItemId::ModuleItem(item) => {
56                // Top level does not have an outer context, create an empty resolver data.
57                let module_file_id = item.module_file_id(db.upcast());
58                let resolver_data =
59                    Arc::new(ResolverData::new(module_file_id, InferenceId::NoContext));
60                Ok(resolver_data)
61            }
62        }
63    }
64}
65
66impl HasResolverData for LookupItemId {
67    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
68        match self {
69            LookupItemId::ModuleItem(item) => item.resolver_data(db),
70            LookupItemId::TraitItem(item) => item.resolver_data(db),
71            LookupItemId::ImplItem(item) => item.resolver_data(db),
72        }
73    }
74}
75
76// === Module Items ===
77
78impl HasResolverData for ModuleItemId {
79    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
80        match self {
81            ModuleItemId::Constant(item) => item.resolver_data(db),
82            ModuleItemId::Submodule(item) => item.resolver_data(db),
83            ModuleItemId::Use(item) => item.resolver_data(db),
84            ModuleItemId::ImplAlias(item) => item.resolver_data(db),
85            ModuleItemId::Impl(item) => item.resolver_data(db),
86            ModuleItemId::ExternType(item) => item.resolver_data(db),
87            ModuleItemId::ExternFunction(item) => item.resolver_data(db),
88            ModuleItemId::FreeFunction(item) => item.resolver_data(db),
89            ModuleItemId::Struct(item) => item.resolver_data(db),
90            ModuleItemId::Enum(item) => item.resolver_data(db),
91            ModuleItemId::TypeAlias(item) => item.resolver_data(db),
92            ModuleItemId::Trait(item) => item.resolver_data(db),
93        }
94    }
95}
96
97impl HasResolverData for ConstantId {
98    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
99        db.constant_resolver_data(*self)
100    }
101}
102
103impl HasResolverData for SubmoduleId {
104    fn resolver_data(&self, _db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
105        let module_id = ModuleId::Submodule(*self);
106        let module_file_id = ModuleFileId(module_id, FileIndex(0));
107        let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::ModuleItem(
108            ModuleItemId::Submodule(*self),
109        ));
110        Ok(Arc::new(ResolverData::new(module_file_id, inference_id)))
111    }
112}
113
114impl HasResolverData for UseId {
115    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
116        db.use_resolver_data(*self)
117    }
118}
119
120impl HasResolverData for ImplAliasId {
121    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
122        db.impl_alias_resolver_data(*self)
123    }
124}
125
126impl HasResolverData for ImplDefId {
127    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
128        db.impl_def_resolver_data(*self)
129    }
130}
131
132impl HasResolverData for ExternTypeId {
133    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
134        let inference_id = InferenceId::LookupItemDeclaration(LookupItemId::ModuleItem(
135            ModuleItemId::ExternType(*self),
136        ));
137        Ok(Arc::new(ResolverData::new(self.module_file_id(db.upcast()), inference_id)))
138    }
139}
140
141impl HasResolverData for ExternFunctionId {
142    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
143        db.extern_function_declaration_resolver_data(*self)
144    }
145}
146
147impl HasResolverData for FreeFunctionId {
148    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
149        db.free_function_declaration_resolver_data(*self)
150    }
151}
152
153impl HasResolverData for StructId {
154    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
155        db.struct_declaration_resolver_data(*self)
156    }
157}
158
159impl HasResolverData for EnumId {
160    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
161        db.enum_declaration_resolver_data(*self)
162    }
163}
164impl HasResolverData for ModuleTypeAliasId {
165    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
166        db.module_type_alias_resolver_data(*self)
167    }
168}
169
170impl HasResolverData for TraitId {
171    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
172        db.trait_resolver_data(*self)
173    }
174}
175
176// === Trait Items ===
177
178impl HasResolverData for TraitItemId {
179    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
180        match self {
181            TraitItemId::Function(item) => item.resolver_data(db),
182            TraitItemId::Type(item) => item.resolver_data(db),
183            TraitItemId::Constant(item) => item.resolver_data(db),
184            TraitItemId::Impl(item) => item.resolver_data(db),
185        }
186    }
187}
188
189impl HasResolverData for TraitTypeId {
190    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
191        db.trait_type_resolver_data(*self)
192    }
193}
194
195impl HasResolverData for TraitConstantId {
196    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
197        db.trait_constant_resolver_data(*self)
198    }
199}
200
201impl HasResolverData for TraitImplId {
202    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
203        db.trait_impl_resolver_data(*self)
204    }
205}
206
207impl HasResolverData for TraitFunctionId {
208    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
209        db.trait_function_resolver_data(*self)
210    }
211}
212
213// === Impl Items ===
214
215impl HasResolverData for ImplItemId {
216    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
217        match self {
218            ImplItemId::Function(item) => item.resolver_data(db),
219            ImplItemId::Type(item) => item.resolver_data(db),
220            ImplItemId::Constant(item) => item.resolver_data(db),
221            ImplItemId::Impl(item) => item.resolver_data(db),
222        }
223    }
224}
225
226impl HasResolverData for ImplTypeDefId {
227    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
228        db.impl_type_def_resolver_data(*self)
229    }
230}
231
232impl HasResolverData for ImplConstantDefId {
233    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
234        db.impl_constant_def_resolver_data(*self)
235    }
236}
237
238impl HasResolverData for ImplImplDefId {
239    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
240        db.impl_impl_def_resolver_data(*self)
241    }
242}
243
244impl HasResolverData for ImplFunctionId {
245    fn resolver_data(&self, db: &dyn SemanticGroup) -> Maybe<Arc<ResolverData>> {
246        db.impl_function_resolver_data(*self)
247    }
248}