]> git.lizzy.rs Git - rust.git/commitdiff
Move ModPath->ast::Path function to IDE layer
authorAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 6 Oct 2020 14:19:18 +0000 (16:19 +0200)
committerAleksey Kladov <aleksey.kladov@gmail.com>
Tue, 6 Oct 2020 14:19:18 +0000 (16:19 +0200)
closes #6092

crates/assists/src/ast_transform.rs
crates/assists/src/handlers/add_missing_impl_members.rs
crates/assists/src/handlers/auto_import.rs
crates/assists/src/handlers/extract_struct_from_enum_variant.rs
crates/assists/src/handlers/fill_match_arms.rs
crates/assists/src/utils.rs
crates/hir/src/lib.rs
crates/hir_def/src/path.rs

index 4307e019188509d24643dfe04ada94ca1227e97e..ac72f3f02e24c7f43134f2c8b3e0b1acb2934f3c 100644 (file)
@@ -1,13 +1,14 @@
 //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined.
-use rustc_hash::FxHashMap;
-
 use hir::{HirDisplay, PathResolution, SemanticsScope};
+use rustc_hash::FxHashMap;
 use syntax::{
     algo::SyntaxRewriter,
     ast::{self, AstNode},
     SyntaxNode,
 };
 
+use crate::utils::mod_path_to_ast;
+
 pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N {
     SyntaxRewriter::from_fn(|element| match element {
         syntax::SyntaxElement::Node(n) => {
@@ -189,7 +190,7 @@ fn get_substitution(
         match resolution {
             PathResolution::Def(def) => {
                 let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?;
-                let mut path = path_to_ast(found_path);
+                let mut path = mod_path_to_ast(&found_path);
 
                 let type_args = p
                     .segment()
@@ -210,13 +211,3 @@ fn get_substitution(
         }
     }
 }
-
-pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path {
-    let parse = ast::SourceFile::parse(&path.to_string());
-    parse
-        .tree()
-        .syntax()
-        .descendants()
-        .find_map(ast::Path::cast)
-        .unwrap_or_else(|| panic!("failed to parse path {:?}, `{}`", path, path))
-}
index 51b5a2eb075def52aa45f2c3d4f68df4c00f42f5..4c400f287b0dae86b823732575e4e9745edd24e6 100644 (file)
@@ -820,4 +820,29 @@ fn foo() {
 }"#,
         )
     }
+
+    #[test]
+    fn weird_path() {
+        check_assist(
+            add_missing_impl_members,
+            r#"
+trait Test {
+    fn foo(&self, x: crate)
+}
+impl Test for () {
+    <|>
+}
+"#,
+            r#"
+trait Test {
+    fn foo(&self, x: crate)
+}
+impl Test for () {
+    fn foo(&self, x: crate) {
+        ${0:todo!()}
+    }
+}
+"#,
+        )
+    }
 }
index 357ff63920a499994eb76651405542d2320c2cd3..d3ee98e5f3edf8df7e8ac995031ff2fb3f919257 100644 (file)
     SyntaxNode,
 };
 
-use crate::{utils::insert_use, AssistContext, AssistId, AssistKind, Assists, GroupLabel};
+use crate::{
+    utils::insert_use, utils::mod_path_to_ast, AssistContext, AssistId, AssistKind, Assists,
+    GroupLabel,
+};
 
 // Assist: auto_import
 //
@@ -54,7 +57,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
             range,
             |builder| {
                 let new_syntax =
-                    insert_use(&scope, import.to_ast_path(), ctx.config.insert_use.merge);
+                    insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use.merge);
                 builder.replace(syntax.text_range(), new_syntax.to_string())
             },
         );
index f5f03ef3628f89dce766c90499fa83dba7c37be8..7f4f80b237058e8dcd113ab2fe46ec5fc6e7325a 100644 (file)
 };
 
 use crate::{
-    assist_context::AssistBuilder, utils::insert_use, AssistContext, AssistId, AssistKind, Assists,
+    assist_context::AssistBuilder,
+    utils::{insert_use, mod_path_to_ast, ImportScope},
+    AssistContext, AssistId, AssistKind, Assists,
 };
-use insert_use::ImportScope;
 
 // Assist: extract_struct_from_enum_variant
 //
@@ -111,7 +112,8 @@ fn insert_import(
         let scope = ImportScope::find_insert_use_container(path.syntax(), ctx)?;
         let syntax = scope.as_syntax_node();
 
-        let new_syntax = insert_use(&scope, mod_path.to_ast_path(), ctx.config.insert_use.merge);
+        let new_syntax =
+            insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge);
         // FIXME: this will currently panic as multiple imports will have overlapping text ranges
         builder.replace(syntax.text_range(), new_syntax.to_string())
     }
index 3d9bdb2bf79dec3867c93490e82d487d1a3bb0ba..676f5ad92600ac7660e7502b0a374b24f1257968 100644 (file)
@@ -7,7 +7,7 @@
 use test_utils::mark;
 
 use crate::{
-    utils::{render_snippet, Cursor, FamousDefs},
+    utils::{mod_path_to_ast, render_snippet, Cursor, FamousDefs},
     AssistContext, AssistId, AssistKind, Assists,
 };
 
@@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def(
 }
 
 fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> {
-    let path = crate::ast_transform::path_to_ast(module.find_use_path(db, ModuleDef::from(var))?);
+    let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?);
 
     // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though
     let pat: ast::Pat = match var.source(db).value.kind() {
index b0511ceb680798873231dceaefa01dbd63759e06..eb69c49a499350fa542fb50c943ee69df2903db6 100644 (file)
 pub use insert_use::MergeBehaviour;
 pub(crate) use insert_use::{insert_use, ImportScope};
 
+pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path {
+    let mut segments = Vec::new();
+    let mut is_abs = false;
+    match path.kind {
+        hir::PathKind::Plain => {}
+        hir::PathKind::Super(0) => segments.push(make::path_segment_self()),
+        hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())),
+        hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => {
+            segments.push(make::path_segment_crate())
+        }
+        hir::PathKind::Abs => is_abs = true,
+    }
+
+    segments.extend(
+        path.segments
+            .iter()
+            .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
+    );
+    make::path_from_segments(segments, is_abs)
+}
+
 pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr {
     extract_trivial_expression(&block)
         .filter(|expr| !expr.syntax().text().contains_char('\n'))
index 87084fa13259f5c5c2d0c23e516db78f0c52aae7..171118d98edb1cce5a9f3f144327bd44fb36109f 100644 (file)
@@ -51,7 +51,7 @@
     find_path::PrefixKind,
     item_scope::ItemInNs,
     nameres::ModuleSource,
-    path::ModPath,
+    path::{ModPath, PathKind},
     type_ref::{Mutability, TypeRef},
 };
 pub use hir_expand::{
@@ -63,7 +63,4 @@
 // These are negative re-exports: pub using these names is forbidden, they
 // should remain private to hir internals.
 #[allow(unused)]
-use {
-    hir_def::path::{Path, PathKind},
-    hir_expand::hygiene::Hygiene,
-};
+use {hir_def::path::Path, hir_expand::hygiene::Hygiene};
index 209b18e78a476c850b4d8f063ddb2b86be0d3aaf..5b8c1e449ea2954925c6778ebdb867d824bd79de 100644 (file)
@@ -13,7 +13,7 @@
     hygiene::Hygiene,
     name::{AsName, Name},
 };
-use syntax::ast::{self, make};
+use syntax::ast::{self};
 
 use crate::{
     type_ref::{TypeBound, TypeRef},
@@ -100,26 +100,6 @@ pub fn as_ident(&self) -> Option<&Name> {
         }
         self.segments.first()
     }
-
-    pub fn to_ast_path(&self) -> ast::Path {
-        let mut segments = Vec::new();
-        let mut is_abs = false;
-        match self.kind {
-            PathKind::Plain => {}
-            PathKind::Super(0) => segments.push(make::path_segment_self()),
-            PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())),
-            PathKind::Crate => segments.push(make::path_segment_crate()),
-            PathKind::Abs => is_abs = true,
-            PathKind::DollarCrate(_) => (),
-        }
-
-        segments.extend(
-            self.segments
-                .iter()
-                .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))),
-        );
-        make::path_from_segments(segments, is_abs)
-    }
 }
 
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]