Skip to content

Commit 27e5192

Browse files
bors[bot]matklad
authored andcommitted
7250: Improve analysis stats legibility r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents 5a0b8a2 + 9fd4e5c commit 27e5192

File tree

11 files changed

+275
-219
lines changed

11 files changed

+275
-219
lines changed

crates/assists/src/handlers/extract_struct_from_enum_variant.rs

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use ide_db::helpers::{
66
insert_use::{insert_use, ImportScope},
77
mod_path_to_ast,
88
};
9-
use ide_db::{defs::Definition, search::Reference, RootDatabase};
9+
use ide_db::{defs::Definition, search::FileReference, RootDatabase};
1010
use rustc_hash::{FxHashMap, FxHashSet};
1111
use syntax::{
1212
algo::{find_node_at_offset, SyntaxRewriter},
@@ -59,20 +59,22 @@ pub(crate) fn extract_struct_from_enum_variant(
5959
let current_module = enum_hir.module(ctx.db());
6060
visited_modules_set.insert(current_module);
6161
let mut rewriters = FxHashMap::default();
62-
for reference in usages {
63-
let rewriter = rewriters
64-
.entry(reference.file_range.file_id)
65-
.or_insert_with(SyntaxRewriter::default);
66-
let source_file = ctx.sema.parse(reference.file_range.file_id);
67-
update_reference(
68-
ctx,
69-
rewriter,
70-
reference,
71-
&source_file,
72-
&enum_module_def,
73-
&variant_hir_name,
74-
&mut visited_modules_set,
75-
);
62+
for references in usages {
63+
// FIXME: is the hashmap needed anymore?
64+
let rewriter =
65+
rewriters.entry(references.file_id).or_insert_with(SyntaxRewriter::default);
66+
let source_file = ctx.sema.parse(references.file_id);
67+
for reference in references.refs {
68+
update_reference(
69+
ctx,
70+
rewriter,
71+
reference,
72+
&source_file,
73+
&enum_module_def,
74+
&variant_hir_name,
75+
&mut visited_modules_set,
76+
);
77+
}
7678
}
7779
let mut rewriter =
7880
rewriters.remove(&ctx.frange.file_id).unwrap_or_else(SyntaxRewriter::default);
@@ -205,13 +207,13 @@ fn update_variant(rewriter: &mut SyntaxRewriter, variant: &ast::Variant) -> Opti
205207
fn update_reference(
206208
ctx: &AssistContext,
207209
rewriter: &mut SyntaxRewriter,
208-
reference: Reference,
210+
reference: FileReference,
209211
source_file: &SourceFile,
210212
enum_module_def: &ModuleDef,
211213
variant_hir_name: &Name,
212214
visited_modules_set: &mut FxHashSet<Module>,
213215
) -> Option<()> {
214-
let offset = reference.file_range.range.start();
216+
let offset = reference.range.start();
215217
let (segment, expr) = if let Some(path_expr) =
216218
find_node_at_offset::<ast::PathExpr>(source_file.syntax(), offset)
217219
{

crates/assists/src/handlers/inline_local_variable.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,9 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
6565

6666
let mut wrap_in_parens = vec![true; refs.len()];
6767

68-
for (i, desc) in refs.iter().enumerate() {
69-
let usage_node = ctx
70-
.covering_node_for_range(desc.file_range.range)
71-
.ancestors()
72-
.find_map(ast::PathExpr::cast)?;
68+
for (i, desc) in refs.iter().flat_map(|refs| &refs.refs).enumerate() {
69+
let usage_node =
70+
ctx.covering_node_for_range(desc.range).ancestors().find_map(ast::PathExpr::cast)?;
7371
let usage_parent_option = usage_node.syntax().parent().and_then(ast::Expr::cast);
7472
let usage_parent = match usage_parent_option {
7573
Some(u) => u,
@@ -116,15 +114,15 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
116114
target,
117115
move |builder| {
118116
builder.delete(delete_range);
119-
for (desc, should_wrap) in refs.iter().zip(wrap_in_parens) {
117+
for (desc, should_wrap) in refs.iter().flat_map(|refs| &refs.refs).zip(wrap_in_parens) {
120118
let replacement =
121119
if should_wrap { init_in_paren.clone() } else { init_str.clone() };
122120
match desc.kind {
123121
ReferenceKind::FieldShorthandForLocal => {
124122
mark::hit!(inline_field_shorthand);
125-
builder.insert(desc.file_range.range.end(), format!(": {}", replacement))
123+
builder.insert(desc.range.end(), format!(": {}", replacement))
126124
}
127-
_ => builder.replace(desc.file_range.range, replacement),
125+
_ => builder.replace(desc.range, replacement),
128126
}
129127
}
130128
},

crates/assists/src/handlers/remove_unused_param.rs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use ide_db::{defs::Definition, search::Reference};
1+
use ide_db::{defs::Definition, search::FileReferences};
22
use syntax::{
33
algo::find_node_at_range,
44
ast::{self, ArgListOwner},
@@ -58,30 +58,30 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext) -> Opt
5858
param.syntax().text_range(),
5959
|builder| {
6060
builder.delete(range_to_remove(param.syntax()));
61-
for usage in fn_def.usages(&ctx.sema).all() {
62-
process_usage(ctx, builder, usage, param_position);
61+
for usages in fn_def.usages(&ctx.sema).all() {
62+
process_usages(ctx, builder, usages, param_position);
6363
}
6464
},
6565
)
6666
}
6767

68-
fn process_usage(
68+
fn process_usages(
6969
ctx: &AssistContext,
7070
builder: &mut AssistBuilder,
71-
usage: Reference,
71+
usages: FileReferences,
7272
arg_to_remove: usize,
7373
) -> Option<()> {
74-
let source_file = ctx.sema.parse(usage.file_range.file_id);
75-
let call_expr: ast::CallExpr =
76-
find_node_at_range(source_file.syntax(), usage.file_range.range)?;
77-
let call_expr_range = call_expr.expr()?.syntax().text_range();
78-
if !call_expr_range.contains_range(usage.file_range.range) {
79-
return None;
74+
let source_file = ctx.sema.parse(usages.file_id);
75+
builder.edit_file(usages.file_id);
76+
for usage in usages.refs {
77+
let call_expr: ast::CallExpr = find_node_at_range(source_file.syntax(), usage.range)?;
78+
let call_expr_range = call_expr.expr()?.syntax().text_range();
79+
if !call_expr_range.contains_range(usage.range) {
80+
return None;
81+
}
82+
let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?;
83+
builder.delete(range_to_remove(arg.syntax()));
8084
}
81-
let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?;
82-
83-
builder.edit_file(usage.file_range.file_id);
84-
builder.delete(range_to_remove(arg.syntax()));
8585

8686
Some(())
8787
}

crates/ide/src/call_hierarchy.rs

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
use indexmap::IndexMap;
44

55
use hir::Semantics;
6-
use ide_db::call_info::FnCallNode;
76
use ide_db::RootDatabase;
7+
use ide_db::{call_info::FnCallNode, search::FileReferences};
88
use syntax::{ast, AstNode, TextRange};
99

1010
use crate::{
@@ -47,22 +47,23 @@ pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Optio
4747

4848
let mut calls = CallLocations::default();
4949

50-
for reference in refs.info.references() {
51-
let file_id = reference.file_range.file_id;
50+
for &FileReferences { file_id, ref refs } in refs.info.references() {
5251
let file = sema.parse(file_id);
5352
let file = file.syntax();
54-
let token = file.token_at_offset(reference.file_range.range.start()).next()?;
55-
let token = sema.descend_into_macros(token);
56-
let syntax = token.parent();
57-
58-
// This target is the containing function
59-
if let Some(nav) = syntax.ancestors().find_map(|node| {
60-
let fn_ = ast::Fn::cast(node)?;
61-
let def = sema.to_def(&fn_)?;
62-
def.try_to_nav(sema.db)
63-
}) {
64-
let relative_range = reference.file_range.range;
65-
calls.add(&nav, relative_range);
53+
for reference in refs {
54+
let token = file.token_at_offset(reference.range.start()).next()?;
55+
let token = sema.descend_into_macros(token);
56+
let syntax = token.parent();
57+
58+
// This target is the containing function
59+
if let Some(nav) = syntax.ancestors().find_map(|node| {
60+
let fn_ = ast::Fn::cast(node)?;
61+
let def = sema.to_def(&fn_)?;
62+
def.try_to_nav(sema.db)
63+
}) {
64+
let relative_range = reference.range;
65+
calls.add(&nav, relative_range);
66+
}
6667
}
6768
}
6869

crates/ide/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ pub use ide_db::base_db::{
9292
};
9393
pub use ide_db::{
9494
call_info::CallInfo,
95-
search::{Reference, ReferenceAccess, ReferenceKind},
95+
search::{FileReference, ReferenceAccess, ReferenceKind},
9696
};
9797
pub use ide_db::{
9898
label::Label,

crates/ide/src/references.rs

Lines changed: 53 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub(crate) mod rename;
1414
use hir::Semantics;
1515
use ide_db::{
1616
defs::{Definition, NameClass, NameRefClass},
17-
search::Reference,
18-
search::{ReferenceAccess, ReferenceKind, SearchScope},
17+
search::FileReference,
18+
search::{FileReferences, ReferenceAccess, ReferenceKind, SearchScope},
1919
RootDatabase,
2020
};
2121
use syntax::{
@@ -29,7 +29,7 @@ use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeI
2929
#[derive(Debug, Clone)]
3030
pub struct ReferenceSearchResult {
3131
declaration: Declaration,
32-
references: Vec<Reference>,
32+
references: Vec<FileReferences>,
3333
}
3434

3535
#[derive(Debug, Clone)]
@@ -48,7 +48,7 @@ impl ReferenceSearchResult {
4848
&self.declaration.nav
4949
}
5050

51-
pub fn references(&self) -> &[Reference] {
51+
pub fn references(&self) -> &[FileReferences] {
5252
&self.references
5353
}
5454

@@ -63,20 +63,22 @@ impl ReferenceSearchResult {
6363
// allow turning ReferenceSearchResult into an iterator
6464
// over References
6565
impl IntoIterator for ReferenceSearchResult {
66-
type Item = Reference;
67-
type IntoIter = std::vec::IntoIter<Reference>;
66+
type Item = FileReferences;
67+
type IntoIter = std::vec::IntoIter<FileReferences>;
6868

6969
fn into_iter(mut self) -> Self::IntoIter {
7070
let mut v = Vec::with_capacity(self.len());
71-
v.push(Reference {
72-
file_range: FileRange {
73-
file_id: self.declaration.nav.file_id,
74-
range: self.declaration.nav.focus_or_full_range(),
75-
},
71+
v.append(&mut self.references);
72+
let decl_ref = FileReference {
73+
range: self.declaration.nav.focus_or_full_range(),
7674
kind: self.declaration.kind,
7775
access: self.declaration.access,
78-
});
79-
v.append(&mut self.references);
76+
};
77+
let file_id = self.declaration.nav.file_id;
78+
match v.iter_mut().find(|it| it.file_id == file_id) {
79+
Some(refs) => refs.refs.push(decl_ref),
80+
None => v.push(FileReferences { file_id, refs: vec![decl_ref] }),
81+
}
8082
v.into_iter()
8183
}
8284
}
@@ -109,13 +111,11 @@ pub(crate) fn find_all_refs(
109111

110112
let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?;
111113

112-
let references = def
113-
.usages(sema)
114-
.set_scope(search_scope)
115-
.all()
116-
.into_iter()
117-
.filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
118-
.collect();
114+
let mut references = def.usages(sema).set_scope(search_scope).all();
115+
references.iter_mut().for_each(|it| {
116+
it.refs.retain(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
117+
});
118+
references.retain(|r| !r.refs.is_empty());
119119

120120
let nav = def.try_to_nav(sema.db)?;
121121
let decl_range = nav.focus_or_full_range();
@@ -255,7 +255,8 @@ fn try_find_self_references(
255255
syntax: &SyntaxNode,
256256
position: FilePosition,
257257
) -> Option<RangeInfo<ReferenceSearchResult>> {
258-
let self_token = syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self])?;
258+
let FilePosition { file_id, offset } = position;
259+
let self_token = syntax.token_at_offset(offset).find(|t| t.kind() == T![self])?;
259260
let parent = self_token.parent();
260261
match_ast! {
261262
match parent {
@@ -276,7 +277,7 @@ fn try_find_self_references(
276277

277278
let declaration = Declaration {
278279
nav: NavigationTarget {
279-
file_id: position.file_id,
280+
file_id,
280281
full_range: self_param.syntax().text_range(),
281282
focus_range: Some(param_self_token.text_range()),
282283
name: param_self_token.text().clone(),
@@ -295,25 +296,29 @@ fn try_find_self_references(
295296
let references = function
296297
.body()
297298
.map(|body| {
298-
body.syntax()
299-
.descendants()
300-
.filter_map(ast::PathExpr::cast)
301-
.filter_map(|expr| {
302-
let path = expr.path()?;
303-
if path.qualifier().is_none() {
304-
path.segment()?.self_token()
305-
} else {
306-
None
307-
}
308-
})
309-
.map(|token| Reference {
310-
file_range: FileRange { file_id: position.file_id, range: token.text_range() },
311-
kind: ReferenceKind::SelfKw,
312-
access: declaration.access, // FIXME: properly check access kind here instead of copying it from the declaration
313-
})
314-
.collect()
299+
FileReferences {
300+
file_id,
301+
refs: body
302+
.syntax()
303+
.descendants()
304+
.filter_map(ast::PathExpr::cast)
305+
.filter_map(|expr| {
306+
let path = expr.path()?;
307+
if path.qualifier().is_none() {
308+
path.segment()?.self_token()
309+
} else {
310+
None
311+
}
312+
})
313+
.map(|token| FileReference {
314+
range: token.text_range(),
315+
kind: ReferenceKind::SelfKw,
316+
access: declaration.access, // FIXME: properly check access kind here instead of copying it from the declaration
317+
})
318+
.collect(),
319+
}
315320
})
316-
.unwrap_or_default();
321+
.map_or_else(Vec::default, |it| vec![it]);
317322

318323
Some(RangeInfo::new(
319324
param_self_token.text_range(),
@@ -324,7 +329,7 @@ fn try_find_self_references(
324329
#[cfg(test)]
325330
mod tests {
326331
use expect_test::{expect, Expect};
327-
use ide_db::base_db::FileId;
332+
use ide_db::{base_db::FileId, search::FileReferences};
328333
use stdx::format_to;
329334

330335
use crate::{fixture, SearchScope};
@@ -1018,12 +1023,14 @@ impl Foo {
10181023
actual += "\n\n";
10191024
}
10201025

1021-
for r in &refs.references {
1022-
format_to!(actual, "{:?} {:?} {:?}", r.file_range.file_id, r.file_range.range, r.kind);
1023-
if let Some(access) = r.access {
1024-
format_to!(actual, " {:?}", access);
1026+
for FileReferences { file_id, refs } in refs.references {
1027+
for r in refs {
1028+
format_to!(actual, "{:?} {:?} {:?}", file_id, r.range, r.kind);
1029+
if let Some(access) = r.access {
1030+
format_to!(actual, " {:?}", access);
1031+
}
1032+
actual += "\n";
10251033
}
1026-
actual += "\n";
10271034
}
10281035
expect.assert_eq(&actual)
10291036
}

0 commit comments

Comments
 (0)