Skip to content

Commit 92d0ee8

Browse files
committed
use token_ancestors_with_macros to simplify goto-def on kw
1 parent 7df7db5 commit 92d0ee8

File tree

2 files changed

+45
-83
lines changed

2 files changed

+45
-83
lines changed

src/tools/rust-analyzer/crates/ide/src/goto_definition.rs

Lines changed: 44 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use crate::{
55
RangeInfo, TryToNav, UpmappingResult,
66
};
77
use hir::{
8-
AsAssocItem, AssocItem, DescendPreference, HirFileId, InFile, MacroFileIdExt, ModuleDef,
9-
Semantics,
8+
AsAssocItem, AssocItem, DescendPreference, InFile, MacroFileIdExt, ModuleDef, Semantics,
109
};
1110
use ide_db::{
1211
base_db::{AnchoredPath, FileLoader},
@@ -15,11 +14,12 @@ use ide_db::{
1514
FileId, RootDatabase,
1615
};
1716
use itertools::Itertools;
17+
use span::FileRange;
1818
use syntax::{
19-
ast::{self, HasLoopBody},
19+
ast::{self, HasLoopBody, Label},
2020
match_ast, AstNode, AstToken,
21-
SyntaxKind::{self, *},
22-
SyntaxNode, SyntaxToken, TextRange, T,
21+
SyntaxKind::*,
22+
SyntaxToken, TextRange, T,
2323
};
2424

2525
// Feature: Go to Definition
@@ -224,30 +224,28 @@ fn try_find_fn_or_closure(
224224
) -> Option<Vec<NavigationTarget>> {
225225
fn find_exit_point(
226226
sema: &Semantics<'_, RootDatabase>,
227-
file_id: HirFileId,
228-
ancestors: impl Iterator<Item = SyntaxNode>,
229-
cursor_token_kind: SyntaxKind,
227+
token: SyntaxToken,
230228
) -> Option<UpmappingResult<NavigationTarget>> {
231229
let db = sema.db;
232230

233-
for anc in ancestors {
231+
for anc in sema.token_ancestors_with_macros(token.clone()) {
232+
let file_id = sema.hir_file_for(&anc);
234233
match_ast! {
235234
match anc {
236235
ast::Fn(fn_) => {
237-
let hir_fn: hir::Function = sema.to_def(&fn_)?;
238-
let nav = hir_fn.try_to_nav(db)?;
239-
236+
let fn_: ast::Fn = fn_;
237+
let nav = sema.to_def(&fn_)?.try_to_nav(db)?;
240238
// For async token, we navigate to itself, which triggers
241239
// VSCode to find the references
242-
let focus_token = if matches!(cursor_token_kind, T![async]) {
240+
let focus_token = if matches!(token.kind(), T![async]) {
243241
fn_.async_token()?
244242
} else {
245243
fn_.fn_token()?
246244
};
247-
let focus_range = InFile::new(file_id, focus_token.text_range())
248-
.original_node_file_range_opt(db)
249-
.map(|(frange, _)| frange.range);
250245

246+
let focus_range = InFile::new(file_id, focus_token.text_range())
247+
.original_node_file_range_opt(db)
248+
.map(|(frange, _)| frange.range);
251249
return Some(nav.map(|it| {
252250
if focus_range.is_some_and(|range| it.full_range.contains_range(range)) {
253251
NavigationTarget { focus_range, ..it }
@@ -258,21 +256,26 @@ fn try_find_fn_or_closure(
258256
},
259257
ast::ClosureExpr(c) => {
260258
let pipe_tok = c.param_list().and_then(|it| it.pipe_token())?.into();
261-
let nav = NavigationTarget::from_expr(db, InFile::new(file_id, c.into()), pipe_tok);
259+
let c_infile = InFile::new(file_id, c.into());
260+
let nav = NavigationTarget::from_expr(db, c_infile, pipe_tok);
262261
return Some(nav);
263262
},
264-
ast::BlockExpr(blk) => match blk.modifier() {
265-
Some(ast::BlockModifier::Async(_)) => {
266-
let async_tok = blk.async_token()?.into();
267-
let nav = NavigationTarget::from_expr(db, InFile::new(file_id, blk.into()), async_tok);
268-
return Some(nav);
269-
},
270-
Some(ast::BlockModifier::Try(_)) if cursor_token_kind != T![return] => {
271-
let try_tok = blk.try_token()?.into();
272-
let nav = NavigationTarget::from_expr(db, InFile::new(file_id, blk.into()), try_tok);
273-
return Some(nav);
274-
},
275-
_ => {}
263+
ast::BlockExpr(blk) => {
264+
match blk.modifier() {
265+
Some(ast::BlockModifier::Async(_)) => {
266+
let async_tok = blk.async_token()?.into();
267+
let blk_infile = InFile::new(file_id, blk.into());
268+
let nav = NavigationTarget::from_expr(db, blk_infile, async_tok);
269+
return Some(nav);
270+
},
271+
Some(ast::BlockModifier::Try(_)) if token.kind() != T![return] => {
272+
let try_tok = blk.try_token()?.into();
273+
let blk_infile = InFile::new(file_id, blk.into());
274+
let nav = NavigationTarget::from_expr(db, blk_infile, try_tok);
275+
return Some(nav);
276+
},
277+
_ => {}
278+
}
276279
},
277280
_ => {}
278281
}
@@ -281,28 +284,9 @@ fn try_find_fn_or_closure(
281284
None
282285
}
283286

284-
let token_kind = token.kind();
285287
sema.descend_into_macros(DescendPreference::None, token.clone())
286288
.into_iter()
287-
.filter_map(|descended| {
288-
let file_id = sema.hir_file_for(&descended.parent()?);
289-
290-
// Try to find the function in the macro file
291-
find_exit_point(sema, file_id, descended.parent_ancestors(), token_kind).or_else(|| {
292-
// If not found, try to find it in the root file
293-
if file_id.is_macro() {
294-
token
295-
.parent_ancestors()
296-
.find(|it| ast::TokenTree::can_cast(it.kind()))
297-
.and_then(|parent| {
298-
let file_id = sema.hir_file_for(&parent);
299-
find_exit_point(sema, file_id, parent.ancestors(), token_kind)
300-
})
301-
} else {
302-
None
303-
}
304-
})
305-
})
289+
.filter_map(|descended| find_exit_point(sema, descended))
306290
.flatten()
307291
.collect_vec()
308292
.into()
@@ -314,19 +298,13 @@ fn try_find_loop(
314298
) -> Option<Vec<NavigationTarget>> {
315299
fn find_break_point(
316300
sema: &Semantics<'_, RootDatabase>,
317-
file_id: HirFileId,
318-
ancestors: impl Iterator<Item = SyntaxNode>,
319-
lbl: &Option<ast::Lifetime>,
301+
token: SyntaxToken,
302+
label_matches: impl Fn(Option<Label>) -> bool,
320303
) -> Option<UpmappingResult<NavigationTarget>> {
321304
let db = sema.db;
322-
let label_matches = |it: Option<ast::Label>| match lbl {
323-
Some(lbl) => {
324-
Some(lbl.text()) == it.and_then(|it| it.lifetime()).as_ref().map(|it| it.text())
325-
}
326-
None => true,
327-
};
305+
let file_id = sema.hir_file_for(&token.parent()?);
328306

329-
for anc in ancestors.filter_map(ast::Expr::cast) {
307+
for anc in sema.token_ancestors_with_macros(token.clone()).filter_map(ast::Expr::cast) {
330308
match anc {
331309
ast::Expr::LoopExpr(loop_) if label_matches(loop_.label()) => {
332310
let expr = ast::Expr::LoopExpr(loop_.clone());
@@ -369,28 +347,16 @@ fn try_find_loop(
369347
_ => None,
370348
}
371349
};
350+
let label_matches =
351+
|it: Option<ast::Label>| match (lbl.as_ref(), it.and_then(|it| it.lifetime())) {
352+
(Some(lbl), Some(it)) => lbl.text() == it.text(),
353+
(None, _) => true,
354+
(Some(_), None) => false,
355+
};
372356

373357
sema.descend_into_macros(DescendPreference::None, token.clone())
374358
.into_iter()
375-
.filter_map(|descended| {
376-
let file_id = sema.hir_file_for(&descended.parent()?);
377-
378-
// Try to find the function in the macro file
379-
find_break_point(sema, file_id, descended.parent_ancestors(), &lbl).or_else(|| {
380-
// If not found, try to find it in the root file
381-
if file_id.is_macro() {
382-
token
383-
.parent_ancestors()
384-
.find(|it| ast::TokenTree::can_cast(it.kind()))
385-
.and_then(|parent| {
386-
let file_id = sema.hir_file_for(&parent);
387-
find_break_point(sema, file_id, parent.ancestors(), &lbl)
388-
})
389-
} else {
390-
None
391-
}
392-
})
393-
})
359+
.filter_map(|descended| find_break_point(sema, descended, label_matches))
394360
.flatten()
395361
.collect_vec()
396362
.into()

src/tools/rust-analyzer/crates/ide/src/highlight_related.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -541,11 +541,7 @@ fn original_range(
541541
file_id: HirFileId,
542542
text_range: Option<TextRange>,
543543
) -> Option<TextRange> {
544-
if text_range.is_none() || !file_id.is_macro() {
545-
return text_range;
546-
}
547-
548-
InFile::new(file_id, text_range.unwrap())
544+
InFile::new(file_id, text_range?)
549545
.original_node_file_range_opt(db)
550546
.map(|(frange, _)| frange.range)
551547
}

0 commit comments

Comments
 (0)