internal: Add offset param to token descending API

This commit is contained in:
Lukas Wirth 2023-08-16 10:07:18 +02:00
parent b14770934a
commit 53b292478d
21 changed files with 185 additions and 143 deletions

View file

@ -17,8 +17,6 @@ use crate::FileRange;
// Extends or shrinks the current selection to the encompassing syntactic construct
// (expression, statement, item, module, etc). It works with multiple cursors.
//
// This is a standard LSP feature and not a protocol extension.
//
// |===
// | Editor | Shortcut
//
@ -142,8 +140,10 @@ fn extend_tokens_from_range(
// compute original mapped token range
let extended = {
let fst_expanded = sema.descend_into_macros_single(first_token.clone());
let lst_expanded = sema.descend_into_macros_single(last_token.clone());
let fst_expanded =
sema.descend_into_macros_single(first_token.clone(), original_range.start());
let lst_expanded =
sema.descend_into_macros_single(last_token.clone(), original_range.end());
let mut lca =
algo::least_common_ancestor(&fst_expanded.parent()?, &lst_expanded.parent()?)?;
lca = shallowest_node(&lca);
@ -154,13 +154,16 @@ fn extend_tokens_from_range(
};
// Compute parent node range
let validate = |token: &SyntaxToken| -> bool {
let expanded = sema.descend_into_macros_single(token.clone());
let parent = match expanded.parent() {
Some(it) => it,
None => return false,
};
algo::least_common_ancestor(&extended, &parent).as_ref() == Some(&extended)
let validate = |offset: TextSize| {
let extended = &extended;
move |token: &SyntaxToken| -> bool {
let expanded = sema.descend_into_macros_single(token.clone(), offset);
let parent = match expanded.parent() {
Some(it) => it,
None => return false,
};
algo::least_common_ancestor(extended, &parent).as_ref() == Some(extended)
}
};
// Find the first and last text range under expanded parent
@ -168,14 +171,14 @@ fn extend_tokens_from_range(
let token = token.prev_token()?;
skip_trivia_token(token, Direction::Prev)
})
.take_while(validate)
.take_while(validate(original_range.start()))
.last()?;
let last = successors(Some(last_token), |token| {
let token = token.next_token()?;
skip_trivia_token(token, Direction::Next)
})
.take_while(validate)
.take_while(validate(original_range.end()))
.last()?;
let range = first.text_range().cover(last.text_range());