diff options
Diffstat (limited to 'crates/ra_assists/src/handlers')
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 | ||
210 | fn main() { | 206 | fn 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 @@ | |||
1 | use ra_ide_db::RootDatabase; | 1 | use ra_ide_db::RootDatabase; |
2 | use ra_syntax::ast::{self, AstNode, NameOwner}; | 2 | use ra_syntax::ast::{self, AstNode, NameOwner}; |
3 | use test_utils::tested_by; | 3 | use test_utils::mark; |
4 | 4 | ||
5 | use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; | 5 | use 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)] |
92 | mod tests { | 92 | mod 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 | ||
106 | impl From<u32> for A { | 106 | impl 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 | ||
121 | impl From<foo::bar::baz::Boo> for A { | 121 | impl 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#" |
155 | enum A { <|>One(u32), } | 155 | enum A { <|>One(u32), } |
@@ -178,7 +178,7 @@ impl From<String> for A { | |||
178 | pub trait From<T> { | 178 | pub 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 | ||
183 | impl From<u32> for A { | 183 | impl 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 | }; |
8 | use stdx::{format_to, SepBy}; | 8 | use 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 | ||
193 | impl Foo { | 191 | impl 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 | ||
203 | impl<T: Clone> Foo<T> { | 201 | impl<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 | ||
213 | impl<'a, T: Foo<'a>> Foo<'a, T> { | 211 | impl<'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 | ||
223 | impl Foo { | 221 | impl 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 | ||
233 | impl Foo { | 231 | impl 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 | ||
245 | impl Foo { | 243 | impl 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 | ||
260 | impl Foo { | 258 | impl 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 | ||
275 | impl Foo { | 273 | impl 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 | ||
296 | impl Foo { | 294 | impl 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 | ||
313 | impl Foo { | 311 | impl 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 | ||
323 | impl Foo { | 321 | impl 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 | ||
416 | impl<T> Source<T> { | 414 | impl<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 @@ | |||
1 | use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass}; | 1 | use ra_ide_db::defs::{classify_name_ref, Definition, NameRefClass}; |
2 | use ra_syntax::{ast, AstNode, SyntaxKind, T}; | 2 | use ra_syntax::{ast, AstNode, SyntaxKind, T}; |
3 | use test_utils::mark; | ||
3 | 4 | ||
4 | use crate::{ | 5 | use crate::{ |
5 | assist_context::{AssistContext, Assists}, | 6 | assist_context::{AssistContext, Assists}, |
6 | AssistId, | 7 | AssistId, |
7 | }; | 8 | }; |
8 | use 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 | ||
498 | fn main() { | 503 | fn 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 @@ | |||
1 | use ra_syntax::{ | 1 | use 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 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 6 | use 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 | // ``` |
21 | pub(crate) fn change_return_type_to_result(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 19 | pub(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 | ||
253 | fn 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)] |
262 | mod tests { | 253 | mod 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 | 10 | use test_utils::mark; | |
11 | use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution}; | ||
12 | use test_utils::tested_by; | ||
13 | 11 | ||
14 | use crate::{AssistContext, AssistId, Assists}; | 12 | use crate::{AssistContext, AssistId, Assists}; |
15 | use 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 | ||
37 | fn add_vis(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 32 | fn 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 | |||
80 | fn 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 | |||
113 | fn 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 | ||
154 | fn 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 | |||
217 | fn vis_offset(node: &SyntaxNode) -> TextSize { | 74 | fn 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)] |
257 | mod tests { | 112 | mod 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}; | |||
4 | use itertools::Itertools; | 4 | use itertools::Itertools; |
5 | use ra_ide_db::RootDatabase; | 5 | use ra_ide_db::RootDatabase; |
6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; | 6 | use ra_syntax::ast::{self, make, AstNode, MatchArm, NameOwner, Pat}; |
7 | use test_utils::mark; | ||
7 | 8 | ||
8 | use crate::{AssistContext, AssistId, Assists}; | 9 | use 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)] |
169 | mod tests { | 192 | mod 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#" | ||
717 | fn 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#" | ||
728 | fn 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 @@ | |||
1 | use hir::{db::HirDatabase, HasSource, HasVisibility, PathResolution}; | ||
2 | use ra_db::FileId; | ||
3 | use ra_syntax::{ | ||
4 | ast, AstNode, | ||
5 | SyntaxKind::{ATTR, COMMENT, WHITESPACE}, | ||
6 | SyntaxNode, TextRange, TextSize, | ||
7 | }; | ||
8 | |||
9 | use 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 | // ``` | ||
34 | pub(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 | |||
39 | fn 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 | |||
74 | fn 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 | |||
117 | fn 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 | |||
180 | fn 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)] | ||
192 | mod 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 | }; |
6 | use test_utils::tested_by; | 6 | use test_utils::mark; |
7 | 7 | ||
8 | use crate::{ | 8 | use 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)] |
124 | mod tests { | 124 | mod 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 | }; |
9 | use stdx::format_to; | 9 | use stdx::format_to; |
10 | use test_utils::tested_by; | 10 | use test_utils::mark; |
11 | 11 | ||
12 | use crate::{AssistContext, AssistId, Assists}; | 12 | use 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)] |
136 | mod tests { | 136 | mod 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 |
168 | string"#; | 168 | string"#; |
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## |
203 | string"#; | 203 | string"#; |
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"## |
221 | string"###; | 221 | string"###; |
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 | " |
90 | use std::fmt::Debug; | 90 | use std::fmt::Debug; |
91 | 91 | ||
92 | Debug<|> | 92 | Debug |
93 | ", | 93 | ", |
94 | ); | 94 | ); |
95 | } | 95 | } |
@@ -106,7 +106,7 @@ fn main() { | |||
106 | " | 106 | " |
107 | use std::fmt::Debug; | 107 | use std::fmt::Debug; |
108 | 108 | ||
109 | Debug<|> | 109 | Debug |
110 | 110 | ||
111 | fn main() { | 111 | fn main() { |
112 | } | 112 | } |
@@ -130,7 +130,7 @@ use std::fmt::Debug; | |||
130 | fn main() { | 130 | fn main() { |
131 | } | 131 | } |
132 | 132 | ||
133 | Debug<|> | 133 | Debug |
134 | ", | 134 | ", |
135 | ); | 135 | ); |
136 | } | 136 | } |
@@ -145,7 +145,7 @@ std::fmt<|>::Debug | |||
145 | " | 145 | " |
146 | use std::fmt; | 146 | use std::fmt; |
147 | 147 | ||
148 | fmt<|>::Debug | 148 | fmt::Debug |
149 | ", | 149 | ", |
150 | ); | 150 | ); |
151 | } | 151 | } |
@@ -164,7 +164,7 @@ impl std::fmt::Debug<|> for Foo { | |||
164 | use stdx; | 164 | use stdx; |
165 | use std::fmt::Debug; | 165 | use std::fmt::Debug; |
166 | 166 | ||
167 | impl Debug<|> for Foo { | 167 | impl Debug for Foo { |
168 | } | 168 | } |
169 | ", | 169 | ", |
170 | ); | 170 | ); |
@@ -181,7 +181,7 @@ impl std::fmt::Debug<|> for Foo { | |||
181 | " | 181 | " |
182 | use std::fmt::Debug; | 182 | use std::fmt::Debug; |
183 | 183 | ||
184 | impl Debug<|> for Foo { | 184 | impl 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 | " |
218 | use std::{io, fmt}; | 218 | use std::{io, fmt}; |
219 | 219 | ||
220 | impl io<|> for Foo { | 220 | impl io for Foo { |
221 | } | 221 | } |
222 | ", | 222 | ", |
223 | ); | 223 | ); |
@@ -236,7 +236,7 @@ impl std::fmt::Debug<|> for Foo { | |||
236 | " | 236 | " |
237 | use std::fmt::{self, Debug, }; | 237 | use std::fmt::{self, Debug, }; |
238 | 238 | ||
239 | impl Debug<|> for Foo { | 239 | impl Debug for Foo { |
240 | } | 240 | } |
241 | ", | 241 | ", |
242 | ); | 242 | ); |
@@ -255,7 +255,7 @@ impl std::fmt<|> for Foo { | |||
255 | " | 255 | " |
256 | use std::fmt::{self, Debug}; | 256 | use std::fmt::{self, Debug}; |
257 | 257 | ||
258 | impl fmt<|> for Foo { | 258 | impl fmt for Foo { |
259 | } | 259 | } |
260 | ", | 260 | ", |
261 | ); | 261 | ); |
@@ -274,7 +274,7 @@ impl std::fmt::nested<|> for Foo { | |||
274 | " | 274 | " |
275 | use std::fmt::{Debug, nested::{Display, self}}; | 275 | use std::fmt::{Debug, nested::{Display, self}}; |
276 | 276 | ||
277 | impl nested<|> for Foo { | 277 | impl nested for Foo { |
278 | } | 278 | } |
279 | ", | 279 | ", |
280 | ); | 280 | ); |
@@ -293,7 +293,7 @@ impl std::fmt::nested<|> for Foo { | |||
293 | " | 293 | " |
294 | use std::fmt::{Debug, nested::{self, Display}}; | 294 | use std::fmt::{Debug, nested::{self, Display}}; |
295 | 295 | ||
296 | impl nested<|> for Foo { | 296 | impl nested for Foo { |
297 | } | 297 | } |
298 | ", | 298 | ", |
299 | ); | 299 | ); |
@@ -312,7 +312,7 @@ impl std::fmt::nested::Debug<|> for Foo { | |||
312 | " | 312 | " |
313 | use std::fmt::{Debug, nested::{Display, Debug}}; | 313 | use std::fmt::{Debug, nested::{Display, Debug}}; |
314 | 314 | ||
315 | impl Debug<|> for Foo { | 315 | impl Debug for Foo { |
316 | } | 316 | } |
317 | ", | 317 | ", |
318 | ); | 318 | ); |
@@ -331,7 +331,7 @@ impl std::fmt::nested::Display<|> for Foo { | |||
331 | " | 331 | " |
332 | use std::fmt::{nested::Display, Debug}; | 332 | use std::fmt::{nested::Display, Debug}; |
333 | 333 | ||
334 | impl Display<|> for Foo { | 334 | impl Display for Foo { |
335 | } | 335 | } |
336 | ", | 336 | ", |
337 | ); | 337 | ); |
@@ -350,7 +350,7 @@ impl std::fmt::Display<|> for Foo { | |||
350 | " | 350 | " |
351 | use std::fmt::{Display, nested::Debug}; | 351 | use std::fmt::{Display, nested::Debug}; |
352 | 352 | ||
353 | impl Display<|> for Foo { | 353 | impl Display for Foo { |
354 | } | 354 | } |
355 | ", | 355 | ", |
356 | ); | 356 | ); |
@@ -374,7 +374,7 @@ use crate::{ | |||
374 | AssocItem, | 374 | AssocItem, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | fn foo() { lower<|>::trait_env() } | 377 | fn foo() { lower::trait_env() } |
378 | ", | 378 | ", |
379 | ); | 379 | ); |
380 | } | 380 | } |
@@ -392,7 +392,7 @@ impl foo::Debug<|> for Foo { | |||
392 | " | 392 | " |
393 | use std::fmt as foo; | 393 | use std::fmt as foo; |
394 | 394 | ||
395 | impl Debug<|> for Foo { | 395 | impl 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() { | |||
458 | use std::fmt::Debug; | 458 | use std::fmt::Debug; |
459 | 459 | ||
460 | fn main() { | 460 | fn 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 @@ | |||
1 | use crate::{AssistContext, AssistId, Assists}; | ||
2 | |||
3 | use ast::{ElseBranch, Expr, LoopBodyOwner}; | ||
4 | use ra_fmt::unwrap_trivial_block; | 1 | use ra_fmt::unwrap_trivial_block; |
5 | use ra_syntax::{ast, match_ast, AstNode, TextRange, T}; | 2 | use ra_syntax::{ |
3 | ast::{self, ElseBranch, Expr, LoopBodyOwner}, | ||
4 | match_ast, AstNode, TextRange, T, | ||
5 | }; | ||
6 | |||
7 | use crate::{AssistContext, AssistId, Assists}; | ||
6 | 8 | ||
7 | // Assist: unwrap_block | 9 | // Assist: unwrap_block |
8 | // | 10 | // |