cairo_lang_semantic/
lsp_helpers.rs

1use std::sync::Arc;
2
3use cairo_lang_defs::db::DefsGroup;
4use cairo_lang_defs::ids::{
5    GenericTypeId, ImportableId, LanguageElementId, ModuleId, ModuleItemId, NamedLanguageElementId,
6    TraitFunctionId, TraitId,
7};
8use cairo_lang_filesystem::db::{
9    CORELIB_CRATE_NAME, FilesGroup, default_crate_settings, ext_as_virtual,
10};
11use cairo_lang_filesystem::ids::{CrateId, CrateLongId, FileId, FileLongId, SmolStrId, Tracked};
12use cairo_lang_syntax::node::ast::ItemModule;
13use cairo_lang_syntax::node::helpers::GetIdentifier;
14use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
15use cairo_lang_utils::Intern;
16use cairo_lang_utils::ordered_hash_map::{Entry, OrderedHashMap};
17use cairo_lang_utils::unordered_hash_set::UnorderedHashSet;
18use itertools::chain;
19use salsa::Database;
20
21use crate::expr::inference::InferenceId;
22use crate::items::constant::ConstantSemantic;
23use crate::items::enm::EnumSemantic;
24use crate::items::free_function::FreeFunctionSemantic;
25use crate::items::functions::GenericFunctionId;
26use crate::items::imp::ImplSemantic;
27use crate::items::macro_call::{MacroCallSemantic, module_macro_modules};
28use crate::items::module::ModuleSemantic;
29use crate::items::module_type_alias::ModuleTypeAliasSemantic;
30use crate::items::trt::TraitSemantic;
31use crate::items::us::SemanticUseEx;
32use crate::keyword::SELF_PARAM_KW;
33use crate::resolve::{ResolvedGenericItem, Resolver};
34use crate::types::TypeHead;
35use crate::{Variant, corelib};
36
37/// A filter for types.
38#[derive(Clone, Debug, Hash, PartialEq, Eq)]
39pub enum TypeFilter<'db> {
40    /// No filter is applied.
41    NoFilter,
42    /// Only methods with the given type head are returned.
43    TypeHead(TypeHead<'db>),
44}
45
46/// Implementation of [LspHelpers::methods_in_module].
47pub fn methods_in_module<'db>(
48    db: &'db dyn Database,
49    module_id: ModuleId<'db>,
50    type_filter: TypeFilter<'db>,
51) -> Arc<Vec<TraitFunctionId<'db>>> {
52    let mut result = Vec::new();
53    let Ok(module_traits_ids) = db.module_traits_ids(module_id) else {
54        return result.into();
55    };
56    for trait_id in module_traits_ids.iter().copied() {
57        if let Ok(trait_functions) = db.trait_functions(trait_id) {
58            for trait_function in trait_functions.values() {
59                let Ok(signature) = db.trait_function_signature(*trait_function) else {
60                    continue;
61                };
62                let Some(first_param) = signature.params.first() else {
63                    continue;
64                };
65                if first_param.name.long(db) != SELF_PARAM_KW {
66                    continue;
67                }
68                if let TypeFilter::TypeHead(type_head) = &type_filter
69                    && let Some(head) = first_param.ty.head(db)
70                    && !fit_for_method(&head, type_head)
71                {
72                    continue;
73                }
74
75                result.push(*trait_function)
76            }
77        }
78    }
79    Arc::new(result)
80}
81
82/// Query implementation of [LspHelpers::methods_in_module].
83#[salsa::tracked]
84pub fn methods_in_module_tracked<'db>(
85    db: &'db dyn Database,
86    module_id: ModuleId<'db>,
87    type_filter: TypeFilter<'db>,
88) -> Arc<Vec<TraitFunctionId<'db>>> {
89    methods_in_module(db, module_id, type_filter)
90}
91
92/// Checks if a type head can fit for a method.
93fn fit_for_method(head: &TypeHead<'_>, type_head: &TypeHead<'_>) -> bool {
94    // Allow generics so we can filter them later with resolver.
95    if let TypeHead::Generic(_) = head {
96        return true;
97    }
98    if head == type_head {
99        return true;
100    }
101    if let TypeHead::Snapshot(snapshot_head) = head {
102        return fit_for_method(snapshot_head.as_ref(), type_head);
103    }
104    false
105}
106
107/// Implementation of [LspHelpers::methods_in_crate].
108pub fn methods_in_crate<'db>(
109    db: &'db dyn Database,
110    crate_id: CrateId<'db>,
111    type_filter: TypeFilter<'db>,
112) -> Arc<Vec<TraitFunctionId<'db>>> {
113    let mut result = Vec::new();
114    for module_id in db.crate_modules(crate_id).iter() {
115        result.extend_from_slice(&db.methods_in_module(*module_id, type_filter.clone())[..])
116    }
117    Arc::new(result)
118}
119
120/// Query implementation of [LspHelpers::methods_in_crate].
121#[salsa::tracked]
122pub fn methods_in_crate_tracked<'db>(
123    db: &'db dyn Database,
124    crate_id: CrateId<'db>,
125    type_filter: TypeFilter<'db>,
126) -> Arc<Vec<TraitFunctionId<'db>>> {
127    methods_in_crate(db, crate_id, type_filter)
128}
129
130/// Implementation of [LspHelpers::visible_importables_in_module].
131pub fn visible_importables_in_module<'db>(
132    db: &'db dyn Database,
133    module_id: ModuleId<'db>,
134    user_module_id: ModuleId<'db>,
135    include_parent: bool,
136) -> Arc<Vec<(ImportableId<'db>, String)>> {
137    let mut visited_modules = UnorderedHashSet::default();
138    visible_importables_in_module_ex(
139        db,
140        module_id,
141        user_module_id,
142        include_parent,
143        &mut visited_modules,
144    )
145    .unwrap_or_else(|| Arc::new(Vec::new()))
146}
147
148/// Query implementation of [LspHelpers::visible_importables_in_module].
149#[salsa::tracked]
150pub fn visible_importables_in_module_tracked<'db>(
151    db: &'db dyn Database,
152    module_id: ModuleId<'db>,
153    user_module_id: ModuleId<'db>,
154    include_parent: bool,
155) -> Arc<Vec<(ImportableId<'db>, String)>> {
156    visible_importables_in_module(db, module_id, user_module_id, include_parent)
157}
158
159/// Returns the visible importables in a module, including the importables in the parent module if
160/// needed. The visibility is relative to the module `user_module_id`.
161fn visible_importables_in_module_ex<'db>(
162    db: &'db dyn Database,
163    module_id: ModuleId<'db>,
164    user_module_id: ModuleId<'db>,
165    include_parent: bool,
166    visited_modules: &mut UnorderedHashSet<ModuleId<'db>>,
167) -> Option<Arc<Vec<(ImportableId<'db>, String)>>> {
168    let mut result = Vec::new();
169    if visited_modules.contains(&module_id) {
170        return Some(result.into());
171    }
172
173    let resolver = Resolver::new(db, user_module_id, InferenceId::NoContext);
174
175    // Check if an item in the current module is visible from the user module.
176    let is_visible = |item_name: SmolStrId<'_>| {
177        let item_info = db.module_item_info_by_name(module_id, item_name).ok()??;
178        Some(resolver.is_item_visible(module_id, &item_info, user_module_id))
179    };
180    visited_modules.insert(module_id);
181    let mut modules_to_visit = vec![];
182    // Add importables and traverse modules imported into the current module.
183    for use_id in db.module_uses_ids(module_id).unwrap_or_default().iter().copied() {
184        if !is_visible(use_id.name(db)).unwrap_or_default() {
185            continue;
186        }
187        let Ok(resolved_item) = db.use_resolved_item(use_id) else {
188            continue;
189        };
190
191        let (resolved_item, name) = match resolved_item {
192            ResolvedGenericItem::Module(ModuleId::CrateRoot(crate_id)) => {
193                result.extend_from_slice(&db.visible_importables_in_crate(crate_id, module_id)[..]);
194
195                (ImportableId::Crate(crate_id), crate_id.long(db).name().long(db))
196            }
197            ResolvedGenericItem::Module(inner_module_id @ ModuleId::Submodule(module)) => {
198                modules_to_visit.push(inner_module_id);
199
200                (ImportableId::Submodule(module), module.name(db).long(db))
201            }
202            ResolvedGenericItem::Module(ModuleId::MacroCall { .. }) => {
203                continue;
204            }
205            ResolvedGenericItem::GenericConstant(item_id) => {
206                (ImportableId::Constant(item_id), item_id.name(db).long(db))
207            }
208            ResolvedGenericItem::GenericFunction(GenericFunctionId::Free(item_id)) => {
209                (ImportableId::FreeFunction(item_id), item_id.name(db).long(db))
210            }
211            ResolvedGenericItem::GenericFunction(GenericFunctionId::Extern(item_id)) => {
212                (ImportableId::ExternFunction(item_id), item_id.name(db).long(db))
213            }
214            ResolvedGenericItem::GenericType(GenericTypeId::Struct(item_id)) => {
215                (ImportableId::Struct(item_id), item_id.name(db).long(db))
216            }
217            ResolvedGenericItem::GenericType(GenericTypeId::Enum(item_id)) => {
218                let enum_name = item_id.name(db);
219
220                if let Ok(variants) = db.enum_variants(item_id) {
221                    for (name, id) in variants.iter() {
222                        result.push((
223                            ImportableId::Variant(*id),
224                            format!("{}::{}", enum_name.long(db), name.long(db)),
225                        ));
226                    }
227                }
228
229                (ImportableId::Enum(item_id), enum_name.long(db))
230            }
231            ResolvedGenericItem::GenericType(GenericTypeId::Extern(item_id)) => {
232                (ImportableId::ExternType(item_id), item_id.name(db).long(db))
233            }
234            ResolvedGenericItem::GenericTypeAlias(item_id) => {
235                (ImportableId::TypeAlias(item_id), item_id.name(db).long(db))
236            }
237            ResolvedGenericItem::GenericImplAlias(item_id) => {
238                (ImportableId::ImplAlias(item_id), item_id.name(db).long(db))
239            }
240            ResolvedGenericItem::Variant(Variant { id, .. }) => {
241                (ImportableId::Variant(id), id.name(db).long(db))
242            }
243            ResolvedGenericItem::Trait(item_id) => {
244                (ImportableId::Trait(item_id), item_id.name(db).long(db))
245            }
246            ResolvedGenericItem::Impl(item_id) => {
247                (ImportableId::Impl(item_id), item_id.name(db).long(db))
248            }
249            ResolvedGenericItem::Macro(item_id) => {
250                (ImportableId::MacroDeclaration(item_id), item_id.name(db).long(db))
251            }
252            ResolvedGenericItem::Variable(_)
253            | ResolvedGenericItem::TraitItem(_)
254            | ResolvedGenericItem::GenericFunction(GenericFunctionId::Impl(_)) => continue,
255        };
256
257        result.push((resolved_item, name.to_string()));
258    }
259
260    if !matches!(module_id, ModuleId::MacroCall { .. }) {
261        modules_to_visit.extend(module_macro_modules(db, false, module_id).iter().copied());
262    }
263
264    for submodule_id in db.module_submodules_ids(module_id).unwrap_or_default().iter().copied() {
265        if !is_visible(submodule_id.name(db)).unwrap_or_default() {
266            continue;
267        }
268        result.push((ImportableId::Submodule(submodule_id), submodule_id.name(db).to_string(db)));
269        modules_to_visit.push(ModuleId::Submodule(submodule_id));
270    }
271
272    // Handle enums separately because we need to include their variants.
273    for enum_id in db.module_enums_ids(module_id).unwrap_or_default().iter().copied() {
274        let enum_name = enum_id.name(db);
275        if !is_visible(enum_name).unwrap_or_default() {
276            continue;
277        }
278
279        result.push((ImportableId::Enum(enum_id), enum_name.to_string(db)));
280
281        if let Ok(variants) = db.enum_variants(enum_id) {
282            for (name, id) in variants.iter() {
283                result.push((
284                    ImportableId::Variant(*id),
285                    format!("{}::{}", enum_name.long(db), name.long(db)),
286                ));
287            }
288        }
289    }
290
291    macro_rules! module_importables {
292        ($query:ident, $map:expr) => {
293            for item_id in db.$query(module_id).ok().unwrap_or_default().iter().copied() {
294                if !is_visible(item_id.name(db)).unwrap_or_default() {
295                    continue;
296                }
297                result.push(($map(item_id), item_id.name(db).to_string(db)));
298            }
299        };
300    }
301
302    module_importables!(module_constants_ids, ImportableId::Constant);
303    module_importables!(module_free_functions_ids, ImportableId::FreeFunction);
304    module_importables!(module_structs_ids, ImportableId::Struct);
305    module_importables!(module_type_aliases_ids, ImportableId::TypeAlias);
306    module_importables!(module_impl_aliases_ids, ImportableId::ImplAlias);
307    module_importables!(module_traits_ids, ImportableId::Trait);
308    module_importables!(module_impls_ids, ImportableId::Impl);
309    module_importables!(module_extern_functions_ids, ImportableId::ExternFunction);
310    module_importables!(module_extern_types_ids, ImportableId::ExternType);
311    module_importables!(module_macro_declarations_ids, ImportableId::MacroDeclaration);
312
313    for submodule in modules_to_visit {
314        for (item_id, path) in
315            visible_importables_in_module_ex(db, submodule, user_module_id, false, visited_modules)
316                .unwrap_or_default()
317                .iter()
318        {
319            result.push((*item_id, format!("{}::{}", submodule.name(db).long(db), path)));
320        }
321    }
322    // Traverse the parent module if needed.
323    if include_parent {
324        match module_id {
325            ModuleId::CrateRoot(_) => {}
326            ModuleId::Submodule(submodule_id) => {
327                let parent_module_id = submodule_id.parent_module(db);
328                for (item_id, path) in visible_importables_in_module_ex(
329                    db,
330                    parent_module_id,
331                    user_module_id,
332                    include_parent,
333                    visited_modules,
334                )
335                .unwrap_or_default()
336                .iter()
337                {
338                    result.push((*item_id, format!("super::{path}")));
339                }
340            }
341            ModuleId::MacroCall { .. } => {}
342        }
343    }
344    Some(Arc::new(result))
345}
346
347/// Implementation of [LspHelpers::visible_importables_in_crate].
348pub fn visible_importables_in_crate<'db>(
349    db: &'db dyn Database,
350    crate_id: CrateId<'db>,
351    user_module_id: ModuleId<'db>,
352) -> Arc<Vec<(ImportableId<'db>, String)>> {
353    let is_current_crate = user_module_id.owning_crate(db) == crate_id;
354    let crate_name = if is_current_crate { "crate" } else { crate_id.long(db).name().long(db) };
355    let crate_as_module = ModuleId::CrateRoot(crate_id);
356    db.visible_importables_in_module(crate_as_module, user_module_id, false)
357        .iter()
358        .map(|(item_id, path)| (*item_id, format!("{crate_name}::{path}")))
359        .collect::<Vec<_>>()
360        .into()
361}
362
363/// Query implementation of [LspHelpers::visible_importables_in_crate].
364#[salsa::tracked]
365pub fn visible_importables_in_crate_tracked<'db>(
366    db: &'db dyn Database,
367    crate_id: CrateId<'db>,
368    user_module_id: ModuleId<'db>,
369) -> Arc<Vec<(ImportableId<'db>, String)>> {
370    visible_importables_in_crate(db, crate_id, user_module_id)
371}
372
373/// Implementation of [LspHelpers::visible_importables_from_module].
374pub fn visible_importables_from_module<'db>(
375    db: &'db dyn Database,
376    module_id: ModuleId<'db>,
377) -> Option<Arc<OrderedHashMap<ImportableId<'db>, String>>> {
378    let current_crate_id = module_id.owning_crate(db);
379    let prelude_submodule =
380        db.get_prelude_submodule(&db.crate_config(current_crate_id)?.settings)?;
381
382    let mut module_visible_importables = Vec::new();
383    // Collect importables from the prelude.
384    module_visible_importables.extend_from_slice(
385        &db.visible_importables_in_module(prelude_submodule, prelude_submodule, false)[..],
386    );
387    // Collect importables from all dependency crates, including the current crate and corelib.
388    let settings = db
389        .crate_config(current_crate_id)
390        .map(|c| &c.settings)
391        .unwrap_or_else(|| default_crate_settings(db));
392    for crate_id in chain!(
393        [current_crate_id],
394        (!settings.dependencies.contains_key(CORELIB_CRATE_NAME)).then(|| corelib::core_crate(db)),
395        settings.dependencies.iter().map(|(name, setting)| {
396            CrateLongId::Real {
397                name: SmolStrId::from(db, name.clone()),
398                discriminator: setting.discriminator.clone(),
399            }
400            .intern(db)
401        })
402    ) {
403        module_visible_importables
404            .extend_from_slice(&db.visible_importables_in_crate(crate_id, module_id)[..]);
405        module_visible_importables
406            .push((ImportableId::Crate(crate_id), crate_id.long(db).name().to_string(db)));
407    }
408
409    // Collect importables visible in the current module.
410    module_visible_importables
411        .extend_from_slice(&db.visible_importables_in_module(module_id, module_id, true)[..]);
412
413    // Deduplicate importables, preferring shorter paths.
414    // This is the reason for searching in the crates before the current module - to prioritize
415    // shorter, canonical paths prefixed with `crate::` over paths using `super::` or local
416    // imports.
417    let mut result: OrderedHashMap<ImportableId<'_>, String> = OrderedHashMap::default();
418    for (trait_id, path) in module_visible_importables {
419        match result.entry(trait_id) {
420            Entry::Occupied(existing_path) => {
421                if path.split("::").count() < existing_path.get().split("::").count() {
422                    *existing_path.into_mut() = path;
423                }
424            }
425            Entry::Vacant(entry) => {
426                entry.insert(path);
427            }
428        }
429    }
430    Some(Arc::new(result))
431}
432
433/// Query implementation of [LspHelpers::visible_importables_from_module].
434pub fn visible_importables_from_module_tracked<'db>(
435    db: &'db dyn Database,
436    module_id: ModuleId<'db>,
437) -> Option<Arc<OrderedHashMap<ImportableId<'db>, String>>> {
438    visible_importables_from_module_helper(db, (), module_id)
439}
440
441#[salsa::tracked]
442fn visible_importables_from_module_helper<'db>(
443    db: &'db dyn Database,
444    _tracked: Tracked,
445    module_id: ModuleId<'db>,
446) -> Option<Arc<OrderedHashMap<ImportableId<'db>, String>>> {
447    visible_importables_from_module(db, module_id)
448}
449
450/// Implementation of [LspHelpers::visible_traits_from_module].
451pub fn visible_traits_from_module<'db>(
452    db: &'db dyn Database,
453    module_id: ModuleId<'db>,
454) -> Option<Arc<OrderedHashMap<TraitId<'db>, String>>> {
455    let importables = db.visible_importables_from_module(module_id)?;
456
457    let traits = importables
458        .iter()
459        .filter_map(|(item, path)| {
460            if let ImportableId::Trait(trait_id) = item {
461                Some((*trait_id, path.clone()))
462            } else {
463                None
464            }
465        })
466        .collect::<OrderedHashMap<_, _>>()
467        .into();
468
469    Some(traits)
470}
471
472/// Query implementation of [LspHelpers::visible_traits_from_module].
473fn visible_traits_from_module_tracked<'db>(
474    db: &'db dyn Database,
475    module_id: ModuleId<'db>,
476) -> Option<Arc<OrderedHashMap<TraitId<'db>, String>>> {
477    visible_traits_from_module_helper(db, (), module_id)
478}
479
480#[salsa::tracked]
481fn visible_traits_from_module_helper<'db>(
482    db: &'db dyn Database,
483    _tracked: Tracked,
484    module_id: ModuleId<'db>,
485) -> Option<Arc<OrderedHashMap<TraitId<'db>, String>>> {
486    visible_traits_from_module(db, module_id)
487}
488
489/// Query implementation of [LspHelpers::inline_macro_expansion_files].
490#[salsa::tracked(returns(ref))]
491fn inline_macro_expansion_files_tracked<'db>(
492    db: &'db dyn Database,
493    _tracked: Tracked,
494    module_id: ModuleId<'db>,
495) -> Vec<FileId<'db>> {
496    let mut files = vec![];
497    if let Ok(module_macro_calls_ids) = db.module_macro_calls_ids(module_id) {
498        for macro_call in module_macro_calls_ids {
499            if let Ok(macro_call_data) = db.priv_macro_call_data(*macro_call)
500                && let Ok(ModuleId::MacroCall { generated_file_id, .. }) =
501                    macro_call_data.macro_call_module
502            {
503                files.push(generated_file_id);
504            }
505        }
506    }
507    if let Ok(traits) = db.module_traits_ids(module_id) {
508        for trait_id in traits {
509            if let Ok(trait_functions) = db.trait_functions(*trait_id) {
510                for trait_function_id in trait_functions.values() {
511                    if let Ok(Some(data)) = db.trait_function_body_resolver_data(*trait_function_id)
512                    {
513                        files.extend(data.files.iter().copied())
514                    }
515                }
516            }
517        }
518    }
519    if let Ok(impls) = db.module_impls_ids(module_id) {
520        for impls_id in impls {
521            if let Ok(impl_functions) = db.impl_functions(*impls_id) {
522                for impl_function_id in impl_functions.values() {
523                    if let Ok(data) = db.impl_function_body_resolver_data(*impl_function_id) {
524                        files.extend(data.files.iter().copied())
525                    }
526                }
527            }
528        }
529    }
530    if let Ok(free_functions) = db.module_free_functions_ids(module_id) {
531        for free_function_id in free_functions {
532            if let Ok(data) = db.free_function_body_resolver_data(*free_function_id) {
533                files.extend(data.files.iter().copied())
534            }
535        }
536    }
537    if let Ok(constants) = db.module_constants_ids(module_id) {
538        for constant_id in constants {
539            if let Ok(data) = db.constant_resolver_data(*constant_id) {
540                files.extend(data.files.iter().copied())
541            }
542        }
543    }
544    if let Ok(type_aliases) = db.module_type_aliases_ids(module_id) {
545        for type_alias_id in type_aliases {
546            if let Ok(data) = db.module_type_alias_resolver_data(*type_alias_id) {
547                files.extend(data.files.iter().copied())
548            }
549        }
550    }
551
552    files
553}
554
555#[salsa::tracked]
556fn find_module_containing_node<'db>(
557    db: &'db dyn Database,
558    _tracked: Tracked,
559    node: SyntaxNode<'db>,
560) -> Option<ModuleId<'db>> {
561    // Get the main module of the main file containing the node.
562    // The node may be located in a virtual file of a submodule.
563    let main_module = {
564        // Get the file where the node is located.
565        // This might be a virtual file generated by a compiler plugin.
566        let mut node_file_id = node.stable_ptr(db).file_id(db);
567
568        // db.file_modules() is DefsGroup defined so for every inline macro expression file there
569        // will be no entry. Go up to first non-expression file.
570        while db.file_modules(node_file_id).is_err() {
571            node_file_id = match node_file_id.long(db) {
572                FileLongId::OnDisk(_) => return None,
573                FileLongId::External(ext) => ext_as_virtual(db, *ext).parent?,
574                FileLongId::Virtual(vfs) => vfs.parent?,
575            }
576            .file_id;
577        }
578
579        // Get the root module of a file containing the node.
580        *db.file_modules(node_file_id).ok()?.first()?
581    };
582
583    // Get the stack (bottom-up) of submodule names in the file containing the node, in the main
584    // module, that lead to the node.
585    node.ancestors(db)
586        .filter_map(|node| ItemModule::cast(db, node))
587        .map(|item_module| {
588            item_module
589                .stable_ptr(db)
590                .name_green(db)
591                .identifier(db)
592        })
593        // Buffer the stack to get DoubleEndedIterator.
594        .collect::<Vec<_>>()
595        .into_iter()
596        // And get id of the (sub)module containing the node by traversing this stack top-down.
597        .try_rfold(main_module, |module, name| {
598            let ModuleItemId::Submodule(submodule) =
599                db.module_item_by_name(module, name).ok()??
600            else {
601                return None;
602            };
603            Some(ModuleId::Submodule(submodule))
604        })
605}
606
607/// Trait for LSP helpers.
608pub trait LspHelpers<'db>: Database {
609    /// Returns all methods in a module that match the given type filter.
610    fn methods_in_module(
611        &'db self,
612        module_id: ModuleId<'db>,
613        type_filter: TypeFilter<'db>,
614    ) -> Arc<Vec<TraitFunctionId<'db>>> {
615        methods_in_module_tracked(self.as_dyn_database(), module_id, type_filter)
616    }
617    /// Returns all methods in a crate that match the given type filter.
618    fn methods_in_crate(
619        &'db self,
620        crate_id: CrateId<'db>,
621        type_filter: TypeFilter<'db>,
622    ) -> Arc<Vec<TraitFunctionId<'db>>> {
623        methods_in_crate_tracked(self.as_dyn_database(), crate_id, type_filter)
624    }
625    /// Returns all the importables visible from a module, alongside a visible use path to the
626    /// trait.
627    fn visible_importables_from_module(
628        &'db self,
629        module_id: ModuleId<'db>,
630    ) -> Option<Arc<OrderedHashMap<ImportableId<'db>, String>>> {
631        visible_importables_from_module_tracked(self.as_dyn_database(), module_id)
632    }
633    /// Returns all visible importables in a module, alongside a visible use path to the trait.
634    /// `user_module_id` is the module from which the importables should be visible. If
635    /// `include_parent` is true, the parent module of `module_id` is also considered.
636    fn visible_importables_in_module(
637        &'db self,
638        module_id: ModuleId<'db>,
639        user_module_id: ModuleId<'db>,
640        include_parent: bool,
641    ) -> Arc<Vec<(ImportableId<'db>, String)>> {
642        visible_importables_in_module_tracked(
643            self.as_dyn_database(),
644            module_id,
645            user_module_id,
646            include_parent,
647        )
648    }
649    /// Returns all visible importables in a crate, alongside a visible use path to the trait.
650    /// `user_module_id` is the module from which the importables should be visible.
651    fn visible_importables_in_crate(
652        &'db self,
653        crate_id: CrateId<'db>,
654        user_module_id: ModuleId<'db>,
655    ) -> Arc<Vec<(ImportableId<'db>, String)>> {
656        visible_importables_in_crate_tracked(self.as_dyn_database(), crate_id, user_module_id)
657    }
658    /// Returns all the traits visible from a module, alongside a visible use path to the trait.
659    fn visible_traits_from_module(
660        &'db self,
661        module_id: ModuleId<'db>,
662    ) -> Option<Arc<OrderedHashMap<TraitId<'db>, String>>> {
663        visible_traits_from_module_tracked(self.as_dyn_database(), module_id)
664    }
665    /// Returns all files generated by inline macro expansion inside provided module.
666    fn inline_macro_expansion_files(&'db self, module_id: ModuleId<'db>) -> &'db Vec<FileId<'db>> {
667        inline_macro_expansion_files_tracked(self.as_dyn_database(), (), module_id)
668    }
669
670    /// Finds a [`ModuleId`] containing the node.
671    fn find_module_containing_node(&'db self, node: SyntaxNode<'db>) -> Option<ModuleId<'db>> {
672        find_module_containing_node(self.as_dyn_database(), (), node)
673    }
674}
675impl<'db, T: Database + ?Sized> LspHelpers<'db> for T {}