Skip to content

Commit c4af9d0

Browse files
committed
refactor(ide): use target alternatives for declarations
1 parent 1716760 commit c4af9d0

1 file changed

Lines changed: 45 additions & 5 deletions

File tree

crates/ide/src/goto_declaration.rs

Lines changed: 45 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use hir::semantics::Semantics;
1+
use hir::{file::HirFileId, semantics::Semantics};
22
use itertools::Itertools;
3+
use utils::line_index::TextRange;
34

45
use crate::{
56
FilePosition, RangeInfo,
@@ -8,6 +9,7 @@ use crate::{
89
goto_definition,
910
navigation_target::{NavTarget, ToNav},
1011
semantic_target::{SemanticTarget, TargetIntent, resolve_semantic_target},
12+
source_targets::SourceTarget,
1113
};
1214

1315
pub(crate) fn goto_declaration(
@@ -24,14 +26,46 @@ pub(crate) fn goto_declaration(
2426
parsed_file.root(),
2527
goto_definition::token_precedence,
2628
);
27-
let SemanticTarget::Source(target) = target.unique_for_intent(TargetIntent::Navigate)? else {
28-
return None;
29-
};
29+
render_declaration_target(
30+
db,
31+
hir_file_id,
32+
&sema,
33+
target.targets_for_intent(TargetIntent::Navigate),
34+
)
35+
}
36+
37+
fn render_declaration_target(
38+
db: &RootDb,
39+
hir_file_id: HirFileId,
40+
sema: &Semantics<RootDb>,
41+
targets: Vec<SemanticTarget<'_>>,
42+
) -> Option<RangeInfo<Vec<NavTarget>>> {
43+
let mut ranges = Vec::new();
44+
let mut navs = Vec::new();
45+
for target in targets {
46+
let SemanticTarget::Source(target) = target else {
47+
return None;
48+
};
49+
let target = render_source_declaration_target(db, hir_file_id, sema, target)?;
50+
ranges.push(target.range);
51+
navs.extend(target.info);
52+
}
53+
54+
let range = covering_range(&ranges)?;
55+
Some(RangeInfo::new(range, navs.into_iter().unique().collect()))
56+
}
57+
58+
fn render_source_declaration_target(
59+
db: &RootDb,
60+
hir_file_id: HirFileId,
61+
sema: &Semantics<RootDb>,
62+
target: SourceTarget<'_>,
63+
) -> Option<RangeInfo<Vec<NavTarget>>> {
3064
let (range, tokens) = target.into_parts();
3165

3266
let origins = tokens
3367
.into_iter()
34-
.filter_map(|token| match DefinitionClass::resolve(&sema, hir_file_id, token)? {
68+
.filter_map(|token| match DefinitionClass::resolve(sema, hir_file_id, token)? {
3569
DefinitionClass::Definition(definition) => {
3670
Some(definition.declaration_origins().into_iter().collect_vec())
3771
}
@@ -52,3 +86,9 @@ pub(crate) fn goto_declaration(
5286

5387
Some(RangeInfo::new(range, navs))
5488
}
89+
90+
fn covering_range(ranges: &[TextRange]) -> Option<TextRange> {
91+
let start = ranges.iter().map(|range| range.start()).min()?;
92+
let end = ranges.iter().map(|range| range.end()).max()?;
93+
Some(TextRange::new(start, end))
94+
}

0 commit comments

Comments
 (0)