1#![allow(clippy::arc_with_non_send_sync)]
2use crate::namespace::items::{
3 self, AttributeId, ContractFieldId, ContractId, DepGraphWrapper, EnumVariantKind, FunctionId,
4 FunctionSigId, ImplId, IngotId, Item, ModuleConstantId, ModuleId, StructFieldId, StructId,
5 TraitId, TypeAliasId,
6};
7use crate::namespace::types::{self, Type, TypeId};
8use crate::{
9 context::{Analysis, Constant, FunctionBody},
10 namespace::items::EnumId,
11};
12use crate::{
13 errors::{ConstEvalError, TypeError},
14 namespace::items::EnumVariantId,
15};
16use fe_common::db::{SourceDb, SourceDbStorage, Upcast, UpcastMut};
17use fe_common::{SourceFileId, Span};
18use fe_parser::ast;
19use indexmap::map::IndexMap;
20use smol_str::SmolStr;
21use std::rc::Rc;
22mod queries;
23
24#[salsa::query_group(AnalyzerDbStorage)]
25pub trait AnalyzerDb: SourceDb + Upcast<dyn SourceDb> + UpcastMut<dyn SourceDb> {
26 #[salsa::interned]
27 fn intern_ingot(&self, data: Rc<items::Ingot>) -> IngotId;
28 #[salsa::interned]
29 fn intern_module(&self, data: Rc<items::Module>) -> ModuleId;
30 #[salsa::interned]
31 fn intern_module_const(&self, data: Rc<items::ModuleConstant>) -> ModuleConstantId;
32 #[salsa::interned]
33 fn intern_struct(&self, data: Rc<items::Struct>) -> StructId;
34 #[salsa::interned]
35 fn intern_struct_field(&self, data: Rc<items::StructField>) -> StructFieldId;
36 #[salsa::interned]
37 fn intern_enum(&self, data: Rc<items::Enum>) -> EnumId;
38 #[salsa::interned]
39 fn intern_attribute(&self, data: Rc<items::Attribute>) -> AttributeId;
40 #[salsa::interned]
41 fn intern_enum_variant(&self, data: Rc<items::EnumVariant>) -> EnumVariantId;
42 #[salsa::interned]
43 fn intern_trait(&self, data: Rc<items::Trait>) -> TraitId;
44 #[salsa::interned]
45 fn intern_impl(&self, data: Rc<items::Impl>) -> ImplId;
46 #[salsa::interned]
47 fn intern_type_alias(&self, data: Rc<items::TypeAlias>) -> TypeAliasId;
48 #[salsa::interned]
49 fn intern_contract(&self, data: Rc<items::Contract>) -> ContractId;
50 #[salsa::interned]
51 fn intern_contract_field(&self, data: Rc<items::ContractField>) -> ContractFieldId;
52 #[salsa::interned]
53 fn intern_function_sig(&self, data: Rc<items::FunctionSig>) -> FunctionSigId;
54 #[salsa::interned]
55 fn intern_function(&self, data: Rc<items::Function>) -> FunctionId;
56 #[salsa::interned]
57 fn intern_type(&self, data: Type) -> TypeId;
58
59 #[salsa::input]
65 fn ingot_files(&self, ingot: IngotId) -> Rc<[SourceFileId]>;
66 #[salsa::input]
67 fn ingot_external_ingots(&self, ingot: IngotId) -> Rc<IndexMap<SmolStr, IngotId>>;
68 #[salsa::input]
72 fn root_ingot(&self) -> IngotId;
73
74 #[salsa::invoke(queries::ingots::ingot_modules)]
75 fn ingot_modules(&self, ingot: IngotId) -> Rc<[ModuleId]>;
76 #[salsa::invoke(queries::ingots::ingot_root_module)]
77 fn ingot_root_module(&self, ingot: IngotId) -> Option<ModuleId>;
78
79 #[salsa::invoke(queries::module::module_file_path)]
81 fn module_file_path(&self, module: ModuleId) -> SmolStr;
82 #[salsa::invoke(queries::module::module_parse)]
83 fn module_parse(&self, module: ModuleId) -> Analysis<Rc<ast::Module>>;
84 #[salsa::invoke(queries::module::module_is_incomplete)]
85 fn module_is_incomplete(&self, module: ModuleId) -> bool;
86 #[salsa::invoke(queries::module::module_all_items)]
87 fn module_all_items(&self, module: ModuleId) -> Rc<[Item]>;
88 #[salsa::invoke(queries::module::module_all_impls)]
89 fn module_all_impls(&self, module: ModuleId) -> Analysis<Rc<[ImplId]>>;
90 #[salsa::invoke(queries::module::module_item_map)]
91 fn module_item_map(&self, module: ModuleId) -> Analysis<Rc<IndexMap<SmolStr, Item>>>;
92 #[salsa::invoke(queries::module::module_impl_map)]
93 fn module_impl_map(
94 &self,
95 module: ModuleId,
96 ) -> Analysis<Rc<IndexMap<(TraitId, TypeId), ImplId>>>;
97 #[salsa::invoke(queries::module::module_contracts)]
98 fn module_contracts(&self, module: ModuleId) -> Rc<[ContractId]>;
99 #[salsa::invoke(queries::module::module_structs)]
100 fn module_structs(&self, module: ModuleId) -> Rc<[StructId]>;
101 #[salsa::invoke(queries::module::module_constants)]
102 fn module_constants(&self, module: ModuleId) -> Rc<Vec<ModuleConstantId>>;
103 #[salsa::invoke(queries::module::module_used_item_map)]
104 fn module_used_item_map(
105 &self,
106 module: ModuleId,
107 ) -> Analysis<Rc<IndexMap<SmolStr, (Span, Item)>>>;
108 #[salsa::invoke(queries::module::module_parent_module)]
109 fn module_parent_module(&self, module: ModuleId) -> Option<ModuleId>;
110 #[salsa::invoke(queries::module::module_submodules)]
111 fn module_submodules(&self, module: ModuleId) -> Rc<[ModuleId]>;
112 #[salsa::invoke(queries::module::module_tests)]
113 fn module_tests(&self, module: ModuleId) -> Vec<FunctionId>;
114
115 #[salsa::cycle(queries::module::module_constant_type_cycle)]
117 #[salsa::invoke(queries::module::module_constant_type)]
118 fn module_constant_type(&self, id: ModuleConstantId) -> Analysis<Result<TypeId, TypeError>>;
119 #[salsa::cycle(queries::module::module_constant_value_cycle)]
120 #[salsa::invoke(queries::module::module_constant_value)]
121 fn module_constant_value(
122 &self,
123 id: ModuleConstantId,
124 ) -> Analysis<Result<Constant, ConstEvalError>>;
125
126 #[salsa::invoke(queries::contracts::contract_all_functions)]
128 fn contract_all_functions(&self, id: ContractId) -> Rc<[FunctionId]>;
129 #[salsa::invoke(queries::contracts::contract_function_map)]
130 fn contract_function_map(&self, id: ContractId) -> Analysis<Rc<IndexMap<SmolStr, FunctionId>>>;
131 #[salsa::invoke(queries::contracts::contract_public_function_map)]
132 fn contract_public_function_map(&self, id: ContractId) -> Rc<IndexMap<SmolStr, FunctionId>>;
133 #[salsa::invoke(queries::contracts::contract_init_function)]
134 fn contract_init_function(&self, id: ContractId) -> Analysis<Option<FunctionId>>;
135 #[salsa::invoke(queries::contracts::contract_call_function)]
136 fn contract_call_function(&self, id: ContractId) -> Analysis<Option<FunctionId>>;
137
138 #[salsa::invoke(queries::contracts::contract_all_fields)]
139 fn contract_all_fields(&self, id: ContractId) -> Rc<[ContractFieldId]>;
140 #[salsa::invoke(queries::contracts::contract_field_map)]
141 fn contract_field_map(
142 &self,
143 id: ContractId,
144 ) -> Analysis<Rc<IndexMap<SmolStr, ContractFieldId>>>;
145 #[salsa::invoke(queries::contracts::contract_field_type)]
146 fn contract_field_type(&self, field: ContractFieldId) -> Analysis<Result<TypeId, TypeError>>;
147 #[salsa::cycle(queries::contracts::contract_dependency_graph_cycle)]
148 #[salsa::invoke(queries::contracts::contract_dependency_graph)]
149 fn contract_dependency_graph(&self, id: ContractId) -> DepGraphWrapper;
150 #[salsa::cycle(queries::contracts::contract_runtime_dependency_graph_cycle)]
151 #[salsa::invoke(queries::contracts::contract_runtime_dependency_graph)]
152 fn contract_runtime_dependency_graph(&self, id: ContractId) -> DepGraphWrapper;
153
154 #[salsa::invoke(queries::functions::function_signature)]
156 fn function_signature(&self, id: FunctionSigId) -> Analysis<Rc<types::FunctionSignature>>;
157 #[salsa::invoke(queries::functions::function_body)]
158 fn function_body(&self, id: FunctionId) -> Analysis<Rc<FunctionBody>>;
159 #[salsa::cycle(queries::functions::function_dependency_graph_cycle)]
160 #[salsa::invoke(queries::functions::function_dependency_graph)]
161 fn function_dependency_graph(&self, id: FunctionId) -> DepGraphWrapper;
162
163 #[salsa::invoke(queries::structs::struct_all_fields)]
165 fn struct_all_fields(&self, id: StructId) -> Rc<[StructFieldId]>;
166 #[salsa::invoke(queries::structs::struct_field_map)]
167 fn struct_field_map(&self, id: StructId) -> Analysis<Rc<IndexMap<SmolStr, StructFieldId>>>;
168 #[salsa::invoke(queries::structs::struct_field_type)]
169 fn struct_field_type(&self, field: StructFieldId) -> Analysis<Result<TypeId, TypeError>>;
170 #[salsa::invoke(queries::structs::struct_all_functions)]
171 fn struct_all_functions(&self, id: StructId) -> Rc<[FunctionId]>;
172 #[salsa::invoke(queries::structs::struct_function_map)]
173 fn struct_function_map(&self, id: StructId) -> Analysis<Rc<IndexMap<SmolStr, FunctionId>>>;
174 #[salsa::cycle(queries::structs::struct_cycle)]
175 #[salsa::invoke(queries::structs::struct_dependency_graph)]
176 fn struct_dependency_graph(&self, id: StructId) -> Analysis<DepGraphWrapper>;
177
178 #[salsa::invoke(queries::enums::enum_all_variants)]
180 fn enum_all_variants(&self, id: EnumId) -> Rc<[EnumVariantId]>;
181 #[salsa::invoke(queries::enums::enum_variant_map)]
182 fn enum_variant_map(&self, id: EnumId) -> Analysis<Rc<IndexMap<SmolStr, EnumVariantId>>>;
183 #[salsa::invoke(queries::enums::enum_all_functions)]
184 fn enum_all_functions(&self, id: EnumId) -> Rc<[FunctionId]>;
185 #[salsa::invoke(queries::enums::enum_function_map)]
186 fn enum_function_map(&self, id: EnumId) -> Analysis<Rc<IndexMap<SmolStr, FunctionId>>>;
187 #[salsa::cycle(queries::enums::enum_cycle)]
188 #[salsa::invoke(queries::enums::enum_dependency_graph)]
189 fn enum_dependency_graph(&self, id: EnumId) -> Analysis<DepGraphWrapper>;
190 #[salsa::invoke(queries::enums::enum_variant_kind)]
191 fn enum_variant_kind(&self, id: EnumVariantId) -> Analysis<Result<EnumVariantKind, TypeError>>;
192
193 #[salsa::invoke(queries::traits::trait_all_functions)]
195 fn trait_all_functions(&self, id: TraitId) -> Rc<[FunctionSigId]>;
196 #[salsa::invoke(queries::traits::trait_function_map)]
197 fn trait_function_map(&self, id: TraitId) -> Analysis<Rc<IndexMap<SmolStr, FunctionSigId>>>;
198 #[salsa::invoke(queries::traits::trait_is_implemented_for)]
199 fn trait_is_implemented_for(&self, id: TraitId, typ: TypeId) -> bool;
200
201 #[salsa::invoke(queries::impls::impl_all_functions)]
203 fn impl_all_functions(&self, id: ImplId) -> Rc<[FunctionId]>;
204 #[salsa::invoke(queries::impls::impl_function_map)]
205 fn impl_function_map(&self, id: ImplId) -> Analysis<Rc<IndexMap<SmolStr, FunctionId>>>;
206
207 #[salsa::invoke(queries::types::all_impls)]
209 fn all_impls(&self, ty: TypeId) -> Rc<[ImplId]>;
210 #[salsa::invoke(queries::types::impl_for)]
211 fn impl_for(&self, ty: TypeId, treit: TraitId) -> Option<ImplId>;
212 #[salsa::invoke(queries::types::function_sigs)]
213 fn function_sigs(&self, ty: TypeId, name: SmolStr) -> Rc<[FunctionSigId]>;
214
215 #[salsa::invoke(queries::types::type_alias_type)]
217 #[salsa::cycle(queries::types::type_alias_type_cycle)]
218 fn type_alias_type(&self, id: TypeAliasId) -> Analysis<Result<TypeId, TypeError>>;
219}
220
221#[salsa::database(AnalyzerDbStorage, SourceDbStorage)]
222#[derive(Default)]
223pub struct TestDb {
224 storage: salsa::Storage<TestDb>,
225}
226impl salsa::Database for TestDb {}
227
228impl Upcast<dyn SourceDb> for TestDb {
229 fn upcast(&self) -> &(dyn SourceDb + 'static) {
230 self
231 }
232}
233
234impl UpcastMut<dyn SourceDb> for TestDb {
235 fn upcast_mut(&mut self) -> &mut (dyn SourceDb + 'static) {
236 &mut *self
237 }
238}