fe_analyzer/db/queries/
impls.rs

1use indexmap::map::Entry;
2use indexmap::IndexMap;
3use smol_str::SmolStr;
4
5use crate::context::{Analysis, AnalyzerContext};
6use crate::namespace::items::{Function, FunctionId, ImplId, Item};
7use crate::namespace::scopes::ItemScope;
8use crate::AnalyzerDb;
9use std::rc::Rc;
10
11pub fn impl_all_functions(db: &dyn AnalyzerDb, impl_: ImplId) -> Rc<[FunctionId]> {
12    let impl_data = impl_.data(db);
13    impl_data
14        .ast
15        .kind
16        .functions
17        .iter()
18        .map(|node| {
19            db.intern_function(Rc::new(Function::new(
20                db,
21                node,
22                Some(Item::Impl(impl_)),
23                impl_data.module,
24            )))
25        })
26        .collect()
27}
28
29pub fn impl_function_map(
30    db: &dyn AnalyzerDb,
31    impl_: ImplId,
32) -> Analysis<Rc<IndexMap<SmolStr, FunctionId>>> {
33    let scope = ItemScope::new(db, impl_.module(db));
34    let mut map = IndexMap::<SmolStr, FunctionId>::new();
35
36    for func in db.impl_all_functions(impl_).iter() {
37        let def_name = func.name(db);
38
39        match map.entry(def_name) {
40            Entry::Occupied(entry) => {
41                scope.duplicate_name_error(
42                    "duplicate function names in `impl` block",
43                    entry.key(),
44                    entry.get().name_span(db),
45                    func.name_span(db),
46                );
47            }
48            Entry::Vacant(entry) => {
49                entry.insert(*func);
50            }
51        }
52    }
53    Analysis::new(Rc::new(map), scope.diagnostics.take().into())
54}