Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/patterns.rs')
-rw-r--r--crates/ide-completion/src/patterns.rs89
1 files changed, 1 insertions, 88 deletions
diff --git a/crates/ide-completion/src/patterns.rs b/crates/ide-completion/src/patterns.rs
index 88cb486f5d..9efb42c4de 100644
--- a/crates/ide-completion/src/patterns.rs
+++ b/crates/ide-completion/src/patterns.rs
@@ -4,103 +4,16 @@
//! This means we for example expand a NameRef token to its outermost Path node, as semantically these act in the same location
//! and the completions usually query for path specific things on the Path context instead. This simplifies some location handling.
-use hir::Semantics;
-use ide_db::RootDatabase;
use syntax::{
ast::{self, HasLoopBody},
match_ast, AstNode, SyntaxElement,
SyntaxKind::*,
- SyntaxNode, SyntaxToken, TextSize,
+ SyntaxNode, SyntaxToken,
};
#[cfg(test)]
use crate::tests::check_pattern_is_applicable;
-/// Direct parent "thing" of what we are currently completing.
-///
-/// This may contain nodes of the fake file as well as the original, comments on the variants specify
-/// from which file the nodes are.
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub(crate) enum ImmediateLocation {
- TypeBound,
- // Only set from a type arg
- /// Original file ast node
- GenericArgList(ast::GenericArgList),
-}
-
-pub(crate) fn determine_location(
- sema: &Semantics<RootDatabase>,
- original_file: &SyntaxNode,
- offset: TextSize,
- name_like: &ast::NameLike,
-) -> Option<ImmediateLocation> {
- let node = match name_like {
- ast::NameLike::NameRef(name_ref) => maximize_name_ref(name_ref),
- ast::NameLike::Name(name) => name.syntax().clone(),
- ast::NameLike::Lifetime(lt) => lt.syntax().clone(),
- };
-
- match_ast! {
- match node {
- ast::TypeBoundList(_it) => return Some(ImmediateLocation::TypeBound),
- _ => (),
- }
- };
-
- let parent = match node.parent() {
- Some(parent) => match ast::MacroCall::cast(parent.clone()) {
- // When a path is being typed in an (Assoc)ItemList the parser will always emit a macro_call.
- // This is usually fine as the node expansion code above already accounts for that with
- // the ancestors call, but there is one exception to this which is that when an attribute
- // precedes it the code above will not walk the Path to the parent MacroCall as their ranges differ.
- // FIXME path expr and statement have a similar problem
- Some(call)
- if call.excl_token().is_none()
- && call.token_tree().is_none()
- && call.semicolon_token().is_none() =>
- {
- call.syntax().parent()?
- }
- _ => parent,
- },
- // SourceFile
- None => return None,
- };
-
- let res = match_ast! {
- match parent {
- ast::TypeBound(_) => ImmediateLocation::TypeBound,
- ast::TypeBoundList(_) => ImmediateLocation::TypeBound,
- ast::GenericArgList(_) => sema
- .find_node_at_offset_with_macros(original_file, offset)
- .map(ImmediateLocation::GenericArgList)?,
- _ => return None,
- }
- };
- Some(res)
-}
-
-/// Maximize a nameref to its enclosing path if its the last segment of said path.
-/// That is, when completing a [`NameRef`] we actually handle it as the path it is part of when determining
-/// its location.
-fn maximize_name_ref(name_ref: &ast::NameRef) -> SyntaxNode {
- if let Some(segment) = name_ref.syntax().parent().and_then(ast::PathSegment::cast) {
- let p = segment.parent_path();
- if p.parent_path().is_none() {
- // Get rid of PathExpr, PathType, etc...
- let path = p
- .syntax()
- .ancestors()
- .take_while(|it| it.text_range() == p.syntax().text_range())
- .last();
- if let Some(it) = path {
- return it;
- }
- }
- }
- name_ref.syntax().clone()
-}
-
pub(crate) fn previous_token(element: SyntaxElement) -> Option<SyntaxToken> {
element.into_token().and_then(previous_non_trivia_token)
}