Skip to content

Commit dadd0fd

Browse files
committed
refactor(ide): project semantic targets by intent
1 parent abfa7aa commit dadd0fd

7 files changed

Lines changed: 96 additions & 210 deletions

File tree

crates/ide/src/document_highlight.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,8 @@ pub(crate) fn document_highlight(
3333
let sema = Semantics::new(db);
3434
let hir_file_id = file_id.into();
3535
let parsed_file = sema.parse_file(file_id);
36-
let target = resolve_semantic_target(
37-
db,
38-
file_id,
39-
offset,
40-
parsed_file.root(),
41-
TargetIntent::Highlight,
42-
token_precedence,
43-
);
44-
let SemanticTarget::Source(target) = target.for_highlight()? else {
36+
let target = resolve_semantic_target(db, file_id, offset, parsed_file.root(), token_precedence);
37+
let SemanticTarget::Source(target) = target.for_intent(TargetIntent::Highlight)? else {
4538
return None;
4639
};
4740
let tokens = target.into_tokens();

crates/ide/src/goto_declaration.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,9 @@ pub(crate) fn goto_declaration(
2222
file_id,
2323
offset,
2424
parsed_file.root(),
25-
TargetIntent::Navigate,
2625
goto_definition::token_precedence,
2726
);
28-
let SemanticTarget::Source(target) = target.for_navigation()? else {
27+
let SemanticTarget::Source(target) = target.for_intent(TargetIntent::Navigate)? else {
2928
return None;
3029
};
3130
let (range, tokens) = target.into_parts();

crates/ide/src/goto_definition.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,7 @@ pub(crate) fn goto_definition(
3030
) -> Option<RangeInfo<Vec<NavTarget>>> {
3131
let sema = Semantics::new(db);
3232
let parsed_file = sema.parse_file(file_id);
33-
let target = resolve_semantic_target(
34-
db,
35-
file_id,
36-
offset,
37-
parsed_file.root(),
38-
TargetIntent::Navigate,
39-
token_precedence,
40-
);
33+
let target = resolve_semantic_target(db, file_id, offset, parsed_file.root(), token_precedence);
4134
render_definition_target(db, file_id, &sema, target)
4235
}
4336

@@ -47,7 +40,7 @@ fn render_definition_target(
4740
sema: &Semantics<RootDb>,
4841
target: TargetResolution<'_>,
4942
) -> Option<RangeInfo<Vec<NavTarget>>> {
50-
match target.for_navigation()? {
43+
match target.for_intent(TargetIntent::Navigate)? {
5144
SemanticTarget::PreprocMacro(target) => render_preproc_definition_target(target),
5245
SemanticTarget::Include(includes) => render_include_definition_target(db, includes),
5346
SemanticTarget::Source(target) => {

crates/ide/src/hover.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,7 @@ pub(crate) fn hover(
5353
) -> Option<RangeInfo<Markup>> {
5454
let sema = Semantics::new(db);
5555
let parsed_file = sema.parse_file(file_id);
56-
let target = resolve_semantic_target(
57-
db,
58-
file_id,
59-
offset,
60-
parsed_file.root(),
61-
TargetIntent::Describe,
62-
token_precedence,
63-
);
56+
let target = resolve_semantic_target(db, file_id, offset, parsed_file.root(), token_precedence);
6457
render_hover_target(db, file_id, offset, &sema, target)
6558
}
6659

@@ -71,7 +64,7 @@ fn render_hover_target(
7164
sema: &Semantics<RootDb>,
7265
target: TargetResolution<'_>,
7366
) -> Option<RangeInfo<Markup>> {
74-
match target.for_hover()? {
67+
match target.for_intent(TargetIntent::Describe)? {
7568
SemanticTarget::PreprocMacro(target) => {
7669
render_macro_hover_target(db, file_id, offset, target)
7770
}

crates/ide/src/references.rs

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,7 @@ pub(crate) fn references(
9292
) -> Option<Vec<References>> {
9393
let sema = Semantics::new(db);
9494
let parsed_file = sema.parse_file(file_id);
95-
let target = resolve_semantic_target(
96-
db,
97-
file_id,
98-
offset,
99-
parsed_file.root(),
100-
TargetIntent::FindReferences,
101-
token_precedence,
102-
);
95+
let target = resolve_semantic_target(db, file_id, offset, parsed_file.root(), token_precedence);
10396
render_references_target(db, file_id, &sema, target, config)
10497
}
10598

@@ -110,7 +103,7 @@ fn render_references_target(
110103
target: TargetResolution<'_>,
111104
config: ReferencesConfig,
112105
) -> Option<Vec<References>> {
113-
match target.for_references()? {
106+
match target.for_intent(TargetIntent::FindReferences)? {
114107
SemanticTarget::PreprocMacro(target) => {
115108
render_preproc_references_target(db, file_id, target, &config)
116109
}

crates/ide/src/rename.rs

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -97,33 +97,13 @@ pub struct RenameCollisionInfo {
9797

9898
pub(crate) fn prepare_rename(
9999
db: &RootDb,
100-
FilePosition { file_id, offset }: FilePosition,
100+
position @ FilePosition { file_id, .. }: FilePosition,
101101
config: RenameConfig,
102102
) -> RenameResult<TextRange> {
103103
let sema = Semantics::new(db);
104-
let hir_file_id = file_id.into();
105-
let parsed_file = sema.parse_file(file_id);
106-
let target = resolve_semantic_target(
107-
db,
108-
file_id,
109-
offset,
110-
parsed_file.root(),
111-
TargetIntent::Rename,
112-
rename_token_precedence,
113-
);
114-
let SemanticTarget::Source(target) = target.for_rename().ok_or(RenameError::NoRefFound)? else {
115-
return Err(RenameError::NoRefFound);
116-
};
117-
let token = target.into_tokens().into_iter().next().ok_or(RenameError::NoRefFound)?;
118-
let text_range = token.text_range().ok_or(RenameError::NoRefFound)?;
119-
let def =
120-
match DefinitionClass::resolve(&sema, hir_file_id, token).ok_or(RenameError::NoDefFound)? {
121-
DefinitionClass::Definition(def) => def,
122-
DefinitionClass::PortConnShorthand { local, .. } => local,
123-
DefinitionClass::Ambiguous(_) => return Err(RenameError::NoDefFound),
124-
};
125-
let _ = config.references_config(db, &def, file_id)?;
126-
Ok(text_range)
104+
let target = resolve_rename_target(&sema, position)?;
105+
let _ = config.references_config(db, &target.selected_def, file_id)?;
106+
Ok(target.range)
127107
}
128108

129109
pub(crate) fn rename(
@@ -221,6 +201,7 @@ pub(crate) fn rename_conflict_info(
221201
}
222202

223203
struct ResolvedRenameTarget {
204+
range: TextRange,
224205
selected_def: Definition,
225206
targets: Vec<Definition>,
226207
}
@@ -237,35 +218,51 @@ fn resolve_rename_target(
237218
sema: &Semantics<'_, RootDb>,
238219
FilePosition { file_id, offset }: FilePosition,
239220
) -> RenameResult<ResolvedRenameTarget> {
221+
let hir_file_id = file_id.into();
240222
let parsed_file = sema.parse_file(file_id);
241223
let target = resolve_semantic_target(
242224
sema.db,
243225
file_id,
244226
offset,
245227
parsed_file.root(),
246-
TargetIntent::Rename,
247228
rename_token_precedence,
248229
);
249-
let SemanticTarget::Source(target) = target.for_rename().ok_or(RenameError::NoRefFound)? else {
230+
let SemanticTarget::Source(target) =
231+
target.for_intent(TargetIntent::Rename).ok_or(RenameError::NoRefFound)?
232+
else {
250233
return Err(RenameError::NoRefFound);
251234
};
252-
let token = target.into_tokens().into_iter().next().ok_or(RenameError::NoRefFound)?;
235+
let (range, tokens) = target.into_parts();
236+
let mut selected_def = None;
253237
let mut targets = UniqVec::<Definition, DefinitionOrigin>::default();
254-
let selected_def = match DefinitionClass::resolve(sema, file_id.into(), token)
255-
.ok_or(RenameError::NoDefFound)?
256-
{
257-
DefinitionClass::Definition(def) => {
258-
targets.push(def.origins(), def.clone());
259-
def
260-
}
261-
DefinitionClass::PortConnShorthand { port, local } => {
262-
targets.push(local.origins(), local.clone());
263-
targets.push(port.origins(), port);
264-
local
238+
239+
for token in tokens {
240+
let token_selected = match DefinitionClass::resolve(sema, hir_file_id, token)
241+
.ok_or(RenameError::NoDefFound)?
242+
{
243+
DefinitionClass::Definition(def) => {
244+
targets.push(def.origins(), def.clone());
245+
def
246+
}
247+
DefinitionClass::PortConnShorthand { port, local } => {
248+
targets.push(local.origins(), local.clone());
249+
targets.push(port.origins(), port);
250+
local
251+
}
252+
DefinitionClass::Ambiguous(_) => return Err(RenameError::NoDefFound),
253+
};
254+
255+
match &selected_def {
256+
Some(selected_def) if selected_def != &token_selected => {
257+
return Err(RenameError::NoDefFound);
258+
}
259+
Some(_) => {}
260+
None => selected_def = Some(token_selected),
265261
}
266-
DefinitionClass::Ambiguous(_) => return Err(RenameError::NoDefFound),
267-
};
268-
Ok(ResolvedRenameTarget { selected_def, targets: targets.into_vec() })
262+
}
263+
264+
let selected_def = selected_def.ok_or(RenameError::NoDefFound)?;
265+
Ok(ResolvedRenameTarget { range, selected_def, targets: targets.into_vec() })
269266
}
270267

271268
#[derive(Debug, Clone, PartialEq, Eq)]

0 commit comments

Comments
 (0)