aboutsummaryrefslogtreecommitdiff
path: root/crates/ide_assists
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ide_assists')
-rw-r--r--crates/ide_assists/src/handlers/auto_import.rs2
-rw-r--r--crates/ide_assists/src/handlers/extract_struct_from_enum_variant.rs55
-rw-r--r--crates/ide_assists/src/handlers/replace_qualified_name_with_use.rs18
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};
5use ide_db::{ 5use 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
190fn update_variant(variant: &ast::Variant) -> Option<()> { 173fn 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
185fn 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
202fn process_references( 202fn 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`.
53fn shorten_paths(node: SyntaxNode, path: &ast::Path) { 53fn 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 }