1mod apply_change;
6
7pub mod active_parameter;
8pub mod assists;
9pub mod defs;
10pub mod documentation;
11pub mod famous_defs;
12pub mod helpers;
13pub mod items_locator;
14pub mod label;
15pub mod path_transform;
16pub mod prime_caches;
17pub mod rename;
18pub mod rust_doc;
19pub mod search;
20pub mod source_change;
21pub mod symbol_index;
22pub mod text_edit;
23pub mod traits;
24pub mod ty_filter;
25pub mod use_trivial_constructor;
26
27pub mod imports {
28 pub mod import_assets;
29 pub mod insert_use;
30 pub mod merge_imports;
31}
32
33pub mod generated {
34 pub mod lints;
35}
36
37pub mod syntax_helpers {
38 pub mod format_string;
39 pub mod format_string_exprs;
40 pub mod tree_diff;
41 pub use hir::prettify_macro_expansion;
42 pub mod node_ext;
43 pub mod suggest_name;
44
45 pub use parser::LexedStr;
46}
47
48pub use hir::{ChangeWithProcMacros, EditionedFileId};
49use salsa::Durability;
50
51use std::{fmt, mem::ManuallyDrop};
52
53use base_db::{
54 CrateGraphBuilder, CratesMap, FileSourceRootInput, FileText, Files, RootQueryDb,
55 SourceDatabase, SourceRoot, SourceRootId, SourceRootInput, query_group,
56};
57use hir::{
58 FilePositionWrapper, FileRangeWrapper,
59 db::{DefDatabase, ExpandDatabase},
60};
61use triomphe::Arc;
62
63use crate::{line_index::LineIndex, symbol_index::SymbolsDatabase};
64pub use rustc_hash::{FxHashMap, FxHashSet, FxHasher};
65
66pub use ::line_index;
67
68pub use base_db;
70pub use span::{self, FileId};
71
72pub type FxIndexSet<T> = indexmap::IndexSet<T, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
73pub type FxIndexMap<K, V> =
74 indexmap::IndexMap<K, V, std::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
75
76pub type FilePosition = FilePositionWrapper<FileId>;
77pub type FileRange = FileRangeWrapper<FileId>;
78
79#[salsa_macros::db]
80pub struct RootDatabase {
81 storage: ManuallyDrop<salsa::Storage<Self>>,
88 files: Arc<Files>,
89 crates_map: Arc<CratesMap>,
90}
91
92impl std::panic::RefUnwindSafe for RootDatabase {}
93
94#[salsa_macros::db]
95impl salsa::Database for RootDatabase {}
96
97impl Drop for RootDatabase {
98 fn drop(&mut self) {
99 unsafe { ManuallyDrop::drop(&mut self.storage) };
100 }
101}
102
103impl Clone for RootDatabase {
104 fn clone(&self) -> Self {
105 Self {
106 storage: self.storage.clone(),
107 files: self.files.clone(),
108 crates_map: self.crates_map.clone(),
109 }
110 }
111}
112
113impl fmt::Debug for RootDatabase {
114 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 f.debug_struct("RootDatabase").finish()
116 }
117}
118
119#[salsa_macros::db]
120impl SourceDatabase for RootDatabase {
121 fn file_text(&self, file_id: vfs::FileId) -> FileText {
122 self.files.file_text(file_id)
123 }
124
125 fn set_file_text(&mut self, file_id: vfs::FileId, text: &str) {
126 let files = Arc::clone(&self.files);
127 files.set_file_text(self, file_id, text);
128 }
129
130 fn set_file_text_with_durability(
131 &mut self,
132 file_id: vfs::FileId,
133 text: &str,
134 durability: Durability,
135 ) {
136 let files = Arc::clone(&self.files);
137 files.set_file_text_with_durability(self, file_id, text, durability);
138 }
139
140 fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput {
142 self.files.source_root(source_root_id)
143 }
144
145 fn set_source_root_with_durability(
146 &mut self,
147 source_root_id: SourceRootId,
148 source_root: Arc<SourceRoot>,
149 durability: Durability,
150 ) {
151 let files = Arc::clone(&self.files);
152 files.set_source_root_with_durability(self, source_root_id, source_root, durability);
153 }
154
155 fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput {
156 self.files.file_source_root(id)
157 }
158
159 fn set_file_source_root_with_durability(
160 &mut self,
161 id: vfs::FileId,
162 source_root_id: SourceRootId,
163 durability: Durability,
164 ) {
165 let files = Arc::clone(&self.files);
166 files.set_file_source_root_with_durability(self, id, source_root_id, durability);
167 }
168
169 fn crates_map(&self) -> Arc<CratesMap> {
170 self.crates_map.clone()
171 }
172}
173
174impl Default for RootDatabase {
175 fn default() -> RootDatabase {
176 RootDatabase::new(None)
177 }
178}
179
180impl RootDatabase {
181 pub fn new(lru_capacity: Option<u16>) -> RootDatabase {
182 let mut db = RootDatabase {
183 storage: ManuallyDrop::new(salsa::Storage::default()),
184 files: Default::default(),
185 crates_map: Default::default(),
186 };
187 db.set_all_crates(Arc::new(Box::new([])));
189 CrateGraphBuilder::default().set_in_db(&mut db);
190 db.set_proc_macros_with_durability(Default::default(), Durability::MEDIUM);
191 db.set_local_roots_with_durability(Default::default(), Durability::MEDIUM);
192 db.set_library_roots_with_durability(Default::default(), Durability::MEDIUM);
193 db.set_expand_proc_attr_macros_with_durability(false, Durability::HIGH);
194 db.update_base_query_lru_capacities(lru_capacity);
195 db
196 }
197
198 pub fn enable_proc_attr_macros(&mut self) {
199 self.set_expand_proc_attr_macros_with_durability(true, Durability::HIGH);
200 }
201
202 pub fn update_base_query_lru_capacities(&mut self, _lru_capacity: Option<u16>) {
203 }
211
212 pub fn update_lru_capacities(&mut self, _lru_capacities: &FxHashMap<Box<str>, u16>) {
213 }
237}
238
239#[query_group::query_group]
240pub trait LineIndexDatabase: base_db::RootQueryDb {
241 #[salsa::invoke_interned(line_index)]
242 fn line_index(&self, file_id: FileId) -> Arc<LineIndex>;
243}
244
245fn line_index(db: &dyn LineIndexDatabase, file_id: FileId) -> Arc<LineIndex> {
246 let text = db.file_text(file_id).text(db);
247 Arc::new(LineIndex::new(&text))
248}
249
250#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
251pub enum SymbolKind {
252 Attribute,
253 BuiltinAttr,
254 Const,
255 ConstParam,
256 Derive,
257 DeriveHelper,
258 Enum,
259 Field,
260 Function,
261 Method,
262 Impl,
263 InlineAsmRegOrRegClass,
264 Label,
265 LifetimeParam,
266 Local,
267 Macro,
268 ProcMacro,
269 Module,
270 SelfParam,
271 SelfType,
272 Static,
273 Struct,
274 ToolModule,
275 Trait,
276 TraitAlias,
277 TypeAlias,
278 TypeParam,
279 Union,
280 ValueParam,
281 Variant,
282}
283
284impl From<hir::MacroKind> for SymbolKind {
285 fn from(it: hir::MacroKind) -> Self {
286 match it {
287 hir::MacroKind::Declarative | hir::MacroKind::DeclarativeBuiltIn => SymbolKind::Macro,
288 hir::MacroKind::ProcMacro => SymbolKind::ProcMacro,
289 hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => SymbolKind::Derive,
290 hir::MacroKind::Attr | hir::MacroKind::AttrBuiltIn => SymbolKind::Attribute,
291 }
292 }
293}
294
295impl From<hir::ModuleDef> for SymbolKind {
296 fn from(it: hir::ModuleDef) -> Self {
297 match it {
298 hir::ModuleDef::Const(..) => SymbolKind::Const,
299 hir::ModuleDef::Variant(..) => SymbolKind::Variant,
300 hir::ModuleDef::Function(..) => SymbolKind::Function,
301 hir::ModuleDef::Macro(mac) if mac.is_proc_macro() => SymbolKind::ProcMacro,
302 hir::ModuleDef::Macro(..) => SymbolKind::Macro,
303 hir::ModuleDef::Module(..) => SymbolKind::Module,
304 hir::ModuleDef::Static(..) => SymbolKind::Static,
305 hir::ModuleDef::Adt(hir::Adt::Struct(..)) => SymbolKind::Struct,
306 hir::ModuleDef::Adt(hir::Adt::Enum(..)) => SymbolKind::Enum,
307 hir::ModuleDef::Adt(hir::Adt::Union(..)) => SymbolKind::Union,
308 hir::ModuleDef::Trait(..) => SymbolKind::Trait,
309 hir::ModuleDef::TraitAlias(..) => SymbolKind::TraitAlias,
310 hir::ModuleDef::TypeAlias(..) => SymbolKind::TypeAlias,
311 hir::ModuleDef::BuiltinType(..) => SymbolKind::TypeAlias,
312 }
313 }
314}
315
316#[derive(Clone, Copy, Debug, PartialEq, Eq)]
317pub struct SnippetCap {
318 _private: (),
319}
320
321impl SnippetCap {
322 pub const fn new(allow_snippets: bool) -> Option<SnippetCap> {
323 if allow_snippets { Some(SnippetCap { _private: () }) } else { None }
324 }
325}
326
327pub struct Ranker<'a> {
328 pub kind: parser::SyntaxKind,
329 pub text: &'a str,
330 pub ident_kind: bool,
331}
332
333impl<'a> Ranker<'a> {
334 pub const MAX_RANK: usize = 0b1110;
335
336 pub fn from_token(token: &'a syntax::SyntaxToken) -> Self {
337 let kind = token.kind();
338 Ranker { kind, text: token.text(), ident_kind: kind.is_any_identifier() }
339 }
340
341 pub fn rank_token(&self, tok: &syntax::SyntaxToken) -> usize {
344 let tok_kind = tok.kind();
345
346 let exact_same_kind = tok_kind == self.kind;
347 let both_idents = exact_same_kind || (tok_kind.is_any_identifier() && self.ident_kind);
348 let same_text = tok.text() == self.text;
349 let no_tt_parent =
351 tok.parent().is_some_and(|it| it.kind() != parser::SyntaxKind::TOKEN_TREE);
352 (both_idents as usize)
353 | ((exact_same_kind as usize) << 1)
354 | ((same_text as usize) << 2)
355 | ((no_tt_parent as usize) << 3)
356 }
357}
358
359#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
360pub enum Severity {
361 Error,
362 Warning,
363 WeakWarning,
364 Allow,
365}