Skip to main content

pilota_build2/
db.rs

1use std::{fmt, path::PathBuf, sync::Arc};
2
3use fxhash::FxHashMap;
4
5use crate::{
6    middle::{
7        rir::{self},
8        ty::{AdtDef, AdtKind, CodegenTy, TyKind},
9        type_graph::TypeGraph,
10    },
11    symbol::{DefId, FileId},
12    TagId,
13    tags::Tags,
14};
15
16#[derive(Default)]
17#[salsa::database(RirDatabaseStorage)]
18pub struct RootDatabase {
19    storage: salsa::Storage<RootDatabase>,
20}
21
22impl fmt::Debug for RootDatabase {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        f.debug_struct("RootDatabase").finish()
25    }
26}
27
28impl salsa::ParallelDatabase for RootDatabase {
29    fn snapshot(&self) -> salsa::Snapshot<RootDatabase> {
30        salsa::Snapshot::new(RootDatabase {
31            storage: self.storage.snapshot(),
32        })
33    }
34}
35
36#[salsa::query_group(RirDatabaseStorage)]
37pub trait RirDatabase {
38    #[salsa::input]
39    fn nodes(&self) -> Arc<FxHashMap<DefId, rir::Node>>;
40    #[salsa::input]
41    fn files(&self) -> Arc<FxHashMap<FileId, Arc<rir::File>>>;
42    #[salsa::input]
43    fn file_ids_map(&self) -> Arc<FxHashMap<Arc<PathBuf>, FileId>>;
44    #[salsa::input]
45    fn type_graph(&self) -> Arc<TypeGraph>;
46    #[salsa::input]
47    fn tags_map(&self) -> Arc<FxHashMap<TagId, Arc<Tags>>>;
48    #[salsa::input]
49    fn input_files(&self) -> Arc<Vec<FileId>>;
50
51    fn node(&self, def_id: DefId) -> Option<rir::Node>;
52    fn file(&self, file_id: FileId) -> Option<Arc<rir::File>>;
53    fn item(&self, def_id: DefId) -> Option<Arc<rir::Item>>;
54    fn expect_item(&self, def_id: DefId) -> Arc<rir::Item>;
55    fn codegen_item_ty(&self, ty: TyKind) -> CodegenTy;
56    fn codegen_const_ty(&self, ty: TyKind) -> CodegenTy;
57    fn codegen_ty(&self, def_id: DefId) -> CodegenTy;
58    fn service_methods(&self, def_id: DefId) -> Arc<[Arc<rir::Method>]>;
59}
60
61fn node(db: &dyn RirDatabase, def_id: DefId) -> Option<rir::Node> {
62    db.nodes().get(&def_id).cloned()
63}
64
65fn item(db: &dyn RirDatabase, def_id: DefId) -> Option<Arc<rir::Item>> {
66    let node = db.node(def_id);
67    match node {
68        Some(rir::Node {
69                 kind: rir::NodeKind::Item(i),
70                 ..
71             }) => Some(i),
72        None => None,
73        _ => panic!("{:?} is not an item", def_id),
74    }
75}
76
77fn expect_item(db: &dyn RirDatabase, def_id: DefId) -> Arc<rir::Item> {
78    db.item(def_id).unwrap()
79}
80
81fn file(db: &dyn RirDatabase, file_id: FileId) -> Option<Arc<rir::File>> {
82    db.files().get(&file_id).cloned()
83}
84
85fn codegen_item_ty(db: &dyn RirDatabase, ty: TyKind) -> CodegenTy {
86    ty.to_codegen_item_ty(db)
87}
88
89fn codegen_const_ty(db: &dyn RirDatabase, ty: TyKind) -> CodegenTy {
90    ty.to_codegen_const_ty(db)
91}
92
93fn codegen_ty(db: &dyn RirDatabase, did: DefId) -> CodegenTy {
94    let node = db.node(did).unwrap();
95    match &node.kind {
96        rir::NodeKind::Item(item) => {
97            let kind = match &**item {
98                rir::Item::Message(_) => AdtKind::Struct,
99                rir::Item::Enum(_) => AdtKind::Enum,
100                rir::Item::Service(_) => unimplemented!(),
101                rir::Item::NewType(t) => {
102                    AdtKind::NewType(Arc::from(db.codegen_item_ty(t.ty.kind.clone())))
103                }
104                rir::Item::Const(c) => {
105                    let mut ty = db.codegen_const_ty(c.ty.kind.clone());
106                    if let CodegenTy::StaticRef(inner) = ty {
107                        ty = CodegenTy::LazyStaticRef(inner)
108                    }
109
110                    return ty;
111                }
112                rir::Item::Mod(_) => unreachable!(),
113            };
114            CodegenTy::Adt(AdtDef { did, kind })
115        }
116        rir::NodeKind::Variant(_) => CodegenTy::Adt(AdtDef {
117            did: node.parent.unwrap(),
118            kind: AdtKind::Enum,
119        }),
120        rir::NodeKind::Field(_) => todo!(),
121        rir::NodeKind::Method(_) => todo!(),
122        rir::NodeKind::Arg(_) => todo!(),
123    }
124}
125
126fn service_methods(db: &dyn RirDatabase, def_id: DefId) -> Arc<[Arc<rir::Method>]> {
127    let item = db.expect_item(def_id);
128    let service = match &*item {
129        rir::Item::Service(s) => s,
130        _ => panic!(),
131    };
132    let methods = service
133        .extend
134        .iter()
135        .flat_map(|p| {
136            db.service_methods(p.did)
137                .iter()
138                .map(|m| match m.source {
139                    rir::MethodSource::Extend(_) => m.clone(),
140                    rir::MethodSource::Own => Arc::from(rir::Method {
141                        source: rir::MethodSource::Extend(p.did),
142                        ..(**m).clone()
143                    }),
144                })
145                .collect::<Vec<_>>()
146        })
147        .chain(service.methods.iter().cloned());
148
149    Arc::from_iter(methods)
150}
151
152impl salsa::Database for RootDatabase {}