aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs33
1 files changed, 11 insertions, 22 deletions
diff --git a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
index 359283802..d5397bf21 100644
--- a/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/ra_assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -39,15 +39,16 @@ pub(crate) fn extract_struct_from_enum(acc: &mut Assists, ctx: &AssistContext) -
39 _ => return None, 39 _ => return None,
40 }; 40 };
41 let variant_name = variant.name()?.to_string(); 41 let variant_name = variant.name()?.to_string();
42 let enum_ast = variant.parent_enum();
43 let enum_name = enum_ast.name()?.to_string();
44 let visibility = enum_ast.visibility();
45 let variant_hir = ctx.sema.to_def(&variant)?; 42 let variant_hir = ctx.sema.to_def(&variant)?;
46
47 if existing_struct_def(ctx.db, &variant_name, &variant_hir) { 43 if existing_struct_def(ctx.db, &variant_name, &variant_hir) {
48 return None; 44 return None;
49 } 45 }
50 46 let enum_ast = variant.parent_enum();
47 let enum_name = enum_ast.name()?.to_string();
48 let visibility = enum_ast.visibility();
49 let current_module_def =
50 ImportsLocator::new(ctx.db).find_imports(&enum_name).first()?.left()?;
51 let current_module = current_module_def.module(ctx.db)?;
51 let target = variant.syntax().text_range(); 52 let target = variant.syntax().text_range();
52 return acc.add_in_multiple_files( 53 return acc.add_in_multiple_files(
53 AssistId("extract_struct_from_enum_variant"), 54 AssistId("extract_struct_from_enum_variant"),
@@ -56,10 +57,9 @@ pub(crate) fn extract_struct_from_enum(acc: &mut Assists, ctx: &AssistContext) -
56 |edit| { 57 |edit| {
57 let definition = Definition::ModuleDef(ModuleDef::EnumVariant(variant_hir)); 58 let definition = Definition::ModuleDef(ModuleDef::EnumVariant(variant_hir));
58 let res = definition.find_usages(&ctx.db, None); 59 let res = definition.find_usages(&ctx.db, None);
59 let module_def = mod_def_for_target_module(ctx, &enum_name);
60 let start_offset = variant.parent_enum().syntax().text_range().start(); 60 let start_offset = variant.parent_enum().syntax().text_range().start();
61 let mut visited_modules_set: FxHashSet<Module> = FxHashSet::default(); 61 let mut visited_modules_set: FxHashSet<Module> = FxHashSet::default();
62 visited_modules_set.insert(module_def.module(ctx.db).unwrap()); 62 visited_modules_set.insert(current_module);
63 for reference in res { 63 for reference in res {
64 let source_file = ctx.sema.parse(reference.file_range.file_id); 64 let source_file = ctx.sema.parse(reference.file_range.file_id);
65 update_reference( 65 update_reference(
@@ -67,7 +67,7 @@ pub(crate) fn extract_struct_from_enum(acc: &mut Assists, ctx: &AssistContext) -
67 edit, 67 edit,
68 reference, 68 reference,
69 &source_file, 69 &source_file,
70 &module_def, 70 &current_module_def,
71 &mut visited_modules_set, 71 &mut visited_modules_set,
72 ); 72 );
73 } 73 }
@@ -95,10 +95,6 @@ fn existing_struct_def(db: &RootDatabase, variant_name: &str, variant: &EnumVari
95 .any(|(name, _)| name.to_string() == variant_name.to_string()) 95 .any(|(name, _)| name.to_string() == variant_name.to_string())
96} 96}
97 97
98fn mod_def_for_target_module(ctx: &AssistContext, enum_name: &str) -> ModuleDef {
99 ImportsLocator::new(ctx.db).find_imports(enum_name).first().unwrap().left().unwrap()
100}
101
102fn insert_import( 98fn insert_import(
103 ctx: &AssistContext, 99 ctx: &AssistContext,
104 builder: &mut AssistBuilder, 100 builder: &mut AssistBuilder,
@@ -186,23 +182,16 @@ fn update_reference(
186 let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; 182 let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?;
187 let list = call.arg_list()?; 183 let list = call.arg_list()?;
188 let segment = path_expr.path()?.segment()?; 184 let segment = path_expr.path()?.segment()?;
185 let segment_name = segment.name_ref()?;
186 let module = ctx.sema.scope(&path_expr.syntax()).module()?;
189 let list_range = list.syntax().text_range(); 187 let list_range = list.syntax().text_range();
190 let inside_list_range = TextRange::new( 188 let inside_list_range = TextRange::new(
191 list_range.start().checked_add(TextSize::from(1))?, 189 list_range.start().checked_add(TextSize::from(1))?,
192 list_range.end().checked_sub(TextSize::from(1))?, 190 list_range.end().checked_sub(TextSize::from(1))?,
193 ); 191 );
194 edit.perform(reference.file_range.file_id, |builder| { 192 edit.perform(reference.file_range.file_id, |builder| {
195 let module = ctx.sema.scope(&path_expr.syntax()).module().unwrap();
196 if !visited_modules_set.contains(&module) { 193 if !visited_modules_set.contains(&module) {
197 if insert_import( 194 if insert_import(ctx, builder, &path_expr, &module, module_def, segment_name).is_some()
198 ctx,
199 builder,
200 &path_expr,
201 &module,
202 module_def,
203 segment.name_ref().unwrap(),
204 )
205 .is_some()
206 { 195 {
207 visited_modules_set.insert(module); 196 visited_modules_set.insert(module);
208 } 197 }