fe_mir/db/queries/
function.rs1use std::{collections::BTreeMap, rc::Rc};
2
3use fe_analyzer::display::Displayable;
4use fe_analyzer::namespace::items as analyzer_items;
5use fe_analyzer::namespace::items::Item;
6use fe_analyzer::namespace::types as analyzer_types;
7
8use smol_str::SmolStr;
9
10use crate::{
11 db::MirDb,
12 ir::{self, function::Linkage, FunctionSignature, TypeId},
13 lower::function::{lower_func_body, lower_func_signature, lower_monomorphized_func_signature},
14};
15
16pub fn mir_lowered_func_signature(
17 db: &dyn MirDb,
18 analyzer_func: analyzer_items::FunctionId,
19) -> ir::FunctionId {
20 lower_func_signature(db, analyzer_func)
21}
22
23pub fn mir_lowered_monomorphized_func_signature(
24 db: &dyn MirDb,
25 analyzer_func: analyzer_items::FunctionId,
26 resolved_generics: BTreeMap<SmolStr, analyzer_types::TypeId>,
27) -> ir::FunctionId {
28 lower_monomorphized_func_signature(db, analyzer_func, resolved_generics)
29}
30
31pub fn mir_lowered_pseudo_monomorphized_func_signature(
34 db: &dyn MirDb,
35 analyzer_func: analyzer_items::FunctionId,
36) -> ir::FunctionId {
37 let resolved_generics = analyzer_func
38 .sig(db.upcast())
39 .generic_params(db.upcast())
40 .iter()
41 .map(|generic| (generic.name(), analyzer_types::TypeId::unit(db.upcast())))
42 .collect::<BTreeMap<_, _>>();
43 lower_monomorphized_func_signature(db, analyzer_func, resolved_generics)
44}
45
46pub fn mir_lowered_func_body(db: &dyn MirDb, func: ir::FunctionId) -> Rc<ir::FunctionBody> {
47 lower_func_body(db, func)
48}
49
50impl ir::FunctionId {
51 pub fn signature(self, db: &dyn MirDb) -> Rc<FunctionSignature> {
52 db.lookup_mir_intern_function(self)
53 }
54
55 pub fn return_type(self, db: &dyn MirDb) -> Option<TypeId> {
56 self.signature(db).return_type
57 }
58
59 pub fn linkage(self, db: &dyn MirDb) -> Linkage {
60 self.signature(db).linkage
61 }
62
63 pub fn analyzer_func(self, db: &dyn MirDb) -> analyzer_items::FunctionId {
64 self.signature(db).analyzer_func_id
65 }
66
67 pub fn body(self, db: &dyn MirDb) -> Rc<ir::FunctionBody> {
68 db.mir_lowered_func_body(self)
69 }
70
71 pub fn module(self, db: &dyn MirDb) -> analyzer_items::ModuleId {
72 let analyzer_func = self.analyzer_func(db);
73 analyzer_func.module(db.upcast())
74 }
75
76 pub fn is_contract_init(self, db: &dyn MirDb) -> bool {
77 self.analyzer_func(db)
78 .data(db.upcast())
79 .sig
80 .is_constructor(db.upcast())
81 }
82
83 pub fn type_suffix(&self, db: &dyn MirDb) -> SmolStr {
85 self.signature(db)
86 .resolved_generics
87 .values()
88 .fold(String::new(), |acc, param| {
89 format!("{}_{}", acc, param.display(db.upcast()))
90 })
91 .into()
92 }
93
94 pub fn name(&self, db: &dyn MirDb) -> SmolStr {
95 let analyzer_func = self.analyzer_func(db);
96 analyzer_func.name(db.upcast())
97 }
98
99 pub fn debug_name(self, db: &dyn MirDb) -> SmolStr {
101 let analyzer_func = self.analyzer_func(db);
102 let func_name = format!(
103 "{}{}",
104 analyzer_func.name(db.upcast()),
105 self.type_suffix(db)
106 );
107
108 match analyzer_func.sig(db.upcast()).self_item(db.upcast()) {
109 Some(Item::Impl(id)) => {
110 let class_name = format!(
111 "<{} as {}>",
112 id.receiver(db.upcast()).display(db.upcast()),
113 id.trait_id(db.upcast()).name(db.upcast())
114 );
115 format!("{class_name}::{func_name}").into()
116 }
117 Some(class) => {
118 let class_name = class.name(db.upcast());
119 format!("{class_name}::{func_name}").into()
120 }
121 _ => func_name.into(),
122 }
123 }
124
125 pub fn returns_aggregate(self, db: &dyn MirDb) -> bool {
126 self.return_type(db)
127 .map(|ty| ty.is_aggregate(db))
128 .unwrap_or_default()
129 }
130}