diff options
author | Aleksey Kladov <[email protected]> | 2020-10-06 15:19:18 +0100 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-10-06 15:19:18 +0100 |
commit | 2090b534fc249a493823bb8e9039c0123aa0b90e (patch) | |
tree | f6f8469d5e4bbd37655aabb75edf32a392b0ed0c /crates | |
parent | 9507a01e9e76afca9f6f8d460089fc199703b820 (diff) |
Move ModPath->ast::Path function to IDE layer
closes #6092
Diffstat (limited to 'crates')
-rw-r--r-- | crates/assists/src/ast_transform.rs | 17 | ||||
-rw-r--r-- | crates/assists/src/handlers/add_missing_impl_members.rs | 25 | ||||
-rw-r--r-- | crates/assists/src/handlers/auto_import.rs | 7 | ||||
-rw-r--r-- | crates/assists/src/handlers/extract_struct_from_enum_variant.rs | 8 | ||||
-rw-r--r-- | crates/assists/src/handlers/fill_match_arms.rs | 4 | ||||
-rw-r--r-- | crates/assists/src/utils.rs | 21 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 7 | ||||
-rw-r--r-- | crates/hir_def/src/path.rs | 22 |
8 files changed, 65 insertions, 46 deletions
diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs index 4307e0191..ac72f3f02 100644 --- a/crates/assists/src/ast_transform.rs +++ b/crates/assists/src/ast_transform.rs | |||
@@ -1,13 +1,14 @@ | |||
1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. | 1 | //! `AstTransformer`s are functions that replace nodes in an AST and can be easily combined. |
2 | use rustc_hash::FxHashMap; | ||
3 | |||
4 | use hir::{HirDisplay, PathResolution, SemanticsScope}; | 2 | use hir::{HirDisplay, PathResolution, SemanticsScope}; |
3 | use rustc_hash::FxHashMap; | ||
5 | use syntax::{ | 4 | use syntax::{ |
6 | algo::SyntaxRewriter, | 5 | algo::SyntaxRewriter, |
7 | ast::{self, AstNode}, | 6 | ast::{self, AstNode}, |
8 | SyntaxNode, | 7 | SyntaxNode, |
9 | }; | 8 | }; |
10 | 9 | ||
10 | use crate::utils::mod_path_to_ast; | ||
11 | |||
11 | pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N { | 12 | pub fn apply<'a, N: AstNode>(transformer: &dyn AstTransform<'a>, node: N) -> N { |
12 | SyntaxRewriter::from_fn(|element| match element { | 13 | SyntaxRewriter::from_fn(|element| match element { |
13 | syntax::SyntaxElement::Node(n) => { | 14 | syntax::SyntaxElement::Node(n) => { |
@@ -189,7 +190,7 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> { | |||
189 | match resolution { | 190 | match resolution { |
190 | PathResolution::Def(def) => { | 191 | PathResolution::Def(def) => { |
191 | let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?; | 192 | let found_path = from.find_use_path(self.source_scope.db.upcast(), def)?; |
192 | let mut path = path_to_ast(found_path); | 193 | let mut path = mod_path_to_ast(&found_path); |
193 | 194 | ||
194 | let type_args = p | 195 | let type_args = p |
195 | .segment() | 196 | .segment() |
@@ -210,13 +211,3 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> { | |||
210 | } | 211 | } |
211 | } | 212 | } |
212 | } | 213 | } |
213 | |||
214 | pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path { | ||
215 | let parse = ast::SourceFile::parse(&path.to_string()); | ||
216 | parse | ||
217 | .tree() | ||
218 | .syntax() | ||
219 | .descendants() | ||
220 | .find_map(ast::Path::cast) | ||
221 | .unwrap_or_else(|| panic!("failed to parse path {:?}, `{}`", path, path)) | ||
222 | } | ||
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs index 51b5a2eb0..4c400f287 100644 --- a/crates/assists/src/handlers/add_missing_impl_members.rs +++ b/crates/assists/src/handlers/add_missing_impl_members.rs | |||
@@ -820,4 +820,29 @@ impl Tr for () { | |||
820 | }"#, | 820 | }"#, |
821 | ) | 821 | ) |
822 | } | 822 | } |
823 | |||
824 | #[test] | ||
825 | fn weird_path() { | ||
826 | check_assist( | ||
827 | add_missing_impl_members, | ||
828 | r#" | ||
829 | trait Test { | ||
830 | fn foo(&self, x: crate) | ||
831 | } | ||
832 | impl Test for () { | ||
833 | <|> | ||
834 | } | ||
835 | "#, | ||
836 | r#" | ||
837 | trait Test { | ||
838 | fn foo(&self, x: crate) | ||
839 | } | ||
840 | impl Test for () { | ||
841 | fn foo(&self, x: crate) { | ||
842 | ${0:todo!()} | ||
843 | } | ||
844 | } | ||
845 | "#, | ||
846 | ) | ||
847 | } | ||
823 | } | 848 | } |
diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs index 357ff6392..d3ee98e5f 100644 --- a/crates/assists/src/handlers/auto_import.rs +++ b/crates/assists/src/handlers/auto_import.rs | |||
@@ -13,7 +13,10 @@ use syntax::{ | |||
13 | SyntaxNode, | 13 | SyntaxNode, |
14 | }; | 14 | }; |
15 | 15 | ||
16 | use crate::{utils::insert_use, AssistContext, AssistId, AssistKind, Assists, GroupLabel}; | 16 | use crate::{ |
17 | utils::insert_use, utils::mod_path_to_ast, AssistContext, AssistId, AssistKind, Assists, | ||
18 | GroupLabel, | ||
19 | }; | ||
17 | 20 | ||
18 | // Assist: auto_import | 21 | // Assist: auto_import |
19 | // | 22 | // |
@@ -54,7 +57,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
54 | range, | 57 | range, |
55 | |builder| { | 58 | |builder| { |
56 | let new_syntax = | 59 | let new_syntax = |
57 | insert_use(&scope, import.to_ast_path(), ctx.config.insert_use.merge); | 60 | insert_use(&scope, mod_path_to_ast(&import), ctx.config.insert_use.merge); |
58 | builder.replace(syntax.text_range(), new_syntax.to_string()) | 61 | builder.replace(syntax.text_range(), new_syntax.to_string()) |
59 | }, | 62 | }, |
60 | ); | 63 | ); |
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs index f5f03ef36..7f4f80b23 100644 --- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs | |||
@@ -10,9 +10,10 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | assist_context::AssistBuilder, utils::insert_use, AssistContext, AssistId, AssistKind, Assists, | 13 | assist_context::AssistBuilder, |
14 | utils::{insert_use, mod_path_to_ast, ImportScope}, | ||
15 | AssistContext, AssistId, AssistKind, Assists, | ||
14 | }; | 16 | }; |
15 | use insert_use::ImportScope; | ||
16 | 17 | ||
17 | // Assist: extract_struct_from_enum_variant | 18 | // Assist: extract_struct_from_enum_variant |
18 | // | 19 | // |
@@ -111,7 +112,8 @@ fn insert_import( | |||
111 | let scope = ImportScope::find_insert_use_container(path.syntax(), ctx)?; | 112 | let scope = ImportScope::find_insert_use_container(path.syntax(), ctx)?; |
112 | let syntax = scope.as_syntax_node(); | 113 | let syntax = scope.as_syntax_node(); |
113 | 114 | ||
114 | let new_syntax = insert_use(&scope, mod_path.to_ast_path(), ctx.config.insert_use.merge); | 115 | let new_syntax = |
116 | insert_use(&scope, mod_path_to_ast(&mod_path), ctx.config.insert_use.merge); | ||
115 | // FIXME: this will currently panic as multiple imports will have overlapping text ranges | 117 | // FIXME: this will currently panic as multiple imports will have overlapping text ranges |
116 | builder.replace(syntax.text_range(), new_syntax.to_string()) | 118 | builder.replace(syntax.text_range(), new_syntax.to_string()) |
117 | } | 119 | } |
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index 3d9bdb2bf..676f5ad92 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs | |||
@@ -7,7 +7,7 @@ use syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; | |||
7 | use test_utils::mark; | 7 | use test_utils::mark; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | utils::{render_snippet, Cursor, FamousDefs}, | 10 | utils::{mod_path_to_ast, render_snippet, Cursor, FamousDefs}, |
11 | AssistContext, AssistId, AssistKind, Assists, | 11 | AssistContext, AssistId, AssistKind, Assists, |
12 | }; | 12 | }; |
13 | 13 | ||
@@ -192,7 +192,7 @@ fn resolve_tuple_of_enum_def( | |||
192 | } | 192 | } |
193 | 193 | ||
194 | fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> { | 194 | fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> Option<ast::Pat> { |
195 | let path = crate::ast_transform::path_to_ast(module.find_use_path(db, ModuleDef::from(var))?); | 195 | let path = mod_path_to_ast(&module.find_use_path(db, ModuleDef::from(var))?); |
196 | 196 | ||
197 | // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though | 197 | // FIXME: use HIR for this; it doesn't currently expose struct vs. tuple vs. unit variants though |
198 | let pat: ast::Pat = match var.source(db).value.kind() { | 198 | let pat: ast::Pat = match var.source(db).value.kind() { |
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index b0511ceb6..eb69c49a4 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -19,6 +19,27 @@ use crate::assist_config::SnippetCap; | |||
19 | pub use insert_use::MergeBehaviour; | 19 | pub use insert_use::MergeBehaviour; |
20 | pub(crate) use insert_use::{insert_use, ImportScope}; | 20 | pub(crate) use insert_use::{insert_use, ImportScope}; |
21 | 21 | ||
22 | pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { | ||
23 | let mut segments = Vec::new(); | ||
24 | let mut is_abs = false; | ||
25 | match path.kind { | ||
26 | hir::PathKind::Plain => {} | ||
27 | hir::PathKind::Super(0) => segments.push(make::path_segment_self()), | ||
28 | hir::PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())), | ||
29 | hir::PathKind::DollarCrate(_) | hir::PathKind::Crate => { | ||
30 | segments.push(make::path_segment_crate()) | ||
31 | } | ||
32 | hir::PathKind::Abs => is_abs = true, | ||
33 | } | ||
34 | |||
35 | segments.extend( | ||
36 | path.segments | ||
37 | .iter() | ||
38 | .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))), | ||
39 | ); | ||
40 | make::path_from_segments(segments, is_abs) | ||
41 | } | ||
42 | |||
22 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | 43 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { |
23 | extract_trivial_expression(&block) | 44 | extract_trivial_expression(&block) |
24 | .filter(|expr| !expr.syntax().text().contains_char('\n')) | 45 | .filter(|expr| !expr.syntax().text().contains_char('\n')) |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 87084fa13..171118d98 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -51,7 +51,7 @@ pub use hir_def::{ | |||
51 | find_path::PrefixKind, | 51 | find_path::PrefixKind, |
52 | item_scope::ItemInNs, | 52 | item_scope::ItemInNs, |
53 | nameres::ModuleSource, | 53 | nameres::ModuleSource, |
54 | path::ModPath, | 54 | path::{ModPath, PathKind}, |
55 | type_ref::{Mutability, TypeRef}, | 55 | type_ref::{Mutability, TypeRef}, |
56 | }; | 56 | }; |
57 | pub use hir_expand::{ | 57 | pub use hir_expand::{ |
@@ -63,7 +63,4 @@ pub use hir_ty::display::HirDisplay; | |||
63 | // These are negative re-exports: pub using these names is forbidden, they | 63 | // These are negative re-exports: pub using these names is forbidden, they |
64 | // should remain private to hir internals. | 64 | // should remain private to hir internals. |
65 | #[allow(unused)] | 65 | #[allow(unused)] |
66 | use { | 66 | use {hir_def::path::Path, hir_expand::hygiene::Hygiene}; |
67 | hir_def::path::{Path, PathKind}, | ||
68 | hir_expand::hygiene::Hygiene, | ||
69 | }; | ||
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index 209b18e78..5b8c1e449 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::{ | |||
13 | hygiene::Hygiene, | 13 | hygiene::Hygiene, |
14 | name::{AsName, Name}, | 14 | name::{AsName, Name}, |
15 | }; | 15 | }; |
16 | use syntax::ast::{self, make}; | 16 | use syntax::ast::{self}; |
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | type_ref::{TypeBound, TypeRef}, | 19 | type_ref::{TypeBound, TypeRef}, |
@@ -100,26 +100,6 @@ impl ModPath { | |||
100 | } | 100 | } |
101 | self.segments.first() | 101 | self.segments.first() |
102 | } | 102 | } |
103 | |||
104 | pub fn to_ast_path(&self) -> ast::Path { | ||
105 | let mut segments = Vec::new(); | ||
106 | let mut is_abs = false; | ||
107 | match self.kind { | ||
108 | PathKind::Plain => {} | ||
109 | PathKind::Super(0) => segments.push(make::path_segment_self()), | ||
110 | PathKind::Super(n) => segments.extend((0..n).map(|_| make::path_segment_super())), | ||
111 | PathKind::Crate => segments.push(make::path_segment_crate()), | ||
112 | PathKind::Abs => is_abs = true, | ||
113 | PathKind::DollarCrate(_) => (), | ||
114 | } | ||
115 | |||
116 | segments.extend( | ||
117 | self.segments | ||
118 | .iter() | ||
119 | .map(|segment| make::path_segment(make::name_ref(&segment.to_string()))), | ||
120 | ); | ||
121 | make::path_from_segments(segments, is_abs) | ||
122 | } | ||
123 | } | 103 | } |
124 | 104 | ||
125 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 105 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |