Skip to content

Commit adb0fb0

Browse files
committed
feat: Virtual macro files
1 parent da1888a commit adb0fb0

File tree

106 files changed

+3187
-2279
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+3187
-2279
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/base-db/src/change.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
44
use std::fmt;
55

6+
use rustc_hash::FxHashSet;
67
use salsa::Durability;
78
use triomphe::Arc;
89
use vfs::FileId;
@@ -49,15 +50,25 @@ impl FileChange {
4950
pub fn apply(self, db: &mut dyn RootQueryDb) -> Option<CratesIdMap> {
5051
let _p = tracing::info_span!("FileChange::apply").entered();
5152
if let Some(roots) = self.roots {
53+
let mut local_roots = FxHashSet::default();
54+
let mut library_roots = FxHashSet::default();
5255
for (idx, root) in roots.into_iter().enumerate() {
5356
let root_id = SourceRootId(idx as u32);
57+
if root.is_library {
58+
library_roots.insert(root_id);
59+
} else {
60+
local_roots.insert(root_id);
61+
}
62+
5463
let durability = source_root_durability(&root);
5564
for file_id in root.iter() {
5665
db.set_file_source_root_with_durability(file_id, root_id, durability);
5766
}
5867

5968
db.set_source_root_with_durability(root_id, Arc::new(root), durability);
6069
}
70+
db.set_local_roots_with_durability(Arc::new(local_roots), Durability::MEDIUM);
71+
db.set_library_roots_with_durability(Arc::new(library_roots), Durability::MEDIUM);
6172
}
6273

6374
for (file_id, text) in self.files_changed {

crates/base-db/src/lib.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,16 @@ pub trait RootQueryDb: SourceDatabase + salsa::Database {
263263
#[salsa::invoke(input::transitive_rev_deps)]
264264
#[salsa::transparent]
265265
fn transitive_rev_deps(&self, of: Crate) -> FxHashSet<Crate>;
266+
267+
/// The set of "local" (that is, from the current workspace) roots.
268+
/// Files in local roots are assumed to change frequently.
269+
#[salsa::input]
270+
fn local_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
271+
272+
/// The set of roots for crates.io libraries.
273+
/// Files in libraries are assumed to never change.
274+
#[salsa::input]
275+
fn library_roots(&self) -> Arc<FxHashSet<SourceRootId>>;
266276
}
267277

268278
pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet<Crate> {

crates/hir-def/src/nameres.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,23 @@ impl DefMap {
519519
.map(|(id, _data)| id)
520520
}
521521

522+
pub fn inline_modules_for_macro_file(
523+
&self,
524+
file_id: MacroCallId,
525+
) -> impl Iterator<Item = LocalModuleId> + '_ {
526+
self.modules
527+
.iter()
528+
.filter(move |(_id, data)| {
529+
(match data.origin {
530+
ModuleOrigin::Inline { definition_tree_id, .. } => {
531+
definition_tree_id.file_id().macro_file()
532+
}
533+
_ => None,
534+
}) == Some(file_id)
535+
})
536+
.map(|(id, _data)| id)
537+
}
538+
522539
pub fn modules(&self) -> impl Iterator<Item = (LocalModuleId, &ModuleData)> + '_ {
523540
self.modules.iter()
524541
}

crates/hir-expand/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,7 @@ intern::impl_internable!(ModPath, attrs::AttrInput);
10681068

10691069
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
10701070
#[doc(alias = "MacroFileId")]
1071+
#[derive(PartialOrd, Ord)]
10711072
pub struct MacroCallId {
10721073
pub loc: MacroCallLoc,
10731074
}
@@ -1086,7 +1087,7 @@ impl From<MacroCallId> for span::MacroCallId {
10861087
}
10871088
}
10881089

1089-
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
1090+
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa_macros::Supertype)]
10901091
pub enum HirFileId {
10911092
FileId(EditionedFileId),
10921093
MacroFile(MacroCallId),

crates/hir-expand/src/prettify_macro_expansion_.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub fn prettify_macro_expansion(
2020
let span_offset = syn.text_range().start();
2121
let target_crate = target_crate_id.data(db);
2222
let mut syntax_ctx_id_to_dollar_crate_replacement = FxHashMap::default();
23+
2324
syntax_bridge::prettify_macro_expansion::prettify_macro_expansion(
2425
syn,
2526
&mut |dollar_crate| {

crates/hir/src/semantics.rs

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -284,18 +284,25 @@ impl<DB: HirDatabase + ?Sized> Semantics<'_, DB> {
284284
self.imp.resolve_variant(record_lit).map(VariantDef::from)
285285
}
286286

287-
pub fn file_to_module_def(&self, file: impl Into<FileId>) -> Option<Module> {
288-
self.imp.file_to_module_defs(file.into()).next()
287+
pub fn file_to_module_def(&self, file: EditionedFileId) -> Option<Module> {
288+
self.imp.ed_file_to_module_defs(file).next()
289289
}
290290

291-
pub fn file_to_module_defs(&self, file: impl Into<FileId>) -> impl Iterator<Item = Module> {
292-
self.imp.file_to_module_defs(file.into())
291+
pub fn file_to_module_def2(&self, file: FileId) -> Option<Module> {
292+
self.imp.file_to_module_defs(file).next()
293293
}
294294

295295
pub fn hir_file_to_module_def(&self, file: impl Into<HirFileId>) -> Option<Module> {
296296
self.imp.hir_file_to_module_defs(file.into()).next()
297297
}
298298

299+
pub fn file_to_module_defs(
300+
&self,
301+
file: impl Into<EditionedFileId>,
302+
) -> impl Iterator<Item = Module> {
303+
self.imp.ed_file_to_module_defs(file.into())
304+
}
305+
299306
pub fn hir_file_to_module_defs(
300307
&self,
301308
file: impl Into<HirFileId>,
@@ -380,6 +387,19 @@ impl<'db> SemanticsImpl<'db> {
380387
}
381388
}
382389

390+
/// If not crate is found for the file, try to return the last crate in topological order.
391+
pub fn first_crate_hir(&self, file: HirFileId) -> Option<Crate> {
392+
match file {
393+
HirFileId::FileId(editioned_file_id) => {
394+
self.first_crate(editioned_file_id.file_id(self.db))
395+
}
396+
HirFileId::MacroFile(macro_call_id) => {
397+
let macro_call = self.db.lookup_intern_macro_call(macro_call_id);
398+
Some(macro_call.krate.into())
399+
}
400+
}
401+
}
402+
383403
pub fn attach_first_edition(&self, file: FileId) -> Option<EditionedFileId> {
384404
Some(EditionedFileId::new(
385405
self.db,
@@ -412,6 +432,7 @@ impl<'db> SemanticsImpl<'db> {
412432
HirFileId::FileId(file_id) => {
413433
let module = self.file_to_module_defs(file_id.file_id(self.db)).next()?;
414434
let def_map = crate_def_map(self.db, module.krate().id);
435+
415436
match def_map[module.id.local_id].origin {
416437
ModuleOrigin::CrateRoot { .. } => None,
417438
ModuleOrigin::File { declaration, declaration_tree_id, .. } => {
@@ -770,7 +791,7 @@ impl<'db> SemanticsImpl<'db> {
770791
// FIXME: Type the return type
771792
/// Returns the range (pre-expansion) in the string literal corresponding to the resolution,
772793
/// absolute file range (post-expansion)
773-
/// of the part in the format string, the corresponding string token and the resolution if it
794+
/// of the part in the format string (post-expansion), the corresponding string token and the resolution if it
774795
/// exists.
775796
pub fn check_for_format_args_template_with_file(
776797
&self,
@@ -904,7 +925,6 @@ impl<'db> SemanticsImpl<'db> {
904925
None => return res,
905926
};
906927
let file = self.find_file(node.syntax());
907-
908928
if first == last {
909929
// node is just the token, so descend the token
910930
self.descend_into_macros_all(
@@ -1877,9 +1897,15 @@ impl<'db> SemanticsImpl<'db> {
18771897
self.with_ctx(|ctx| ctx.file_to_def(file).to_owned()).into_iter().map(Module::from)
18781898
}
18791899

1900+
fn ed_file_to_module_defs(&self, file: EditionedFileId) -> impl Iterator<Item = Module> {
1901+
self.with_ctx(|ctx| ctx.file_to_def(file.file_id(self.db)).to_owned())
1902+
.into_iter()
1903+
.map(Module::from)
1904+
}
1905+
18801906
fn hir_file_to_module_defs(&self, file: HirFileId) -> impl Iterator<Item = Module> {
18811907
// FIXME: Do we need to care about inline modules for macro expansions?
1882-
self.file_to_module_defs(file.original_file_respecting_includes(self.db).file_id(self.db))
1908+
self.ed_file_to_module_defs(file.original_file_respecting_includes(self.db))
18831909
}
18841910

18851911
pub fn scope(&self, node: &SyntaxNode) -> Option<SemanticsScope<'db>> {

crates/ide-assists/src/handlers/convert_bool_to_enum.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ fn replace_usages(
208208
target_module: &hir::Module,
209209
delayed_mutations: &mut Vec<(ImportScope, ast::Path)>,
210210
) {
211-
for (file_id, references) in usages {
211+
for (file_id, references) in usages.map_out_of_macros(&ctx.sema) {
212212
edit.edit_file(file_id.file_id(ctx.db()));
213213

214214
let refs_with_imports = augment_references_with_imports(ctx, references, target_module);

crates/ide-assists/src/handlers/convert_named_struct_to_tuple_struct.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ fn edit_struct_references(
156156
};
157157
let usages = strukt_def.usages(&ctx.sema).include_self_refs().all();
158158

159-
for (file_id, refs) in usages {
159+
for (file_id, refs) in usages.map_out_of_macros(&ctx.sema) {
160160
edit.edit_file(file_id.file_id(ctx.db()));
161161
for r in refs {
162162
process_struct_name_reference(ctx, r, edit);
@@ -234,7 +234,7 @@ fn edit_field_references(
234234
};
235235
let def = Definition::Field(field);
236236
let usages = def.usages(&ctx.sema).all();
237-
for (file_id, refs) in usages {
237+
for (file_id, refs) in usages.map_out_of_macros(&ctx.sema) {
238238
edit.edit_file(file_id.file_id(ctx.db()));
239239
for r in refs {
240240
if let Some(name_ref) = r.name.as_name_ref() {

crates/ide-assists/src/handlers/convert_tuple_return_type_to_struct.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ide_db::{
66
defs::Definition,
77
helpers::mod_path_to_ast,
88
imports::insert_use::{ImportScope, insert_use},
9-
search::{FileReference, UsageSearchResult},
9+
search::{FileReference, RealFileUsageSearchResult},
1010
source_change::SourceChangeBuilder,
1111
syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
1212
};
@@ -70,7 +70,8 @@ pub(crate) fn convert_tuple_return_type_to_struct(
7070
let ret_type = edit.make_mut(ret_type);
7171
let fn_ = edit.make_mut(fn_);
7272

73-
let usages = Definition::Function(fn_def).usages(&ctx.sema).all();
73+
let usages =
74+
Definition::Function(fn_def).usages(&ctx.sema).all().map_out_of_macros(&ctx.sema);
7475
let struct_name = format!("{}Result", stdx::to_camel_case(&fn_name.to_string()));
7576
let parent = fn_.syntax().ancestors().find_map(<Either<ast::Impl, ast::Trait>>::cast);
7677
add_tuple_struct_def(
@@ -101,7 +102,7 @@ pub(crate) fn convert_tuple_return_type_to_struct(
101102
fn replace_usages(
102103
edit: &mut SourceChangeBuilder,
103104
ctx: &AssistContext<'_>,
104-
usages: &UsageSearchResult,
105+
usages: &RealFileUsageSearchResult,
105106
struct_name: &str,
106107
target_module: &hir::Module,
107108
) {
@@ -231,7 +232,7 @@ fn augment_references_with_imports(
231232
fn add_tuple_struct_def(
232233
edit: &mut SourceChangeBuilder,
233234
ctx: &AssistContext<'_>,
234-
usages: &UsageSearchResult,
235+
usages: &RealFileUsageSearchResult,
235236
parent: &SyntaxNode,
236237
tuple_ty: &ast::TupleType,
237238
struct_name: &str,

0 commit comments

Comments
 (0)