mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-02 06:41:48 +00:00
Merge #7498
7498: Clone for update r=matklad a=matklad rowan counterpart https://github.com/rust-analyzer/rowan/pull/93 #6857 Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
c49b5b7468
41 changed files with 376 additions and 176 deletions
|
@ -33,7 +33,7 @@ pub(crate) fn complete_fn_param(acc: &mut Completions, ctx: &CompletionContext)
|
|||
});
|
||||
};
|
||||
|
||||
for node in ctx.token.parent().ancestors() {
|
||||
for node in ctx.token.ancestors() {
|
||||
match_ast! {
|
||||
match node {
|
||||
ast::SourceFile(it) => it.items().filter_map(|item| match item {
|
||||
|
|
|
@ -82,13 +82,14 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext
|
|||
|
||||
fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> {
|
||||
let mut token = ctx.token.clone();
|
||||
// For keywork without name like `impl .. { fn $0 }`, the current position is inside
|
||||
// For keyword without name like `impl .. { fn $0 }`, the current position is inside
|
||||
// the whitespace token, which is outside `FN` syntax node.
|
||||
// We need to follow the previous token in this case.
|
||||
if token.kind() == SyntaxKind::WHITESPACE {
|
||||
token = token.prev_token()?;
|
||||
}
|
||||
|
||||
let parent_kind = token.parent().map_or(SyntaxKind::EOF, |it| it.kind());
|
||||
let impl_item_offset = match token.kind() {
|
||||
// `impl .. { const $0 }`
|
||||
// ERROR 0
|
||||
|
@ -102,14 +103,14 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt
|
|||
// FN/TYPE_ALIAS/CONST 1
|
||||
// NAME 0
|
||||
// IDENT <- *
|
||||
SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1,
|
||||
SyntaxKind::IDENT if parent_kind == SyntaxKind::NAME => 1,
|
||||
// `impl .. { foo$0 }`
|
||||
// MACRO_CALL 3
|
||||
// PATH 2
|
||||
// PATH_SEGMENT 1
|
||||
// NAME_REF 0
|
||||
// IDENT <- *
|
||||
SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME_REF => 3,
|
||||
SyntaxKind::IDENT if parent_kind == SyntaxKind::NAME_REF => 3,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ impl<'a> CompletionContext<'a> {
|
|||
let original_token =
|
||||
original_file.syntax().token_at_offset(position.offset).left_biased()?;
|
||||
let token = sema.descend_into_macros(original_token.clone());
|
||||
let scope = sema.scope_at_offset(&token.parent(), position.offset);
|
||||
let scope = sema.scope_at_offset(&token, position.offset);
|
||||
let mut locals = vec![];
|
||||
scope.process_all_names(&mut |name, scope| {
|
||||
if let ScopeDef::Local(local) = scope {
|
||||
|
@ -281,7 +281,7 @@ impl<'a> CompletionContext<'a> {
|
|||
fn fill_impl_def(&mut self) {
|
||||
self.impl_def = self
|
||||
.sema
|
||||
.ancestors_with_macros(self.token.parent())
|
||||
.token_ancestors_with_macros(self.token.clone())
|
||||
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
|
||||
.find_map(ast::Impl::cast);
|
||||
}
|
||||
|
@ -293,7 +293,10 @@ impl<'a> CompletionContext<'a> {
|
|||
offset: TextSize,
|
||||
) {
|
||||
let expected = {
|
||||
let mut node = self.token.parent();
|
||||
let mut node = match self.token.parent() {
|
||||
Some(it) => it,
|
||||
None => return,
|
||||
};
|
||||
loop {
|
||||
let ret = match_ast! {
|
||||
match node {
|
||||
|
@ -474,17 +477,17 @@ impl<'a> CompletionContext<'a> {
|
|||
}
|
||||
|
||||
self.use_item_syntax =
|
||||
self.sema.ancestors_with_macros(self.token.parent()).find_map(ast::Use::cast);
|
||||
self.sema.token_ancestors_with_macros(self.token.clone()).find_map(ast::Use::cast);
|
||||
|
||||
self.function_syntax = self
|
||||
.sema
|
||||
.ancestors_with_macros(self.token.parent())
|
||||
.token_ancestors_with_macros(self.token.clone())
|
||||
.take_while(|it| it.kind() != SOURCE_FILE && it.kind() != MODULE)
|
||||
.find_map(ast::Fn::cast);
|
||||
|
||||
self.record_field_syntax = self
|
||||
.sema
|
||||
.ancestors_with_macros(self.token.parent())
|
||||
.token_ancestors_with_macros(self.token.clone())
|
||||
.take_while(|it| {
|
||||
it.kind() != SOURCE_FILE && it.kind() != MODULE && it.kind() != CALL_EXPR
|
||||
})
|
||||
|
|
|
@ -184,11 +184,7 @@ fn test_has_impl_as_prev_sibling() {
|
|||
}
|
||||
|
||||
pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
|
||||
let leaf = match element {
|
||||
NodeOrToken::Node(node) => node,
|
||||
NodeOrToken::Token(token) => token.parent(),
|
||||
};
|
||||
for node in leaf.ancestors() {
|
||||
for node in element.ancestors() {
|
||||
if node.kind() == FN || node.kind() == CLOSURE_EXPR {
|
||||
break;
|
||||
}
|
||||
|
@ -201,7 +197,7 @@ pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool {
|
|||
}
|
||||
};
|
||||
if let Some(body) = loop_body {
|
||||
if body.syntax().text_range().contains_range(leaf.text_range()) {
|
||||
if body.syntax().text_range().contains_range(element.text_range()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -235,12 +231,8 @@ fn previous_sibling_or_ancestor_sibling(element: SyntaxElement) -> Option<Syntax
|
|||
Some(sibling)
|
||||
} else {
|
||||
// if not trying to find first ancestor which has such a sibling
|
||||
let node = match element {
|
||||
NodeOrToken::Node(node) => node,
|
||||
NodeOrToken::Token(token) => token.parent(),
|
||||
};
|
||||
let range = node.text_range();
|
||||
let top_node = node.ancestors().take_while(|it| it.text_range() == range).last()?;
|
||||
let range = element.text_range();
|
||||
let top_node = element.ancestors().take_while(|it| it.text_range() == range).last()?;
|
||||
let prev_sibling_node = top_node.ancestors().find(|it| {
|
||||
non_trivia_sibling(NodeOrToken::Node(it.to_owned()), Direction::Prev).is_some()
|
||||
})?;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue