Skip to content

Commit 36f6126

Browse files
committed
feat: add semantic indexes for references and module hierarchy
1 parent 8285fc6 commit 36f6126

8 files changed

Lines changed: 822 additions & 301 deletions

File tree

crates/ide/src/analysis.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ use crate::{
3939
references::{self, References, ReferencesConfig},
4040
rename::{self, RenameConfig, RenameResult},
4141
selection_ranges,
42+
semantic_index::{self, ModuleCallEdge},
4243
semantic_tokens::{self, SemaToken, SemaTokenConfig},
4344
signature_help::{self, SignatureHelp, SignatureHelpConfig},
4445
source_change::SourceChange,
@@ -184,6 +185,22 @@ impl Analysis {
184185
self.with_db(|db| references::references(db, position, config))
185186
}
186187

188+
pub fn module_incoming_calls(
189+
&self,
190+
file_id: FileId,
191+
name_range: TextRange,
192+
) -> Cancellable<Vec<ModuleCallEdge>> {
193+
self.with_db(|db| semantic_index::incoming_module_edges(db, file_id, name_range))
194+
}
195+
196+
pub fn module_outgoing_calls(
197+
&self,
198+
file_id: FileId,
199+
name_range: TextRange,
200+
) -> Cancellable<Vec<ModuleCallEdge>> {
201+
self.with_db(|db| semantic_index::outgoing_module_edges(db, file_id, name_range))
202+
}
203+
187204
pub fn prepare_rename(
188205
&self,
189206
position: FilePosition,

crates/ide/src/db/workspace_symbol_index_db.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,15 @@ use vfs::FileId;
77

88
use crate::{
99
db::root_db::RootDb,
10+
semantic_index::{ModuleIndex, SemanticIndex},
1011
workspace_symbols::{SymbolIndex, WorkspaceSymbol},
1112
};
1213

1314
#[salsa::query_group(WorkspaceSymbolIndexDbStorage)]
1415
pub trait WorkspaceSymbolIndexDb: SourceRootDb + HirDb {
1516
fn file_workspace_symbols(&self, file_id: FileId) -> Arc<[WorkspaceSymbol]>;
1617
fn source_root_symbol_index(&self, source_root_id: SourceRootId) -> Arc<SymbolIndex>;
18+
fn source_root_module_index(&self, source_root_id: SourceRootId) -> Arc<ModuleIndex>;
1719
}
1820

1921
fn file_workspace_symbols(
@@ -30,9 +32,30 @@ fn source_root_symbol_index(
3032
Arc::new(SymbolIndex::for_source_root(db, source_root_id))
3133
}
3234

35+
fn source_root_module_index(
36+
db: &dyn WorkspaceSymbolIndexDb,
37+
source_root_id: SourceRootId,
38+
) -> Arc<ModuleIndex> {
39+
Arc::new(ModuleIndex::for_source_root(db, source_root_id))
40+
}
41+
3342
pub(crate) fn source_root_symbol_index_for_root(
3443
db: &RootDb,
3544
source_root_id: SourceRootId,
3645
) -> Arc<SymbolIndex> {
3746
WorkspaceSymbolIndexDb::source_root_symbol_index(db, source_root_id)
3847
}
48+
49+
pub(crate) fn source_root_module_index_for_root(
50+
db: &RootDb,
51+
source_root_id: SourceRootId,
52+
) -> Arc<ModuleIndex> {
53+
WorkspaceSymbolIndexDb::source_root_module_index(db, source_root_id)
54+
}
55+
56+
pub(crate) fn source_root_semantic_index_for_root(
57+
db: &RootDb,
58+
source_root_id: SourceRootId,
59+
) -> Arc<SemanticIndex> {
60+
Arc::new(SemanticIndex::for_source_root(db, source_root_id))
61+
}

crates/ide/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub mod range;
4040
pub mod references;
4141
pub mod rename;
4242
pub mod selection_ranges;
43+
pub mod semantic_index;
4344
pub(crate) mod semantic_target;
4445
pub mod semantic_tokens;
4546
pub mod signature_help;

crates/ide/src/module_resolution.rs

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
use std::cmp::Ordering;
22

33
use hir::{
4-
base_db::{source_db::SourceRootDb, source_root::SourceRootRole},
4+
base_db::{
5+
source_db::{SourceDb, SourceRootDb},
6+
source_root::SourceRootRole,
7+
},
58
container::InModule,
69
db::HirDb,
710
hir_def::{
@@ -11,7 +14,7 @@ use hir::{
1114
lower_ident_opt,
1215
module::{ModuleId, instantiation::Instantiation},
1316
},
14-
scope::{ModuleEntry, ScopeResolution},
17+
scope::ModuleEntry,
1518
semantics::pathres::PathResolution,
1619
};
1720
use syntax::{
@@ -21,7 +24,7 @@ use syntax::{
2124
use utils::get::GetRef;
2225
use vfs::{FileId, VfsPath};
2326

24-
use crate::db::root_db::RootDb;
27+
use crate::db::{root_db::RootDb, workspace_symbol_index_db::source_root_module_index_for_root};
2528

2629
#[derive(Debug, Clone, PartialEq, Eq)]
2730
pub(crate) enum ModuleResolution {
@@ -154,13 +157,34 @@ fn resolve_module_name_with_policy(
154157
name: &Ident,
155158
policy: ModuleResolutionPolicy,
156159
) -> ModuleResolution {
157-
match db.unit_scope().resolve_module(name) {
158-
ScopeResolution::Unique(module_id) => ModuleResolution::Unique(module_id),
159-
ScopeResolution::Unresolved => ModuleResolution::Unresolved,
160-
ScopeResolution::Ambiguous(candidates) => {
161-
policy.resolve_ambiguous(db, candidates.into_vec())
162-
}
160+
let candidates = module_candidates(db, name);
161+
match candidates.as_slice() {
162+
[module_id] => ModuleResolution::Unique(*module_id),
163+
[] => ModuleResolution::Unresolved,
164+
_ => policy.resolve_ambiguous(db, candidates),
165+
}
166+
}
167+
168+
fn module_candidates(db: &RootDb, name: &Ident) -> Vec<ModuleId> {
169+
let mut source_root_ids =
170+
db.files().iter().map(|&file_id| db.source_root_id(file_id)).collect::<Vec<_>>();
171+
source_root_ids.sort_unstable();
172+
source_root_ids.dedup();
173+
174+
let mut candidates = Vec::new();
175+
for source_root_id in source_root_ids {
176+
let module_index = source_root_module_index_for_root(db, source_root_id);
177+
candidates.extend(
178+
module_index
179+
.module_definitions(name)
180+
.iter()
181+
.map(|module| (module.file_id, module.name_range.start(), module.module_id)),
182+
);
163183
}
184+
185+
candidates.sort_by_key(|(file_id, name_start, _)| (file_id.0, *name_start));
186+
candidates.dedup_by_key(|(_, _, module_id)| *module_id);
187+
candidates.into_iter().map(|(_, _, module_id)| module_id).collect()
164188
}
165189

166190
#[derive(Debug, Clone, Copy, PartialEq, Eq)]

0 commit comments

Comments
 (0)