aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_assists/src/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_assists/src/handlers')
-rw-r--r--crates/ra_assists/src/handlers/add_explicit_type.rs18
-rw-r--r--crates/ra_assists/src/handlers/add_from_impl_for_enum.rs14
-rw-r--r--crates/ra_assists/src/handlers/add_new.rs56
-rw-r--r--crates/ra_assists/src/handlers/add_turbo_fish.rs12
-rw-r--r--crates/ra_assists/src/handlers/apply_demorgan.rs8
-rw-r--r--crates/ra_assists/src/handlers/auto_import.rs29
-rw-r--r--crates/ra_assists/src/handlers/change_return_type_to_result.rs98
-rw-r--r--crates/ra_assists/src/handlers/change_visibility.rs548
-rw-r--r--crates/ra_assists/src/handlers/fill_match_arms.rs232
-rw-r--r--crates/ra_assists/src/handlers/fix_visibility.rs559
-rw-r--r--crates/ra_assists/src/handlers/flip_binexpr.rs14
-rw-r--r--crates/ra_assists/src/handlers/flip_comma.rs2
-rw-r--r--crates/ra_assists/src/handlers/flip_trait_bound.rs14
-rw-r--r--crates/ra_assists/src/handlers/inline_local_variable.rs16
-rw-r--r--crates/ra_assists/src/handlers/introduce_variable.rs16
-rw-r--r--crates/ra_assists/src/handlers/invert_if.rs6
-rw-r--r--crates/ra_assists/src/handlers/move_bounds.rs8
-rw-r--r--crates/ra_assists/src/handlers/raw_string.rs26
-rw-r--r--crates/ra_assists/src/handlers/reorder_fields.rs6
-rw-r--r--crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs40
-rw-r--r--crates/ra_assists/src/handlers/unwrap_block.rs10
21 files changed, 882 insertions, 850 deletions
diff --git a/crates/ra_assists/src/handlers/add_explicit_type.rs b/crates/ra_assists/src/handlers/add_explicit_type.rs
index 770049212..ab20c6649 100644
--- a/crates/ra_assists/src/handlers/add_explicit_type.rs
+++ b/crates/ra_assists/src/handlers/add_explicit_type.rs
@@ -86,11 +86,7 @@ mod tests {
86 86
87 #[test] 87 #[test]
88 fn add_explicit_type_works_for_simple_expr() { 88 fn add_explicit_type_works_for_simple_expr() {
89 check_assist( 89 check_assist(add_explicit_type, "fn f() { let a<|> = 1; }", "fn f() { let a: i32 = 1; }");
90 add_explicit_type,
91 "fn f() { let a<|> = 1; }",
92 "fn f() { let a<|>: i32 = 1; }",
93 );
94 } 90 }
95 91
96 #[test] 92 #[test]
@@ -98,7 +94,7 @@ mod tests {
98 check_assist( 94 check_assist(
99 add_explicit_type, 95 add_explicit_type,
100 "fn f() { let a<|>: _ = 1; }", 96 "fn f() { let a<|>: _ = 1; }",
101 "fn f() { let a<|>: i32 = 1; }", 97 "fn f() { let a: i32 = 1; }",
102 ); 98 );
103 } 99 }
104 100
@@ -122,7 +118,7 @@ mod tests {
122 } 118 }
123 119
124 fn f() { 120 fn f() {
125 let a<|>: Option<i32> = Option::Some(1); 121 let a: Option<i32> = Option::Some(1);
126 }"#, 122 }"#,
127 ); 123 );
128 } 124 }
@@ -132,7 +128,7 @@ mod tests {
132 check_assist( 128 check_assist(
133 add_explicit_type, 129 add_explicit_type,
134 r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }", 130 r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }",
135 r"macro_rules! v { () => {0u64} } fn f() { let a<|>: u64 = v!(); }", 131 r"macro_rules! v { () => {0u64} } fn f() { let a: u64 = v!(); }",
136 ); 132 );
137 } 133 }
138 134
@@ -140,8 +136,8 @@ mod tests {
140 fn add_explicit_type_works_for_macro_call_recursive() { 136 fn add_explicit_type_works_for_macro_call_recursive() {
141 check_assist( 137 check_assist(
142 add_explicit_type, 138 add_explicit_type,
143 "macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|> = v!(); }", 139 r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|> = v!(); }"#,
144 "macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|>: u64 = v!(); }", 140 r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a: u64 = v!(); }"#,
145 ); 141 );
146 } 142 }
147 143
@@ -208,7 +204,7 @@ struct Test<K, T = u8> {
208} 204}
209 205
210fn main() { 206fn main() {
211 let test<|>: Test<i32> = Test { t: 23, k: 33 }; 207 let test: Test<i32> = Test { t: 23, k: 33 };
212}"#, 208}"#,
213 ); 209 );
214 } 210 }
diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
index eb57b7231..6a675e812 100644
--- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
+++ b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
@@ -1,6 +1,6 @@
1use ra_ide_db::RootDatabase; 1use ra_ide_db::RootDatabase;
2use ra_syntax::ast::{self, AstNode, NameOwner}; 2use ra_syntax::ast::{self, AstNode, NameOwner};
3use test_utils::tested_by; 3use test_utils::mark;
4 4
5use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; 5use crate::{utils::FamousDefs, AssistContext, AssistId, Assists};
6 6
@@ -39,7 +39,7 @@ pub(crate) fn add_from_impl_for_enum(acc: &mut Assists, ctx: &AssistContext) ->
39 }; 39 };
40 40
41 if existing_from_impl(&ctx.sema, &variant).is_some() { 41 if existing_from_impl(&ctx.sema, &variant).is_some() {
42 tested_by!(test_add_from_impl_already_exists); 42 mark::hit!(test_add_from_impl_already_exists);
43 return None; 43 return None;
44 } 44 }
45 45
@@ -90,7 +90,7 @@ fn existing_from_impl(
90 90
91#[cfg(test)] 91#[cfg(test)]
92mod tests { 92mod tests {
93 use test_utils::covers; 93 use test_utils::mark;
94 94
95 use crate::tests::{check_assist, check_assist_not_applicable}; 95 use crate::tests::{check_assist, check_assist_not_applicable};
96 96
@@ -101,7 +101,7 @@ mod tests {
101 check_assist( 101 check_assist(
102 add_from_impl_for_enum, 102 add_from_impl_for_enum,
103 "enum A { <|>One(u32) }", 103 "enum A { <|>One(u32) }",
104 r#"enum A { <|>One(u32) } 104 r#"enum A { One(u32) }
105 105
106impl From<u32> for A { 106impl From<u32> for A {
107 fn from(v: u32) -> Self { 107 fn from(v: u32) -> Self {
@@ -116,7 +116,7 @@ impl From<u32> for A {
116 check_assist( 116 check_assist(
117 add_from_impl_for_enum, 117 add_from_impl_for_enum,
118 r#"enum A { <|>One(foo::bar::baz::Boo) }"#, 118 r#"enum A { <|>One(foo::bar::baz::Boo) }"#,
119 r#"enum A { <|>One(foo::bar::baz::Boo) } 119 r#"enum A { One(foo::bar::baz::Boo) }
120 120
121impl From<foo::bar::baz::Boo> for A { 121impl From<foo::bar::baz::Boo> for A {
122 fn from(v: foo::bar::baz::Boo) -> Self { 122 fn from(v: foo::bar::baz::Boo) -> Self {
@@ -149,7 +149,7 @@ impl From<foo::bar::baz::Boo> for A {
149 149
150 #[test] 150 #[test]
151 fn test_add_from_impl_already_exists() { 151 fn test_add_from_impl_already_exists() {
152 covers!(test_add_from_impl_already_exists); 152 mark::check!(test_add_from_impl_already_exists);
153 check_not_applicable( 153 check_not_applicable(
154 r#" 154 r#"
155enum A { <|>One(u32), } 155enum A { <|>One(u32), }
@@ -178,7 +178,7 @@ impl From<String> for A {
178pub trait From<T> { 178pub trait From<T> {
179 fn from(T) -> Self; 179 fn from(T) -> Self;
180}"#, 180}"#,
181 r#"enum A { <|>One(u32), Two(String), } 181 r#"enum A { One(u32), Two(String), }
182 182
183impl From<u32> for A { 183impl From<u32> for A {
184 fn from(v: u32) -> Self { 184 fn from(v: u32) -> Self {
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs
index fe7451dcf..837aa8377 100644
--- a/crates/ra_assists/src/handlers/add_new.rs
+++ b/crates/ra_assists/src/handlers/add_new.rs
@@ -3,7 +3,7 @@ use ra_syntax::{
3 ast::{ 3 ast::{
4 self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, 4 self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner,
5 }, 5 },
6 TextSize, T, 6 T,
7}; 7};
8use stdx::{format_to, SepBy}; 8use stdx::{format_to, SepBy};
9 9
@@ -25,7 +25,7 @@ use crate::{AssistContext, AssistId, Assists};
25// } 25// }
26// 26//
27// impl<T: Clone> Ctx<T> { 27// impl<T: Clone> Ctx<T> {
28// fn new(data: T) -> Self { Self { data } } 28// fn $0new(data: T) -> Self { Self { data } }
29// } 29// }
30// 30//
31// ``` 31// ```
@@ -42,31 +42,26 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
42 let impl_def = find_struct_impl(&ctx, &strukt)?; 42 let impl_def = find_struct_impl(&ctx, &strukt)?;
43 43
44 let target = strukt.syntax().text_range(); 44 let target = strukt.syntax().text_range();
45 acc.add(AssistId("add_new"), "Add default constructor", target, |edit| { 45 acc.add(AssistId("add_new"), "Add default constructor", target, |builder| {
46 let mut buf = String::with_capacity(512); 46 let mut buf = String::with_capacity(512);
47 47
48 if impl_def.is_some() { 48 if impl_def.is_some() {
49 buf.push('\n'); 49 buf.push('\n');
50 } 50 }
51 51
52 let vis = strukt.visibility().map(|v| format!("{} ", v)); 52 let vis = strukt.visibility().map_or(String::new(), |v| format!("{} ", v));
53 let vis = vis.as_deref().unwrap_or("");
54 53
55 let params = field_list 54 let params = field_list
56 .fields() 55 .fields()
57 .filter_map(|f| { 56 .filter_map(|f| {
58 Some(format!( 57 Some(format!("{}: {}", f.name()?.syntax(), f.ascribed_type()?.syntax()))
59 "{}: {}",
60 f.name()?.syntax().text(),
61 f.ascribed_type()?.syntax().text()
62 ))
63 }) 58 })
64 .sep_by(", "); 59 .sep_by(", ");
65 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); 60 let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", ");
66 61
67 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); 62 format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
68 63
69 let (start_offset, end_offset) = impl_def 64 let start_offset = impl_def
70 .and_then(|impl_def| { 65 .and_then(|impl_def| {
71 buf.push('\n'); 66 buf.push('\n');
72 let start = impl_def 67 let start = impl_def
@@ -76,17 +71,20 @@ pub(crate) fn add_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
76 .text_range() 71 .text_range()
77 .end(); 72 .end();
78 73
79 Some((start, TextSize::of("\n"))) 74 Some(start)
80 }) 75 })
81 .unwrap_or_else(|| { 76 .unwrap_or_else(|| {
82 buf = generate_impl_text(&strukt, &buf); 77 buf = generate_impl_text(&strukt, &buf);
83 let start = strukt.syntax().text_range().end(); 78 strukt.syntax().text_range().end()
84
85 (start, TextSize::of("\n}\n"))
86 }); 79 });
87 80
88 edit.set_cursor(start_offset + TextSize::of(&buf) - end_offset); 81 match ctx.config.snippet_cap {
89 edit.insert(start_offset, buf); 82 None => builder.insert(start_offset, buf),
83 Some(cap) => {
84 buf = buf.replace("fn new", "fn $0new");
85 builder.insert_snippet(cap, start_offset, buf);
86 }
87 }
90 }) 88 })
91} 89}
92 90
@@ -191,7 +189,7 @@ mod tests {
191"struct Foo {} 189"struct Foo {}
192 190
193impl Foo { 191impl Foo {
194 fn new() -> Self { Self { } }<|> 192 fn $0new() -> Self { Self { } }
195} 193}
196", 194",
197 ); 195 );
@@ -201,7 +199,7 @@ impl Foo {
201"struct Foo<T: Clone> {} 199"struct Foo<T: Clone> {}
202 200
203impl<T: Clone> Foo<T> { 201impl<T: Clone> Foo<T> {
204 fn new() -> Self { Self { } }<|> 202 fn $0new() -> Self { Self { } }
205} 203}
206", 204",
207 ); 205 );
@@ -211,7 +209,7 @@ impl<T: Clone> Foo<T> {
211"struct Foo<'a, T: Foo<'a>> {} 209"struct Foo<'a, T: Foo<'a>> {}
212 210
213impl<'a, T: Foo<'a>> Foo<'a, T> { 211impl<'a, T: Foo<'a>> Foo<'a, T> {
214 fn new() -> Self { Self { } }<|> 212 fn $0new() -> Self { Self { } }
215} 213}
216", 214",
217 ); 215 );
@@ -221,7 +219,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> {
221"struct Foo { baz: String } 219"struct Foo { baz: String }
222 220
223impl Foo { 221impl Foo {
224 fn new(baz: String) -> Self { Self { baz } }<|> 222 fn $0new(baz: String) -> Self { Self { baz } }
225} 223}
226", 224",
227 ); 225 );
@@ -231,7 +229,7 @@ impl Foo {
231"struct Foo { baz: String, qux: Vec<i32> } 229"struct Foo { baz: String, qux: Vec<i32> }
232 230
233impl Foo { 231impl Foo {
234 fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> 232 fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }
235} 233}
236", 234",
237 ); 235 );
@@ -243,7 +241,7 @@ impl Foo {
243"struct Foo { pub baz: String, pub qux: Vec<i32> } 241"struct Foo { pub baz: String, pub qux: Vec<i32> }
244 242
245impl Foo { 243impl Foo {
246 fn new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }<|> 244 fn $0new(baz: String, qux: Vec<i32>) -> Self { Self { baz, qux } }
247} 245}
248", 246",
249 ); 247 );
@@ -258,7 +256,7 @@ impl Foo {}
258"struct Foo {} 256"struct Foo {}
259 257
260impl Foo { 258impl Foo {
261 fn new() -> Self { Self { } }<|> 259 fn $0new() -> Self { Self { } }
262} 260}
263", 261",
264 ); 262 );
@@ -273,7 +271,7 @@ impl Foo {
273"struct Foo {} 271"struct Foo {}
274 272
275impl Foo { 273impl Foo {
276 fn new() -> Self { Self { } }<|> 274 fn $0new() -> Self { Self { } }
277 275
278 fn qux(&self) {} 276 fn qux(&self) {}
279} 277}
@@ -294,7 +292,7 @@ impl Foo {
294"struct Foo {} 292"struct Foo {}
295 293
296impl Foo { 294impl Foo {
297 fn new() -> Self { Self { } }<|> 295 fn $0new() -> Self { Self { } }
298 296
299 fn qux(&self) {} 297 fn qux(&self) {}
300 fn baz() -> i32 { 298 fn baz() -> i32 {
@@ -311,7 +309,7 @@ impl Foo {
311"pub struct Foo {} 309"pub struct Foo {}
312 310
313impl Foo { 311impl Foo {
314 pub fn new() -> Self { Self { } }<|> 312 pub fn $0new() -> Self { Self { } }
315} 313}
316", 314",
317 ); 315 );
@@ -321,7 +319,7 @@ impl Foo {
321"pub(crate) struct Foo {} 319"pub(crate) struct Foo {}
322 320
323impl Foo { 321impl Foo {
324 pub(crate) fn new() -> Self { Self { } }<|> 322 pub(crate) fn $0new() -> Self { Self { } }
325} 323}
326", 324",
327 ); 325 );
@@ -414,7 +412,7 @@ pub struct Source<T> {
414} 412}
415 413
416impl<T> Source<T> { 414impl<T> Source<T> {
417 pub fn new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }<|> 415 pub fn $0new(file_id: HirFileId, ast: T) -> Self { Self { file_id, ast } }
418 416
419 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> { 417 pub fn map<F: FnOnce(T) -> U, U>(self, f: F) -> Source<U> {
420 Source { file_id: self.file_id, ast: f(self.ast) } 418 Source { file_id: self.file_id, ast: f(self.ast) }
diff --git a/crates/ra_assists/src/handlers/add_turbo_fish.rs b/crates/ra_assists/src/handlers/add_turbo_fish.rs
index a0363bc78..26acf81f2 100644
--- a/crates/ra_assists/src/handlers/add_turbo_fish.rs
+++ b/crates/ra_assists/src/handlers/add_turbo_fish.rs
@@ -1,11 +1,11 @@
1use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass}; 1use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass};
2use ra_syntax::{ast, AstNode, SyntaxKind, T}; 2use ra_syntax::{ast, AstNode, SyntaxKind, T};
3use test_utils::mark;
3 4
4use crate::{ 5use crate::{
5 assist_context::{AssistContext, Assists}, 6 assist_context::{AssistContext, Assists},
6 AssistId, 7 AssistId,
7}; 8};
8use test_utils::tested_by;
9 9
10// Assist: add_turbo_fish 10// Assist: add_turbo_fish
11// 11//
@@ -28,7 +28,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
28 let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?; 28 let ident = ctx.find_token_at_offset(SyntaxKind::IDENT)?;
29 let next_token = ident.next_token()?; 29 let next_token = ident.next_token()?;
30 if next_token.kind() == T![::] { 30 if next_token.kind() == T![::] {
31 tested_by!(add_turbo_fish_one_fish_is_enough); 31 mark::hit!(add_turbo_fish_one_fish_is_enough);
32 return None; 32 return None;
33 } 33 }
34 let name_ref = ast::NameRef::cast(ident.parent())?; 34 let name_ref = ast::NameRef::cast(ident.parent())?;
@@ -42,7 +42,7 @@ pub(crate) fn add_turbo_fish(acc: &mut Assists, ctx: &AssistContext) -> Option<(
42 }; 42 };
43 let generics = hir::GenericDef::Function(fun).params(ctx.sema.db); 43 let generics = hir::GenericDef::Function(fun).params(ctx.sema.db);
44 if generics.is_empty() { 44 if generics.is_empty() {
45 tested_by!(add_turbo_fish_non_generic); 45 mark::hit!(add_turbo_fish_non_generic);
46 return None; 46 return None;
47 } 47 }
48 acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| { 48 acc.add(AssistId("add_turbo_fish"), "Add `::<>`", ident.text_range(), |builder| {
@@ -58,7 +58,7 @@ mod tests {
58 use crate::tests::{check_assist, check_assist_not_applicable}; 58 use crate::tests::{check_assist, check_assist_not_applicable};
59 59
60 use super::*; 60 use super::*;
61 use test_utils::covers; 61 use test_utils::mark;
62 62
63 #[test] 63 #[test]
64 fn add_turbo_fish_function() { 64 fn add_turbo_fish_function() {
@@ -106,7 +106,7 @@ fn main() {
106 106
107 #[test] 107 #[test]
108 fn add_turbo_fish_one_fish_is_enough() { 108 fn add_turbo_fish_one_fish_is_enough() {
109 covers!(add_turbo_fish_one_fish_is_enough); 109 mark::check!(add_turbo_fish_one_fish_is_enough);
110 check_assist_not_applicable( 110 check_assist_not_applicable(
111 add_turbo_fish, 111 add_turbo_fish,
112 r#" 112 r#"
@@ -120,7 +120,7 @@ fn main() {
120 120
121 #[test] 121 #[test]
122 fn add_turbo_fish_non_generic() { 122 fn add_turbo_fish_non_generic() {
123 covers!(add_turbo_fish_non_generic); 123 mark::check!(add_turbo_fish_non_generic);
124 check_assist_not_applicable( 124 check_assist_not_applicable(
125 add_turbo_fish, 125 add_turbo_fish,
126 r#" 126 r#"
diff --git a/crates/ra_assists/src/handlers/apply_demorgan.rs b/crates/ra_assists/src/handlers/apply_demorgan.rs
index 0feba5e11..233e8fb8e 100644
--- a/crates/ra_assists/src/handlers/apply_demorgan.rs
+++ b/crates/ra_assists/src/handlers/apply_demorgan.rs
@@ -63,22 +63,22 @@ mod tests {
63 63
64 #[test] 64 #[test]
65 fn demorgan_turns_and_into_or() { 65 fn demorgan_turns_and_into_or() {
66 check_assist(apply_demorgan, "fn f() { !x &&<|> !x }", "fn f() { !(x ||<|> x) }") 66 check_assist(apply_demorgan, "fn f() { !x &&<|> !x }", "fn f() { !(x || x) }")
67 } 67 }
68 68
69 #[test] 69 #[test]
70 fn demorgan_turns_or_into_and() { 70 fn demorgan_turns_or_into_and() {
71 check_assist(apply_demorgan, "fn f() { !x ||<|> !x }", "fn f() { !(x &&<|> x) }") 71 check_assist(apply_demorgan, "fn f() { !x ||<|> !x }", "fn f() { !(x && x) }")
72 } 72 }
73 73
74 #[test] 74 #[test]
75 fn demorgan_removes_inequality() { 75 fn demorgan_removes_inequality() {
76 check_assist(apply_demorgan, "fn f() { x != x ||<|> !x }", "fn f() { !(x == x &&<|> x) }") 76 check_assist(apply_demorgan, "fn f() { x != x ||<|> !x }", "fn f() { !(x == x && x) }")
77 } 77 }
78 78
79 #[test] 79 #[test]
80 fn demorgan_general_case() { 80 fn demorgan_general_case() {
81 check_assist(apply_demorgan, "fn f() { x ||<|> x }", "fn f() { !(!x &&<|> !x) }") 81 check_assist(apply_demorgan, "fn f() { x ||<|> x }", "fn f() { !(!x && !x) }")
82 } 82 }
83 83
84 #[test] 84 #[test]
diff --git a/crates/ra_assists/src/handlers/auto_import.rs b/crates/ra_assists/src/handlers/auto_import.rs
index 78d23150d..edf96d50e 100644
--- a/crates/ra_assists/src/handlers/auto_import.rs
+++ b/crates/ra_assists/src/handlers/auto_import.rs
@@ -50,7 +50,12 @@ pub(crate) fn auto_import(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
50 format!("Import `{}`", &import), 50 format!("Import `{}`", &import),
51 range, 51 range,
52 |builder| { 52 |builder| {
53 insert_use_statement(&auto_import_assets.syntax_under_caret, &import, ctx, builder); 53 insert_use_statement(
54 &auto_import_assets.syntax_under_caret,
55 &import,
56 ctx,
57 builder.text_edit_builder(),
58 );
54 }, 59 },
55 ); 60 );
56 } 61 }
@@ -293,7 +298,7 @@ mod tests {
293 } 298 }
294 ", 299 ",
295 r" 300 r"
296 <|>use PubMod::PubStruct; 301 use PubMod::PubStruct;
297 302
298 PubStruct 303 PubStruct
299 304
@@ -324,7 +329,7 @@ mod tests {
324 macro_rules! foo { 329 macro_rules! foo {
325 ($i:ident) => { fn foo(a: $i) {} } 330 ($i:ident) => { fn foo(a: $i) {} }
326 } 331 }
327 foo!(Pub<|>Struct); 332 foo!(PubStruct);
328 333
329 pub mod PubMod { 334 pub mod PubMod {
330 pub struct PubStruct; 335 pub struct PubStruct;
@@ -355,7 +360,7 @@ mod tests {
355 use PubMod::{PubStruct2, PubStruct1}; 360 use PubMod::{PubStruct2, PubStruct1};
356 361
357 struct Test { 362 struct Test {
358 test: Pub<|>Struct2<u8>, 363 test: PubStruct2<u8>,
359 } 364 }
360 365
361 pub mod PubMod { 366 pub mod PubMod {
@@ -388,7 +393,7 @@ mod tests {
388 r" 393 r"
389 use PubMod3::PubStruct; 394 use PubMod3::PubStruct;
390 395
391 PubSt<|>ruct 396 PubStruct
392 397
393 pub mod PubMod1 { 398 pub mod PubMod1 {
394 pub struct PubStruct; 399 pub struct PubStruct;
@@ -469,7 +474,7 @@ mod tests {
469 r" 474 r"
470 use PubMod::test_function; 475 use PubMod::test_function;
471 476
472 test_function<|> 477 test_function
473 478
474 pub mod PubMod { 479 pub mod PubMod {
475 pub fn test_function() {}; 480 pub fn test_function() {};
@@ -496,7 +501,7 @@ mod tests {
496 r"use crate_with_macro::foo; 501 r"use crate_with_macro::foo;
497 502
498fn main() { 503fn main() {
499 foo<|> 504 foo
500} 505}
501", 506",
502 ); 507 );
@@ -582,7 +587,7 @@ fn main() {
582 } 587 }
583 588
584 fn main() { 589 fn main() {
585 TestStruct::test_function<|> 590 TestStruct::test_function
586 } 591 }
587 ", 592 ",
588 ); 593 );
@@ -615,7 +620,7 @@ fn main() {
615 } 620 }
616 621
617 fn main() { 622 fn main() {
618 TestStruct::TEST_CONST<|> 623 TestStruct::TEST_CONST
619 } 624 }
620 ", 625 ",
621 ); 626 );
@@ -654,7 +659,7 @@ fn main() {
654 } 659 }
655 660
656 fn main() { 661 fn main() {
657 test_mod::TestStruct::test_function<|> 662 test_mod::TestStruct::test_function
658 } 663 }
659 ", 664 ",
660 ); 665 );
@@ -725,7 +730,7 @@ fn main() {
725 } 730 }
726 731
727 fn main() { 732 fn main() {
728 test_mod::TestStruct::TEST_CONST<|> 733 test_mod::TestStruct::TEST_CONST
729 } 734 }
730 ", 735 ",
731 ); 736 );
@@ -798,7 +803,7 @@ fn main() {
798 803
799 fn main() { 804 fn main() {
800 let test_struct = test_mod::TestStruct {}; 805 let test_struct = test_mod::TestStruct {};
801 test_struct.test_meth<|>od() 806 test_struct.test_method()
802 } 807 }
803 ", 808 ",
804 ); 809 );
diff --git a/crates/ra_assists/src/handlers/change_return_type_to_result.rs b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
index 5c907097e..c6baa0a57 100644
--- a/crates/ra_assists/src/handlers/change_return_type_to_result.rs
+++ b/crates/ra_assists/src/handlers/change_return_type_to_result.rs
@@ -1,8 +1,6 @@
1use ra_syntax::{ 1use ra_syntax::{
2 ast::{self, BlockExpr, Expr, LoopBodyOwner}, 2 ast::{self, BlockExpr, Expr, LoopBodyOwner},
3 AstNode, 3 AstNode, SyntaxNode,
4 SyntaxKind::{COMMENT, WHITESPACE},
5 SyntaxNode, TextSize,
6}; 4};
7 5
8use crate::{AssistContext, AssistId, Assists}; 6use crate::{AssistContext, AssistId, Assists};
@@ -16,39 +14,40 @@ use crate::{AssistContext, AssistId, Assists};
16// ``` 14// ```
17// -> 15// ->
18// ``` 16// ```
19// fn foo() -> Result<i32, > { Ok(42i32) } 17// fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }
20// ``` 18// ```
21pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 19pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
22 let fn_def = ctx.find_node_at_offset::<ast::FnDef>(); 20 let ret_type = ctx.find_node_at_offset::<ast::RetType>()?;
23 let fn_def = &mut fn_def?; 21 // FIXME: extend to lambdas as well
24 let ret_type = &fn_def.ret_type()?.type_ref()?; 22 let fn_def = ret_type.syntax().parent().and_then(ast::FnDef::cast)?;
25 if ret_type.syntax().text().to_string().starts_with("Result<") { 23
24 let type_ref = &ret_type.type_ref()?;
25 if type_ref.syntax().text().to_string().starts_with("Result<") {
26 return None; 26 return None;
27 } 27 }
28 28
29 let block_expr = &fn_def.body()?; 29 let block_expr = &fn_def.body()?;
30 let cursor_in_ret_type =
31 fn_def.ret_type()?.syntax().text_range().contains_range(ctx.frange.range);
32 if !cursor_in_ret_type {
33 return None;
34 }
35 30
36 acc.add( 31 acc.add(
37 AssistId("change_return_type_to_result"), 32 AssistId("change_return_type_to_result"),
38 "Change return type to Result", 33 "Change return type to Result",
39 ret_type.syntax().text_range(), 34 type_ref.syntax().text_range(),
40 |edit| { 35 |builder| {
41 let mut tail_return_expr_collector = TailReturnCollector::new(); 36 let mut tail_return_expr_collector = TailReturnCollector::new();
42 tail_return_expr_collector.collect_jump_exprs(block_expr, false); 37 tail_return_expr_collector.collect_jump_exprs(block_expr, false);
43 tail_return_expr_collector.collect_tail_exprs(block_expr); 38 tail_return_expr_collector.collect_tail_exprs(block_expr);
44 39
45 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap { 40 for ret_expr_arg in tail_return_expr_collector.exprs_to_wrap {
46 edit.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg)); 41 builder.replace_node_and_indent(&ret_expr_arg, format!("Ok({})", ret_expr_arg));
47 } 42 }
48 edit.replace_node_and_indent(ret_type.syntax(), format!("Result<{}, >", ret_type));
49 43
50 if let Some(node_start) = result_insertion_offset(&ret_type) { 44 match ctx.config.snippet_cap {
51 edit.set_cursor(node_start + TextSize::of(&format!("Result<{}, ", ret_type))); 45 Some(cap) => {
46 let snippet = format!("Result<{}, ${{0:_}}>", type_ref);
47 builder.replace_snippet(cap, type_ref.syntax().text_range(), snippet)
48 }
49 None => builder
50 .replace(type_ref.syntax().text_range(), format!("Result<{}, _>", type_ref)),
52 } 51 }
53 }, 52 },
54 ) 53 )
@@ -250,17 +249,8 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> {
250 } 249 }
251} 250}
252 251
253fn result_insertion_offset(ret_type: &ast::TypeRef) -> Option<TextSize> {
254 let non_ws_child = ret_type
255 .syntax()
256 .children_with_tokens()
257 .find(|it| it.kind() != COMMENT && it.kind() != WHITESPACE)?;
258 Some(non_ws_child.text_range().start())
259}
260
261#[cfg(test)] 252#[cfg(test)]
262mod tests { 253mod tests {
263
264 use crate::tests::{check_assist, check_assist_not_applicable}; 254 use crate::tests::{check_assist, check_assist_not_applicable};
265 255
266 use super::*; 256 use super::*;
@@ -273,7 +263,7 @@ mod tests {
273 let test = "test"; 263 let test = "test";
274 return 42i32; 264 return 42i32;
275 }"#, 265 }"#,
276 r#"fn foo() -> Result<i32, <|>> { 266 r#"fn foo() -> Result<i32, ${0:_}> {
277 let test = "test"; 267 let test = "test";
278 return Ok(42i32); 268 return Ok(42i32);
279 }"#, 269 }"#,
@@ -288,7 +278,7 @@ mod tests {
288 let test = "test"; 278 let test = "test";
289 return 42i32; 279 return 42i32;
290 }"#, 280 }"#,
291 r#"fn foo() -> Result<i32, <|>> { 281 r#"fn foo() -> Result<i32, ${0:_}> {
292 let test = "test"; 282 let test = "test";
293 return Ok(42i32); 283 return Ok(42i32);
294 }"#, 284 }"#,
@@ -314,7 +304,7 @@ mod tests {
314 let test = "test"; 304 let test = "test";
315 return 42i32; 305 return 42i32;
316 }"#, 306 }"#,
317 r#"fn foo() -> Result<i32, <|>> { 307 r#"fn foo() -> Result<i32, ${0:_}> {
318 let test = "test"; 308 let test = "test";
319 return Ok(42i32); 309 return Ok(42i32);
320 }"#, 310 }"#,
@@ -329,7 +319,7 @@ mod tests {
329 let test = "test"; 319 let test = "test";
330 42i32 320 42i32
331 }"#, 321 }"#,
332 r#"fn foo() -> Result<i32, <|>> { 322 r#"fn foo() -> Result<i32, ${0:_}> {
333 let test = "test"; 323 let test = "test";
334 Ok(42i32) 324 Ok(42i32)
335 }"#, 325 }"#,
@@ -343,7 +333,7 @@ mod tests {
343 r#"fn foo() -> i32<|> { 333 r#"fn foo() -> i32<|> {
344 42i32 334 42i32
345 }"#, 335 }"#,
346 r#"fn foo() -> Result<i32, <|>> { 336 r#"fn foo() -> Result<i32, ${0:_}> {
347 Ok(42i32) 337 Ok(42i32)
348 }"#, 338 }"#,
349 ); 339 );
@@ -359,7 +349,7 @@ mod tests {
359 24i32 349 24i32
360 } 350 }
361 }"#, 351 }"#,
362 r#"fn foo() -> Result<i32, <|>> { 352 r#"fn foo() -> Result<i32, ${0:_}> {
363 if true { 353 if true {
364 Ok(42i32) 354 Ok(42i32)
365 } else { 355 } else {
@@ -384,7 +374,7 @@ mod tests {
384 24i32 374 24i32
385 } 375 }
386 }"#, 376 }"#,
387 r#"fn foo() -> Result<i32, <|>> { 377 r#"fn foo() -> Result<i32, ${0:_}> {
388 if true { 378 if true {
389 if false { 379 if false {
390 Ok(1) 380 Ok(1)
@@ -413,7 +403,7 @@ mod tests {
413 24i32.await 403 24i32.await
414 } 404 }
415 }"#, 405 }"#,
416 r#"async fn foo() -> Result<i32, <|>> { 406 r#"async fn foo() -> Result<i32, ${0:_}> {
417 if true { 407 if true {
418 if false { 408 if false {
419 Ok(1.await) 409 Ok(1.await)
@@ -434,7 +424,7 @@ mod tests {
434 r#"fn foo() -> [i32;<|> 3] { 424 r#"fn foo() -> [i32;<|> 3] {
435 [1, 2, 3] 425 [1, 2, 3]
436 }"#, 426 }"#,
437 r#"fn foo() -> Result<[i32; 3], <|>> { 427 r#"fn foo() -> Result<[i32; 3], ${0:_}> {
438 Ok([1, 2, 3]) 428 Ok([1, 2, 3])
439 }"#, 429 }"#,
440 ); 430 );
@@ -455,7 +445,7 @@ mod tests {
455 24 as i32 445 24 as i32
456 } 446 }
457 }"#, 447 }"#,
458 r#"fn foo() -> Result<i32, <|>> { 448 r#"fn foo() -> Result<i32, ${0:_}> {
459 if true { 449 if true {
460 if false { 450 if false {
461 Ok(1 as i32) 451 Ok(1 as i32)
@@ -480,7 +470,7 @@ mod tests {
480 _ => 24i32, 470 _ => 24i32,
481 } 471 }
482 }"#, 472 }"#,
483 r#"fn foo() -> Result<i32, <|>> { 473 r#"fn foo() -> Result<i32, ${0:_}> {
484 let my_var = 5; 474 let my_var = 5;
485 match my_var { 475 match my_var {
486 5 => Ok(42i32), 476 5 => Ok(42i32),
@@ -503,7 +493,7 @@ mod tests {
503 493
504 my_var 494 my_var
505 }"#, 495 }"#,
506 r#"fn foo() -> Result<i32, <|>> { 496 r#"fn foo() -> Result<i32, ${0:_}> {
507 let my_var = 5; 497 let my_var = 5;
508 loop { 498 loop {
509 println!("test"); 499 println!("test");
@@ -526,7 +516,7 @@ mod tests {
526 516
527 my_var 517 my_var
528 }"#, 518 }"#,
529 r#"fn foo() -> Result<i32, <|>> { 519 r#"fn foo() -> Result<i32, ${0:_}> {
530 let my_var = let x = loop { 520 let my_var = let x = loop {
531 break 1; 521 break 1;
532 }; 522 };
@@ -549,7 +539,7 @@ mod tests {
549 539
550 res 540 res
551 }"#, 541 }"#,
552 r#"fn foo() -> Result<i32, <|>> { 542 r#"fn foo() -> Result<i32, ${0:_}> {
553 let my_var = 5; 543 let my_var = 5;
554 let res = match my_var { 544 let res = match my_var {
555 5 => 42i32, 545 5 => 42i32,
@@ -572,7 +562,7 @@ mod tests {
572 562
573 res 563 res
574 }"#, 564 }"#,
575 r#"fn foo() -> Result<i32, <|>> { 565 r#"fn foo() -> Result<i32, ${0:_}> {
576 let my_var = 5; 566 let my_var = 5;
577 let res = if my_var == 5 { 567 let res = if my_var == 5 {
578 42i32 568 42i32
@@ -608,7 +598,7 @@ mod tests {
608 }, 598 },
609 } 599 }
610 }"#, 600 }"#,
611 r#"fn foo() -> Result<i32, <|>> { 601 r#"fn foo() -> Result<i32, ${0:_}> {
612 let my_var = 5; 602 let my_var = 5;
613 match my_var { 603 match my_var {
614 5 => { 604 5 => {
@@ -641,7 +631,7 @@ mod tests {
641 } 631 }
642 53i32 632 53i32
643 }"#, 633 }"#,
644 r#"fn foo() -> Result<i32, <|>> { 634 r#"fn foo() -> Result<i32, ${0:_}> {
645 let test = "test"; 635 let test = "test";
646 if test == "test" { 636 if test == "test" {
647 return Ok(24i32); 637 return Ok(24i32);
@@ -672,7 +662,7 @@ mod tests {
672 662
673 the_field 663 the_field
674 }"#, 664 }"#,
675 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 665 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
676 let true_closure = || { 666 let true_closure = || {
677 return true; 667 return true;
678 }; 668 };
@@ -711,7 +701,7 @@ mod tests {
711 701
712 t.unwrap_or_else(|| the_field) 702 t.unwrap_or_else(|| the_field)
713 }"#, 703 }"#,
714 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 704 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
715 let true_closure = || { 705 let true_closure = || {
716 return true; 706 return true;
717 }; 707 };
@@ -749,7 +739,7 @@ mod tests {
749 i += 1; 739 i += 1;
750 } 740 }
751 }"#, 741 }"#,
752 r#"fn foo() -> Result<i32, <|>> { 742 r#"fn foo() -> Result<i32, ${0:_}> {
753 let test = "test"; 743 let test = "test";
754 if test == "test" { 744 if test == "test" {
755 return Ok(24i32); 745 return Ok(24i32);
@@ -781,7 +771,7 @@ mod tests {
781 } 771 }
782 } 772 }
783 }"#, 773 }"#,
784 r#"fn foo() -> Result<i32, <|>> { 774 r#"fn foo() -> Result<i32, ${0:_}> {
785 let test = "test"; 775 let test = "test";
786 if test == "test" { 776 if test == "test" {
787 return Ok(24i32); 777 return Ok(24i32);
@@ -819,7 +809,7 @@ mod tests {
819 } 809 }
820 } 810 }
821 }"#, 811 }"#,
822 r#"fn foo() -> Result<i32, <|>> { 812 r#"fn foo() -> Result<i32, ${0:_}> {
823 let test = "test"; 813 let test = "test";
824 let other = 5; 814 let other = 5;
825 if test == "test" { 815 if test == "test" {
@@ -860,7 +850,7 @@ mod tests {
860 850
861 the_field 851 the_field
862 }"#, 852 }"#,
863 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 853 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
864 if the_field < 5 { 854 if the_field < 5 {
865 let mut i = 0; 855 let mut i = 0;
866 loop { 856 loop {
@@ -894,7 +884,7 @@ mod tests {
894 884
895 the_field 885 the_field
896 }"#, 886 }"#,
897 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 887 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
898 if the_field < 5 { 888 if the_field < 5 {
899 let mut i = 0; 889 let mut i = 0;
900 890
@@ -923,7 +913,7 @@ mod tests {
923 913
924 the_field 914 the_field
925 }"#, 915 }"#,
926 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 916 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
927 if the_field < 5 { 917 if the_field < 5 {
928 let mut i = 0; 918 let mut i = 0;
929 919
@@ -953,7 +943,7 @@ mod tests {
953 943
954 the_field 944 the_field
955 }"#, 945 }"#,
956 r#"fn foo(the_field: u32) -> Result<u32, <|>> { 946 r#"fn foo(the_field: u32) -> Result<u32, ${0:_}> {
957 if the_field < 5 { 947 if the_field < 5 {
958 let mut i = 0; 948 let mut i = 0;
959 949
diff --git a/crates/ra_assists/src/handlers/change_visibility.rs b/crates/ra_assists/src/handlers/change_visibility.rs
index 40cf4b422..c21d75be0 100644
--- a/crates/ra_assists/src/handlers/change_visibility.rs
+++ b/crates/ra_assists/src/handlers/change_visibility.rs
@@ -5,14 +5,11 @@ use ra_syntax::{
5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY, 5 ATTR, COMMENT, CONST_DEF, ENUM_DEF, FN_DEF, MODULE, STRUCT_DEF, TRAIT_DEF, VISIBILITY,
6 WHITESPACE, 6 WHITESPACE,
7 }, 7 },
8 SyntaxNode, TextRange, TextSize, T, 8 SyntaxNode, TextSize, T,
9}; 9};
10 10use test_utils::mark;
11use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
12use test_utils::tested_by;
13 11
14use crate::{AssistContext, AssistId, Assists}; 12use crate::{AssistContext, AssistId, Assists};
15use ra_db::FileId;
16 13
17// Assist: change_visibility 14// Assist: change_visibility
18// 15//
@@ -30,8 +27,6 @@ pub(crate) fn change_visibility(acc: &mut Assists, ctx: &AssistContext) -> Optio
30 return change_vis(acc, vis); 27 return change_vis(acc, vis);
31 } 28 }
32 add_vis(acc, ctx) 29 add_vis(acc, ctx)
33 .or_else(|| add_vis_to_referenced_module_def(acc, ctx))
34 .or_else(|| add_vis_to_referenced_record_field(acc, ctx))
35} 30}
36 31
37fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 32fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
@@ -55,7 +50,7 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
55 } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() { 50 } else if let Some(field_name) = ctx.find_node_at_offset::<ast::Name>() {
56 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?; 51 let field = field_name.syntax().ancestors().find_map(ast::RecordFieldDef::cast)?;
57 if field.name()? != field_name { 52 if field.name()? != field_name {
58 tested_by!(change_visibility_field_false_positive); 53 mark::hit!(change_visibility_field_false_positive);
59 return None; 54 return None;
60 } 55 }
61 if field.visibility().is_some() { 56 if field.visibility().is_some() {
@@ -73,147 +68,9 @@ fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
73 68
74 acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| { 69 acc.add(AssistId("change_visibility"), "Change visibility to pub(crate)", target, |edit| {
75 edit.insert(offset, "pub(crate) "); 70 edit.insert(offset, "pub(crate) ");
76 edit.set_cursor(offset);
77 })
78}
79
80fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
81 let path: ast::Path = ctx.find_node_at_offset()?;
82 let path_res = ctx.sema.resolve_path(&path)?;
83 let def = match path_res {
84 PathResolution::Def(def) => def,
85 _ => return None,
86 };
87
88 let current_module = ctx.sema.scope(&path.syntax()).module()?;
89 let target_module = def.module(ctx.db)?;
90
91 let vis = target_module.visibility_of(ctx.db, &def)?;
92 if vis.is_visible_from(ctx.db, current_module.into()) {
93 return None;
94 };
95
96 let (offset, target, target_file, target_name) = target_data_for_def(ctx.db, def)?;
97
98 let missing_visibility =
99 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
100
101 let assist_label = match target_name {
102 None => format!("Change visibility to {}", missing_visibility),
103 Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
104 };
105
106 acc.add(AssistId("change_visibility"), assist_label, target, |edit| {
107 edit.set_file(target_file);
108 edit.insert(offset, format!("{} ", missing_visibility));
109 edit.set_cursor(offset);
110 })
111}
112
113fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
114 let record_field: ast::RecordField = ctx.find_node_at_offset()?;
115 let (record_field_def, _) = ctx.sema.resolve_record_field(&record_field)?;
116
117 let current_module = ctx.sema.scope(record_field.syntax()).module()?;
118 let visibility = record_field_def.visibility(ctx.db);
119 if visibility.is_visible_from(ctx.db, current_module.into()) {
120 return None;
121 }
122
123 let parent = record_field_def.parent_def(ctx.db);
124 let parent_name = parent.name(ctx.db);
125 let target_module = parent.module(ctx.db);
126
127 let in_file_source = record_field_def.source(ctx.db);
128 let (offset, target) = match in_file_source.value {
129 hir::FieldSource::Named(it) => {
130 let s = it.syntax();
131 (vis_offset(s), s.text_range())
132 }
133 hir::FieldSource::Pos(it) => {
134 let s = it.syntax();
135 (vis_offset(s), s.text_range())
136 }
137 };
138
139 let missing_visibility =
140 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
141 let target_file = in_file_source.file_id.original_file(ctx.db);
142
143 let target_name = record_field_def.name(ctx.db);
144 let assist_label =
145 format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
146
147 acc.add(AssistId("change_visibility"), assist_label, target, |edit| {
148 edit.set_file(target_file);
149 edit.insert(offset, format!("{} ", missing_visibility));
150 edit.set_cursor(offset)
151 }) 71 })
152} 72}
153 73
154fn target_data_for_def(
155 db: &dyn HirDatabase,
156 def: hir::ModuleDef,
157) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> {
158 fn offset_target_and_file_id<S, Ast>(
159 db: &dyn HirDatabase,
160 x: S,
161 ) -> (TextSize, TextRange, FileId)
162 where
163 S: HasSource<Ast = Ast>,
164 Ast: AstNode,
165 {
166 let source = x.source(db);
167 let in_file_syntax = source.syntax();
168 let file_id = in_file_syntax.file_id;
169 let syntax = in_file_syntax.value;
170 (vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast()))
171 }
172
173 let target_name;
174 let (offset, target, target_file) = match def {
175 hir::ModuleDef::Function(f) => {
176 target_name = Some(f.name(db));
177 offset_target_and_file_id(db, f)
178 }
179 hir::ModuleDef::Adt(adt) => {
180 target_name = Some(adt.name(db));
181 match adt {
182 hir::Adt::Struct(s) => offset_target_and_file_id(db, s),
183 hir::Adt::Union(u) => offset_target_and_file_id(db, u),
184 hir::Adt::Enum(e) => offset_target_and_file_id(db, e),
185 }
186 }
187 hir::ModuleDef::Const(c) => {
188 target_name = c.name(db);
189 offset_target_and_file_id(db, c)
190 }
191 hir::ModuleDef::Static(s) => {
192 target_name = s.name(db);
193 offset_target_and_file_id(db, s)
194 }
195 hir::ModuleDef::Trait(t) => {
196 target_name = Some(t.name(db));
197 offset_target_and_file_id(db, t)
198 }
199 hir::ModuleDef::TypeAlias(t) => {
200 target_name = Some(t.name(db));
201 offset_target_and_file_id(db, t)
202 }
203 hir::ModuleDef::Module(m) => {
204 target_name = m.name(db);
205 let in_file_source = m.declaration_source(db)?;
206 let file_id = in_file_source.file_id.original_file(db.upcast());
207 let syntax = in_file_source.value.syntax();
208 (vis_offset(syntax), syntax.text_range(), file_id)
209 }
210 // Enum variants can't be private, we can't modify builtin types
211 hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None,
212 };
213
214 Some((offset, target, target_file, target_name))
215}
216
217fn vis_offset(node: &SyntaxNode) -> TextSize { 74fn vis_offset(node: &SyntaxNode) -> TextSize {
218 node.children_with_tokens() 75 node.children_with_tokens()
219 .skip_while(|it| match it.kind() { 76 .skip_while(|it| match it.kind() {
@@ -234,7 +91,6 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
234 target, 91 target,
235 |edit| { 92 |edit| {
236 edit.replace(vis.syntax().text_range(), "pub(crate)"); 93 edit.replace(vis.syntax().text_range(), "pub(crate)");
237 edit.set_cursor(vis.syntax().text_range().start())
238 }, 94 },
239 ); 95 );
240 } 96 }
@@ -246,7 +102,6 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
246 target, 102 target,
247 |edit| { 103 |edit| {
248 edit.replace(vis.syntax().text_range(), "pub"); 104 edit.replace(vis.syntax().text_range(), "pub");
249 edit.set_cursor(vis.syntax().text_range().start());
250 }, 105 },
251 ); 106 );
252 } 107 }
@@ -255,7 +110,7 @@ fn change_vis(acc: &mut Assists, vis: ast::Visibility) -> Option<()> {
255 110
256#[cfg(test)] 111#[cfg(test)]
257mod tests { 112mod tests {
258 use test_utils::covers; 113 use test_utils::mark;
259 114
260 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 115 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
261 116
@@ -263,17 +118,13 @@ mod tests {
263 118
264 #[test] 119 #[test]
265 fn change_visibility_adds_pub_crate_to_items() { 120 fn change_visibility_adds_pub_crate_to_items() {
266 check_assist(change_visibility, "<|>fn foo() {}", "<|>pub(crate) fn foo() {}"); 121 check_assist(change_visibility, "<|>fn foo() {}", "pub(crate) fn foo() {}");
267 check_assist(change_visibility, "f<|>n foo() {}", "<|>pub(crate) fn foo() {}"); 122 check_assist(change_visibility, "f<|>n foo() {}", "pub(crate) fn foo() {}");
268 check_assist(change_visibility, "<|>struct Foo {}", "<|>pub(crate) struct Foo {}"); 123 check_assist(change_visibility, "<|>struct Foo {}", "pub(crate) struct Foo {}");
269 check_assist(change_visibility, "<|>mod foo {}", "<|>pub(crate) mod foo {}"); 124 check_assist(change_visibility, "<|>mod foo {}", "pub(crate) mod foo {}");
270 check_assist(change_visibility, "<|>trait Foo {}", "<|>pub(crate) trait Foo {}"); 125 check_assist(change_visibility, "<|>trait Foo {}", "pub(crate) trait Foo {}");
271 check_assist(change_visibility, "m<|>od {}", "<|>pub(crate) mod {}"); 126 check_assist(change_visibility, "m<|>od {}", "pub(crate) mod {}");
272 check_assist( 127 check_assist(change_visibility, "unsafe f<|>n foo() {}", "pub(crate) unsafe fn foo() {}");
273 change_visibility,
274 "unsafe f<|>n foo() {}",
275 "<|>pub(crate) unsafe fn foo() {}",
276 );
277 } 128 }
278 129
279 #[test] 130 #[test]
@@ -281,14 +132,14 @@ mod tests {
281 check_assist( 132 check_assist(
282 change_visibility, 133 change_visibility,
283 r"struct S { <|>field: u32 }", 134 r"struct S { <|>field: u32 }",
284 r"struct S { <|>pub(crate) field: u32 }", 135 r"struct S { pub(crate) field: u32 }",
285 ); 136 );
286 check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( <|>pub(crate) u32 )"); 137 check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( pub(crate) u32 )");
287 } 138 }
288 139
289 #[test] 140 #[test]
290 fn change_visibility_field_false_positive() { 141 fn change_visibility_field_false_positive() {
291 covers!(change_visibility_field_false_positive); 142 mark::check!(change_visibility_field_false_positive);
292 check_assist_not_applicable( 143 check_assist_not_applicable(
293 change_visibility, 144 change_visibility,
294 r"struct S { field: [(); { let <|>x = ();}] }", 145 r"struct S { field: [(); { let <|>x = ();}] }",
@@ -297,17 +148,17 @@ mod tests {
297 148
298 #[test] 149 #[test]
299 fn change_visibility_pub_to_pub_crate() { 150 fn change_visibility_pub_to_pub_crate() {
300 check_assist(change_visibility, "<|>pub fn foo() {}", "<|>pub(crate) fn foo() {}") 151 check_assist(change_visibility, "<|>pub fn foo() {}", "pub(crate) fn foo() {}")
301 } 152 }
302 153
303 #[test] 154 #[test]
304 fn change_visibility_pub_crate_to_pub() { 155 fn change_visibility_pub_crate_to_pub() {
305 check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "<|>pub fn foo() {}") 156 check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "pub fn foo() {}")
306 } 157 }
307 158
308 #[test] 159 #[test]
309 fn change_visibility_const() { 160 fn change_visibility_const() {
310 check_assist(change_visibility, "<|>const FOO = 3u8;", "<|>pub(crate) const FOO = 3u8;"); 161 check_assist(change_visibility, "<|>const FOO = 3u8;", "pub(crate) const FOO = 3u8;");
311 } 162 }
312 163
313 #[test] 164 #[test]
@@ -328,199 +179,12 @@ mod tests {
328 // comments 179 // comments
329 180
330 #[derive(Debug)] 181 #[derive(Debug)]
331 <|>pub(crate) struct Foo; 182 pub(crate) struct Foo;
332 ", 183 ",
333 ) 184 )
334 } 185 }
335 186
336 #[test] 187 #[test]
337 fn change_visibility_of_fn_via_path() {
338 check_assist(
339 change_visibility,
340 r"mod foo { fn foo() {} }
341 fn main() { foo::foo<|>() } ",
342 r"mod foo { <|>pub(crate) fn foo() {} }
343 fn main() { foo::foo() } ",
344 );
345 check_assist_not_applicable(
346 change_visibility,
347 r"mod foo { pub fn foo() {} }
348 fn main() { foo::foo<|>() } ",
349 )
350 }
351
352 #[test]
353 fn change_visibility_of_adt_in_submodule_via_path() {
354 check_assist(
355 change_visibility,
356 r"mod foo { struct Foo; }
357 fn main() { foo::Foo<|> } ",
358 r"mod foo { <|>pub(crate) struct Foo; }
359 fn main() { foo::Foo } ",
360 );
361 check_assist_not_applicable(
362 change_visibility,
363 r"mod foo { pub struct Foo; }
364 fn main() { foo::Foo<|> } ",
365 );
366 check_assist(
367 change_visibility,
368 r"mod foo { enum Foo; }
369 fn main() { foo::Foo<|> } ",
370 r"mod foo { <|>pub(crate) enum Foo; }
371 fn main() { foo::Foo } ",
372 );
373 check_assist_not_applicable(
374 change_visibility,
375 r"mod foo { pub enum Foo; }
376 fn main() { foo::Foo<|> } ",
377 );
378 check_assist(
379 change_visibility,
380 r"mod foo { union Foo; }
381 fn main() { foo::Foo<|> } ",
382 r"mod foo { <|>pub(crate) union Foo; }
383 fn main() { foo::Foo } ",
384 );
385 check_assist_not_applicable(
386 change_visibility,
387 r"mod foo { pub union Foo; }
388 fn main() { foo::Foo<|> } ",
389 );
390 }
391
392 #[test]
393 fn change_visibility_of_adt_in_other_file_via_path() {
394 check_assist(
395 change_visibility,
396 r"
397 //- /main.rs
398 mod foo;
399 fn main() { foo::Foo<|> }
400
401 //- /foo.rs
402 struct Foo;
403 ",
404 r"<|>pub(crate) struct Foo;
405
406",
407 );
408 }
409
410 #[test]
411 fn change_visibility_of_struct_field_via_path() {
412 check_assist(
413 change_visibility,
414 r"mod foo { pub struct Foo { bar: (), } }
415 fn main() { foo::Foo { <|>bar: () }; } ",
416 r"mod foo { pub struct Foo { <|>pub(crate) bar: (), } }
417 fn main() { foo::Foo { bar: () }; } ",
418 );
419 check_assist(
420 change_visibility,
421 r"//- /lib.rs
422 mod foo;
423 fn main() { foo::Foo { <|>bar: () }; }
424 //- /foo.rs
425 pub struct Foo { bar: () }
426 ",
427 r"pub struct Foo { <|>pub(crate) bar: () }
428
429",
430 );
431 check_assist_not_applicable(
432 change_visibility,
433 r"mod foo { pub struct Foo { pub bar: (), } }
434 fn main() { foo::Foo { <|>bar: () }; } ",
435 );
436 check_assist_not_applicable(
437 change_visibility,
438 r"//- /lib.rs
439 mod foo;
440 fn main() { foo::Foo { <|>bar: () }; }
441 //- /foo.rs
442 pub struct Foo { pub bar: () }
443 ",
444 );
445 }
446
447 #[test]
448 fn change_visibility_of_enum_variant_field_via_path() {
449 check_assist(
450 change_visibility,
451 r"mod foo { pub enum Foo { Bar { bar: () } } }
452 fn main() { foo::Foo::Bar { <|>bar: () }; } ",
453 r"mod foo { pub enum Foo { Bar { <|>pub(crate) bar: () } } }
454 fn main() { foo::Foo::Bar { bar: () }; } ",
455 );
456 check_assist(
457 change_visibility,
458 r"//- /lib.rs
459 mod foo;
460 fn main() { foo::Foo::Bar { <|>bar: () }; }
461 //- /foo.rs
462 pub enum Foo { Bar { bar: () } }
463 ",
464 r"pub enum Foo { Bar { <|>pub(crate) bar: () } }
465
466",
467 );
468 check_assist_not_applicable(
469 change_visibility,
470 r"mod foo { pub struct Foo { pub bar: (), } }
471 fn main() { foo::Foo { <|>bar: () }; } ",
472 );
473 check_assist_not_applicable(
474 change_visibility,
475 r"//- /lib.rs
476 mod foo;
477 fn main() { foo::Foo { <|>bar: () }; }
478 //- /foo.rs
479 pub struct Foo { pub bar: () }
480 ",
481 );
482 }
483
484 #[test]
485 #[ignore]
486 // FIXME reenable this test when `Semantics::resolve_record_field` works with union fields
487 fn change_visibility_of_union_field_via_path() {
488 check_assist(
489 change_visibility,
490 r"mod foo { pub union Foo { bar: (), } }
491 fn main() { foo::Foo { <|>bar: () }; } ",
492 r"mod foo { pub union Foo { <|>pub(crate) bar: (), } }
493 fn main() { foo::Foo { bar: () }; } ",
494 );
495 check_assist(
496 change_visibility,
497 r"//- /lib.rs
498 mod foo;
499 fn main() { foo::Foo { <|>bar: () }; }
500 //- /foo.rs
501 pub union Foo { bar: () }
502 ",
503 r"pub union Foo { <|>pub(crate) bar: () }
504
505",
506 );
507 check_assist_not_applicable(
508 change_visibility,
509 r"mod foo { pub union Foo { pub bar: (), } }
510 fn main() { foo::Foo { <|>bar: () }; } ",
511 );
512 check_assist_not_applicable(
513 change_visibility,
514 r"//- /lib.rs
515 mod foo;
516 fn main() { foo::Foo { <|>bar: () }; }
517 //- /foo.rs
518 pub union Foo { pub bar: () }
519 ",
520 );
521 }
522
523 #[test]
524 fn not_applicable_for_enum_variants() { 188 fn not_applicable_for_enum_variants() {
525 check_assist_not_applicable( 189 check_assist_not_applicable(
526 change_visibility, 190 change_visibility,
@@ -530,182 +194,6 @@ mod tests {
530 } 194 }
531 195
532 #[test] 196 #[test]
533 fn change_visibility_of_const_via_path() {
534 check_assist(
535 change_visibility,
536 r"mod foo { const FOO: () = (); }
537 fn main() { foo::FOO<|> } ",
538 r"mod foo { <|>pub(crate) const FOO: () = (); }
539 fn main() { foo::FOO } ",
540 );
541 check_assist_not_applicable(
542 change_visibility,
543 r"mod foo { pub const FOO: () = (); }
544 fn main() { foo::FOO<|> } ",
545 );
546 }
547
548 #[test]
549 fn change_visibility_of_static_via_path() {
550 check_assist(
551 change_visibility,
552 r"mod foo { static FOO: () = (); }
553 fn main() { foo::FOO<|> } ",
554 r"mod foo { <|>pub(crate) static FOO: () = (); }
555 fn main() { foo::FOO } ",
556 );
557 check_assist_not_applicable(
558 change_visibility,
559 r"mod foo { pub static FOO: () = (); }
560 fn main() { foo::FOO<|> } ",
561 );
562 }
563
564 #[test]
565 fn change_visibility_of_trait_via_path() {
566 check_assist(
567 change_visibility,
568 r"mod foo { trait Foo { fn foo(&self) {} } }
569 fn main() { let x: &dyn foo::<|>Foo; } ",
570 r"mod foo { <|>pub(crate) trait Foo { fn foo(&self) {} } }
571 fn main() { let x: &dyn foo::Foo; } ",
572 );
573 check_assist_not_applicable(
574 change_visibility,
575 r"mod foo { pub trait Foo { fn foo(&self) {} } }
576 fn main() { let x: &dyn foo::Foo<|>; } ",
577 );
578 }
579
580 #[test]
581 fn change_visibility_of_type_alias_via_path() {
582 check_assist(
583 change_visibility,
584 r"mod foo { type Foo = (); }
585 fn main() { let x: foo::Foo<|>; } ",
586 r"mod foo { <|>pub(crate) type Foo = (); }
587 fn main() { let x: foo::Foo; } ",
588 );
589 check_assist_not_applicable(
590 change_visibility,
591 r"mod foo { pub type Foo = (); }
592 fn main() { let x: foo::Foo<|>; } ",
593 );
594 }
595
596 #[test]
597 fn change_visibility_of_module_via_path() {
598 check_assist(
599 change_visibility,
600 r"mod foo { mod bar { fn bar() {} } }
601 fn main() { foo::bar<|>::bar(); } ",
602 r"mod foo { <|>pub(crate) mod bar { fn bar() {} } }
603 fn main() { foo::bar::bar(); } ",
604 );
605
606 check_assist(
607 change_visibility,
608 r"
609 //- /main.rs
610 mod foo;
611 fn main() { foo::bar<|>::baz(); }
612
613 //- /foo.rs
614 mod bar {
615 pub fn baz() {}
616 }
617 ",
618 r"<|>pub(crate) mod bar {
619 pub fn baz() {}
620}
621
622",
623 );
624
625 check_assist_not_applicable(
626 change_visibility,
627 r"mod foo { pub mod bar { pub fn bar() {} } }
628 fn main() { foo::bar<|>::bar(); } ",
629 );
630 }
631
632 #[test]
633 fn change_visibility_of_inline_module_in_other_file_via_path() {
634 check_assist(
635 change_visibility,
636 r"
637 //- /main.rs
638 mod foo;
639 fn main() { foo::bar<|>::baz(); }
640
641 //- /foo.rs
642 mod bar;
643
644 //- /foo/bar.rs
645 pub fn baz() {}
646 }
647 ",
648 r"<|>pub(crate) mod bar;
649",
650 );
651 }
652
653 #[test]
654 fn change_visibility_of_module_declaration_in_other_file_via_path() {
655 check_assist(
656 change_visibility,
657 r"//- /main.rs
658 mod foo;
659 fn main() { foo::bar<|>>::baz(); }
660
661 //- /foo.rs
662 mod bar {
663 pub fn baz() {}
664 }",
665 r"<|>pub(crate) mod bar {
666 pub fn baz() {}
667}
668",
669 );
670 }
671
672 #[test]
673 #[ignore]
674 // FIXME handle reexports properly
675 fn change_visibility_of_reexport() {
676 check_assist(
677 change_visibility,
678 r"
679 mod foo {
680 use bar::Baz;
681 mod bar { pub(super) struct Baz; }
682 }
683 foo::Baz<|>
684 ",
685 r"
686 mod foo {
687 <|>pub(crate) use bar::Baz;
688 mod bar { pub(super) struct Baz; }
689 }
690 foo::Baz
691 ",
692 )
693 }
694
695 #[test]
696 fn adds_pub_when_target_is_in_another_crate() {
697 check_assist(
698 change_visibility,
699 r"//- /main.rs crate:a deps:foo
700 foo::Bar<|>
701 //- /lib.rs crate:foo
702 struct Bar;",
703 r"<|>pub struct Bar;
704",
705 )
706 }
707
708 #[test]
709 fn change_visibility_target() { 197 fn change_visibility_target() {
710 check_assist_target(change_visibility, "<|>fn foo() {}", "fn"); 198 check_assist_target(change_visibility, "<|>fn foo() {}", "fn");
711 check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)"); 199 check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)");
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs
index 13c1e7e80..cc303285b 100644
--- a/crates/ra_assists/src/handlers/fill_match_arms.rs
+++ b/crates/ra_assists/src/handlers/fill_match_arms.rs
@@ -4,8 +4,12 @@ use hir::{Adt, HasSource, ModuleDef, Semantics};
4use itertools::Itertools; 4use itertools::Itertools;
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; 6use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat};
7use test_utils::mark;
7 8
8use crate::{AssistContext, AssistId, Assists}; 9use crate::{
10 utils::{render_snippet, Cursor, FamousDefs},
11 AssistContext, AssistId, Assists,
12};
9 13
10// Assist: fill_match_arms 14// Assist: fill_match_arms
11// 15//
@@ -26,7 +30,7 @@ use crate::{AssistContext, AssistId, Assists};
26// 30//
27// fn handle(action: Action) { 31// fn handle(action: Action) {
28// match action { 32// match action {
29// Action::Move { distance } => {} 33// $0Action::Move { distance } => {}
30// Action::Stop => {} 34// Action::Stop => {}
31// } 35// }
32// } 36// }
@@ -49,12 +53,18 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
49 let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) { 53 let missing_arms: Vec<MatchArm> = if let Some(enum_def) = resolve_enum_def(&ctx.sema, &expr) {
50 let variants = enum_def.variants(ctx.db); 54 let variants = enum_def.variants(ctx.db);
51 55
52 variants 56 let mut variants = variants
53 .into_iter() 57 .into_iter()
54 .filter_map(|variant| build_pat(ctx.db, module, variant)) 58 .filter_map(|variant| build_pat(ctx.db, module, variant))
55 .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat)) 59 .filter(|variant_pat| is_variant_missing(&mut arms, variant_pat))
56 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block())) 60 .map(|pat| make::match_arm(iter::once(pat), make::expr_empty_block()))
57 .collect() 61 .collect::<Vec<_>>();
62 if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() {
63 // Match `Some` variant first.
64 mark::hit!(option_order);
65 variants.reverse()
66 }
67 variants
58 } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) { 68 } else if let Some(enum_defs) = resolve_tuple_of_enum_def(&ctx.sema, &expr) {
59 // Partial fill not currently supported for tuple of enums. 69 // Partial fill not currently supported for tuple of enums.
60 if !arms.is_empty() { 70 if !arms.is_empty() {
@@ -93,10 +103,23 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option<
93 } 103 }
94 104
95 let target = match_expr.syntax().text_range(); 105 let target = match_expr.syntax().text_range();
96 acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |edit| { 106 acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |builder| {
97 let new_arm_list = match_arm_list.remove_placeholder().append_arms(missing_arms); 107 let new_arm_list = match_arm_list.remove_placeholder();
98 edit.set_cursor(expr.syntax().text_range().start()); 108 let n_old_arms = new_arm_list.arms().count();
99 edit.replace_ast(match_arm_list, new_arm_list); 109 let new_arm_list = new_arm_list.append_arms(missing_arms);
110 let first_new_arm = new_arm_list.arms().nth(n_old_arms);
111 let old_range = match_arm_list.syntax().text_range();
112 match (first_new_arm, ctx.config.snippet_cap) {
113 (Some(first_new_arm), Some(cap)) => {
114 let snippet = render_snippet(
115 cap,
116 new_arm_list.syntax(),
117 Cursor::Before(first_new_arm.syntax()),
118 );
119 builder.replace_snippet(cap, old_range, snippet);
120 }
121 _ => builder.replace(old_range, new_arm_list.to_string()),
122 }
100 }) 123 })
101} 124}
102 125
@@ -167,7 +190,12 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O
167 190
168#[cfg(test)] 191#[cfg(test)]
169mod tests { 192mod tests {
170 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 193 use test_utils::mark;
194
195 use crate::{
196 tests::{check_assist, check_assist_not_applicable, check_assist_target},
197 utils::FamousDefs,
198 };
171 199
172 use super::fill_match_arms; 200 use super::fill_match_arms;
173 201
@@ -214,12 +242,12 @@ mod tests {
214 r#" 242 r#"
215 enum A { 243 enum A {
216 As, 244 As,
217 Bs{x:i32, y:Option<i32>}, 245 Bs { x: i32, y: Option<i32> },
218 Cs(i32, Option<i32>), 246 Cs(i32, Option<i32>),
219 } 247 }
220 fn main() { 248 fn main() {
221 match A::As<|> { 249 match A::As<|> {
222 A::Bs{x,y:Some(_)} => {} 250 A::Bs { x, y: Some(_) } => {}
223 A::Cs(_, Some(_)) => {} 251 A::Cs(_, Some(_)) => {}
224 } 252 }
225 } 253 }
@@ -227,14 +255,14 @@ mod tests {
227 r#" 255 r#"
228 enum A { 256 enum A {
229 As, 257 As,
230 Bs{x:i32, y:Option<i32>}, 258 Bs { x: i32, y: Option<i32> },
231 Cs(i32, Option<i32>), 259 Cs(i32, Option<i32>),
232 } 260 }
233 fn main() { 261 fn main() {
234 match <|>A::As { 262 match A::As {
235 A::Bs{x,y:Some(_)} => {} 263 A::Bs { x, y: Some(_) } => {}
236 A::Cs(_, Some(_)) => {} 264 A::Cs(_, Some(_)) => {}
237 A::As => {} 265 $0A::As => {}
238 } 266 }
239 } 267 }
240 "#, 268 "#,
@@ -264,9 +292,9 @@ mod tests {
264 Cs(Option<i32>), 292 Cs(Option<i32>),
265 } 293 }
266 fn main() { 294 fn main() {
267 match <|>A::As { 295 match A::As {
268 A::Cs(_) | A::Bs => {} 296 A::Cs(_) | A::Bs => {}
269 A::As => {} 297 $0A::As => {}
270 } 298 }
271 } 299 }
272 "#, 300 "#,
@@ -310,11 +338,11 @@ mod tests {
310 Ys, 338 Ys,
311 } 339 }
312 fn main() { 340 fn main() {
313 match <|>A::As { 341 match A::As {
314 A::Bs if 0 < 1 => {} 342 A::Bs if 0 < 1 => {}
315 A::Ds(_value) => { let x = 1; } 343 A::Ds(_value) => { let x = 1; }
316 A::Es(B::Xs) => (), 344 A::Es(B::Xs) => (),
317 A::As => {} 345 $0A::As => {}
318 A::Cs => {} 346 A::Cs => {}
319 } 347 }
320 } 348 }
@@ -332,7 +360,7 @@ mod tests {
332 Bs, 360 Bs,
333 Cs(String), 361 Cs(String),
334 Ds(String, String), 362 Ds(String, String),
335 Es{ x: usize, y: usize } 363 Es { x: usize, y: usize }
336 } 364 }
337 365
338 fn main() { 366 fn main() {
@@ -346,13 +374,13 @@ mod tests {
346 Bs, 374 Bs,
347 Cs(String), 375 Cs(String),
348 Ds(String, String), 376 Ds(String, String),
349 Es{ x: usize, y: usize } 377 Es { x: usize, y: usize }
350 } 378 }
351 379
352 fn main() { 380 fn main() {
353 let a = A::As; 381 let a = A::As;
354 match <|>a { 382 match a {
355 A::As => {} 383 $0A::As => {}
356 A::Bs => {} 384 A::Bs => {}
357 A::Cs(_) => {} 385 A::Cs(_) => {}
358 A::Ds(_, _) => {} 386 A::Ds(_, _) => {}
@@ -368,14 +396,8 @@ mod tests {
368 check_assist( 396 check_assist(
369 fill_match_arms, 397 fill_match_arms,
370 r#" 398 r#"
371 enum A { 399 enum A { One, Two }
372 One, 400 enum B { One, Two }
373 Two,
374 }
375 enum B {
376 One,
377 Two,
378 }
379 401
380 fn main() { 402 fn main() {
381 let a = A::One; 403 let a = A::One;
@@ -384,20 +406,14 @@ mod tests {
384 } 406 }
385 "#, 407 "#,
386 r#" 408 r#"
387 enum A { 409 enum A { One, Two }
388 One, 410 enum B { One, Two }
389 Two,
390 }
391 enum B {
392 One,
393 Two,
394 }
395 411
396 fn main() { 412 fn main() {
397 let a = A::One; 413 let a = A::One;
398 let b = B::One; 414 let b = B::One;
399 match <|>(a, b) { 415 match (a, b) {
400 (A::One, B::One) => {} 416 $0(A::One, B::One) => {}
401 (A::One, B::Two) => {} 417 (A::One, B::Two) => {}
402 (A::Two, B::One) => {} 418 (A::Two, B::One) => {}
403 (A::Two, B::Two) => {} 419 (A::Two, B::Two) => {}
@@ -412,14 +428,8 @@ mod tests {
412 check_assist( 428 check_assist(
413 fill_match_arms, 429 fill_match_arms,
414 r#" 430 r#"
415 enum A { 431 enum A { One, Two }
416 One, 432 enum B { One, Two }
417 Two,
418 }
419 enum B {
420 One,
421 Two,
422 }
423 433
424 fn main() { 434 fn main() {
425 let a = A::One; 435 let a = A::One;
@@ -428,20 +438,14 @@ mod tests {
428 } 438 }
429 "#, 439 "#,
430 r#" 440 r#"
431 enum A { 441 enum A { One, Two }
432 One, 442 enum B { One, Two }
433 Two,
434 }
435 enum B {
436 One,
437 Two,
438 }
439 443
440 fn main() { 444 fn main() {
441 let a = A::One; 445 let a = A::One;
442 let b = B::One; 446 let b = B::One;
443 match <|>(&a, &b) { 447 match (&a, &b) {
444 (A::One, B::One) => {} 448 $0(A::One, B::One) => {}
445 (A::One, B::Two) => {} 449 (A::One, B::Two) => {}
446 (A::Two, B::One) => {} 450 (A::Two, B::One) => {}
447 (A::Two, B::Two) => {} 451 (A::Two, B::Two) => {}
@@ -456,14 +460,8 @@ mod tests {
456 check_assist_not_applicable( 460 check_assist_not_applicable(
457 fill_match_arms, 461 fill_match_arms,
458 r#" 462 r#"
459 enum A { 463 enum A { One, Two }
460 One, 464 enum B { One, Two }
461 Two,
462 }
463 enum B {
464 One,
465 Two,
466 }
467 465
468 fn main() { 466 fn main() {
469 let a = A::One; 467 let a = A::One;
@@ -481,14 +479,8 @@ mod tests {
481 check_assist_not_applicable( 479 check_assist_not_applicable(
482 fill_match_arms, 480 fill_match_arms,
483 r#" 481 r#"
484 enum A { 482 enum A { One, Two }
485 One, 483 enum B { One, Two }
486 Two,
487 }
488 enum B {
489 One,
490 Two,
491 }
492 484
493 fn main() { 485 fn main() {
494 let a = A::One; 486 let a = A::One;
@@ -512,10 +504,7 @@ mod tests {
512 check_assist_not_applicable( 504 check_assist_not_applicable(
513 fill_match_arms, 505 fill_match_arms,
514 r#" 506 r#"
515 enum A { 507 enum A { One, Two }
516 One,
517 Two,
518 }
519 508
520 fn main() { 509 fn main() {
521 let a = A::One; 510 let a = A::One;
@@ -531,9 +520,7 @@ mod tests {
531 check_assist( 520 check_assist(
532 fill_match_arms, 521 fill_match_arms,
533 r#" 522 r#"
534 enum A { 523 enum A { As }
535 As,
536 }
537 524
538 fn foo(a: &A) { 525 fn foo(a: &A) {
539 match a<|> { 526 match a<|> {
@@ -541,13 +528,11 @@ mod tests {
541 } 528 }
542 "#, 529 "#,
543 r#" 530 r#"
544 enum A { 531 enum A { As }
545 As,
546 }
547 532
548 fn foo(a: &A) { 533 fn foo(a: &A) {
549 match <|>a { 534 match a {
550 A::As => {} 535 $0A::As => {}
551 } 536 }
552 } 537 }
553 "#, 538 "#,
@@ -557,7 +542,7 @@ mod tests {
557 fill_match_arms, 542 fill_match_arms,
558 r#" 543 r#"
559 enum A { 544 enum A {
560 Es{ x: usize, y: usize } 545 Es { x: usize, y: usize }
561 } 546 }
562 547
563 fn foo(a: &mut A) { 548 fn foo(a: &mut A) {
@@ -567,12 +552,12 @@ mod tests {
567 "#, 552 "#,
568 r#" 553 r#"
569 enum A { 554 enum A {
570 Es{ x: usize, y: usize } 555 Es { x: usize, y: usize }
571 } 556 }
572 557
573 fn foo(a: &mut A) { 558 fn foo(a: &mut A) {
574 match <|>a { 559 match a {
575 A::Es { x, y } => {} 560 $0A::Es { x, y } => {}
576 } 561 }
577 } 562 }
578 "#, 563 "#,
@@ -611,8 +596,8 @@ mod tests {
611 enum E { X, Y } 596 enum E { X, Y }
612 597
613 fn main() { 598 fn main() {
614 match <|>E::X { 599 match E::X {
615 E::X => {} 600 $0E::X => {}
616 E::Y => {} 601 E::Y => {}
617 } 602 }
618 } 603 }
@@ -639,8 +624,8 @@ mod tests {
639 use foo::E::X; 624 use foo::E::X;
640 625
641 fn main() { 626 fn main() {
642 match <|>X { 627 match X {
643 X => {} 628 $0X => {}
644 foo::E::Y => {} 629 foo::E::Y => {}
645 } 630 }
646 } 631 }
@@ -653,10 +638,7 @@ mod tests {
653 check_assist( 638 check_assist(
654 fill_match_arms, 639 fill_match_arms,
655 r#" 640 r#"
656 enum A { 641 enum A { One, Two }
657 One,
658 Two,
659 }
660 fn foo(a: A) { 642 fn foo(a: A) {
661 match a { 643 match a {
662 // foo bar baz<|> 644 // foo bar baz<|>
@@ -666,16 +648,13 @@ mod tests {
666 } 648 }
667 "#, 649 "#,
668 r#" 650 r#"
669 enum A { 651 enum A { One, Two }
670 One,
671 Two,
672 }
673 fn foo(a: A) { 652 fn foo(a: A) {
674 match <|>a { 653 match a {
675 // foo bar baz 654 // foo bar baz
676 A::One => {} 655 A::One => {}
677 // This is where the rest should be 656 // This is where the rest should be
678 A::Two => {} 657 $0A::Two => {}
679 } 658 }
680 } 659 }
681 "#, 660 "#,
@@ -687,10 +666,7 @@ mod tests {
687 check_assist( 666 check_assist(
688 fill_match_arms, 667 fill_match_arms,
689 r#" 668 r#"
690 enum A { 669 enum A { One, Two }
691 One,
692 Two,
693 }
694 fn foo(a: A) { 670 fn foo(a: A) {
695 match a { 671 match a {
696 // foo bar baz<|> 672 // foo bar baz<|>
@@ -698,14 +674,11 @@ mod tests {
698 } 674 }
699 "#, 675 "#,
700 r#" 676 r#"
701 enum A { 677 enum A { One, Two }
702 One,
703 Two,
704 }
705 fn foo(a: A) { 678 fn foo(a: A) {
706 match <|>a { 679 match a {
707 // foo bar baz 680 // foo bar baz
708 A::One => {} 681 $0A::One => {}
709 A::Two => {} 682 A::Two => {}
710 } 683 }
711 } 684 }
@@ -728,12 +701,37 @@ mod tests {
728 r#" 701 r#"
729 enum A { One, Two, } 702 enum A { One, Two, }
730 fn foo(a: A) { 703 fn foo(a: A) {
731 match <|>a { 704 match a {
732 A::One => {} 705 $0A::One => {}
733 A::Two => {} 706 A::Two => {}
734 } 707 }
735 } 708 }
736 "#, 709 "#,
737 ); 710 );
738 } 711 }
712
713 #[test]
714 fn option_order() {
715 mark::check!(option_order);
716 let before = r#"
717fn foo(opt: Option<i32>) {
718 match opt<|> {
719 }
720}"#;
721 let before =
722 &format!("//- main.rs crate:main deps:core\n{}{}", before, FamousDefs::FIXTURE);
723
724 check_assist(
725 fill_match_arms,
726 before,
727 r#"
728fn foo(opt: Option<i32>) {
729 match opt {
730 $0Some(_) => {}
731 None => {}
732 }
733}
734"#,
735 );
736 }
739} 737}
diff --git a/crates/ra_assists/src/handlers/fix_visibility.rs b/crates/ra_assists/src/handlers/fix_visibility.rs
new file mode 100644
index 000000000..9ec42f568
--- /dev/null
+++ b/crates/ra_assists/src/handlers/fix_visibility.rs
@@ -0,0 +1,559 @@
1use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution};
2use ra_db::FileId;
3use ra_syntax::{
4 ast, AstNode,
5 SyntaxKind::{ATTR, COMMENT, WHITESPACE},
6 SyntaxNode, TextRange, TextSize,
7};
8
9use crate::{AssistContext, AssistId, Assists};
10
11// FIXME: this really should be a fix for diagnostic, rather than an assist.
12
13// Assist: fix_visibility
14//
15// Makes inaccessible item public.
16//
17// ```
18// mod m {
19// fn frobnicate() {}
20// }
21// fn main() {
22// m::frobnicate<|>() {}
23// }
24// ```
25// ->
26// ```
27// mod m {
28// $0pub(crate) fn frobnicate() {}
29// }
30// fn main() {
31// m::frobnicate() {}
32// }
33// ```
34pub(crate) fn fix_visibility(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
35 add_vis_to_referenced_module_def(acc, ctx)
36 .or_else(|| add_vis_to_referenced_record_field(acc, ctx))
37}
38
39fn add_vis_to_referenced_module_def(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
40 let path: ast::Path = ctx.find_node_at_offset()?;
41 let path_res = ctx.sema.resolve_path(&path)?;
42 let def = match path_res {
43 PathResolution::Def(def) => def,
44 _ => return None,
45 };
46
47 let current_module = ctx.sema.scope(&path.syntax()).module()?;
48 let target_module = def.module(ctx.db)?;
49
50 let vis = target_module.visibility_of(ctx.db, &def)?;
51 if vis.is_visible_from(ctx.db, current_module.into()) {
52 return None;
53 };
54
55 let (offset, target, target_file, target_name) = target_data_for_def(ctx.db, def)?;
56
57 let missing_visibility =
58 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
59
60 let assist_label = match target_name {
61 None => format!("Change visibility to {}", missing_visibility),
62 Some(name) => format!("Change visibility of {} to {}", name, missing_visibility),
63 };
64
65 acc.add(AssistId("fix_visibility"), assist_label, target, |builder| {
66 builder.set_file(target_file);
67 match ctx.config.snippet_cap {
68 Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
69 None => builder.insert(offset, format!("{} ", missing_visibility)),
70 }
71 })
72}
73
74fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
75 let record_field: ast::RecordField = ctx.find_node_at_offset()?;
76 let (record_field_def, _) = ctx.sema.resolve_record_field(&record_field)?;
77
78 let current_module = ctx.sema.scope(record_field.syntax()).module()?;
79 let visibility = record_field_def.visibility(ctx.db);
80 if visibility.is_visible_from(ctx.db, current_module.into()) {
81 return None;
82 }
83
84 let parent = record_field_def.parent_def(ctx.db);
85 let parent_name = parent.name(ctx.db);
86 let target_module = parent.module(ctx.db);
87
88 let in_file_source = record_field_def.source(ctx.db);
89 let (offset, target) = match in_file_source.value {
90 hir::FieldSource::Named(it) => {
91 let s = it.syntax();
92 (vis_offset(s), s.text_range())
93 }
94 hir::FieldSource::Pos(it) => {
95 let s = it.syntax();
96 (vis_offset(s), s.text_range())
97 }
98 };
99
100 let missing_visibility =
101 if current_module.krate() == target_module.krate() { "pub(crate)" } else { "pub" };
102 let target_file = in_file_source.file_id.original_file(ctx.db);
103
104 let target_name = record_field_def.name(ctx.db);
105 let assist_label =
106 format!("Change visibility of {}.{} to {}", parent_name, target_name, missing_visibility);
107
108 acc.add(AssistId("fix_visibility"), assist_label, target, |builder| {
109 builder.set_file(target_file);
110 match ctx.config.snippet_cap {
111 Some(cap) => builder.insert_snippet(cap, offset, format!("$0{} ", missing_visibility)),
112 None => builder.insert(offset, format!("{} ", missing_visibility)),
113 }
114 })
115}
116
117fn target_data_for_def(
118 db: &dyn HirDatabase,
119 def: hir::ModuleDef,
120) -> Option<(TextSize, TextRange, FileId, Option<hir::Name>)> {
121 fn offset_target_and_file_id<S, Ast>(
122 db: &dyn HirDatabase,
123 x: S,
124 ) -> (TextSize, TextRange, FileId)
125 where
126 S: HasSource<Ast = Ast>,
127 Ast: AstNode,
128 {
129 let source = x.source(db);
130 let in_file_syntax = source.syntax();
131 let file_id = in_file_syntax.file_id;
132 let syntax = in_file_syntax.value;
133 (vis_offset(syntax), syntax.text_range(), file_id.original_file(db.upcast()))
134 }
135
136 let target_name;
137 let (offset, target, target_file) = match def {
138 hir::ModuleDef::Function(f) => {
139 target_name = Some(f.name(db));
140 offset_target_and_file_id(db, f)
141 }
142 hir::ModuleDef::Adt(adt) => {
143 target_name = Some(adt.name(db));
144 match adt {
145 hir::Adt::Struct(s) => offset_target_and_file_id(db, s),
146 hir::Adt::Union(u) => offset_target_and_file_id(db, u),
147 hir::Adt::Enum(e) => offset_target_and_file_id(db, e),
148 }
149 }
150 hir::ModuleDef::Const(c) => {
151 target_name = c.name(db);
152 offset_target_and_file_id(db, c)
153 }
154 hir::ModuleDef::Static(s) => {
155 target_name = s.name(db);
156 offset_target_and_file_id(db, s)
157 }
158 hir::ModuleDef::Trait(t) => {
159 target_name = Some(t.name(db));
160 offset_target_and_file_id(db, t)
161 }
162 hir::ModuleDef::TypeAlias(t) => {
163 target_name = Some(t.name(db));
164 offset_target_and_file_id(db, t)
165 }
166 hir::ModuleDef::Module(m) => {
167 target_name = m.name(db);
168 let in_file_source = m.declaration_source(db)?;
169 let file_id = in_file_source.file_id.original_file(db.upcast());
170 let syntax = in_file_source.value.syntax();
171 (vis_offset(syntax), syntax.text_range(), file_id)
172 }
173 // Enum variants can't be private, we can't modify builtin types
174 hir::ModuleDef::EnumVariant(_) | hir::ModuleDef::BuiltinType(_) => return None,
175 };
176
177 Some((offset, target, target_file, target_name))
178}
179
180fn vis_offset(node: &SyntaxNode) -> TextSize {
181 node.children_with_tokens()
182 .skip_while(|it| match it.kind() {
183 WHITESPACE | COMMENT | ATTR => true,
184 _ => false,
185 })
186 .next()
187 .map(|it| it.text_range().start())
188 .unwrap_or_else(|| node.text_range().start())
189}
190
191#[cfg(test)]
192mod tests {
193 use crate::tests::{check_assist, check_assist_not_applicable};
194
195 use super::*;
196
197 #[test]
198 fn fix_visibility_of_fn() {
199 check_assist(
200 fix_visibility,
201 r"mod foo { fn foo() {} }
202 fn main() { foo::foo<|>() } ",
203 r"mod foo { $0pub(crate) fn foo() {} }
204 fn main() { foo::foo() } ",
205 );
206 check_assist_not_applicable(
207 fix_visibility,
208 r"mod foo { pub fn foo() {} }
209 fn main() { foo::foo<|>() } ",
210 )
211 }
212
213 #[test]
214 fn fix_visibility_of_adt_in_submodule() {
215 check_assist(
216 fix_visibility,
217 r"mod foo { struct Foo; }
218 fn main() { foo::Foo<|> } ",
219 r"mod foo { $0pub(crate) struct Foo; }
220 fn main() { foo::Foo } ",
221 );
222 check_assist_not_applicable(
223 fix_visibility,
224 r"mod foo { pub struct Foo; }
225 fn main() { foo::Foo<|> } ",
226 );
227 check_assist(
228 fix_visibility,
229 r"mod foo { enum Foo; }
230 fn main() { foo::Foo<|> } ",
231 r"mod foo { $0pub(crate) enum Foo; }
232 fn main() { foo::Foo } ",
233 );
234 check_assist_not_applicable(
235 fix_visibility,
236 r"mod foo { pub enum Foo; }
237 fn main() { foo::Foo<|> } ",
238 );
239 check_assist(
240 fix_visibility,
241 r"mod foo { union Foo; }
242 fn main() { foo::Foo<|> } ",
243 r"mod foo { $0pub(crate) union Foo; }
244 fn main() { foo::Foo } ",
245 );
246 check_assist_not_applicable(
247 fix_visibility,
248 r"mod foo { pub union Foo; }
249 fn main() { foo::Foo<|> } ",
250 );
251 }
252
253 #[test]
254 fn fix_visibility_of_adt_in_other_file() {
255 check_assist(
256 fix_visibility,
257 r"
258 //- /main.rs
259 mod foo;
260 fn main() { foo::Foo<|> }
261
262 //- /foo.rs
263 struct Foo;
264 ",
265 r"$0pub(crate) struct Foo;
266
267",
268 );
269 }
270
271 #[test]
272 fn fix_visibility_of_struct_field() {
273 check_assist(
274 fix_visibility,
275 r"mod foo { pub struct Foo { bar: (), } }
276 fn main() { foo::Foo { <|>bar: () }; } ",
277 r"mod foo { pub struct Foo { $0pub(crate) bar: (), } }
278 fn main() { foo::Foo { bar: () }; } ",
279 );
280 check_assist(
281 fix_visibility,
282 r"//- /lib.rs
283 mod foo;
284 fn main() { foo::Foo { <|>bar: () }; }
285 //- /foo.rs
286 pub struct Foo { bar: () }
287 ",
288 r"pub struct Foo { $0pub(crate) bar: () }
289
290",
291 );
292 check_assist_not_applicable(
293 fix_visibility,
294 r"mod foo { pub struct Foo { pub bar: (), } }
295 fn main() { foo::Foo { <|>bar: () }; } ",
296 );
297 check_assist_not_applicable(
298 fix_visibility,
299 r"//- /lib.rs
300 mod foo;
301 fn main() { foo::Foo { <|>bar: () }; }
302 //- /foo.rs
303 pub struct Foo { pub bar: () }
304 ",
305 );
306 }
307
308 #[test]
309 fn fix_visibility_of_enum_variant_field() {
310 check_assist(
311 fix_visibility,
312 r"mod foo { pub enum Foo { Bar { bar: () } } }
313 fn main() { foo::Foo::Bar { <|>bar: () }; } ",
314 r"mod foo { pub enum Foo { Bar { $0pub(crate) bar: () } } }
315 fn main() { foo::Foo::Bar { bar: () }; } ",
316 );
317 check_assist(
318 fix_visibility,
319 r"//- /lib.rs
320 mod foo;
321 fn main() { foo::Foo::Bar { <|>bar: () }; }
322 //- /foo.rs
323 pub enum Foo { Bar { bar: () } }
324 ",
325 r"pub enum Foo { Bar { $0pub(crate) bar: () } }
326
327",
328 );
329 check_assist_not_applicable(
330 fix_visibility,
331 r"mod foo { pub struct Foo { pub bar: (), } }
332 fn main() { foo::Foo { <|>bar: () }; } ",
333 );
334 check_assist_not_applicable(
335 fix_visibility,
336 r"//- /lib.rs
337 mod foo;
338 fn main() { foo::Foo { <|>bar: () }; }
339 //- /foo.rs
340 pub struct Foo { pub bar: () }
341 ",
342 );
343 }
344
345 #[test]
346 #[ignore]
347 // FIXME reenable this test when `Semantics::resolve_record_field` works with union fields
348 fn fix_visibility_of_union_field() {
349 check_assist(
350 fix_visibility,
351 r"mod foo { pub union Foo { bar: (), } }
352 fn main() { foo::Foo { <|>bar: () }; } ",
353 r"mod foo { pub union Foo { $0pub(crate) bar: (), } }
354 fn main() { foo::Foo { bar: () }; } ",
355 );
356 check_assist(
357 fix_visibility,
358 r"//- /lib.rs
359 mod foo;
360 fn main() { foo::Foo { <|>bar: () }; }
361 //- /foo.rs
362 pub union Foo { bar: () }
363 ",
364 r"pub union Foo { $0pub(crate) bar: () }
365
366",
367 );
368 check_assist_not_applicable(
369 fix_visibility,
370 r"mod foo { pub union Foo { pub bar: (), } }
371 fn main() { foo::Foo { <|>bar: () }; } ",
372 );
373 check_assist_not_applicable(
374 fix_visibility,
375 r"//- /lib.rs
376 mod foo;
377 fn main() { foo::Foo { <|>bar: () }; }
378 //- /foo.rs
379 pub union Foo { pub bar: () }
380 ",
381 );
382 }
383
384 #[test]
385 fn fix_visibility_of_const() {
386 check_assist(
387 fix_visibility,
388 r"mod foo { const FOO: () = (); }
389 fn main() { foo::FOO<|> } ",
390 r"mod foo { $0pub(crate) const FOO: () = (); }
391 fn main() { foo::FOO } ",
392 );
393 check_assist_not_applicable(
394 fix_visibility,
395 r"mod foo { pub const FOO: () = (); }
396 fn main() { foo::FOO<|> } ",
397 );
398 }
399
400 #[test]
401 fn fix_visibility_of_static() {
402 check_assist(
403 fix_visibility,
404 r"mod foo { static FOO: () = (); }
405 fn main() { foo::FOO<|> } ",
406 r"mod foo { $0pub(crate) static FOO: () = (); }
407 fn main() { foo::FOO } ",
408 );
409 check_assist_not_applicable(
410 fix_visibility,
411 r"mod foo { pub static FOO: () = (); }
412 fn main() { foo::FOO<|> } ",
413 );
414 }
415
416 #[test]
417 fn fix_visibility_of_trait() {
418 check_assist(
419 fix_visibility,
420 r"mod foo { trait Foo { fn foo(&self) {} } }
421 fn main() { let x: &dyn foo::<|>Foo; } ",
422 r"mod foo { $0pub(crate) trait Foo { fn foo(&self) {} } }
423 fn main() { let x: &dyn foo::Foo; } ",
424 );
425 check_assist_not_applicable(
426 fix_visibility,
427 r"mod foo { pub trait Foo { fn foo(&self) {} } }
428 fn main() { let x: &dyn foo::Foo<|>; } ",
429 );
430 }
431
432 #[test]
433 fn fix_visibility_of_type_alias() {
434 check_assist(
435 fix_visibility,
436 r"mod foo { type Foo = (); }
437 fn main() { let x: foo::Foo<|>; } ",
438 r"mod foo { $0pub(crate) type Foo = (); }
439 fn main() { let x: foo::Foo; } ",
440 );
441 check_assist_not_applicable(
442 fix_visibility,
443 r"mod foo { pub type Foo = (); }
444 fn main() { let x: foo::Foo<|>; } ",
445 );
446 }
447
448 #[test]
449 fn fix_visibility_of_module() {
450 check_assist(
451 fix_visibility,
452 r"mod foo { mod bar { fn bar() {} } }
453 fn main() { foo::bar<|>::bar(); } ",
454 r"mod foo { $0pub(crate) mod bar { fn bar() {} } }
455 fn main() { foo::bar::bar(); } ",
456 );
457
458 check_assist(
459 fix_visibility,
460 r"
461 //- /main.rs
462 mod foo;
463 fn main() { foo::bar<|>::baz(); }
464
465 //- /foo.rs
466 mod bar {
467 pub fn baz() {}
468 }
469 ",
470 r"$0pub(crate) mod bar {
471 pub fn baz() {}
472}
473
474",
475 );
476
477 check_assist_not_applicable(
478 fix_visibility,
479 r"mod foo { pub mod bar { pub fn bar() {} } }
480 fn main() { foo::bar<|>::bar(); } ",
481 );
482 }
483
484 #[test]
485 fn fix_visibility_of_inline_module_in_other_file() {
486 check_assist(
487 fix_visibility,
488 r"
489 //- /main.rs
490 mod foo;
491 fn main() { foo::bar<|>::baz(); }
492
493 //- /foo.rs
494 mod bar;
495
496 //- /foo/bar.rs
497 pub fn baz() {}
498 }
499 ",
500 r"$0pub(crate) mod bar;
501",
502 );
503 }
504
505 #[test]
506 fn fix_visibility_of_module_declaration_in_other_file() {
507 check_assist(
508 fix_visibility,
509 r"//- /main.rs
510 mod foo;
511 fn main() { foo::bar<|>>::baz(); }
512
513 //- /foo.rs
514 mod bar {
515 pub fn baz() {}
516 }",
517 r"$0pub(crate) mod bar {
518 pub fn baz() {}
519}
520",
521 );
522 }
523
524 #[test]
525 fn adds_pub_when_target_is_in_another_crate() {
526 check_assist(
527 fix_visibility,
528 r"//- /main.rs crate:a deps:foo
529 foo::Bar<|>
530 //- /lib.rs crate:foo
531 struct Bar;",
532 r"$0pub struct Bar;
533",
534 )
535 }
536
537 #[test]
538 #[ignore]
539 // FIXME handle reexports properly
540 fn fix_visibility_of_reexport() {
541 check_assist(
542 fix_visibility,
543 r"
544 mod foo {
545 use bar::Baz;
546 mod bar { pub(super) struct Baz; }
547 }
548 foo::Baz<|>
549 ",
550 r"
551 mod foo {
552 $0pub(crate) use bar::Baz;
553 mod bar { pub(super) struct Baz; }
554 }
555 foo::Baz
556 ",
557 )
558 }
559}
diff --git a/crates/ra_assists/src/handlers/flip_binexpr.rs b/crates/ra_assists/src/handlers/flip_binexpr.rs
index 692ba4895..573196576 100644
--- a/crates/ra_assists/src/handlers/flip_binexpr.rs
+++ b/crates/ra_assists/src/handlers/flip_binexpr.rs
@@ -85,17 +85,13 @@ mod tests {
85 check_assist( 85 check_assist(
86 flip_binexpr, 86 flip_binexpr,
87 "fn f() { let res = 1 ==<|> 2; }", 87 "fn f() { let res = 1 ==<|> 2; }",
88 "fn f() { let res = 2 ==<|> 1; }", 88 "fn f() { let res = 2 == 1; }",
89 ) 89 )
90 } 90 }
91 91
92 #[test] 92 #[test]
93 fn flip_binexpr_works_for_gt() { 93 fn flip_binexpr_works_for_gt() {
94 check_assist( 94 check_assist(flip_binexpr, "fn f() { let res = 1 ><|> 2; }", "fn f() { let res = 2 < 1; }")
95 flip_binexpr,
96 "fn f() { let res = 1 ><|> 2; }",
97 "fn f() { let res = 2 <<|> 1; }",
98 )
99 } 95 }
100 96
101 #[test] 97 #[test]
@@ -103,7 +99,7 @@ mod tests {
103 check_assist( 99 check_assist(
104 flip_binexpr, 100 flip_binexpr,
105 "fn f() { let res = 1 <=<|> 2; }", 101 "fn f() { let res = 1 <=<|> 2; }",
106 "fn f() { let res = 2 >=<|> 1; }", 102 "fn f() { let res = 2 >= 1; }",
107 ) 103 )
108 } 104 }
109 105
@@ -112,7 +108,7 @@ mod tests {
112 check_assist( 108 check_assist(
113 flip_binexpr, 109 flip_binexpr,
114 "fn f() { let res = (1 + 1) ==<|> (2 + 2); }", 110 "fn f() { let res = (1 + 1) ==<|> (2 + 2); }",
115 "fn f() { let res = (2 + 2) ==<|> (1 + 1); }", 111 "fn f() { let res = (2 + 2) == (1 + 1); }",
116 ) 112 )
117 } 113 }
118 114
@@ -132,7 +128,7 @@ mod tests {
132 fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { 128 fn dyn_eq(&self, other: &dyn Diagnostic) -> bool {
133 match other.downcast_ref::<Self>() { 129 match other.downcast_ref::<Self>() {
134 None => false, 130 None => false,
135 Some(it) => self ==<|> it, 131 Some(it) => self == it,
136 } 132 }
137 } 133 }
138 "#, 134 "#,
diff --git a/crates/ra_assists/src/handlers/flip_comma.rs b/crates/ra_assists/src/handlers/flip_comma.rs
index dfe2a7fed..a57a1c463 100644
--- a/crates/ra_assists/src/handlers/flip_comma.rs
+++ b/crates/ra_assists/src/handlers/flip_comma.rs
@@ -45,7 +45,7 @@ mod tests {
45 check_assist( 45 check_assist(
46 flip_comma, 46 flip_comma,
47 "fn foo(x: i32,<|> y: Result<(), ()>) {}", 47 "fn foo(x: i32,<|> y: Result<(), ()>) {}",
48 "fn foo(y: Result<(), ()>,<|> x: i32) {}", 48 "fn foo(y: Result<(), ()>, x: i32) {}",
49 ) 49 )
50 } 50 }
51 51
diff --git a/crates/ra_assists/src/handlers/flip_trait_bound.rs b/crates/ra_assists/src/handlers/flip_trait_bound.rs
index 8a08702ab..0115adc8b 100644
--- a/crates/ra_assists/src/handlers/flip_trait_bound.rs
+++ b/crates/ra_assists/src/handlers/flip_trait_bound.rs
@@ -60,7 +60,7 @@ mod tests {
60 check_assist( 60 check_assist(
61 flip_trait_bound, 61 flip_trait_bound,
62 "struct S<T> where T: A <|>+ B { }", 62 "struct S<T> where T: A <|>+ B { }",
63 "struct S<T> where T: B <|>+ A { }", 63 "struct S<T> where T: B + A { }",
64 ) 64 )
65 } 65 }
66 66
@@ -69,13 +69,13 @@ mod tests {
69 check_assist( 69 check_assist(
70 flip_trait_bound, 70 flip_trait_bound,
71 "impl X for S<T> where T: A +<|> B { }", 71 "impl X for S<T> where T: A +<|> B { }",
72 "impl X for S<T> where T: B +<|> A { }", 72 "impl X for S<T> where T: B + A { }",
73 ) 73 )
74 } 74 }
75 75
76 #[test] 76 #[test]
77 fn flip_trait_bound_works_for_fn() { 77 fn flip_trait_bound_works_for_fn() {
78 check_assist(flip_trait_bound, "fn f<T: A <|>+ B>(t: T) { }", "fn f<T: B <|>+ A>(t: T) { }") 78 check_assist(flip_trait_bound, "fn f<T: A <|>+ B>(t: T) { }", "fn f<T: B + A>(t: T) { }")
79 } 79 }
80 80
81 #[test] 81 #[test]
@@ -83,7 +83,7 @@ mod tests {
83 check_assist( 83 check_assist(
84 flip_trait_bound, 84 flip_trait_bound,
85 "fn f<T>(t: T) where T: A +<|> B { }", 85 "fn f<T>(t: T) where T: A +<|> B { }",
86 "fn f<T>(t: T) where T: B +<|> A { }", 86 "fn f<T>(t: T) where T: B + A { }",
87 ) 87 )
88 } 88 }
89 89
@@ -92,7 +92,7 @@ mod tests {
92 check_assist( 92 check_assist(
93 flip_trait_bound, 93 flip_trait_bound,
94 "fn f<T>(t: T) where T: A <|>+ 'static { }", 94 "fn f<T>(t: T) where T: A <|>+ 'static { }",
95 "fn f<T>(t: T) where T: 'static <|>+ A { }", 95 "fn f<T>(t: T) where T: 'static + A { }",
96 ) 96 )
97 } 97 }
98 98
@@ -101,7 +101,7 @@ mod tests {
101 check_assist( 101 check_assist(
102 flip_trait_bound, 102 flip_trait_bound,
103 "struct S<T> where T: A<T> <|>+ b_mod::B<T> + C<T> { }", 103 "struct S<T> where T: A<T> <|>+ b_mod::B<T> + C<T> { }",
104 "struct S<T> where T: b_mod::B<T> <|>+ A<T> + C<T> { }", 104 "struct S<T> where T: b_mod::B<T> + A<T> + C<T> { }",
105 ) 105 )
106 } 106 }
107 107
@@ -110,7 +110,7 @@ mod tests {
110 check_assist( 110 check_assist(
111 flip_trait_bound, 111 flip_trait_bound,
112 "struct S<T> where T: A + B + C + D + E + F +<|> G + H + I + J { }", 112 "struct S<T> where T: A + B + C + D + E + F +<|> G + H + I + J { }",
113 "struct S<T> where T: A + B + C + D + E + G +<|> F + H + I + J { }", 113 "struct S<T> where T: A + B + C + D + E + G + F + H + I + J { }",
114 ) 114 )
115 } 115 }
116} 116}
diff --git a/crates/ra_assists/src/handlers/inline_local_variable.rs b/crates/ra_assists/src/handlers/inline_local_variable.rs
index 5b26814d3..46d675a4e 100644
--- a/crates/ra_assists/src/handlers/inline_local_variable.rs
+++ b/crates/ra_assists/src/handlers/inline_local_variable.rs
@@ -3,7 +3,7 @@ use ra_syntax::{
3 ast::{self, AstNode, AstToken}, 3 ast::{self, AstNode, AstToken},
4 TextRange, 4 TextRange,
5}; 5};
6use test_utils::tested_by; 6use test_utils::mark;
7 7
8use crate::{ 8use crate::{
9 assist_context::{AssistContext, Assists}, 9 assist_context::{AssistContext, Assists},
@@ -33,11 +33,11 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
33 _ => return None, 33 _ => return None,
34 }; 34 };
35 if bind_pat.mut_token().is_some() { 35 if bind_pat.mut_token().is_some() {
36 tested_by!(test_not_inline_mut_variable); 36 mark::hit!(test_not_inline_mut_variable);
37 return None; 37 return None;
38 } 38 }
39 if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) { 39 if !bind_pat.syntax().text_range().contains_inclusive(ctx.offset()) {
40 tested_by!(not_applicable_outside_of_bind_pat); 40 mark::hit!(not_applicable_outside_of_bind_pat);
41 return None; 41 return None;
42 } 42 }
43 let initializer_expr = let_stmt.initializer()?; 43 let initializer_expr = let_stmt.initializer()?;
@@ -46,7 +46,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
46 let def = Definition::Local(def); 46 let def = Definition::Local(def);
47 let refs = def.find_usages(ctx.db, None); 47 let refs = def.find_usages(ctx.db, None);
48 if refs.is_empty() { 48 if refs.is_empty() {
49 tested_by!(test_not_applicable_if_variable_unused); 49 mark::hit!(test_not_applicable_if_variable_unused);
50 return None; 50 return None;
51 }; 51 };
52 52
@@ -122,7 +122,7 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O
122 122
123#[cfg(test)] 123#[cfg(test)]
124mod tests { 124mod tests {
125 use test_utils::covers; 125 use test_utils::mark;
126 126
127 use crate::tests::{check_assist, check_assist_not_applicable}; 127 use crate::tests::{check_assist, check_assist_not_applicable};
128 128
@@ -330,7 +330,7 @@ fn foo() {
330 330
331 #[test] 331 #[test]
332 fn test_not_inline_mut_variable() { 332 fn test_not_inline_mut_variable() {
333 covers!(test_not_inline_mut_variable); 333 mark::check!(test_not_inline_mut_variable);
334 check_assist_not_applicable( 334 check_assist_not_applicable(
335 inline_local_variable, 335 inline_local_variable,
336 r" 336 r"
@@ -663,7 +663,7 @@ fn foo() {
663 663
664 #[test] 664 #[test]
665 fn test_not_applicable_if_variable_unused() { 665 fn test_not_applicable_if_variable_unused() {
666 covers!(test_not_applicable_if_variable_unused); 666 mark::check!(test_not_applicable_if_variable_unused);
667 check_assist_not_applicable( 667 check_assist_not_applicable(
668 inline_local_variable, 668 inline_local_variable,
669 r" 669 r"
@@ -676,7 +676,7 @@ fn foo() {
676 676
677 #[test] 677 #[test]
678 fn not_applicable_outside_of_bind_pat() { 678 fn not_applicable_outside_of_bind_pat() {
679 covers!(not_applicable_outside_of_bind_pat); 679 mark::check!(not_applicable_outside_of_bind_pat);
680 check_assist_not_applicable( 680 check_assist_not_applicable(
681 inline_local_variable, 681 inline_local_variable,
682 r" 682 r"
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs
index fdf3ada0d..56c610fed 100644
--- a/crates/ra_assists/src/handlers/introduce_variable.rs
+++ b/crates/ra_assists/src/handlers/introduce_variable.rs
@@ -7,7 +7,7 @@ use ra_syntax::{
7 SyntaxNode, TextSize, 7 SyntaxNode, TextSize,
8}; 8};
9use stdx::format_to; 9use stdx::format_to;
10use test_utils::tested_by; 10use test_utils::mark;
11 11
12use crate::{AssistContext, AssistId, Assists}; 12use crate::{AssistContext, AssistId, Assists};
13 13
@@ -33,7 +33,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti
33 } 33 }
34 let node = ctx.covering_element(); 34 let node = ctx.covering_element();
35 if node.kind() == COMMENT { 35 if node.kind() == COMMENT {
36 tested_by!(introduce_var_in_comment_is_not_applicable); 36 mark::hit!(introduce_var_in_comment_is_not_applicable);
37 return None; 37 return None;
38 } 38 }
39 let expr = node.ancestors().find_map(valid_target_expr)?; 39 let expr = node.ancestors().find_map(valid_target_expr)?;
@@ -61,7 +61,7 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti
61 false 61 false
62 }; 62 };
63 if is_full_stmt { 63 if is_full_stmt {
64 tested_by!(test_introduce_var_expr_stmt); 64 mark::hit!(test_introduce_var_expr_stmt);
65 if full_stmt.unwrap().semicolon_token().is_none() { 65 if full_stmt.unwrap().semicolon_token().is_none() {
66 buf.push_str(";"); 66 buf.push_str(";");
67 } 67 }
@@ -113,7 +113,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
113 expr.syntax().ancestors().find_map(|node| { 113 expr.syntax().ancestors().find_map(|node| {
114 if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { 114 if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) {
115 if expr.syntax() == &node { 115 if expr.syntax() == &node {
116 tested_by!(test_introduce_var_last_expr); 116 mark::hit!(test_introduce_var_last_expr);
117 return Some((node, false)); 117 return Some((node, false));
118 } 118 }
119 } 119 }
@@ -134,7 +134,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
134 134
135#[cfg(test)] 135#[cfg(test)]
136mod tests { 136mod tests {
137 use test_utils::covers; 137 use test_utils::mark;
138 138
139 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; 139 use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
140 140
@@ -158,13 +158,13 @@ fn foo() {
158 158
159 #[test] 159 #[test]
160 fn introduce_var_in_comment_is_not_applicable() { 160 fn introduce_var_in_comment_is_not_applicable() {
161 covers!(introduce_var_in_comment_is_not_applicable); 161 mark::check!(introduce_var_in_comment_is_not_applicable);
162 check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); 162 check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }");
163 } 163 }
164 164
165 #[test] 165 #[test]
166 fn test_introduce_var_expr_stmt() { 166 fn test_introduce_var_expr_stmt() {
167 covers!(test_introduce_var_expr_stmt); 167 mark::check!(test_introduce_var_expr_stmt);
168 check_assist( 168 check_assist(
169 introduce_variable, 169 introduce_variable,
170 " 170 "
@@ -209,7 +209,7 @@ fn foo() {
209 209
210 #[test] 210 #[test]
211 fn test_introduce_var_last_expr() { 211 fn test_introduce_var_last_expr() {
212 covers!(test_introduce_var_last_expr); 212 mark::check!(test_introduce_var_last_expr);
213 check_assist( 213 check_assist(
214 introduce_variable, 214 introduce_variable,
215 " 215 "
diff --git a/crates/ra_assists/src/handlers/invert_if.rs b/crates/ra_assists/src/handlers/invert_if.rs
index 527c7caef..59d278eb9 100644
--- a/crates/ra_assists/src/handlers/invert_if.rs
+++ b/crates/ra_assists/src/handlers/invert_if.rs
@@ -72,7 +72,7 @@ mod tests {
72 check_assist( 72 check_assist(
73 invert_if, 73 invert_if,
74 "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }", 74 "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }",
75 "fn f() { i<|>f x == 3 { 3 + 2 } else { 1 } }", 75 "fn f() { if x == 3 { 3 + 2 } else { 1 } }",
76 ) 76 )
77 } 77 }
78 78
@@ -81,7 +81,7 @@ mod tests {
81 check_assist( 81 check_assist(
82 invert_if, 82 invert_if,
83 "fn f() { <|>if !cond { 3 * 2 } else { 1 } }", 83 "fn f() { <|>if !cond { 3 * 2 } else { 1 } }",
84 "fn f() { <|>if cond { 1 } else { 3 * 2 } }", 84 "fn f() { if cond { 1 } else { 3 * 2 } }",
85 ) 85 )
86 } 86 }
87 87
@@ -90,7 +90,7 @@ mod tests {
90 check_assist( 90 check_assist(
91 invert_if, 91 invert_if,
92 "fn f() { i<|>f cond { 3 * 2 } else { 1 } }", 92 "fn f() { i<|>f cond { 3 * 2 } else { 1 } }",
93 "fn f() { i<|>f !cond { 1 } else { 3 * 2 } }", 93 "fn f() { if !cond { 1 } else { 3 * 2 } }",
94 ) 94 )
95 } 95 }
96 96
diff --git a/crates/ra_assists/src/handlers/move_bounds.rs b/crates/ra_assists/src/handlers/move_bounds.rs
index a41aacfc3..be2a7eddc 100644
--- a/crates/ra_assists/src/handlers/move_bounds.rs
+++ b/crates/ra_assists/src/handlers/move_bounds.rs
@@ -99,7 +99,7 @@ mod tests {
99 fn foo<T: u32, <|>F: FnOnce(T) -> T>() {} 99 fn foo<T: u32, <|>F: FnOnce(T) -> T>() {}
100 "#, 100 "#,
101 r#" 101 r#"
102 fn foo<T, <|>F>() where T: u32, F: FnOnce(T) -> T {} 102 fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {}
103 "#, 103 "#,
104 ); 104 );
105 } 105 }
@@ -112,7 +112,7 @@ mod tests {
112 impl<U: u32, <|>T> A<U, T> {} 112 impl<U: u32, <|>T> A<U, T> {}
113 "#, 113 "#,
114 r#" 114 r#"
115 impl<U, <|>T> A<U, T> where U: u32 {} 115 impl<U, T> A<U, T> where U: u32 {}
116 "#, 116 "#,
117 ); 117 );
118 } 118 }
@@ -125,7 +125,7 @@ mod tests {
125 struct A<<|>T: Iterator<Item = u32>> {} 125 struct A<<|>T: Iterator<Item = u32>> {}
126 "#, 126 "#,
127 r#" 127 r#"
128 struct A<<|>T> where T: Iterator<Item = u32> {} 128 struct A<T> where T: Iterator<Item = u32> {}
129 "#, 129 "#,
130 ); 130 );
131 } 131 }
@@ -138,7 +138,7 @@ mod tests {
138 struct Pair<<|>T: u32>(T, T); 138 struct Pair<<|>T: u32>(T, T);
139 "#, 139 "#,
140 r#" 140 r#"
141 struct Pair<<|>T>(T, T) where T: u32; 141 struct Pair<T>(T, T) where T: u32;
142 "#, 142 "#,
143 ); 143 );
144 } 144 }
diff --git a/crates/ra_assists/src/handlers/raw_string.rs b/crates/ra_assists/src/handlers/raw_string.rs
index c20ffe0b3..16002d2ac 100644
--- a/crates/ra_assists/src/handlers/raw_string.rs
+++ b/crates/ra_assists/src/handlers/raw_string.rs
@@ -164,7 +164,7 @@ mod test {
164 "#, 164 "#,
165 r##" 165 r##"
166 fn f() { 166 fn f() {
167 let s = <|>r#"random 167 let s = r#"random
168string"#; 168string"#;
169 } 169 }
170 "##, 170 "##,
@@ -182,7 +182,7 @@ string"#;
182 "#, 182 "#,
183 r##" 183 r##"
184 fn f() { 184 fn f() {
185 format!(<|>r#"x = {}"#, 92) 185 format!(r#"x = {}"#, 92)
186 } 186 }
187 "##, 187 "##,
188 ) 188 )
@@ -199,7 +199,7 @@ string"#;
199 "###, 199 "###,
200 r####" 200 r####"
201 fn f() { 201 fn f() {
202 let s = <|>r#"#random## 202 let s = r#"#random##
203string"#; 203string"#;
204 } 204 }
205 "####, 205 "####,
@@ -217,7 +217,7 @@ string"#;
217 "###, 217 "###,
218 r####" 218 r####"
219 fn f() { 219 fn f() {
220 let s = <|>r###"#random"## 220 let s = r###"#random"##
221string"###; 221string"###;
222 } 222 }
223 "####, 223 "####,
@@ -235,7 +235,7 @@ string"###;
235 "#, 235 "#,
236 r##" 236 r##"
237 fn f() { 237 fn f() {
238 let s = <|>r#"random string"#; 238 let s = r#"random string"#;
239 } 239 }
240 "##, 240 "##,
241 ) 241 )
@@ -289,7 +289,7 @@ string"###;
289 "#, 289 "#,
290 r##" 290 r##"
291 fn f() { 291 fn f() {
292 let s = <|>r#"random string"#; 292 let s = r#"random string"#;
293 } 293 }
294 "##, 294 "##,
295 ) 295 )
@@ -306,7 +306,7 @@ string"###;
306 "##, 306 "##,
307 r###" 307 r###"
308 fn f() { 308 fn f() {
309 let s = <|>r##"random"string"##; 309 let s = r##"random"string"##;
310 } 310 }
311 "###, 311 "###,
312 ) 312 )
@@ -348,7 +348,7 @@ string"###;
348 "##, 348 "##,
349 r#" 349 r#"
350 fn f() { 350 fn f() {
351 let s = <|>r"random string"; 351 let s = r"random string";
352 } 352 }
353 "#, 353 "#,
354 ) 354 )
@@ -365,7 +365,7 @@ string"###;
365 "##, 365 "##,
366 r#" 366 r#"
367 fn f() { 367 fn f() {
368 let s = <|>r"random\"str\"ing"; 368 let s = r"random\"str\"ing";
369 } 369 }
370 "#, 370 "#,
371 ) 371 )
@@ -382,7 +382,7 @@ string"###;
382 "###, 382 "###,
383 r##" 383 r##"
384 fn f() { 384 fn f() {
385 let s = <|>r#"random string"#; 385 let s = r#"random string"#;
386 } 386 }
387 "##, 387 "##,
388 ) 388 )
@@ -436,7 +436,7 @@ string"###;
436 "##, 436 "##,
437 r#" 437 r#"
438 fn f() { 438 fn f() {
439 let s = <|>"random string"; 439 let s = "random string";
440 } 440 }
441 "#, 441 "#,
442 ) 442 )
@@ -453,7 +453,7 @@ string"###;
453 "##, 453 "##,
454 r#" 454 r#"
455 fn f() { 455 fn f() {
456 let s = <|>"random\"str\"ing"; 456 let s = "random\"str\"ing";
457 } 457 }
458 "#, 458 "#,
459 ) 459 )
@@ -470,7 +470,7 @@ string"###;
470 "###, 470 "###,
471 r##" 471 r##"
472 fn f() { 472 fn f() {
473 let s = <|>"random string"; 473 let s = "random string";
474 } 474 }
475 "##, 475 "##,
476 ) 476 )
diff --git a/crates/ra_assists/src/handlers/reorder_fields.rs b/crates/ra_assists/src/handlers/reorder_fields.rs
index 757f6406e..30229edc2 100644
--- a/crates/ra_assists/src/handlers/reorder_fields.rs
+++ b/crates/ra_assists/src/handlers/reorder_fields.rs
@@ -140,7 +140,7 @@ mod tests {
140 "#, 140 "#,
141 r#" 141 r#"
142 struct Foo {foo: i32, bar: i32}; 142 struct Foo {foo: i32, bar: i32};
143 const test: Foo = <|>Foo {foo: 1, bar: 0} 143 const test: Foo = Foo {foo: 1, bar: 0}
144 "#, 144 "#,
145 ) 145 )
146 } 146 }
@@ -164,7 +164,7 @@ mod tests {
164 164
165 fn f(f: Foo) -> { 165 fn f(f: Foo) -> {
166 match f { 166 match f {
167 <|>Foo { ref mut bar, baz: 0, .. } => (), 167 Foo { ref mut bar, baz: 0, .. } => (),
168 _ => () 168 _ => ()
169 } 169 }
170 } 170 }
@@ -202,7 +202,7 @@ mod tests {
202 impl Foo { 202 impl Foo {
203 fn new() -> Foo { 203 fn new() -> Foo {
204 let foo = String::new(); 204 let foo = String::new();
205 <|>Foo { 205 Foo {
206 foo, 206 foo,
207 bar: foo.clone(), 207 bar: foo.clone(),
208 extra: "Extra field", 208 extra: "Extra field",
diff --git a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
index 1a81d8a0e..0197a8cf0 100644
--- a/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
+++ b/crates/ra_assists/src/handlers/replace_qualified_name_with_use.rs
@@ -39,7 +39,7 @@ pub(crate) fn replace_qualified_name_with_use(
39 target, 39 target,
40 |builder| { 40 |builder| {
41 let path_to_import = hir_path.mod_path().clone(); 41 let path_to_import = hir_path.mod_path().clone();
42 insert_use_statement(path.syntax(), &path_to_import, ctx, builder); 42 insert_use_statement(path.syntax(), &path_to_import, ctx, builder.text_edit_builder());
43 43
44 if let Some(last) = path.segment() { 44 if let Some(last) = path.segment() {
45 // Here we are assuming the assist will provide a correct use statement 45 // Here we are assuming the assist will provide a correct use statement
@@ -89,7 +89,7 @@ std::fmt::Debug<|>
89 " 89 "
90use std::fmt::Debug; 90use std::fmt::Debug;
91 91
92Debug<|> 92Debug
93 ", 93 ",
94 ); 94 );
95 } 95 }
@@ -106,7 +106,7 @@ fn main() {
106 " 106 "
107use std::fmt::Debug; 107use std::fmt::Debug;
108 108
109Debug<|> 109Debug
110 110
111fn main() { 111fn main() {
112} 112}
@@ -130,7 +130,7 @@ use std::fmt::Debug;
130fn main() { 130fn main() {
131} 131}
132 132
133Debug<|> 133Debug
134 ", 134 ",
135 ); 135 );
136 } 136 }
@@ -145,7 +145,7 @@ std::fmt<|>::Debug
145 " 145 "
146use std::fmt; 146use std::fmt;
147 147
148fmt<|>::Debug 148fmt::Debug
149 ", 149 ",
150 ); 150 );
151 } 151 }
@@ -164,7 +164,7 @@ impl std::fmt::Debug<|> for Foo {
164use stdx; 164use stdx;
165use std::fmt::Debug; 165use std::fmt::Debug;
166 166
167impl Debug<|> for Foo { 167impl Debug for Foo {
168} 168}
169 ", 169 ",
170 ); 170 );
@@ -181,7 +181,7 @@ impl std::fmt::Debug<|> for Foo {
181 " 181 "
182use std::fmt::Debug; 182use std::fmt::Debug;
183 183
184impl Debug<|> for Foo { 184impl Debug for Foo {
185} 185}
186 ", 186 ",
187 ); 187 );
@@ -198,7 +198,7 @@ impl Debug<|> for Foo {
198 " 198 "
199 use std::fmt::Debug; 199 use std::fmt::Debug;
200 200
201 impl Debug<|> for Foo { 201 impl Debug for Foo {
202 } 202 }
203 ", 203 ",
204 ); 204 );
@@ -217,7 +217,7 @@ impl std::io<|> for Foo {
217 " 217 "
218use std::{io, fmt}; 218use std::{io, fmt};
219 219
220impl io<|> for Foo { 220impl io for Foo {
221} 221}
222 ", 222 ",
223 ); 223 );
@@ -236,7 +236,7 @@ impl std::fmt::Debug<|> for Foo {
236 " 236 "
237use std::fmt::{self, Debug, }; 237use std::fmt::{self, Debug, };
238 238
239impl Debug<|> for Foo { 239impl Debug for Foo {
240} 240}
241 ", 241 ",
242 ); 242 );
@@ -255,7 +255,7 @@ impl std::fmt<|> for Foo {
255 " 255 "
256use std::fmt::{self, Debug}; 256use std::fmt::{self, Debug};
257 257
258impl fmt<|> for Foo { 258impl fmt for Foo {
259} 259}
260 ", 260 ",
261 ); 261 );
@@ -274,7 +274,7 @@ impl std::fmt::nested<|> for Foo {
274 " 274 "
275use std::fmt::{Debug, nested::{Display, self}}; 275use std::fmt::{Debug, nested::{Display, self}};
276 276
277impl nested<|> for Foo { 277impl nested for Foo {
278} 278}
279", 279",
280 ); 280 );
@@ -293,7 +293,7 @@ impl std::fmt::nested<|> for Foo {
293 " 293 "
294use std::fmt::{Debug, nested::{self, Display}}; 294use std::fmt::{Debug, nested::{self, Display}};
295 295
296impl nested<|> for Foo { 296impl nested for Foo {
297} 297}
298", 298",
299 ); 299 );
@@ -312,7 +312,7 @@ impl std::fmt::nested::Debug<|> for Foo {
312 " 312 "
313use std::fmt::{Debug, nested::{Display, Debug}}; 313use std::fmt::{Debug, nested::{Display, Debug}};
314 314
315impl Debug<|> for Foo { 315impl Debug for Foo {
316} 316}
317", 317",
318 ); 318 );
@@ -331,7 +331,7 @@ impl std::fmt::nested::Display<|> for Foo {
331 " 331 "
332use std::fmt::{nested::Display, Debug}; 332use std::fmt::{nested::Display, Debug};
333 333
334impl Display<|> for Foo { 334impl Display for Foo {
335} 335}
336", 336",
337 ); 337 );
@@ -350,7 +350,7 @@ impl std::fmt::Display<|> for Foo {
350 " 350 "
351use std::fmt::{Display, nested::Debug}; 351use std::fmt::{Display, nested::Debug};
352 352
353impl Display<|> for Foo { 353impl Display for Foo {
354} 354}
355", 355",
356 ); 356 );
@@ -374,7 +374,7 @@ use crate::{
374 AssocItem, 374 AssocItem,
375}; 375};
376 376
377fn foo() { lower<|>::trait_env() } 377fn foo() { lower::trait_env() }
378", 378",
379 ); 379 );
380 } 380 }
@@ -392,7 +392,7 @@ impl foo::Debug<|> for Foo {
392 " 392 "
393use std::fmt as foo; 393use std::fmt as foo;
394 394
395impl Debug<|> for Foo { 395impl Debug for Foo {
396} 396}
397", 397",
398 ); 398 );
@@ -435,7 +435,7 @@ mod foo {
435 mod bar { 435 mod bar {
436 use std::fmt::Debug; 436 use std::fmt::Debug;
437 437
438 Debug<|> 438 Debug
439 } 439 }
440} 440}
441 ", 441 ",
@@ -458,7 +458,7 @@ fn main() {
458use std::fmt::Debug; 458use std::fmt::Debug;
459 459
460fn main() { 460fn main() {
461 Debug<|> 461 Debug
462} 462}
463 ", 463 ",
464 ); 464 );
diff --git a/crates/ra_assists/src/handlers/unwrap_block.rs b/crates/ra_assists/src/handlers/unwrap_block.rs
index e52ec557e..b76182d79 100644
--- a/crates/ra_assists/src/handlers/unwrap_block.rs
+++ b/crates/ra_assists/src/handlers/unwrap_block.rs
@@ -1,8 +1,10 @@
1use crate::{AssistContext, AssistId, Assists};
2
3use ast::{ElseBranch, Expr, LoopBodyOwner};
4use ra_fmt::unwrap_trivial_block; 1use ra_fmt::unwrap_trivial_block;
5use ra_syntax::{ast, match_ast, AstNode, TextRange, T}; 2use ra_syntax::{
3 ast::{self, ElseBranch, Expr, LoopBodyOwner},
4 match_ast, AstNode, TextRange, T,
5};
6
7use crate::{AssistContext, AssistId, Assists};
6 8
7// Assist: unwrap_block 9// Assist: unwrap_block
8// 10//