diff options
Diffstat (limited to 'crates/ide_assists')
3 files changed, 36 insertions, 39 deletions
diff --git a/crates/ide_assists/src/handlers/auto_import.rs b/crates/ide_assists/src/handlers/auto_import.rs index 6db2d2edd..a454a2af3 100644 --- a/crates/ide_assists/src/handlers/auto_import.rs +++ b/crates/ide_assists/src/handlers/auto_import.rs | |||
@@ -93,7 +93,7 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()> | |||
93 | 93 | ||
94 | let range = ctx.sema.original_range(&syntax_under_caret).range; | 94 | let range = ctx.sema.original_range(&syntax_under_caret).range; |
95 | let group_label = group_label(import_assets.import_candidate()); | 95 | let group_label = group_label(import_assets.import_candidate()); |
96 | let scope = ImportScope::find_insert_use_container(&syntax_under_caret, &ctx.sema)?; | 96 | let scope = ImportScope::find_insert_use_container_with_macros(&syntax_under_caret, &ctx.sema)?; |
97 | for import in proposed_imports { | 97 | for import in proposed_imports { |
98 | acc.add_group( | 98 | acc.add_group( |
99 | &group_label, | 99 | &group_label, |
diff --git a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs index 1f800f82b..66f274fa7 100644 --- a/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs | |||
@@ -5,7 +5,7 @@ use hir::{Module, ModuleDef, Name, Variant}; | |||
5 | use ide_db::{ | 5 | use ide_db::{ |
6 | defs::Definition, | 6 | defs::Definition, |
7 | helpers::{ | 7 | helpers::{ |
8 | insert_use::{insert_use, ImportScope}, | 8 | insert_use::{insert_use, ImportScope, InsertUseConfig}, |
9 | mod_path_to_ast, | 9 | mod_path_to_ast, |
10 | }, | 10 | }, |
11 | search::FileReference, | 11 | search::FileReference, |
@@ -79,16 +79,8 @@ pub(crate) fn extract_struct_from_enum_variant( | |||
79 | &variant_hir_name, | 79 | &variant_hir_name, |
80 | references, | 80 | references, |
81 | ); | 81 | ); |
82 | processed.into_iter().for_each(|(segment, node, import)| { | 82 | processed.into_iter().for_each(|(path, node, import)| { |
83 | if let Some((scope, path)) = import { | 83 | apply_references(ctx.config.insert_use, path, node, import) |
84 | insert_use(&scope, mod_path_to_ast(&path), ctx.config.insert_use); | ||
85 | } | ||
86 | ted::insert_raw( | ||
87 | ted::Position::before(segment.syntax()), | ||
88 | make::path_from_text(&format!("{}", segment)).clone_for_update().syntax(), | ||
89 | ); | ||
90 | ted::insert_raw(ted::Position::before(segment.syntax()), make::token(T!['('])); | ||
91 | ted::insert_raw(ted::Position::after(&node), make::token(T![')'])); | ||
92 | }); | 84 | }); |
93 | } | 85 | } |
94 | builder.edit_file(ctx.frange.file_id); | 86 | builder.edit_file(ctx.frange.file_id); |
@@ -103,21 +95,12 @@ pub(crate) fn extract_struct_from_enum_variant( | |||
103 | &variant_hir_name, | 95 | &variant_hir_name, |
104 | references, | 96 | references, |
105 | ); | 97 | ); |
106 | processed.into_iter().for_each(|(segment, node, import)| { | 98 | processed.into_iter().for_each(|(path, node, import)| { |
107 | if let Some((scope, path)) = import { | 99 | apply_references(ctx.config.insert_use, path, node, import) |
108 | insert_use(&scope, mod_path_to_ast(&path), ctx.config.insert_use); | ||
109 | } | ||
110 | ted::insert_raw( | ||
111 | ted::Position::before(segment.syntax()), | ||
112 | make::path_from_text(&format!("{}", segment)).clone_for_update().syntax(), | ||
113 | ); | ||
114 | ted::insert_raw(ted::Position::before(segment.syntax()), make::token(T!['('])); | ||
115 | ted::insert_raw(ted::Position::after(&node), make::token(T![')'])); | ||
116 | }); | 100 | }); |
117 | } | 101 | } |
118 | 102 | ||
119 | let def = create_struct_def(variant_name.clone(), &field_list, enum_ast.visibility()) | 103 | let def = create_struct_def(variant_name.clone(), &field_list, enum_ast.visibility()); |
120 | .unwrap(); | ||
121 | let start_offset = &variant.parent_enum().syntax().clone(); | 104 | let start_offset = &variant.parent_enum().syntax().clone(); |
122 | ted::insert_raw(ted::Position::before(start_offset), def.syntax()); | 105 | ted::insert_raw(ted::Position::before(start_offset), def.syntax()); |
123 | ted::insert_raw(ted::Position::before(start_offset), &make::tokens::blank_line()); | 106 | ted::insert_raw(ted::Position::before(start_offset), &make::tokens::blank_line()); |
@@ -167,7 +150,7 @@ fn create_struct_def( | |||
167 | variant_name: ast::Name, | 150 | variant_name: ast::Name, |
168 | field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>, | 151 | field_list: &Either<ast::RecordFieldList, ast::TupleFieldList>, |
169 | visibility: Option<ast::Visibility>, | 152 | visibility: Option<ast::Visibility>, |
170 | ) -> Option<ast::Struct> { | 153 | ) -> ast::Struct { |
171 | let pub_vis = Some(make::visibility_pub()); | 154 | let pub_vis = Some(make::visibility_pub()); |
172 | let field_list = match field_list { | 155 | let field_list = match field_list { |
173 | Either::Left(field_list) => { | 156 | Either::Left(field_list) => { |
@@ -184,7 +167,7 @@ fn create_struct_def( | |||
184 | .into(), | 167 | .into(), |
185 | }; | 168 | }; |
186 | 169 | ||
187 | Some(make::struct_(visibility, variant_name, None, field_list).clone_for_update()) | 170 | make::struct_(visibility, variant_name, None, field_list).clone_for_update() |
188 | } | 171 | } |
189 | 172 | ||
190 | fn update_variant(variant: &ast::Variant) -> Option<()> { | 173 | fn update_variant(variant: &ast::Variant) -> Option<()> { |
@@ -199,6 +182,23 @@ fn update_variant(variant: &ast::Variant) -> Option<()> { | |||
199 | Some(()) | 182 | Some(()) |
200 | } | 183 | } |
201 | 184 | ||
185 | fn apply_references( | ||
186 | insert_use_cfg: InsertUseConfig, | ||
187 | segment: ast::PathSegment, | ||
188 | node: SyntaxNode, | ||
189 | import: Option<(ImportScope, hir::ModPath)>, | ||
190 | ) { | ||
191 | if let Some((scope, path)) = import { | ||
192 | insert_use(&scope, mod_path_to_ast(&path), insert_use_cfg); | ||
193 | } | ||
194 | ted::insert_raw( | ||
195 | ted::Position::before(segment.syntax()), | ||
196 | make::path_from_text(&format!("{}", segment)).clone_for_update().syntax(), | ||
197 | ); | ||
198 | ted::insert_raw(ted::Position::before(segment.syntax()), make::token(T!['('])); | ||
199 | ted::insert_raw(ted::Position::after(&node), make::token(T![')'])); | ||
200 | } | ||
201 | |||
202 | fn process_references( | 202 | fn process_references( |
203 | ctx: &AssistContext, | 203 | ctx: &AssistContext, |
204 | visited_modules: &mut FxHashSet<Module>, | 204 | visited_modules: &mut FxHashSet<Module>, |
@@ -207,6 +207,8 @@ fn process_references( | |||
207 | variant_hir_name: &Name, | 207 | variant_hir_name: &Name, |
208 | refs: Vec<FileReference>, | 208 | refs: Vec<FileReference>, |
209 | ) -> Vec<(ast::PathSegment, SyntaxNode, Option<(ImportScope, hir::ModPath)>)> { | 209 | ) -> Vec<(ast::PathSegment, SyntaxNode, Option<(ImportScope, hir::ModPath)>)> { |
210 | // we have to recollect here eagerly as we are about to edit the tree we need to calculate the changes | ||
211 | // and corresponding nodes up front | ||
210 | refs.into_iter() | 212 | refs.into_iter() |
211 | .flat_map(|reference| { | 213 | .flat_map(|reference| { |
212 | let (segment, scope_node, module) = | 214 | let (segment, scope_node, module) = |
@@ -220,8 +222,7 @@ fn process_references( | |||
220 | if let Some(mut mod_path) = mod_path { | 222 | if let Some(mut mod_path) = mod_path { |
221 | mod_path.pop_segment(); | 223 | mod_path.pop_segment(); |
222 | mod_path.push_segment(variant_hir_name.clone()); | 224 | mod_path.push_segment(variant_hir_name.clone()); |
223 | // uuuh this wont properly work, find_insert_use_container ascends macros so we might a get new syntax node??? | 225 | let scope = ImportScope::find_insert_use_container(&scope_node)?; |
224 | let scope = ImportScope::find_insert_use_container(&scope_node, &ctx.sema)?; | ||
225 | visited_modules.insert(module); | 226 | visited_modules.insert(module); |
226 | return Some((segment, scope_node, Some((scope, mod_path)))); | 227 | return Some((segment, scope_node, Some((scope, mod_path)))); |
227 | } | 228 | } |
diff --git a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs index 2f2306fcc..99ba79860 100644 --- a/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs | |||
@@ -31,7 +31,7 @@ pub(crate) fn replace_qualified_name_with_use( | |||
31 | } | 31 | } |
32 | 32 | ||
33 | let target = path.syntax().text_range(); | 33 | let target = path.syntax().text_range(); |
34 | let scope = ImportScope::find_insert_use_container(path.syntax(), &ctx.sema)?; | 34 | let scope = ImportScope::find_insert_use_container_with_macros(path.syntax(), &ctx.sema)?; |
35 | let syntax = scope.as_syntax_node(); | 35 | let syntax = scope.as_syntax_node(); |
36 | acc.add( | 36 | acc.add( |
37 | AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), | 37 | AssistId("replace_qualified_name_with_use", AssistKind::RefactorRewrite), |
@@ -42,15 +42,15 @@ pub(crate) fn replace_qualified_name_with_use( | |||
42 | // affected (that is, all paths inside the node we added the `use` to). | 42 | // affected (that is, all paths inside the node we added the `use` to). |
43 | let syntax = builder.make_mut(syntax.clone()); | 43 | let syntax = builder.make_mut(syntax.clone()); |
44 | if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { | 44 | if let Some(ref import_scope) = ImportScope::from(syntax.clone()) { |
45 | insert_use(import_scope, path.clone(), ctx.config.insert_use); | 45 | shorten_paths(&syntax, &path.clone_for_update()); |
46 | insert_use(import_scope, path, ctx.config.insert_use); | ||
46 | } | 47 | } |
47 | shorten_paths(syntax.clone(), &path.clone_for_update()); | ||
48 | }, | 48 | }, |
49 | ) | 49 | ) |
50 | } | 50 | } |
51 | 51 | ||
52 | /// Adds replacements to `re` that shorten `path` in all descendants of `node`. | 52 | /// Adds replacements to `re` that shorten `path` in all descendants of `node`. |
53 | fn shorten_paths(node: SyntaxNode, path: &ast::Path) { | 53 | fn shorten_paths(node: &SyntaxNode, path: &ast::Path) { |
54 | for child in node.children() { | 54 | for child in node.children() { |
55 | match_ast! { | 55 | match_ast! { |
56 | match child { | 56 | match child { |
@@ -59,14 +59,10 @@ fn shorten_paths(node: SyntaxNode, path: &ast::Path) { | |||
59 | ast::Use(_it) => continue, | 59 | ast::Use(_it) => continue, |
60 | // Don't descend into submodules, they don't have the same `use` items in scope. | 60 | // Don't descend into submodules, they don't have the same `use` items in scope. |
61 | ast::Module(_it) => continue, | 61 | ast::Module(_it) => continue, |
62 | 62 | ast::Path(p) => if maybe_replace_path(p.clone(), path.clone()).is_none() { | |
63 | ast::Path(p) => { | 63 | shorten_paths(p.syntax(), path); |
64 | match maybe_replace_path(p.clone(), path.clone()) { | ||
65 | Some(()) => {}, | ||
66 | None => shorten_paths(p.syntax().clone(), path), | ||
67 | } | ||
68 | }, | 64 | }, |
69 | _ => shorten_paths(child, path), | 65 | _ => shorten_paths(&child, path), |
70 | } | 66 | } |
71 | } | 67 | } |
72 | } | 68 | } |