Skip to content

Commit ea3535c

Browse files
committed
fix: multi-token mapping aware goto definition
1 parent 959c7ef commit ea3535c

File tree

1 file changed

+56
-39
lines changed

1 file changed

+56
-39
lines changed

crates/ide/src/goto_definition.rs

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -39,48 +39,65 @@ pub(crate) fn goto_definition(
3939
kind if kind.is_trivia() => 0,
4040
_ => 1,
4141
})?;
42-
let token = sema.descend_into_macros(original_token.clone());
43-
let parent = token.parent()?;
44-
if let Some(_) = ast::Comment::cast(token.clone()) {
45-
let (attributes, def) = doc_attributes(&sema, &parent)?;
46-
let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?;
47-
let (_, link, ns) =
48-
extract_definitions_from_docs(&docs).into_iter().find(|&(range, ..)| {
49-
doc_mapping.map(range).map_or(false, |InFile { file_id, value: range }| {
50-
file_id == position.file_id.into() && range.contains(position.offset)
51-
})
52-
})?;
53-
let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?;
54-
return Some(RangeInfo::new(original_token.text_range(), vec![nav]));
55-
}
56-
57-
let navs = match_ast! {
58-
match parent {
59-
ast::NameRef(name_ref) => {
60-
reference_definition(&sema, Either::Right(&name_ref))
61-
},
62-
ast::Name(name) => {
63-
match NameClass::classify(&sema, &name)? {
64-
NameClass::Definition(def) | NameClass::ConstReference(def) => {
65-
try_find_trait_item_definition(sema.db, &def).unwrap_or_else(|| def_to_nav(sema.db, def))
66-
}
67-
NameClass::PatFieldShorthand { local_def, field_ref } => {
68-
local_and_field_to_nav(sema.db, local_def, field_ref)
42+
let tokens = sema.descend_into_macros_many(original_token.clone());
43+
let navs = tokens
44+
.clone()
45+
.into_iter()
46+
.filter_map(|token| {
47+
let parent = token.parent()?;
48+
if let Some(_) = ast::Comment::cast(token.clone()) {
49+
let (attributes, def) = doc_attributes(&sema, &parent)?;
50+
let (docs, doc_mapping) = attributes.docs_with_rangemap(db)?;
51+
let (_, link, ns) =
52+
extract_definitions_from_docs(&docs).into_iter().find(|&(range, ..)| {
53+
doc_mapping.map(range).map_or(false, |InFile { file_id, value: range }| {
54+
file_id == position.file_id.into() && range.contains(position.offset)
55+
})
56+
})?;
57+
let nav = resolve_doc_path_for_def(db, def, &link, ns)?.try_to_nav(db)?;
58+
return Some(nav);
59+
}
60+
None
61+
})
62+
.collect::<Vec<NavigationTarget>>();
63+
if navs.len() > 0 {
64+
return Some(RangeInfo::new(original_token.text_range(), navs));
65+
}
66+
let navs = tokens
67+
.into_iter()
68+
.filter_map(|token| {
69+
let parent = token.parent()?;
70+
let navs = match_ast! {
71+
match parent {
72+
ast::NameRef(name_ref) => {
73+
reference_definition(&sema, Either::Right(&name_ref))
6974
},
70-
}
71-
},
72-
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
73-
match name_class {
74-
NameClass::Definition(def) => def_to_nav(sema.db, def),
75+
ast::Name(name) => {
76+
match NameClass::classify(&sema, &name)? {
77+
NameClass::Definition(def) | NameClass::ConstReference(def) => {
78+
try_find_trait_item_definition(sema.db, &def).unwrap_or_else(|| def_to_nav(sema.db, def))
79+
}
80+
NameClass::PatFieldShorthand { local_def, field_ref } => {
81+
local_and_field_to_nav(sema.db, local_def, field_ref)
82+
},
83+
}
84+
},
85+
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, &lt) {
86+
match name_class {
87+
NameClass::Definition(def) => def_to_nav(sema.db, def),
88+
_ => return None,
89+
}
90+
} else {
91+
reference_definition(&sema, Either::Left(&lt))
92+
},
93+
ast::TokenTree(tt) => try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
7594
_ => return None,
7695
}
77-
} else {
78-
reference_definition(&sema, Either::Left(&lt))
79-
},
80-
ast::TokenTree(tt) => try_lookup_include_path_or_derive(&sema, tt, token, position.file_id)?,
81-
_ => return None,
82-
}
83-
};
96+
};
97+
Some(navs)
98+
})
99+
.flatten()
100+
.collect::<Vec<NavigationTarget>>();
84101

85102
Some(RangeInfo::new(original_token.text_range(), navs))
86103
}

0 commit comments

Comments
 (0)