Skip to content

Commit 13b25d7

Browse files
bors[bot]matklad
andauthored
Merge #3426
3426: Refactor reference search a bit r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
2 parents cebb995 + 7d71cc7 commit 13b25d7

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

crates/ra_hir/src/code_model.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use hir_ty::{
2727
use ra_db::{CrateId, Edition, FileId};
2828
use ra_prof::profile;
2929
use ra_syntax::{
30-
ast::{self, AttrsOwner},
30+
ast::{self, AttrsOwner, NameOwner},
3131
AstNode,
3232
};
3333
use rustc_hash::FxHashSet;
@@ -603,6 +603,10 @@ impl Static {
603603
pub fn krate(self, db: &impl DefDatabase) -> Option<Crate> {
604604
Some(self.module(db).krate())
605605
}
606+
607+
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
608+
db.static_data(self.id).name.clone()
609+
}
606610
}
607611

608612
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -674,6 +678,11 @@ impl MacroDef {
674678
let module_id = db.crate_def_map(krate).root;
675679
Some(Module::new(Crate { id: krate }, module_id))
676680
}
681+
682+
/// XXX: this parses the file
683+
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
684+
self.source(db).value.name().map(|it| it.as_name())
685+
}
677686
}
678687

679688
/// Invariant: `inner.as_assoc_item(db).is_some()`
@@ -783,6 +792,7 @@ pub struct Local {
783792
}
784793

785794
impl Local {
795+
// FIXME: why is this an option? It shouldn't be?
786796
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
787797
let body = db.body(self.parent.into());
788798
match &body[self.pat_id] {

crates/ra_ide/src/references.rs

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,29 @@ pub(crate) fn find_all_refs(
125125
(find_node_at_offset::<ast::Name>(&syntax, position.offset), ReferenceKind::Other)
126126
};
127127

128-
let RangeInfo { range, info: (name, def) } = find_name(&sema, &syntax, position, opt_name)?;
129-
let declaration = def.try_to_nav(db)?;
128+
let RangeInfo { range, info: def } = find_name(&sema, &syntax, position, opt_name)?;
130129

130+
let references = find_refs_to_def(db, &def, search_scope)
131+
.into_iter()
132+
.filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
133+
.collect();
134+
135+
let decl_range = def.try_to_nav(db)?.range();
136+
137+
let declaration = Declaration {
138+
nav: def.try_to_nav(db)?,
139+
kind: ReferenceKind::Other,
140+
access: decl_access(&def, &syntax, decl_range),
141+
};
142+
143+
Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }))
144+
}
145+
146+
pub(crate) fn find_refs_to_def(
147+
db: &RootDatabase,
148+
def: &NameDefinition,
149+
search_scope: Option<SearchScope>,
150+
) -> Vec<Reference> {
131151
let search_scope = {
132152
let base = SearchScope::for_def(&def, db);
133153
match search_scope {
@@ -136,42 +156,34 @@ pub(crate) fn find_all_refs(
136156
}
137157
};
138158

139-
let decl_range = declaration.range();
140-
141-
let declaration = Declaration {
142-
nav: declaration,
143-
kind: ReferenceKind::Other,
144-
access: decl_access(&def, &name, &syntax, decl_range),
159+
let name = match def.name(db) {
160+
None => return Vec::new(),
161+
Some(it) => it.to_string(),
145162
};
146163

147-
let references = process_definition(db, def, name, search_scope)
148-
.into_iter()
149-
.filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
150-
.collect();
151-
152-
Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references }))
164+
process_definition(db, def, name, search_scope)
153165
}
154166

155167
fn find_name(
156168
sema: &Semantics<RootDatabase>,
157169
syntax: &SyntaxNode,
158170
position: FilePosition,
159171
opt_name: Option<ast::Name>,
160-
) -> Option<RangeInfo<(String, NameDefinition)>> {
172+
) -> Option<RangeInfo<NameDefinition>> {
161173
if let Some(name) = opt_name {
162174
let def = classify_name(sema, &name)?.definition();
163175
let range = name.syntax().text_range();
164-
return Some(RangeInfo::new(range, (name.text().to_string(), def)));
176+
return Some(RangeInfo::new(range, def));
165177
}
166178
let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?;
167179
let def = classify_name_ref(sema, &name_ref)?.definition();
168180
let range = name_ref.syntax().text_range();
169-
Some(RangeInfo::new(range, (name_ref.text().to_string(), def)))
181+
Some(RangeInfo::new(range, def))
170182
}
171183

172184
fn process_definition(
173185
db: &RootDatabase,
174-
def: NameDefinition,
186+
def: &NameDefinition,
175187
name: String,
176188
scope: SearchScope,
177189
) -> Vec<Reference> {
@@ -217,7 +229,7 @@ fn process_definition(
217229

218230
if let Some(d) = classify_name_ref(&sema, &name_ref) {
219231
let d = d.definition();
220-
if d == def {
232+
if &d == def {
221233
let kind =
222234
if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
223235
ReferenceKind::StructLiteral
@@ -240,7 +252,6 @@ fn process_definition(
240252

241253
fn decl_access(
242254
def: &NameDefinition,
243-
name: &str,
244255
syntax: &SyntaxNode,
245256
range: TextRange,
246257
) -> Option<ReferenceAccess> {
@@ -253,7 +264,7 @@ fn decl_access(
253264
if stmt.initializer().is_some() {
254265
let pat = stmt.pat()?;
255266
if let ast::Pat::BindPat(it) = pat {
256-
if it.name()?.text().as_str() == name {
267+
if it.is_mutable() {
257268
return Some(ReferenceAccess::Write);
258269
}
259270
}
@@ -463,7 +474,7 @@ mod tests {
463474
let refs = get_all_refs(code);
464475
check_result(
465476
refs,
466-
"spam BIND_PAT FileId(1) [44; 48) Other Write",
477+
"spam BIND_PAT FileId(1) [44; 48) Other",
467478
&["FileId(1) [71; 75) Other Read", "FileId(1) [78; 82) Other Read"],
468479
);
469480
}
@@ -709,15 +720,15 @@ mod tests {
709720
fn test_basic_highlight_read_write() {
710721
let code = r#"
711722
fn foo() {
712-
let i<|> = 0;
723+
let mut i<|> = 0;
713724
i = i + 1;
714725
}"#;
715726

716727
let refs = get_all_refs(code);
717728
check_result(
718729
refs,
719-
"i BIND_PAT FileId(1) [36; 37) Other Write",
720-
&["FileId(1) [55; 56) Other Write", "FileId(1) [59; 60) Other Read"],
730+
"i BIND_PAT FileId(1) [40; 41) Other Write",
731+
&["FileId(1) [59; 60) Other Write", "FileId(1) [63; 64) Other Read"],
721732
);
722733
}
723734

crates/ra_ide_db/src/defs.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// FIXME: this badly needs rename/rewrite (matklad, 2020-02-06).
77

88
use hir::{
9-
Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Semantics,
9+
Adt, FieldSource, HasSource, ImplDef, Local, MacroDef, Module, ModuleDef, Name, Semantics,
1010
StructField, TypeParam,
1111
};
1212
use ra_prof::profile;
@@ -66,6 +66,32 @@ impl NameDefinition {
6666
NameDefinition::TypeParam(_) => None,
6767
}
6868
}
69+
70+
pub fn name(&self, db: &RootDatabase) -> Option<Name> {
71+
let name = match self {
72+
NameDefinition::Macro(it) => it.name(db)?,
73+
NameDefinition::StructField(it) => it.name(db),
74+
NameDefinition::ModuleDef(def) => match def {
75+
hir::ModuleDef::Module(it) => it.name(db)?,
76+
hir::ModuleDef::Function(it) => it.name(db),
77+
hir::ModuleDef::Adt(def) => match def {
78+
hir::Adt::Struct(it) => it.name(db),
79+
hir::Adt::Union(it) => it.name(db),
80+
hir::Adt::Enum(it) => it.name(db),
81+
},
82+
hir::ModuleDef::EnumVariant(it) => it.name(db),
83+
hir::ModuleDef::Const(it) => it.name(db)?,
84+
hir::ModuleDef::Static(it) => it.name(db)?,
85+
hir::ModuleDef::Trait(it) => it.name(db),
86+
hir::ModuleDef::TypeAlias(it) => it.name(db),
87+
hir::ModuleDef::BuiltinType(_) => return None,
88+
},
89+
NameDefinition::SelfType(_) => return None,
90+
NameDefinition::Local(it) => it.name(db)?,
91+
NameDefinition::TypeParam(it) => it.name(db),
92+
};
93+
Some(name)
94+
}
6995
}
7096

7197
pub enum NameClass {

0 commit comments

Comments
 (0)