Skip to content

Commit 2538fdb

Browse files
authored
Merge pull request #21415 from Veykril/push-qusurvyqwmxt
feat: Allow rust paths in symbol search
2 parents 25c155a + c471c5c commit 2538fdb

File tree

11 files changed

+1166
-242
lines changed

11 files changed

+1166
-242
lines changed

crates/hir/src/symbols.rs

Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use hir_def::{
99
ModuleDefId, ModuleId, TraitId,
1010
db::DefDatabase,
1111
item_scope::{ImportId, ImportOrExternCrate, ImportOrGlob},
12+
nameres::crate_def_map,
1213
per_ns::Item,
1314
src::{HasChildSource, HasSource},
1415
visibility::{Visibility, VisibilityExplicitness},
@@ -40,14 +41,14 @@ pub struct FileSymbol<'db> {
4041
_marker: PhantomData<&'db ()>,
4142
}
4243

43-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
44+
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
4445
pub struct DeclarationLocation {
4546
/// The file id for both the `ptr` and `name_ptr`.
4647
pub hir_file_id: HirFileId,
4748
/// This points to the whole syntax node of the declaration.
4849
pub ptr: SyntaxNodePtr,
4950
/// This points to the [`syntax::ast::Name`] identifier of the declaration.
50-
pub name_ptr: AstPtr<Either<syntax::ast::Name, syntax::ast::NameRef>>,
51+
pub name_ptr: Option<AstPtr<Either<syntax::ast::Name, syntax::ast::NameRef>>>,
5152
}
5253

5354
impl DeclarationLocation {
@@ -99,6 +100,11 @@ impl<'a> SymbolCollector<'a> {
99100
let _p = tracing::info_span!("SymbolCollector::collect", ?module).entered();
100101
tracing::info!(?module, "SymbolCollector::collect");
101102

103+
// If this is a crate root module, add a symbol for the crate itself
104+
if module.is_crate_root(self.db) {
105+
self.push_crate_root(module);
106+
}
107+
102108
// The initial work is the root module we're collecting, additional work will
103109
// be populated as we traverse the module's definitions.
104110
self.work.push(SymbolCollectorWork { module_id: module.into(), parent: None });
@@ -108,6 +114,51 @@ impl<'a> SymbolCollector<'a> {
108114
}
109115
}
110116

117+
/// Push a symbol for a crate's root module.
118+
/// This allows crate roots to appear in the symbol index for queries like `::` or `::foo`.
119+
fn push_crate_root(&mut self, module: Module) {
120+
let krate = module.krate(self.db);
121+
let Some(display_name) = krate.display_name(self.db) else { return };
122+
let crate_name = display_name.crate_name();
123+
let canonical_name = display_name.canonical_name();
124+
125+
let def_map = crate_def_map(self.db, krate.into());
126+
let module_data = &def_map[def_map.crate_root(self.db)];
127+
128+
let definition = module_data.origin.definition_source(self.db);
129+
let hir_file_id = definition.file_id;
130+
let syntax_node = definition.value.node();
131+
let ptr = SyntaxNodePtr::new(&syntax_node);
132+
133+
let loc = DeclarationLocation { hir_file_id, ptr, name_ptr: None };
134+
135+
self.symbols.insert(FileSymbol {
136+
name: crate_name.symbol().clone(),
137+
def: ModuleDef::Module(module),
138+
loc,
139+
container_name: None,
140+
is_alias: false,
141+
is_assoc: false,
142+
is_import: false,
143+
do_not_complete: Complete::Yes,
144+
_marker: PhantomData,
145+
});
146+
147+
if canonical_name != crate_name.symbol() {
148+
self.symbols.insert(FileSymbol {
149+
name: canonical_name.clone(),
150+
def: ModuleDef::Module(module),
151+
loc,
152+
container_name: None,
153+
is_alias: false,
154+
is_assoc: false,
155+
is_import: false,
156+
do_not_complete: Complete::Yes,
157+
_marker: PhantomData,
158+
});
159+
}
160+
}
161+
111162
pub fn finish(self) -> Box<[FileSymbol<'a>]> {
112163
self.symbols.into_iter().collect()
113164
}
@@ -209,7 +260,7 @@ impl<'a> SymbolCollector<'a> {
209260
let dec_loc = DeclarationLocation {
210261
hir_file_id: source.file_id,
211262
ptr: SyntaxNodePtr::new(use_tree_src.syntax()),
212-
name_ptr: AstPtr::new(&name_syntax),
263+
name_ptr: Some(AstPtr::new(&name_syntax)),
213264
};
214265
this.symbols.insert(FileSymbol {
215266
name: name.symbol().clone(),
@@ -244,7 +295,7 @@ impl<'a> SymbolCollector<'a> {
244295
let dec_loc = DeclarationLocation {
245296
hir_file_id: source.file_id,
246297
ptr: SyntaxNodePtr::new(source.value.syntax()),
247-
name_ptr: AstPtr::new(&name_syntax),
298+
name_ptr: Some(AstPtr::new(&name_syntax)),
248299
};
249300
this.symbols.insert(FileSymbol {
250301
name: name.symbol().clone(),
@@ -409,10 +460,10 @@ impl<'a> SymbolCollector<'a> {
409460
let source = loc.source(self.db);
410461
let Some(name_node) = source.value.name() else { return Complete::Yes };
411462
let def = ModuleDef::from(id.into());
412-
let dec_loc = DeclarationLocation {
463+
let loc = DeclarationLocation {
413464
hir_file_id: source.file_id,
414465
ptr: SyntaxNodePtr::new(source.value.syntax()),
415-
name_ptr: AstPtr::new(&name_node).wrap_left(),
466+
name_ptr: Some(AstPtr::new(&name_node).wrap_left()),
416467
};
417468

418469
let mut do_not_complete = Complete::Yes;
@@ -427,7 +478,7 @@ impl<'a> SymbolCollector<'a> {
427478
self.symbols.insert(FileSymbol {
428479
name: alias.clone(),
429480
def,
430-
loc: dec_loc.clone(),
481+
loc,
431482
container_name: self.current_container_name.clone(),
432483
is_alias: true,
433484
is_assoc,
@@ -442,7 +493,7 @@ impl<'a> SymbolCollector<'a> {
442493
name: name.symbol().clone(),
443494
def,
444495
container_name: self.current_container_name.clone(),
445-
loc: dec_loc,
496+
loc,
446497
is_alias: false,
447498
is_assoc,
448499
is_import: false,
@@ -459,10 +510,10 @@ impl<'a> SymbolCollector<'a> {
459510
let Some(declaration) = module_data.origin.declaration() else { return };
460511
let module = declaration.to_node(self.db);
461512
let Some(name_node) = module.name() else { return };
462-
let dec_loc = DeclarationLocation {
513+
let loc = DeclarationLocation {
463514
hir_file_id: declaration.file_id,
464515
ptr: SyntaxNodePtr::new(module.syntax()),
465-
name_ptr: AstPtr::new(&name_node).wrap_left(),
516+
name_ptr: Some(AstPtr::new(&name_node).wrap_left()),
466517
};
467518

468519
let def = ModuleDef::Module(module_id.into());
@@ -475,7 +526,7 @@ impl<'a> SymbolCollector<'a> {
475526
self.symbols.insert(FileSymbol {
476527
name: alias.clone(),
477528
def,
478-
loc: dec_loc.clone(),
529+
loc,
479530
container_name: self.current_container_name.clone(),
480531
is_alias: true,
481532
is_assoc: false,
@@ -490,7 +541,7 @@ impl<'a> SymbolCollector<'a> {
490541
name: name.symbol().clone(),
491542
def: ModuleDef::Module(module_id.into()),
492543
container_name: self.current_container_name.clone(),
493-
loc: dec_loc,
544+
loc,
494545
is_alias: false,
495546
is_assoc: false,
496547
is_import: false,

0 commit comments

Comments
 (0)