From f5a81ec4683613bd62624811733345d627f2127b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 30 Jan 2021 18:19:21 +0300 Subject: Upgrade rowan Notably, new rowan comes with support for mutable syntax trees. --- crates/ide_completion/src/completions/fn_param.rs | 2 +- crates/ide_completion/src/completions/trait_impl.rs | 7 ++++--- crates/ide_completion/src/context.rs | 15 +++++++++------ crates/ide_completion/src/patterns.rs | 16 ++++------------ 4 files changed, 18 insertions(+), 22 deletions(-) (limited to 'crates/ide_completion') diff --git a/crates/ide_completion/src/completions/fn_param.rs b/crates/ide_completion/src/completions/fn_param.rs index 0243dce56..0ea558489 100644 --- a/crates/ide_completion/src/completions/fn_param.rs +++ b/crates/ide_completion/src/completions/fn_param.rs @@ -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 { diff --git a/crates/ide_completion/src/completions/trait_impl.rs b/crates/ide_completion/src/completions/trait_impl.rs index 5a7361f8e..a26fe7c6c 100644 --- a/crates/ide_completion/src/completions/trait_impl.rs +++ b/crates/ide_completion/src/completions/trait_impl.rs @@ -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, }; diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index e6cc6329c..8cbbdb477 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -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 }) diff --git a/crates/ide_completion/src/patterns.rs b/crates/ide_completion/src/patterns.rs index f3ce91dd1..cf5ef07b7 100644 --- a/crates/ide_completion/src/patterns.rs +++ b/crates/ide_completion/src/patterns.rs @@ -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 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() })?; -- cgit v1.2.3