]> git.lizzy.rs Git - rust.git/commitdiff
Remove Hygiene from completion
authorAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 13 Aug 2020 20:41:55 +0000 (22:41 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Thu, 13 Aug 2020 20:41:55 +0000 (22:41 +0200)
crates/ide/src/completion/complete_keyword.rs
crates/ide/src/completion/complete_qualified_path.rs
crates/ide/src/completion/completion_context.rs

index a80708935ea1badd7e9c123f9aa0f27c896b29b6..22ada3cf2937d69666f1657c49a2e8444c9f8019 100644 (file)
 pub(super) fn complete_use_tree_keyword(acc: &mut Completions, ctx: &CompletionContext) {
     // complete keyword "crate" in use stmt
     let source_range = ctx.source_range();
-    match (ctx.use_item_syntax.as_ref(), ctx.path_prefix.as_ref()) {
-        (Some(_), None) => {
+
+    if ctx.use_item_syntax.is_some() {
+        if ctx.path_qual.is_none() {
             CompletionItem::new(CompletionKind::Keyword, source_range, "crate::")
                 .kind(CompletionItemKind::Keyword)
                 .insert_text("crate::")
                 .add_to(acc);
-            CompletionItem::new(CompletionKind::Keyword, source_range, "self")
-                .kind(CompletionItemKind::Keyword)
-                .add_to(acc);
-            CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
-                .kind(CompletionItemKind::Keyword)
-                .insert_text("super::")
-                .add_to(acc);
-        }
-        (Some(_), Some(_)) => {
-            CompletionItem::new(CompletionKind::Keyword, source_range, "self")
-                .kind(CompletionItemKind::Keyword)
-                .add_to(acc);
-            CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
-                .kind(CompletionItemKind::Keyword)
-                .insert_text("super::")
-                .add_to(acc);
         }
-        _ => {}
+        CompletionItem::new(CompletionKind::Keyword, source_range, "self")
+            .kind(CompletionItemKind::Keyword)
+            .add_to(acc);
+        CompletionItem::new(CompletionKind::Keyword, source_range, "super::")
+            .kind(CompletionItemKind::Keyword)
+            .insert_text("super::")
+            .add_to(acc);
     }
 
     // Suggest .await syntax for types that implement Future trait
index cb7dd23c187d02387b425ad6ade407bb9ccac288..74794dc88bf52ed79d208061d6a1642ac1c55cc7 100644 (file)
@@ -8,7 +8,7 @@
 use crate::completion::{CompletionContext, Completions};
 
 pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionContext) {
-    let path = match &ctx.path_prefix {
+    let path = match &ctx.path_qual {
         Some(path) => path.clone(),
         None => return,
     };
@@ -19,7 +19,7 @@ pub(super) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon
 
     let context_module = ctx.scope.module();
 
-    let resolution = match ctx.scope.resolve_hir_path_qualifier(&path) {
+    let resolution = match ctx.sema.resolve_path(&path) {
         Some(res) => res,
         None => return,
     };
index 09440334d3f3baa05da21f55d4cb381ddea6983b..3857dce6721b106cf838f43999342e66768526e2 100644 (file)
@@ -56,7 +56,7 @@ pub(crate) struct CompletionContext<'a> {
     /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path.
     pub(super) is_trivial_path: bool,
     /// If not a trivial path, the prefix (qualifier).
-    pub(super) path_prefix: Option<hir::Path>,
+    pub(super) path_qual: Option<ast::Path>,
     pub(super) after_if: bool,
     /// `true` if we are a statement or a last expr in the block.
     pub(super) can_be_stmt: bool,
@@ -137,7 +137,7 @@ pub(super) fn new(
             is_param: false,
             is_pat_binding_or_const: false,
             is_trivial_path: false,
-            path_prefix: None,
+            path_qual: None,
             after_if: false,
             can_be_stmt: false,
             is_expr: false,
@@ -385,48 +385,54 @@ fn classify_name_ref(
             self.is_path_type = path.syntax().parent().and_then(ast::PathType::cast).is_some();
             self.has_type_args = segment.generic_arg_list().is_some();
 
-            let hygiene = hir::Hygiene::new(self.db, self.position.file_id.into());
-            if let Some(path) = hir::Path::from_src(path.clone(), &hygiene) {
-                if let Some(path_prefix) = path.qualifier() {
-                    self.path_prefix = Some(path_prefix);
+            if let Some(path) = path_or_use_tree_qualifier(&path) {
+                self.path_qual = path
+                    .segment()
+                    .and_then(|it| {
+                        find_node_with_range::<ast::PathSegment>(
+                            original_file,
+                            it.syntax().text_range(),
+                        )
+                    })
+                    .map(|it| it.parent_path());
+                return;
+            }
+
+            if let Some(segment) = path.segment() {
+                if segment.coloncolon_token().is_some() {
                     return;
                 }
             }
 
-            if path.qualifier().is_none() {
-                self.is_trivial_path = true;
-
-                // Find either enclosing expr statement (thing with `;`) or a
-                // block. If block, check that we are the last expr.
-                self.can_be_stmt = name_ref
-                    .syntax()
-                    .ancestors()
-                    .find_map(|node| {
-                        if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
-                            return Some(
-                                stmt.syntax().text_range() == name_ref.syntax().text_range(),
-                            );
-                        }
-                        if let Some(block) = ast::BlockExpr::cast(node) {
-                            return Some(
-                                block.expr().map(|e| e.syntax().text_range())
-                                    == Some(name_ref.syntax().text_range()),
-                            );
-                        }
-                        None
-                    })
-                    .unwrap_or(false);
-                self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
+            self.is_trivial_path = true;
 
-                if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
-                    if let Some(if_expr) =
-                        self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
+            // Find either enclosing expr statement (thing with `;`) or a
+            // block. If block, check that we are the last expr.
+            self.can_be_stmt = name_ref
+                .syntax()
+                .ancestors()
+                .find_map(|node| {
+                    if let Some(stmt) = ast::ExprStmt::cast(node.clone()) {
+                        return Some(stmt.syntax().text_range() == name_ref.syntax().text_range());
+                    }
+                    if let Some(block) = ast::BlockExpr::cast(node) {
+                        return Some(
+                            block.expr().map(|e| e.syntax().text_range())
+                                == Some(name_ref.syntax().text_range()),
+                        );
+                    }
+                    None
+                })
+                .unwrap_or(false);
+            self.is_expr = path.syntax().parent().and_then(ast::PathExpr::cast).is_some();
+
+            if let Some(off) = name_ref.syntax().text_range().start().checked_sub(2.into()) {
+                if let Some(if_expr) =
+                    self.sema.find_node_at_offset_with_macros::<ast::IfExpr>(original_file, off)
+                {
+                    if if_expr.syntax().text_range().end() < name_ref.syntax().text_range().start()
                     {
-                        if if_expr.syntax().text_range().end()
-                            < name_ref.syntax().text_range().start()
-                        {
-                            self.after_if = true;
-                        }
+                        self.after_if = true;
                     }
                 }
             }
@@ -469,3 +475,12 @@ fn is_node<N: AstNode>(node: &SyntaxNode) -> bool {
         Some(n) => n.syntax().text_range() == node.text_range(),
     }
 }
+
+fn path_or_use_tree_qualifier(path: &ast::Path) -> Option<ast::Path> {
+    if let Some(qual) = path.qualifier() {
+        return Some(qual);
+    }
+    let use_tree_list = path.syntax().ancestors().find_map(ast::UseTreeList::cast)?;
+    let use_tree = use_tree_list.syntax().parent().and_then(ast::UseTree::cast)?;
+    use_tree.path()
+}