Skip to content

Commit 67f3b51

Browse files
bors[bot]Veykril
andauthored
Merge #11189
11189: internal: Remove lossy `Definition::from_token`/`Definition::from_node` methods r=Veykril a=Veykril Fixes #11129 bors r+ Co-authored-by: Lukas Wirth <[email protected]>
2 parents 68bc12c + c5a9985 commit 67f3b51

File tree

6 files changed

+91
-92
lines changed

6 files changed

+91
-92
lines changed

crates/ide/src/goto_definition.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{doc_links::token_as_doc_comment, FilePosition, NavigationTarget, Ran
44
use hir::{AsAssocItem, Semantics};
55
use ide_db::{
66
base_db::{AnchoredPath, FileId, FileLoader},
7-
defs::Definition,
7+
defs::{Definition, IdentClass},
88
helpers::pick_best_token,
99
RootDatabase,
1010
};
@@ -46,20 +46,20 @@ pub(crate) fn goto_definition(
4646
.filter_map(|token| {
4747
let parent = token.parent()?;
4848
if let Some(tt) = ast::TokenTree::cast(parent) {
49-
if let x @ Some(_) =
50-
try_lookup_include_path(sema, tt, token.clone(), position.file_id)
49+
if let Some(x) = try_lookup_include_path(sema, tt, token.clone(), position.file_id)
5150
{
52-
return x;
51+
return Some(vec![x]);
5352
}
5453
}
5554
Some(
56-
Definition::from_token(sema, &token)
55+
IdentClass::classify_token(sema, &token)?
56+
.definitions()
5757
.into_iter()
5858
.flat_map(|def| {
5959
try_find_trait_item_definition(sema.db, &def)
6060
.unwrap_or_else(|| def_to_nav(sema.db, def))
6161
})
62-
.collect::<Vec<_>>(),
62+
.collect(),
6363
)
6464
})
6565
.flatten()
@@ -74,7 +74,7 @@ fn try_lookup_include_path(
7474
tt: ast::TokenTree,
7575
token: SyntaxToken,
7676
file_id: FileId,
77-
) -> Option<Vec<NavigationTarget>> {
77+
) -> Option<NavigationTarget> {
7878
let token = ast::String::cast(token)?;
7979
let path = token.value()?.into_owned();
8080
let macro_call = tt.syntax().parent().and_then(ast::MacroCall::cast)?;
@@ -84,7 +84,7 @@ fn try_lookup_include_path(
8484
}
8585
let file_id = sema.db.resolve_path(AnchoredPath { anchor: file_id, path: &path })?;
8686
let size = sema.db.file_text(file_id).len().try_into().ok()?;
87-
Some(vec![NavigationTarget {
87+
Some(NavigationTarget {
8888
file_id,
8989
full_range: TextRange::new(0.into(), size),
9090
name: path.into(),
@@ -93,7 +93,7 @@ fn try_lookup_include_path(
9393
container_name: None,
9494
description: None,
9595
docs: None,
96-
}])
96+
})
9797
}
9898

9999
/// finds the trait definition of an impl'd item

crates/ide/src/highlight_related.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use hir::Semantics;
22
use ide_db::{
33
base_db::{FileId, FilePosition},
4-
defs::Definition,
4+
defs::{Definition, IdentClass},
55
helpers::{for_each_break_expr, for_each_tail_expr, node_ext::walk_expr, pick_best_token},
66
search::{FileReference, ReferenceCategory, SearchScope},
77
RootDatabase,
@@ -293,7 +293,8 @@ fn cover_range(r0: Option<TextRange>, r1: Option<TextRange>) -> Option<TextRange
293293
fn find_defs(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> FxHashSet<Definition> {
294294
sema.descend_into_macros(token)
295295
.into_iter()
296-
.flat_map(|token| Definition::from_token(sema, &token))
296+
.filter_map(|token| IdentClass::classify_token(sema, &token).map(IdentClass::definitions))
297+
.flatten()
297298
.collect()
298299
}
299300

crates/ide/src/hover.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use either::Either;
99
use hir::{HasSource, Semantics};
1010
use ide_db::{
1111
base_db::FileRange,
12-
defs::Definition,
12+
defs::{Definition, IdentClass},
1313
helpers::{pick_best_token, FamousDefs},
1414
FxIndexSet, RootDatabase,
1515
};
@@ -129,8 +129,8 @@ pub(crate) fn hover(
129129
.iter()
130130
.filter_map(|token| {
131131
let node = token.parent()?;
132-
let defs = Definition::from_token(sema, token);
133-
Some(defs.into_iter().zip(iter::once(node).cycle()))
132+
let class = IdentClass::classify_token(sema, token)?;
133+
Some(class.definitions().into_iter().zip(iter::once(node).cycle()))
134134
})
135135
.flatten()
136136
.unique_by(|&(def, _)| def)

crates/ide/src/moniker.rs

+5-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use hir::{db::DefDatabase, AsAssocItem, AssocItemContainer, Crate, Name, Semantics};
55
use ide_db::{
66
base_db::{CrateOrigin, FileId, FileLoader, FilePosition},
7-
defs::Definition,
7+
defs::{Definition, IdentClass},
88
helpers::pick_best_token,
99
RootDatabase,
1010
};
@@ -82,11 +82,10 @@ pub(crate) fn moniker(
8282
let navs = sema
8383
.descend_into_macros(original_token.clone())
8484
.into_iter()
85-
.map(|token| {
86-
Definition::from_token(sema, &token)
87-
.into_iter()
88-
.flat_map(|def| def_to_moniker(sema.db, def, current_crate))
89-
.collect::<Vec<_>>()
85+
.filter_map(|token| {
86+
IdentClass::classify_token(sema, &token).map(IdentClass::definitions).map(|it| {
87+
it.into_iter().flat_map(|def| def_to_moniker(sema.db, def, current_crate))
88+
})
9089
})
9190
.flatten()
9291
.unique()

crates/ide/src/static_index.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::collections::HashMap;
66
use hir::{db::HirDatabase, Crate, Module, Semantics};
77
use ide_db::{
88
base_db::{FileId, FileRange, SourceDatabaseExt},
9-
defs::Definition,
9+
defs::{Definition, IdentClass},
1010
RootDatabase,
1111
};
1212
use rustc_hash::FxHashSet;
@@ -195,9 +195,9 @@ impl StaticIndex<'_> {
195195

196196
fn get_definition(sema: &Semantics<RootDatabase>, token: SyntaxToken) -> Option<Definition> {
197197
for token in sema.descend_into_macros(token) {
198-
let def = Definition::from_token(sema, &token);
199-
if let [x] = def.as_slice() {
200-
return Some(*x);
198+
let def = IdentClass::classify_token(sema, &token).map(IdentClass::definitions);
199+
if let Some(&[x]) = def.as_deref() {
200+
return Some(x);
201201
} else {
202202
continue;
203203
};

crates/ide_db/src/defs.rs

+67-68
Original file line numberDiff line numberDiff line change
@@ -42,74 +42,6 @@ pub enum Definition {
4242
}
4343

4444
impl Definition {
45-
pub fn from_token(
46-
sema: &Semantics<RootDatabase>,
47-
token: &SyntaxToken,
48-
) -> ArrayVec<Definition, 2> {
49-
let parent = match token.parent() {
50-
Some(parent) => parent,
51-
None => return Default::default(),
52-
};
53-
// resolve derives if possible
54-
if let Some(ident) = ast::Ident::cast(token.clone()) {
55-
let attr = ast::TokenTree::cast(parent.clone())
56-
.and_then(|tt| tt.parent_meta())
57-
.and_then(|meta| meta.parent_attr());
58-
if let Some(attr) = attr {
59-
return sema
60-
.resolve_derive_ident(&attr, &ident)
61-
.map(Into::into)
62-
.into_iter()
63-
.collect();
64-
}
65-
}
66-
Self::from_node(sema, &parent)
67-
}
68-
69-
pub fn from_node(sema: &Semantics<RootDatabase>, node: &SyntaxNode) -> ArrayVec<Definition, 2> {
70-
let mut res = ArrayVec::new();
71-
(|| {
72-
match_ast! {
73-
match node {
74-
ast::Name(name) => {
75-
match NameClass::classify(&sema, &name)? {
76-
NameClass::Definition(it) | NameClass::ConstReference(it) => res.push(it),
77-
NameClass::PatFieldShorthand { local_def, field_ref } => {
78-
res.push(Definition::Local(local_def));
79-
res.push(Definition::Field(field_ref));
80-
}
81-
}
82-
},
83-
ast::NameRef(name_ref) => {
84-
match NameRefClass::classify(sema, &name_ref)? {
85-
NameRefClass::Definition(it) => res.push(it),
86-
NameRefClass::FieldShorthand { local_ref, field_ref } => {
87-
res.push(Definition::Local(local_ref));
88-
res.push(Definition::Field(field_ref));
89-
}
90-
}
91-
},
92-
ast::Lifetime(lifetime) => {
93-
let def = if let Some(x) = NameClass::classify_lifetime(&sema, &lifetime) {
94-
NameClass::defined(x)
95-
} else {
96-
NameRefClass::classify_lifetime(&sema, &lifetime).and_then(|class| match class {
97-
NameRefClass::Definition(it) => Some(it),
98-
_ => None,
99-
})
100-
};
101-
if let Some(def) = def {
102-
res.push(def);
103-
}
104-
},
105-
_ => (),
106-
}
107-
}
108-
Some(())
109-
})();
110-
res
111-
}
112-
11345
pub fn canonical_module_path(&self, db: &RootDatabase) -> Option<impl Iterator<Item = Module>> {
11446
self.module(db).map(|it| it.path_to_root(db).into_iter().rev())
11547
}
@@ -184,6 +116,65 @@ impl Definition {
184116
}
185117
}
186118

119+
pub enum IdentClass {
120+
NameClass(NameClass),
121+
NameRefClass(NameRefClass),
122+
}
123+
124+
impl IdentClass {
125+
pub fn classify_node(sema: &Semantics<RootDatabase>, node: &SyntaxNode) -> Option<IdentClass> {
126+
match_ast! {
127+
match node {
128+
ast::Name(name) => NameClass::classify(sema, &name).map(IdentClass::NameClass),
129+
ast::NameRef(name_ref) => NameRefClass::classify(sema, &name_ref).map(IdentClass::NameRefClass),
130+
ast::Lifetime(lifetime) => {
131+
NameClass::classify_lifetime(sema, &lifetime)
132+
.map(IdentClass::NameClass)
133+
.or_else(|| NameRefClass::classify_lifetime(sema, &lifetime).map(IdentClass::NameRefClass))
134+
},
135+
_ => None,
136+
}
137+
}
138+
}
139+
140+
pub fn classify_token(
141+
sema: &Semantics<RootDatabase>,
142+
token: &SyntaxToken,
143+
) -> Option<IdentClass> {
144+
let parent = token.parent()?;
145+
// resolve derives if possible
146+
if let Some(ident) = ast::Ident::cast(token.clone()) {
147+
let attr = ast::TokenTree::cast(parent.clone())
148+
.and_then(|tt| tt.parent_meta())
149+
.and_then(|meta| meta.parent_attr());
150+
if let Some(attr) = attr {
151+
return NameRefClass::classify_derive(sema, &attr, &ident)
152+
.map(IdentClass::NameRefClass);
153+
}
154+
}
155+
Self::classify_node(sema, &parent)
156+
}
157+
158+
pub fn definitions(self) -> ArrayVec<Definition, 2> {
159+
let mut res = ArrayVec::new();
160+
match self {
161+
IdentClass::NameClass(NameClass::Definition(it) | NameClass::ConstReference(it)) => {
162+
res.push(it)
163+
}
164+
IdentClass::NameClass(NameClass::PatFieldShorthand { local_def, field_ref }) => {
165+
res.push(Definition::Local(local_def));
166+
res.push(Definition::Field(field_ref));
167+
}
168+
IdentClass::NameRefClass(NameRefClass::Definition(it)) => res.push(it),
169+
IdentClass::NameRefClass(NameRefClass::FieldShorthand { local_ref, field_ref }) => {
170+
res.push(Definition::Local(local_ref));
171+
res.push(Definition::Field(field_ref));
172+
}
173+
}
174+
res
175+
}
176+
}
177+
187178
/// On a first blush, a single `ast::Name` defines a single definition at some
188179
/// scope. That is, that, by just looking at the syntactical category, we can
189180
/// unambiguously define the semantic category.
@@ -465,6 +456,14 @@ impl NameRefClass {
465456
_ => None,
466457
}
467458
}
459+
460+
pub fn classify_derive(
461+
sema: &Semantics<RootDatabase>,
462+
attr: &ast::Attr,
463+
ident: &ast::Ident,
464+
) -> Option<NameRefClass> {
465+
sema.resolve_derive_ident(&attr, &ident).map(Definition::from).map(NameRefClass::Definition)
466+
}
468467
}
469468

470469
impl_from!(

0 commit comments

Comments
 (0)