diff options
118 files changed, 3255 insertions, 3000 deletions
diff --git a/Cargo.lock b/Cargo.lock index c06236692..007f05b4d 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -114,7 +114,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" | |||
114 | [[package]] | 114 | [[package]] |
115 | name = "chalk-derive" | 115 | name = "chalk-derive" |
116 | version = "0.10.1-dev" | 116 | version = "0.10.1-dev" |
117 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 117 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
118 | dependencies = [ | 118 | dependencies = [ |
119 | "proc-macro2", | 119 | "proc-macro2", |
120 | "quote", | 120 | "quote", |
@@ -125,7 +125,7 @@ dependencies = [ | |||
125 | [[package]] | 125 | [[package]] |
126 | name = "chalk-engine" | 126 | name = "chalk-engine" |
127 | version = "0.10.1-dev" | 127 | version = "0.10.1-dev" |
128 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 128 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
129 | dependencies = [ | 129 | dependencies = [ |
130 | "chalk-macros", | 130 | "chalk-macros", |
131 | "rustc-hash", | 131 | "rustc-hash", |
@@ -134,7 +134,7 @@ dependencies = [ | |||
134 | [[package]] | 134 | [[package]] |
135 | name = "chalk-ir" | 135 | name = "chalk-ir" |
136 | version = "0.10.1-dev" | 136 | version = "0.10.1-dev" |
137 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 137 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
138 | dependencies = [ | 138 | dependencies = [ |
139 | "chalk-derive", | 139 | "chalk-derive", |
140 | "chalk-engine", | 140 | "chalk-engine", |
@@ -144,7 +144,7 @@ dependencies = [ | |||
144 | [[package]] | 144 | [[package]] |
145 | name = "chalk-macros" | 145 | name = "chalk-macros" |
146 | version = "0.10.1-dev" | 146 | version = "0.10.1-dev" |
147 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 147 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
148 | dependencies = [ | 148 | dependencies = [ |
149 | "lazy_static", | 149 | "lazy_static", |
150 | ] | 150 | ] |
@@ -152,7 +152,7 @@ dependencies = [ | |||
152 | [[package]] | 152 | [[package]] |
153 | name = "chalk-rust-ir" | 153 | name = "chalk-rust-ir" |
154 | version = "0.10.1-dev" | 154 | version = "0.10.1-dev" |
155 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 155 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
156 | dependencies = [ | 156 | dependencies = [ |
157 | "chalk-derive", | 157 | "chalk-derive", |
158 | "chalk-engine", | 158 | "chalk-engine", |
@@ -163,14 +163,14 @@ dependencies = [ | |||
163 | [[package]] | 163 | [[package]] |
164 | name = "chalk-solve" | 164 | name = "chalk-solve" |
165 | version = "0.10.1-dev" | 165 | version = "0.10.1-dev" |
166 | source = "git+https://github.com/rust-lang/chalk.git?rev=3e9c2503ae9c5277c2acb74624dc267876dd89b3#3e9c2503ae9c5277c2acb74624dc267876dd89b3" | 166 | source = "git+https://github.com/rust-lang/chalk.git?rev=eaab84b394007d1bed15f5470409a6ea02900a96#eaab84b394007d1bed15f5470409a6ea02900a96" |
167 | dependencies = [ | 167 | dependencies = [ |
168 | "chalk-derive", | 168 | "chalk-derive", |
169 | "chalk-engine", | 169 | "chalk-engine", |
170 | "chalk-ir", | 170 | "chalk-ir", |
171 | "chalk-macros", | 171 | "chalk-macros", |
172 | "chalk-rust-ir", | 172 | "chalk-rust-ir", |
173 | "ena 0.13.1", | 173 | "ena", |
174 | "itertools", | 174 | "itertools", |
175 | "petgraph", | 175 | "petgraph", |
176 | "rustc-hash", | 176 | "rustc-hash", |
@@ -309,15 +309,6 @@ checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" | |||
309 | 309 | ||
310 | [[package]] | 310 | [[package]] |
311 | name = "ena" | 311 | name = "ena" |
312 | version = "0.13.1" | ||
313 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
314 | checksum = "8944dc8fa28ce4a38f778bd46bf7d923fe73eed5a439398507246c8e017e6f36" | ||
315 | dependencies = [ | ||
316 | "log", | ||
317 | ] | ||
318 | |||
319 | [[package]] | ||
320 | name = "ena" | ||
321 | version = "0.14.0" | 312 | version = "0.14.0" |
322 | source = "registry+https://github.com/rust-lang/crates.io-index" | 313 | source = "registry+https://github.com/rust-lang/crates.io-index" |
323 | checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" | 314 | checksum = "d7402b94a93c24e742487327a7cd839dc9d36fec9de9fb25b09f2dae459f36c3" |
@@ -354,9 +345,9 @@ dependencies = [ | |||
354 | 345 | ||
355 | [[package]] | 346 | [[package]] |
356 | name = "fixedbitset" | 347 | name = "fixedbitset" |
357 | version = "0.1.9" | 348 | version = "0.2.0" |
358 | source = "registry+https://github.com/rust-lang/crates.io-index" | 349 | source = "registry+https://github.com/rust-lang/crates.io-index" |
359 | checksum = "86d4de0081402f5e88cdac65c8dcdcc73118c1a7a465e2a05f0da05843a8ea33" | 350 | checksum = "37ab347416e802de484e4d03c7316c48f1ecb56574dfd4a46a80f173ce1de04d" |
360 | 351 | ||
361 | [[package]] | 352 | [[package]] |
362 | name = "fnv" | 353 | name = "fnv" |
@@ -658,9 +649,9 @@ dependencies = [ | |||
658 | 649 | ||
659 | [[package]] | 650 | [[package]] |
660 | name = "lsp-server" | 651 | name = "lsp-server" |
661 | version = "0.3.1" | 652 | version = "0.3.2" |
662 | source = "registry+https://github.com/rust-lang/crates.io-index" | 653 | source = "registry+https://github.com/rust-lang/crates.io-index" |
663 | checksum = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" | 654 | checksum = "dccec31bfd027ac0dd288a78e19005fd89624d9099456e284b5241316a6c3072" |
664 | dependencies = [ | 655 | dependencies = [ |
665 | "crossbeam-channel", | 656 | "crossbeam-channel", |
666 | "log", | 657 | "log", |
@@ -814,12 +805,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" | |||
814 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" | 805 | checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d" |
815 | 806 | ||
816 | [[package]] | 807 | [[package]] |
817 | name = "ordermap" | ||
818 | version = "0.3.5" | ||
819 | source = "registry+https://github.com/rust-lang/crates.io-index" | ||
820 | checksum = "a86ed3f5f244b372d6b1a00b72ef7f8876d0bc6a78a4c9985c53614041512063" | ||
821 | |||
822 | [[package]] | ||
823 | name = "parking_lot" | 808 | name = "parking_lot" |
824 | version = "0.10.2" | 809 | version = "0.10.2" |
825 | source = "registry+https://github.com/rust-lang/crates.io-index" | 810 | source = "registry+https://github.com/rust-lang/crates.io-index" |
@@ -873,12 +858,12 @@ checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" | |||
873 | 858 | ||
874 | [[package]] | 859 | [[package]] |
875 | name = "petgraph" | 860 | name = "petgraph" |
876 | version = "0.4.13" | 861 | version = "0.5.0" |
877 | source = "registry+https://github.com/rust-lang/crates.io-index" | 862 | source = "registry+https://github.com/rust-lang/crates.io-index" |
878 | checksum = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" | 863 | checksum = "29c127eea4a29ec6c85d153c59dc1213f33ec74cead30fe4730aecc88cc1fd92" |
879 | dependencies = [ | 864 | dependencies = [ |
880 | "fixedbitset", | 865 | "fixedbitset", |
881 | "ordermap", | 866 | "indexmap", |
882 | ] | 867 | ] |
883 | 868 | ||
884 | [[package]] | 869 | [[package]] |
@@ -1053,7 +1038,7 @@ dependencies = [ | |||
1053 | "chalk-ir", | 1038 | "chalk-ir", |
1054 | "chalk-rust-ir", | 1039 | "chalk-rust-ir", |
1055 | "chalk-solve", | 1040 | "chalk-solve", |
1056 | "ena 0.14.0", | 1041 | "ena", |
1057 | "insta", | 1042 | "insta", |
1058 | "itertools", | 1043 | "itertools", |
1059 | "log", | 1044 | "log", |
diff --git a/crates/ra_assists/src/assist_context.rs b/crates/ra_assists/src/assist_context.rs index 005c17776..5b1a4680b 100644 --- a/crates/ra_assists/src/assist_context.rs +++ b/crates/ra_assists/src/assist_context.rs | |||
@@ -5,7 +5,7 @@ use hir::Semantics; | |||
5 | use ra_db::{FileId, FileRange}; | 5 | use ra_db::{FileId, FileRange}; |
6 | use ra_fmt::{leading_indent, reindent}; | 6 | use ra_fmt::{leading_indent, reindent}; |
7 | use ra_ide_db::{ | 7 | use ra_ide_db::{ |
8 | source_change::{SingleFileChange, SourceChange}, | 8 | source_change::{SourceChange, SourceFileEdit}, |
9 | RootDatabase, | 9 | RootDatabase, |
10 | }; | 10 | }; |
11 | use ra_syntax::{ | 11 | use ra_syntax::{ |
@@ -150,11 +150,10 @@ impl Assists { | |||
150 | self.add_impl(label, f) | 150 | self.add_impl(label, f) |
151 | } | 151 | } |
152 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { | 152 | fn add_impl(&mut self, label: Assist, f: impl FnOnce(&mut AssistBuilder)) -> Option<()> { |
153 | let change_label = label.label.clone(); | ||
154 | let source_change = if self.resolve { | 153 | let source_change = if self.resolve { |
155 | let mut builder = AssistBuilder::new(self.file); | 154 | let mut builder = AssistBuilder::new(self.file); |
156 | f(&mut builder); | 155 | f(&mut builder); |
157 | Some(builder.finish(change_label)) | 156 | Some(builder.finish()) |
158 | } else { | 157 | } else { |
159 | None | 158 | None |
160 | }; | 159 | }; |
@@ -171,19 +170,13 @@ impl Assists { | |||
171 | 170 | ||
172 | pub(crate) struct AssistBuilder { | 171 | pub(crate) struct AssistBuilder { |
173 | edit: TextEditBuilder, | 172 | edit: TextEditBuilder, |
174 | cursor_position: Option<TextSize>, | ||
175 | file: FileId, | 173 | file: FileId, |
176 | is_snippet: bool, | 174 | is_snippet: bool, |
177 | } | 175 | } |
178 | 176 | ||
179 | impl AssistBuilder { | 177 | impl AssistBuilder { |
180 | pub(crate) fn new(file: FileId) -> AssistBuilder { | 178 | pub(crate) fn new(file: FileId) -> AssistBuilder { |
181 | AssistBuilder { | 179 | AssistBuilder { edit: TextEditBuilder::default(), file, is_snippet: false } |
182 | edit: TextEditBuilder::default(), | ||
183 | cursor_position: None, | ||
184 | file, | ||
185 | is_snippet: false, | ||
186 | } | ||
187 | } | 180 | } |
188 | 181 | ||
189 | /// Remove specified `range` of text. | 182 | /// Remove specified `range` of text. |
@@ -241,10 +234,6 @@ impl AssistBuilder { | |||
241 | algo::diff(&node, &new).into_text_edit(&mut self.edit) | 234 | algo::diff(&node, &new).into_text_edit(&mut self.edit) |
242 | } | 235 | } |
243 | 236 | ||
244 | /// Specify desired position of the cursor after the assist is applied. | ||
245 | pub(crate) fn set_cursor(&mut self, offset: TextSize) { | ||
246 | self.cursor_position = Some(offset) | ||
247 | } | ||
248 | // FIXME: better API | 237 | // FIXME: better API |
249 | pub(crate) fn set_file(&mut self, assist_file: FileId) { | 238 | pub(crate) fn set_file(&mut self, assist_file: FileId) { |
250 | self.file = assist_file; | 239 | self.file = assist_file; |
@@ -256,14 +245,10 @@ impl AssistBuilder { | |||
256 | &mut self.edit | 245 | &mut self.edit |
257 | } | 246 | } |
258 | 247 | ||
259 | fn finish(self, change_label: String) -> SourceChange { | 248 | fn finish(self) -> SourceChange { |
260 | let edit = self.edit.finish(); | 249 | let edit = self.edit.finish(); |
261 | if edit.is_empty() && self.cursor_position.is_none() { | 250 | let source_file_edit = SourceFileEdit { file_id: self.file, edit }; |
262 | panic!("Only call `add_assist` if the assist can be applied") | 251 | let mut res: SourceChange = source_file_edit.into(); |
263 | } | ||
264 | let mut res = | ||
265 | SingleFileChange { label: change_label, edit, cursor_position: self.cursor_position } | ||
266 | .into_source_change(self.file); | ||
267 | if self.is_snippet { | 252 | if self.is_snippet { |
268 | res.is_snippet = true; | 253 | res.is_snippet = true; |
269 | } | 254 | } |
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_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 f6d25579e..edf96d50e 100644 --- a/crates/ra_assists/src/handlers/auto_import.rs +++ b/crates/ra_assists/src/handlers/auto_import.rs | |||
@@ -298,7 +298,7 @@ mod tests { | |||
298 | } | 298 | } |
299 | ", | 299 | ", |
300 | r" | 300 | r" |
301 | <|>use PubMod::PubStruct; | 301 | use PubMod::PubStruct; |
302 | 302 | ||
303 | PubStruct | 303 | PubStruct |
304 | 304 | ||
@@ -329,7 +329,7 @@ mod tests { | |||
329 | macro_rules! foo { | 329 | macro_rules! foo { |
330 | ($i:ident) => { fn foo(a: $i) {} } | 330 | ($i:ident) => { fn foo(a: $i) {} } |
331 | } | 331 | } |
332 | foo!(Pub<|>Struct); | 332 | foo!(PubStruct); |
333 | 333 | ||
334 | pub mod PubMod { | 334 | pub mod PubMod { |
335 | pub struct PubStruct; | 335 | pub struct PubStruct; |
@@ -360,7 +360,7 @@ mod tests { | |||
360 | use PubMod::{PubStruct2, PubStruct1}; | 360 | use PubMod::{PubStruct2, PubStruct1}; |
361 | 361 | ||
362 | struct Test { | 362 | struct Test { |
363 | test: Pub<|>Struct2<u8>, | 363 | test: PubStruct2<u8>, |
364 | } | 364 | } |
365 | 365 | ||
366 | pub mod PubMod { | 366 | pub mod PubMod { |
@@ -393,7 +393,7 @@ mod tests { | |||
393 | r" | 393 | r" |
394 | use PubMod3::PubStruct; | 394 | use PubMod3::PubStruct; |
395 | 395 | ||
396 | PubSt<|>ruct | 396 | PubStruct |
397 | 397 | ||
398 | pub mod PubMod1 { | 398 | pub mod PubMod1 { |
399 | pub struct PubStruct; | 399 | pub struct PubStruct; |
@@ -474,7 +474,7 @@ mod tests { | |||
474 | r" | 474 | r" |
475 | use PubMod::test_function; | 475 | use PubMod::test_function; |
476 | 476 | ||
477 | test_function<|> | 477 | test_function |
478 | 478 | ||
479 | pub mod PubMod { | 479 | pub mod PubMod { |
480 | pub fn test_function() {}; | 480 | pub fn test_function() {}; |
@@ -501,7 +501,7 @@ mod tests { | |||
501 | r"use crate_with_macro::foo; | 501 | r"use crate_with_macro::foo; |
502 | 502 | ||
503 | fn main() { | 503 | fn main() { |
504 | foo<|> | 504 | foo |
505 | } | 505 | } |
506 | ", | 506 | ", |
507 | ); | 507 | ); |
@@ -587,7 +587,7 @@ fn main() { | |||
587 | } | 587 | } |
588 | 588 | ||
589 | fn main() { | 589 | fn main() { |
590 | TestStruct::test_function<|> | 590 | TestStruct::test_function |
591 | } | 591 | } |
592 | ", | 592 | ", |
593 | ); | 593 | ); |
@@ -620,7 +620,7 @@ fn main() { | |||
620 | } | 620 | } |
621 | 621 | ||
622 | fn main() { | 622 | fn main() { |
623 | TestStruct::TEST_CONST<|> | 623 | TestStruct::TEST_CONST |
624 | } | 624 | } |
625 | ", | 625 | ", |
626 | ); | 626 | ); |
@@ -659,7 +659,7 @@ fn main() { | |||
659 | } | 659 | } |
660 | 660 | ||
661 | fn main() { | 661 | fn main() { |
662 | test_mod::TestStruct::test_function<|> | 662 | test_mod::TestStruct::test_function |
663 | } | 663 | } |
664 | ", | 664 | ", |
665 | ); | 665 | ); |
@@ -730,7 +730,7 @@ fn main() { | |||
730 | } | 730 | } |
731 | 731 | ||
732 | fn main() { | 732 | fn main() { |
733 | test_mod::TestStruct::TEST_CONST<|> | 733 | test_mod::TestStruct::TEST_CONST |
734 | } | 734 | } |
735 | ", | 735 | ", |
736 | ); | 736 | ); |
@@ -803,7 +803,7 @@ fn main() { | |||
803 | 803 | ||
804 | fn main() { | 804 | fn main() { |
805 | let test_struct = test_mod::TestStruct {}; | 805 | let test_struct = test_mod::TestStruct {}; |
806 | test_struct.test_meth<|>od() | 806 | test_struct.test_method() |
807 | } | 807 | } |
808 | ", | 808 | ", |
809 | ); | 809 | ); |
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/early_return.rs b/crates/ra_assists/src/handlers/early_return.rs index 66b296081..4cc75a7ce 100644 --- a/crates/ra_assists/src/handlers/early_return.rs +++ b/crates/ra_assists/src/handlers/early_return.rs | |||
@@ -97,7 +97,6 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) | |||
97 | } | 97 | } |
98 | 98 | ||
99 | then_block.syntax().last_child_or_token().filter(|t| t.kind() == R_CURLY)?; | 99 | then_block.syntax().last_child_or_token().filter(|t| t.kind() == R_CURLY)?; |
100 | let cursor_position = ctx.offset(); | ||
101 | 100 | ||
102 | let target = if_expr.syntax().text_range(); | 101 | let target = if_expr.syntax().text_range(); |
103 | acc.add(AssistId("convert_to_guarded_return"), "Convert to guarded return", target, |edit| { | 102 | acc.add(AssistId("convert_to_guarded_return"), "Convert to guarded return", target, |edit| { |
@@ -148,7 +147,6 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) | |||
148 | } | 147 | } |
149 | }; | 148 | }; |
150 | edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap()); | 149 | edit.replace_ast(parent_block, ast::BlockExpr::cast(new_block).unwrap()); |
151 | edit.set_cursor(cursor_position); | ||
152 | 150 | ||
153 | fn replace( | 151 | fn replace( |
154 | new_expr: &SyntaxNode, | 152 | new_expr: &SyntaxNode, |
@@ -207,7 +205,7 @@ mod tests { | |||
207 | r#" | 205 | r#" |
208 | fn main() { | 206 | fn main() { |
209 | bar(); | 207 | bar(); |
210 | if<|> !true { | 208 | if !true { |
211 | return; | 209 | return; |
212 | } | 210 | } |
213 | foo(); | 211 | foo(); |
@@ -237,7 +235,7 @@ mod tests { | |||
237 | r#" | 235 | r#" |
238 | fn main(n: Option<String>) { | 236 | fn main(n: Option<String>) { |
239 | bar(); | 237 | bar(); |
240 | le<|>t n = match n { | 238 | let n = match n { |
241 | Some(it) => it, | 239 | Some(it) => it, |
242 | _ => return, | 240 | _ => return, |
243 | }; | 241 | }; |
@@ -263,7 +261,7 @@ mod tests { | |||
263 | "#, | 261 | "#, |
264 | r#" | 262 | r#" |
265 | fn main() { | 263 | fn main() { |
266 | le<|>t x = match Err(92) { | 264 | let x = match Err(92) { |
267 | Ok(it) => it, | 265 | Ok(it) => it, |
268 | _ => return, | 266 | _ => return, |
269 | }; | 267 | }; |
@@ -291,7 +289,7 @@ mod tests { | |||
291 | r#" | 289 | r#" |
292 | fn main(n: Option<String>) { | 290 | fn main(n: Option<String>) { |
293 | bar(); | 291 | bar(); |
294 | le<|>t n = match n { | 292 | let n = match n { |
295 | Ok(it) => it, | 293 | Ok(it) => it, |
296 | _ => return, | 294 | _ => return, |
297 | }; | 295 | }; |
@@ -321,7 +319,7 @@ mod tests { | |||
321 | r#" | 319 | r#" |
322 | fn main() { | 320 | fn main() { |
323 | while true { | 321 | while true { |
324 | if<|> !true { | 322 | if !true { |
325 | continue; | 323 | continue; |
326 | } | 324 | } |
327 | foo(); | 325 | foo(); |
@@ -349,7 +347,7 @@ mod tests { | |||
349 | r#" | 347 | r#" |
350 | fn main() { | 348 | fn main() { |
351 | while true { | 349 | while true { |
352 | le<|>t n = match n { | 350 | let n = match n { |
353 | Some(it) => it, | 351 | Some(it) => it, |
354 | _ => continue, | 352 | _ => continue, |
355 | }; | 353 | }; |
@@ -378,7 +376,7 @@ mod tests { | |||
378 | r#" | 376 | r#" |
379 | fn main() { | 377 | fn main() { |
380 | loop { | 378 | loop { |
381 | if<|> !true { | 379 | if !true { |
382 | continue; | 380 | continue; |
383 | } | 381 | } |
384 | foo(); | 382 | foo(); |
@@ -406,7 +404,7 @@ mod tests { | |||
406 | r#" | 404 | r#" |
407 | fn main() { | 405 | fn main() { |
408 | loop { | 406 | loop { |
409 | le<|>t n = match n { | 407 | let n = match n { |
410 | Some(it) => it, | 408 | Some(it) => it, |
411 | _ => continue, | 409 | _ => continue, |
412 | }; | 410 | }; |
diff --git a/crates/ra_assists/src/handlers/fill_match_arms.rs b/crates/ra_assists/src/handlers/fill_match_arms.rs index b57ff75ae..cc303285b 100644 --- a/crates/ra_assists/src/handlers/fill_match_arms.rs +++ b/crates/ra_assists/src/handlers/fill_match_arms.rs | |||
@@ -4,9 +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::tested_by; | 7 | use test_utils::mark; |
8 | 8 | ||
9 | use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; | 9 | use crate::{ |
10 | utils::{render_snippet, Cursor, FamousDefs}, | ||
11 | AssistContext, AssistId, Assists, | ||
12 | }; | ||
10 | 13 | ||
11 | // Assist: fill_match_arms | 14 | // Assist: fill_match_arms |
12 | // | 15 | // |
@@ -27,7 +30,7 @@ use crate::{utils::FamousDefs, AssistContext, AssistId, Assists}; | |||
27 | // | 30 | // |
28 | // fn handle(action: Action) { | 31 | // fn handle(action: Action) { |
29 | // match action { | 32 | // match action { |
30 | // Action::Move { distance } => {} | 33 | // $0Action::Move { distance } => {} |
31 | // Action::Stop => {} | 34 | // Action::Stop => {} |
32 | // } | 35 | // } |
33 | // } | 36 | // } |
@@ -58,7 +61,7 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
58 | .collect::<Vec<_>>(); | 61 | .collect::<Vec<_>>(); |
59 | if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() { | 62 | if Some(enum_def) == FamousDefs(&ctx.sema, module.krate()).core_option_Option() { |
60 | // Match `Some` variant first. | 63 | // Match `Some` variant first. |
61 | tested_by!(option_order); | 64 | mark::hit!(option_order); |
62 | variants.reverse() | 65 | variants.reverse() |
63 | } | 66 | } |
64 | variants | 67 | variants |
@@ -100,10 +103,23 @@ pub(crate) fn fill_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
100 | } | 103 | } |
101 | 104 | ||
102 | let target = match_expr.syntax().text_range(); | 105 | let target = match_expr.syntax().text_range(); |
103 | acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |edit| { | 106 | acc.add(AssistId("fill_match_arms"), "Fill match arms", target, |builder| { |
104 | let new_arm_list = match_arm_list.remove_placeholder().append_arms(missing_arms); | 107 | let new_arm_list = match_arm_list.remove_placeholder(); |
105 | edit.set_cursor(expr.syntax().text_range().start()); | 108 | let n_old_arms = new_arm_list.arms().count(); |
106 | 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 | } | ||
107 | }) | 123 | }) |
108 | } | 124 | } |
109 | 125 | ||
@@ -174,13 +190,14 @@ fn build_pat(db: &RootDatabase, module: hir::Module, var: hir::EnumVariant) -> O | |||
174 | 190 | ||
175 | #[cfg(test)] | 191 | #[cfg(test)] |
176 | mod tests { | 192 | mod tests { |
193 | use test_utils::mark; | ||
194 | |||
177 | use crate::{ | 195 | use crate::{ |
178 | tests::{check_assist, check_assist_not_applicable, check_assist_target}, | 196 | tests::{check_assist, check_assist_not_applicable, check_assist_target}, |
179 | utils::FamousDefs, | 197 | utils::FamousDefs, |
180 | }; | 198 | }; |
181 | 199 | ||
182 | use super::fill_match_arms; | 200 | use super::fill_match_arms; |
183 | use test_utils::covers; | ||
184 | 201 | ||
185 | #[test] | 202 | #[test] |
186 | fn all_match_arms_provided() { | 203 | fn all_match_arms_provided() { |
@@ -225,12 +242,12 @@ mod tests { | |||
225 | r#" | 242 | r#" |
226 | enum A { | 243 | enum A { |
227 | As, | 244 | As, |
228 | Bs{x:i32, y:Option<i32>}, | 245 | Bs { x: i32, y: Option<i32> }, |
229 | Cs(i32, Option<i32>), | 246 | Cs(i32, Option<i32>), |
230 | } | 247 | } |
231 | fn main() { | 248 | fn main() { |
232 | match A::As<|> { | 249 | match A::As<|> { |
233 | A::Bs{x,y:Some(_)} => {} | 250 | A::Bs { x, y: Some(_) } => {} |
234 | A::Cs(_, Some(_)) => {} | 251 | A::Cs(_, Some(_)) => {} |
235 | } | 252 | } |
236 | } | 253 | } |
@@ -238,14 +255,14 @@ mod tests { | |||
238 | r#" | 255 | r#" |
239 | enum A { | 256 | enum A { |
240 | As, | 257 | As, |
241 | Bs{x:i32, y:Option<i32>}, | 258 | Bs { x: i32, y: Option<i32> }, |
242 | Cs(i32, Option<i32>), | 259 | Cs(i32, Option<i32>), |
243 | } | 260 | } |
244 | fn main() { | 261 | fn main() { |
245 | match <|>A::As { | 262 | match A::As { |
246 | A::Bs{x,y:Some(_)} => {} | 263 | A::Bs { x, y: Some(_) } => {} |
247 | A::Cs(_, Some(_)) => {} | 264 | A::Cs(_, Some(_)) => {} |
248 | A::As => {} | 265 | $0A::As => {} |
249 | } | 266 | } |
250 | } | 267 | } |
251 | "#, | 268 | "#, |
@@ -275,9 +292,9 @@ mod tests { | |||
275 | Cs(Option<i32>), | 292 | Cs(Option<i32>), |
276 | } | 293 | } |
277 | fn main() { | 294 | fn main() { |
278 | match <|>A::As { | 295 | match A::As { |
279 | A::Cs(_) | A::Bs => {} | 296 | A::Cs(_) | A::Bs => {} |
280 | A::As => {} | 297 | $0A::As => {} |
281 | } | 298 | } |
282 | } | 299 | } |
283 | "#, | 300 | "#, |
@@ -321,11 +338,11 @@ mod tests { | |||
321 | Ys, | 338 | Ys, |
322 | } | 339 | } |
323 | fn main() { | 340 | fn main() { |
324 | match <|>A::As { | 341 | match A::As { |
325 | A::Bs if 0 < 1 => {} | 342 | A::Bs if 0 < 1 => {} |
326 | A::Ds(_value) => { let x = 1; } | 343 | A::Ds(_value) => { let x = 1; } |
327 | A::Es(B::Xs) => (), | 344 | A::Es(B::Xs) => (), |
328 | A::As => {} | 345 | $0A::As => {} |
329 | A::Cs => {} | 346 | A::Cs => {} |
330 | } | 347 | } |
331 | } | 348 | } |
@@ -343,7 +360,7 @@ mod tests { | |||
343 | Bs, | 360 | Bs, |
344 | Cs(String), | 361 | Cs(String), |
345 | Ds(String, String), | 362 | Ds(String, String), |
346 | Es{ x: usize, y: usize } | 363 | Es { x: usize, y: usize } |
347 | } | 364 | } |
348 | 365 | ||
349 | fn main() { | 366 | fn main() { |
@@ -357,13 +374,13 @@ mod tests { | |||
357 | Bs, | 374 | Bs, |
358 | Cs(String), | 375 | Cs(String), |
359 | Ds(String, String), | 376 | Ds(String, String), |
360 | Es{ x: usize, y: usize } | 377 | Es { x: usize, y: usize } |
361 | } | 378 | } |
362 | 379 | ||
363 | fn main() { | 380 | fn main() { |
364 | let a = A::As; | 381 | let a = A::As; |
365 | match <|>a { | 382 | match a { |
366 | A::As => {} | 383 | $0A::As => {} |
367 | A::Bs => {} | 384 | A::Bs => {} |
368 | A::Cs(_) => {} | 385 | A::Cs(_) => {} |
369 | A::Ds(_, _) => {} | 386 | A::Ds(_, _) => {} |
@@ -379,14 +396,8 @@ mod tests { | |||
379 | check_assist( | 396 | check_assist( |
380 | fill_match_arms, | 397 | fill_match_arms, |
381 | r#" | 398 | r#" |
382 | enum A { | 399 | enum A { One, Two } |
383 | One, | 400 | enum B { One, Two } |
384 | Two, | ||
385 | } | ||
386 | enum B { | ||
387 | One, | ||
388 | Two, | ||
389 | } | ||
390 | 401 | ||
391 | fn main() { | 402 | fn main() { |
392 | let a = A::One; | 403 | let a = A::One; |
@@ -395,20 +406,14 @@ mod tests { | |||
395 | } | 406 | } |
396 | "#, | 407 | "#, |
397 | r#" | 408 | r#" |
398 | enum A { | 409 | enum A { One, Two } |
399 | One, | 410 | enum B { One, Two } |
400 | Two, | ||
401 | } | ||
402 | enum B { | ||
403 | One, | ||
404 | Two, | ||
405 | } | ||
406 | 411 | ||
407 | fn main() { | 412 | fn main() { |
408 | let a = A::One; | 413 | let a = A::One; |
409 | let b = B::One; | 414 | let b = B::One; |
410 | match <|>(a, b) { | 415 | match (a, b) { |
411 | (A::One, B::One) => {} | 416 | $0(A::One, B::One) => {} |
412 | (A::One, B::Two) => {} | 417 | (A::One, B::Two) => {} |
413 | (A::Two, B::One) => {} | 418 | (A::Two, B::One) => {} |
414 | (A::Two, B::Two) => {} | 419 | (A::Two, B::Two) => {} |
@@ -423,14 +428,8 @@ mod tests { | |||
423 | check_assist( | 428 | check_assist( |
424 | fill_match_arms, | 429 | fill_match_arms, |
425 | r#" | 430 | r#" |
426 | enum A { | 431 | enum A { One, Two } |
427 | One, | 432 | enum B { One, Two } |
428 | Two, | ||
429 | } | ||
430 | enum B { | ||
431 | One, | ||
432 | Two, | ||
433 | } | ||
434 | 433 | ||
435 | fn main() { | 434 | fn main() { |
436 | let a = A::One; | 435 | let a = A::One; |
@@ -439,20 +438,14 @@ mod tests { | |||
439 | } | 438 | } |
440 | "#, | 439 | "#, |
441 | r#" | 440 | r#" |
442 | enum A { | 441 | enum A { One, Two } |
443 | One, | 442 | enum B { One, Two } |
444 | Two, | ||
445 | } | ||
446 | enum B { | ||
447 | One, | ||
448 | Two, | ||
449 | } | ||
450 | 443 | ||
451 | fn main() { | 444 | fn main() { |
452 | let a = A::One; | 445 | let a = A::One; |
453 | let b = B::One; | 446 | let b = B::One; |
454 | match <|>(&a, &b) { | 447 | match (&a, &b) { |
455 | (A::One, B::One) => {} | 448 | $0(A::One, B::One) => {} |
456 | (A::One, B::Two) => {} | 449 | (A::One, B::Two) => {} |
457 | (A::Two, B::One) => {} | 450 | (A::Two, B::One) => {} |
458 | (A::Two, B::Two) => {} | 451 | (A::Two, B::Two) => {} |
@@ -467,14 +460,8 @@ mod tests { | |||
467 | check_assist_not_applicable( | 460 | check_assist_not_applicable( |
468 | fill_match_arms, | 461 | fill_match_arms, |
469 | r#" | 462 | r#" |
470 | enum A { | 463 | enum A { One, Two } |
471 | One, | 464 | enum B { One, Two } |
472 | Two, | ||
473 | } | ||
474 | enum B { | ||
475 | One, | ||
476 | Two, | ||
477 | } | ||
478 | 465 | ||
479 | fn main() { | 466 | fn main() { |
480 | let a = A::One; | 467 | let a = A::One; |
@@ -492,14 +479,8 @@ mod tests { | |||
492 | check_assist_not_applicable( | 479 | check_assist_not_applicable( |
493 | fill_match_arms, | 480 | fill_match_arms, |
494 | r#" | 481 | r#" |
495 | enum A { | 482 | enum A { One, Two } |
496 | One, | 483 | enum B { One, Two } |
497 | Two, | ||
498 | } | ||
499 | enum B { | ||
500 | One, | ||
501 | Two, | ||
502 | } | ||
503 | 484 | ||
504 | fn main() { | 485 | fn main() { |
505 | let a = A::One; | 486 | let a = A::One; |
@@ -523,10 +504,7 @@ mod tests { | |||
523 | check_assist_not_applicable( | 504 | check_assist_not_applicable( |
524 | fill_match_arms, | 505 | fill_match_arms, |
525 | r#" | 506 | r#" |
526 | enum A { | 507 | enum A { One, Two } |
527 | One, | ||
528 | Two, | ||
529 | } | ||
530 | 508 | ||
531 | fn main() { | 509 | fn main() { |
532 | let a = A::One; | 510 | let a = A::One; |
@@ -542,9 +520,7 @@ mod tests { | |||
542 | check_assist( | 520 | check_assist( |
543 | fill_match_arms, | 521 | fill_match_arms, |
544 | r#" | 522 | r#" |
545 | enum A { | 523 | enum A { As } |
546 | As, | ||
547 | } | ||
548 | 524 | ||
549 | fn foo(a: &A) { | 525 | fn foo(a: &A) { |
550 | match a<|> { | 526 | match a<|> { |
@@ -552,13 +528,11 @@ mod tests { | |||
552 | } | 528 | } |
553 | "#, | 529 | "#, |
554 | r#" | 530 | r#" |
555 | enum A { | 531 | enum A { As } |
556 | As, | ||
557 | } | ||
558 | 532 | ||
559 | fn foo(a: &A) { | 533 | fn foo(a: &A) { |
560 | match <|>a { | 534 | match a { |
561 | A::As => {} | 535 | $0A::As => {} |
562 | } | 536 | } |
563 | } | 537 | } |
564 | "#, | 538 | "#, |
@@ -568,7 +542,7 @@ mod tests { | |||
568 | fill_match_arms, | 542 | fill_match_arms, |
569 | r#" | 543 | r#" |
570 | enum A { | 544 | enum A { |
571 | Es{ x: usize, y: usize } | 545 | Es { x: usize, y: usize } |
572 | } | 546 | } |
573 | 547 | ||
574 | fn foo(a: &mut A) { | 548 | fn foo(a: &mut A) { |
@@ -578,12 +552,12 @@ mod tests { | |||
578 | "#, | 552 | "#, |
579 | r#" | 553 | r#" |
580 | enum A { | 554 | enum A { |
581 | Es{ x: usize, y: usize } | 555 | Es { x: usize, y: usize } |
582 | } | 556 | } |
583 | 557 | ||
584 | fn foo(a: &mut A) { | 558 | fn foo(a: &mut A) { |
585 | match <|>a { | 559 | match a { |
586 | A::Es { x, y } => {} | 560 | $0A::Es { x, y } => {} |
587 | } | 561 | } |
588 | } | 562 | } |
589 | "#, | 563 | "#, |
@@ -622,8 +596,8 @@ mod tests { | |||
622 | enum E { X, Y } | 596 | enum E { X, Y } |
623 | 597 | ||
624 | fn main() { | 598 | fn main() { |
625 | match <|>E::X { | 599 | match E::X { |
626 | E::X => {} | 600 | $0E::X => {} |
627 | E::Y => {} | 601 | E::Y => {} |
628 | } | 602 | } |
629 | } | 603 | } |
@@ -650,8 +624,8 @@ mod tests { | |||
650 | use foo::E::X; | 624 | use foo::E::X; |
651 | 625 | ||
652 | fn main() { | 626 | fn main() { |
653 | match <|>X { | 627 | match X { |
654 | X => {} | 628 | $0X => {} |
655 | foo::E::Y => {} | 629 | foo::E::Y => {} |
656 | } | 630 | } |
657 | } | 631 | } |
@@ -664,10 +638,7 @@ mod tests { | |||
664 | check_assist( | 638 | check_assist( |
665 | fill_match_arms, | 639 | fill_match_arms, |
666 | r#" | 640 | r#" |
667 | enum A { | 641 | enum A { One, Two } |
668 | One, | ||
669 | Two, | ||
670 | } | ||
671 | fn foo(a: A) { | 642 | fn foo(a: A) { |
672 | match a { | 643 | match a { |
673 | // foo bar baz<|> | 644 | // foo bar baz<|> |
@@ -677,16 +648,13 @@ mod tests { | |||
677 | } | 648 | } |
678 | "#, | 649 | "#, |
679 | r#" | 650 | r#" |
680 | enum A { | 651 | enum A { One, Two } |
681 | One, | ||
682 | Two, | ||
683 | } | ||
684 | fn foo(a: A) { | 652 | fn foo(a: A) { |
685 | match <|>a { | 653 | match a { |
686 | // foo bar baz | 654 | // foo bar baz |
687 | A::One => {} | 655 | A::One => {} |
688 | // This is where the rest should be | 656 | // This is where the rest should be |
689 | A::Two => {} | 657 | $0A::Two => {} |
690 | } | 658 | } |
691 | } | 659 | } |
692 | "#, | 660 | "#, |
@@ -698,10 +666,7 @@ mod tests { | |||
698 | check_assist( | 666 | check_assist( |
699 | fill_match_arms, | 667 | fill_match_arms, |
700 | r#" | 668 | r#" |
701 | enum A { | 669 | enum A { One, Two } |
702 | One, | ||
703 | Two, | ||
704 | } | ||
705 | fn foo(a: A) { | 670 | fn foo(a: A) { |
706 | match a { | 671 | match a { |
707 | // foo bar baz<|> | 672 | // foo bar baz<|> |
@@ -709,14 +674,11 @@ mod tests { | |||
709 | } | 674 | } |
710 | "#, | 675 | "#, |
711 | r#" | 676 | r#" |
712 | enum A { | 677 | enum A { One, Two } |
713 | One, | ||
714 | Two, | ||
715 | } | ||
716 | fn foo(a: A) { | 678 | fn foo(a: A) { |
717 | match <|>a { | 679 | match a { |
718 | // foo bar baz | 680 | // foo bar baz |
719 | A::One => {} | 681 | $0A::One => {} |
720 | A::Two => {} | 682 | A::Two => {} |
721 | } | 683 | } |
722 | } | 684 | } |
@@ -739,8 +701,8 @@ mod tests { | |||
739 | r#" | 701 | r#" |
740 | enum A { One, Two, } | 702 | enum A { One, Two, } |
741 | fn foo(a: A) { | 703 | fn foo(a: A) { |
742 | match <|>a { | 704 | match a { |
743 | A::One => {} | 705 | $0A::One => {} |
744 | A::Two => {} | 706 | A::Two => {} |
745 | } | 707 | } |
746 | } | 708 | } |
@@ -750,7 +712,7 @@ mod tests { | |||
750 | 712 | ||
751 | #[test] | 713 | #[test] |
752 | fn option_order() { | 714 | fn option_order() { |
753 | covers!(option_order); | 715 | mark::check!(option_order); |
754 | let before = r#" | 716 | let before = r#" |
755 | fn foo(opt: Option<i32>) { | 717 | fn foo(opt: Option<i32>) { |
756 | match opt<|> { | 718 | match opt<|> { |
@@ -764,8 +726,8 @@ fn foo(opt: Option<i32>) { | |||
764 | before, | 726 | before, |
765 | r#" | 727 | r#" |
766 | fn foo(opt: Option<i32>) { | 728 | fn foo(opt: Option<i32>) { |
767 | match <|>opt { | 729 | match opt { |
768 | Some(_) => {} | 730 | $0Some(_) => {} |
769 | None => {} | 731 | None => {} |
770 | } | 732 | } |
771 | } | 733 | } |
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..d26e68847 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 | ||
@@ -116,13 +116,12 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O | |||
116 | let replacement = if should_wrap { init_in_paren.clone() } else { init_str.clone() }; | 116 | let replacement = if should_wrap { init_in_paren.clone() } else { init_str.clone() }; |
117 | builder.replace(desc.file_range.range, replacement) | 117 | builder.replace(desc.file_range.range, replacement) |
118 | } | 118 | } |
119 | builder.set_cursor(delete_range.start()) | ||
120 | }) | 119 | }) |
121 | } | 120 | } |
122 | 121 | ||
123 | #[cfg(test)] | 122 | #[cfg(test)] |
124 | mod tests { | 123 | mod tests { |
125 | use test_utils::covers; | 124 | use test_utils::mark; |
126 | 125 | ||
127 | use crate::tests::{check_assist, check_assist_not_applicable}; | 126 | use crate::tests::{check_assist, check_assist_not_applicable}; |
128 | 127 | ||
@@ -149,7 +148,7 @@ fn foo() { | |||
149 | r" | 148 | r" |
150 | fn bar(a: usize) {} | 149 | fn bar(a: usize) {} |
151 | fn foo() { | 150 | fn foo() { |
152 | <|>1 + 1; | 151 | 1 + 1; |
153 | if 1 > 10 { | 152 | if 1 > 10 { |
154 | } | 153 | } |
155 | 154 | ||
@@ -183,7 +182,7 @@ fn foo() { | |||
183 | r" | 182 | r" |
184 | fn bar(a: usize) {} | 183 | fn bar(a: usize) {} |
185 | fn foo() { | 184 | fn foo() { |
186 | <|>(1 + 1) + 1; | 185 | (1 + 1) + 1; |
187 | if (1 + 1) > 10 { | 186 | if (1 + 1) > 10 { |
188 | } | 187 | } |
189 | 188 | ||
@@ -217,7 +216,7 @@ fn foo() { | |||
217 | r" | 216 | r" |
218 | fn bar(a: usize) {} | 217 | fn bar(a: usize) {} |
219 | fn foo() { | 218 | fn foo() { |
220 | <|>bar(1) + 1; | 219 | bar(1) + 1; |
221 | if bar(1) > 10 { | 220 | if bar(1) > 10 { |
222 | } | 221 | } |
223 | 222 | ||
@@ -251,7 +250,7 @@ fn foo() { | |||
251 | r" | 250 | r" |
252 | fn bar(a: usize): usize { a } | 251 | fn bar(a: usize): usize { a } |
253 | fn foo() { | 252 | fn foo() { |
254 | <|>(bar(1) as u64) + 1; | 253 | (bar(1) as u64) + 1; |
255 | if (bar(1) as u64) > 10 { | 254 | if (bar(1) as u64) > 10 { |
256 | } | 255 | } |
257 | 256 | ||
@@ -283,7 +282,7 @@ fn foo() { | |||
283 | }", | 282 | }", |
284 | r" | 283 | r" |
285 | fn foo() { | 284 | fn foo() { |
286 | <|>{ 10 + 1 } + 1; | 285 | { 10 + 1 } + 1; |
287 | if { 10 + 1 } > 10 { | 286 | if { 10 + 1 } > 10 { |
288 | } | 287 | } |
289 | 288 | ||
@@ -315,7 +314,7 @@ fn foo() { | |||
315 | }", | 314 | }", |
316 | r" | 315 | r" |
317 | fn foo() { | 316 | fn foo() { |
318 | <|>( 10 + 1 ) + 1; | 317 | ( 10 + 1 ) + 1; |
319 | if ( 10 + 1 ) > 10 { | 318 | if ( 10 + 1 ) > 10 { |
320 | } | 319 | } |
321 | 320 | ||
@@ -330,7 +329,7 @@ fn foo() { | |||
330 | 329 | ||
331 | #[test] | 330 | #[test] |
332 | fn test_not_inline_mut_variable() { | 331 | fn test_not_inline_mut_variable() { |
333 | covers!(test_not_inline_mut_variable); | 332 | mark::check!(test_not_inline_mut_variable); |
334 | check_assist_not_applicable( | 333 | check_assist_not_applicable( |
335 | inline_local_variable, | 334 | inline_local_variable, |
336 | r" | 335 | r" |
@@ -353,7 +352,7 @@ fn foo() { | |||
353 | }", | 352 | }", |
354 | r" | 353 | r" |
355 | fn foo() { | 354 | fn foo() { |
356 | <|>let b = bar(10 + 1) * 10; | 355 | let b = bar(10 + 1) * 10; |
357 | let c = bar(10 + 1) as usize; | 356 | let c = bar(10 + 1) as usize; |
358 | }", | 357 | }", |
359 | ); | 358 | ); |
@@ -373,7 +372,7 @@ fn foo() { | |||
373 | r" | 372 | r" |
374 | fn foo() { | 373 | fn foo() { |
375 | let x = vec![1, 2, 3]; | 374 | let x = vec![1, 2, 3]; |
376 | <|>let b = x[0] * 10; | 375 | let b = x[0] * 10; |
377 | let c = x[0] as usize; | 376 | let c = x[0] as usize; |
378 | }", | 377 | }", |
379 | ); | 378 | ); |
@@ -393,7 +392,7 @@ fn foo() { | |||
393 | r" | 392 | r" |
394 | fn foo() { | 393 | fn foo() { |
395 | let bar = vec![1]; | 394 | let bar = vec![1]; |
396 | <|>let b = bar.len() * 10; | 395 | let b = bar.len() * 10; |
397 | let c = bar.len() as usize; | 396 | let c = bar.len() as usize; |
398 | }", | 397 | }", |
399 | ); | 398 | ); |
@@ -421,7 +420,7 @@ struct Bar { | |||
421 | 420 | ||
422 | fn foo() { | 421 | fn foo() { |
423 | let bar = Bar { foo: 1 }; | 422 | let bar = Bar { foo: 1 }; |
424 | <|>let b = bar.foo * 10; | 423 | let b = bar.foo * 10; |
425 | let c = bar.foo as usize; | 424 | let c = bar.foo as usize; |
426 | }", | 425 | }", |
427 | ); | 426 | ); |
@@ -442,7 +441,7 @@ fn foo() -> Option<usize> { | |||
442 | r" | 441 | r" |
443 | fn foo() -> Option<usize> { | 442 | fn foo() -> Option<usize> { |
444 | let bar = Some(1); | 443 | let bar = Some(1); |
445 | <|>let b = bar? * 10; | 444 | let b = bar? * 10; |
446 | let c = bar? as usize; | 445 | let c = bar? as usize; |
447 | None | 446 | None |
448 | }", | 447 | }", |
@@ -462,7 +461,7 @@ fn foo() { | |||
462 | r" | 461 | r" |
463 | fn foo() { | 462 | fn foo() { |
464 | let bar = 10; | 463 | let bar = 10; |
465 | <|>let b = &bar * 10; | 464 | let b = &bar * 10; |
466 | }", | 465 | }", |
467 | ); | 466 | ); |
468 | } | 467 | } |
@@ -478,7 +477,7 @@ fn foo() { | |||
478 | }", | 477 | }", |
479 | r" | 478 | r" |
480 | fn foo() { | 479 | fn foo() { |
481 | <|>let b = (10, 20)[0]; | 480 | let b = (10, 20)[0]; |
482 | }", | 481 | }", |
483 | ); | 482 | ); |
484 | } | 483 | } |
@@ -494,7 +493,7 @@ fn foo() { | |||
494 | }", | 493 | }", |
495 | r" | 494 | r" |
496 | fn foo() { | 495 | fn foo() { |
497 | <|>let b = [1, 2, 3].len(); | 496 | let b = [1, 2, 3].len(); |
498 | }", | 497 | }", |
499 | ); | 498 | ); |
500 | } | 499 | } |
@@ -511,7 +510,7 @@ fn foo() { | |||
511 | }", | 510 | }", |
512 | r" | 511 | r" |
513 | fn foo() { | 512 | fn foo() { |
514 | <|>let b = (10 + 20) * 10; | 513 | let b = (10 + 20) * 10; |
515 | let c = (10 + 20) as usize; | 514 | let c = (10 + 20) as usize; |
516 | }", | 515 | }", |
517 | ); | 516 | ); |
@@ -531,7 +530,7 @@ fn foo() { | |||
531 | r" | 530 | r" |
532 | fn foo() { | 531 | fn foo() { |
533 | let d = 10; | 532 | let d = 10; |
534 | <|>let b = d * 10; | 533 | let b = d * 10; |
535 | let c = d as usize; | 534 | let c = d as usize; |
536 | }", | 535 | }", |
537 | ); | 536 | ); |
@@ -549,7 +548,7 @@ fn foo() { | |||
549 | }", | 548 | }", |
550 | r" | 549 | r" |
551 | fn foo() { | 550 | fn foo() { |
552 | <|>let b = { 10 } * 10; | 551 | let b = { 10 } * 10; |
553 | let c = { 10 } as usize; | 552 | let c = { 10 } as usize; |
554 | }", | 553 | }", |
555 | ); | 554 | ); |
@@ -569,7 +568,7 @@ fn foo() { | |||
569 | }", | 568 | }", |
570 | r" | 569 | r" |
571 | fn foo() { | 570 | fn foo() { |
572 | <|>let b = (10 + 20) * 10; | 571 | let b = (10 + 20) * 10; |
573 | let c = (10 + 20, 20); | 572 | let c = (10 + 20, 20); |
574 | let d = [10 + 20, 10]; | 573 | let d = [10 + 20, 10]; |
575 | let e = (10 + 20); | 574 | let e = (10 + 20); |
@@ -588,7 +587,7 @@ fn foo() { | |||
588 | }", | 587 | }", |
589 | r" | 588 | r" |
590 | fn foo() { | 589 | fn foo() { |
591 | <|>for i in vec![10, 20] {} | 590 | for i in vec![10, 20] {} |
592 | }", | 591 | }", |
593 | ); | 592 | ); |
594 | } | 593 | } |
@@ -604,7 +603,7 @@ fn foo() { | |||
604 | }", | 603 | }", |
605 | r" | 604 | r" |
606 | fn foo() { | 605 | fn foo() { |
607 | <|>while 1 > 0 {} | 606 | while 1 > 0 {} |
608 | }", | 607 | }", |
609 | ); | 608 | ); |
610 | } | 609 | } |
@@ -622,7 +621,7 @@ fn foo() { | |||
622 | }", | 621 | }", |
623 | r" | 622 | r" |
624 | fn foo() { | 623 | fn foo() { |
625 | <|>loop { | 624 | loop { |
626 | break 1 + 1; | 625 | break 1 + 1; |
627 | } | 626 | } |
628 | }", | 627 | }", |
@@ -640,7 +639,7 @@ fn foo() { | |||
640 | }", | 639 | }", |
641 | r" | 640 | r" |
642 | fn foo() { | 641 | fn foo() { |
643 | <|>return 1 > 0; | 642 | return 1 > 0; |
644 | }", | 643 | }", |
645 | ); | 644 | ); |
646 | } | 645 | } |
@@ -656,14 +655,14 @@ fn foo() { | |||
656 | }", | 655 | }", |
657 | r" | 656 | r" |
658 | fn foo() { | 657 | fn foo() { |
659 | <|>match 1 > 0 {} | 658 | match 1 > 0 {} |
660 | }", | 659 | }", |
661 | ); | 660 | ); |
662 | } | 661 | } |
663 | 662 | ||
664 | #[test] | 663 | #[test] |
665 | fn test_not_applicable_if_variable_unused() { | 664 | fn test_not_applicable_if_variable_unused() { |
666 | covers!(test_not_applicable_if_variable_unused); | 665 | mark::check!(test_not_applicable_if_variable_unused); |
667 | check_assist_not_applicable( | 666 | check_assist_not_applicable( |
668 | inline_local_variable, | 667 | inline_local_variable, |
669 | r" | 668 | r" |
@@ -676,7 +675,7 @@ fn foo() { | |||
676 | 675 | ||
677 | #[test] | 676 | #[test] |
678 | fn not_applicable_outside_of_bind_pat() { | 677 | fn not_applicable_outside_of_bind_pat() { |
679 | covers!(not_applicable_outside_of_bind_pat); | 678 | mark::check!(not_applicable_outside_of_bind_pat); |
680 | check_assist_not_applicable( | 679 | check_assist_not_applicable( |
681 | inline_local_variable, | 680 | inline_local_variable, |
682 | r" | 681 | r" |
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index fdf3ada0d..31d6539f7 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs | |||
@@ -4,10 +4,10 @@ use ra_syntax::{ | |||
4 | BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, | 4 | BLOCK_EXPR, BREAK_EXPR, COMMENT, LAMBDA_EXPR, LOOP_EXPR, MATCH_ARM, PATH_EXPR, RETURN_EXPR, |
5 | WHITESPACE, | 5 | WHITESPACE, |
6 | }, | 6 | }, |
7 | SyntaxNode, TextSize, | 7 | SyntaxNode, |
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 | ||
@@ -23,7 +23,7 @@ use crate::{AssistContext, AssistId, Assists}; | |||
23 | // -> | 23 | // -> |
24 | // ``` | 24 | // ``` |
25 | // fn main() { | 25 | // fn main() { |
26 | // let var_name = (1 + 2); | 26 | // let $0var_name = (1 + 2); |
27 | // var_name * 4; | 27 | // var_name * 4; |
28 | // } | 28 | // } |
29 | // ``` | 29 | // ``` |
@@ -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)?; |
@@ -46,14 +46,13 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
46 | acc.add(AssistId("introduce_variable"), "Extract into variable", target, move |edit| { | 46 | acc.add(AssistId("introduce_variable"), "Extract into variable", target, move |edit| { |
47 | let mut buf = String::new(); | 47 | let mut buf = String::new(); |
48 | 48 | ||
49 | let cursor_offset = if wrap_in_block { | 49 | if wrap_in_block { |
50 | buf.push_str("{ let var_name = "); | 50 | buf.push_str("{ let var_name = "); |
51 | TextSize::of("{ let ") | ||
52 | } else { | 51 | } else { |
53 | buf.push_str("let var_name = "); | 52 | buf.push_str("let var_name = "); |
54 | TextSize::of("let ") | ||
55 | }; | 53 | }; |
56 | format_to!(buf, "{}", expr.syntax()); | 54 | format_to!(buf, "{}", expr.syntax()); |
55 | |||
57 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); | 56 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); |
58 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { | 57 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { |
59 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) | 58 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) |
@@ -61,32 +60,47 @@ pub(crate) fn introduce_variable(acc: &mut Assists, ctx: &AssistContext) -> Opti | |||
61 | false | 60 | false |
62 | }; | 61 | }; |
63 | if is_full_stmt { | 62 | if is_full_stmt { |
64 | tested_by!(test_introduce_var_expr_stmt); | 63 | mark::hit!(test_introduce_var_expr_stmt); |
65 | if full_stmt.unwrap().semicolon_token().is_none() { | 64 | if full_stmt.unwrap().semicolon_token().is_none() { |
66 | buf.push_str(";"); | 65 | buf.push_str(";"); |
67 | } | 66 | } |
68 | edit.replace(expr.syntax().text_range(), buf); | 67 | let offset = expr.syntax().text_range(); |
69 | } else { | 68 | match ctx.config.snippet_cap { |
70 | buf.push_str(";"); | 69 | Some(cap) => { |
71 | 70 | let snip = buf.replace("let var_name", "let $0var_name"); | |
72 | // We want to maintain the indent level, | 71 | edit.replace_snippet(cap, offset, snip) |
73 | // but we do not want to duplicate possible | 72 | } |
74 | // extra newlines in the indent block | 73 | None => edit.replace(offset, buf), |
75 | let text = indent.text(); | ||
76 | if text.starts_with('\n') { | ||
77 | buf.push_str("\n"); | ||
78 | buf.push_str(text.trim_start_matches('\n')); | ||
79 | } else { | ||
80 | buf.push_str(text); | ||
81 | } | 74 | } |
75 | return; | ||
76 | } | ||
82 | 77 | ||
83 | edit.replace(expr.syntax().text_range(), "var_name".to_string()); | 78 | buf.push_str(";"); |
84 | edit.insert(anchor_stmt.text_range().start(), buf); | 79 | |
85 | if wrap_in_block { | 80 | // We want to maintain the indent level, |
86 | edit.insert(anchor_stmt.text_range().end(), " }"); | 81 | // but we do not want to duplicate possible |
82 | // extra newlines in the indent block | ||
83 | let text = indent.text(); | ||
84 | if text.starts_with('\n') { | ||
85 | buf.push_str("\n"); | ||
86 | buf.push_str(text.trim_start_matches('\n')); | ||
87 | } else { | ||
88 | buf.push_str(text); | ||
89 | } | ||
90 | |||
91 | edit.replace(expr.syntax().text_range(), "var_name".to_string()); | ||
92 | let offset = anchor_stmt.text_range().start(); | ||
93 | match ctx.config.snippet_cap { | ||
94 | Some(cap) => { | ||
95 | let snip = buf.replace("let var_name", "let $0var_name"); | ||
96 | edit.insert_snippet(cap, offset, snip) | ||
87 | } | 97 | } |
98 | None => edit.insert(offset, buf), | ||
99 | } | ||
100 | |||
101 | if wrap_in_block { | ||
102 | edit.insert(anchor_stmt.text_range().end(), " }"); | ||
88 | } | 103 | } |
89 | edit.set_cursor(anchor_stmt.text_range().start() + cursor_offset); | ||
90 | }) | 104 | }) |
91 | } | 105 | } |
92 | 106 | ||
@@ -113,7 +127,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { | |||
113 | expr.syntax().ancestors().find_map(|node| { | 127 | expr.syntax().ancestors().find_map(|node| { |
114 | if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { | 128 | if let Some(expr) = node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) { |
115 | if expr.syntax() == &node { | 129 | if expr.syntax() == &node { |
116 | tested_by!(test_introduce_var_last_expr); | 130 | mark::hit!(test_introduce_var_last_expr); |
117 | return Some((node, false)); | 131 | return Some((node, false)); |
118 | } | 132 | } |
119 | } | 133 | } |
@@ -134,7 +148,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> { | |||
134 | 148 | ||
135 | #[cfg(test)] | 149 | #[cfg(test)] |
136 | mod tests { | 150 | mod tests { |
137 | use test_utils::covers; | 151 | use test_utils::mark; |
138 | 152 | ||
139 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; | 153 | use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target}; |
140 | 154 | ||
@@ -144,37 +158,37 @@ mod tests { | |||
144 | fn test_introduce_var_simple() { | 158 | fn test_introduce_var_simple() { |
145 | check_assist( | 159 | check_assist( |
146 | introduce_variable, | 160 | introduce_variable, |
147 | " | 161 | r#" |
148 | fn foo() { | 162 | fn foo() { |
149 | foo(<|>1 + 1<|>); | 163 | foo(<|>1 + 1<|>); |
150 | }", | 164 | }"#, |
151 | " | 165 | r#" |
152 | fn foo() { | 166 | fn foo() { |
153 | let <|>var_name = 1 + 1; | 167 | let $0var_name = 1 + 1; |
154 | foo(var_name); | 168 | foo(var_name); |
155 | }", | 169 | }"#, |
156 | ); | 170 | ); |
157 | } | 171 | } |
158 | 172 | ||
159 | #[test] | 173 | #[test] |
160 | fn introduce_var_in_comment_is_not_applicable() { | 174 | fn introduce_var_in_comment_is_not_applicable() { |
161 | covers!(introduce_var_in_comment_is_not_applicable); | 175 | mark::check!(introduce_var_in_comment_is_not_applicable); |
162 | check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); | 176 | check_assist_not_applicable(introduce_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); |
163 | } | 177 | } |
164 | 178 | ||
165 | #[test] | 179 | #[test] |
166 | fn test_introduce_var_expr_stmt() { | 180 | fn test_introduce_var_expr_stmt() { |
167 | covers!(test_introduce_var_expr_stmt); | 181 | mark::check!(test_introduce_var_expr_stmt); |
168 | check_assist( | 182 | check_assist( |
169 | introduce_variable, | 183 | introduce_variable, |
170 | " | 184 | r#" |
171 | fn foo() { | 185 | fn foo() { |
172 | <|>1 + 1<|>; | 186 | <|>1 + 1<|>; |
173 | }", | 187 | }"#, |
174 | " | 188 | r#" |
175 | fn foo() { | 189 | fn foo() { |
176 | let <|>var_name = 1 + 1; | 190 | let $0var_name = 1 + 1; |
177 | }", | 191 | }"#, |
178 | ); | 192 | ); |
179 | check_assist( | 193 | check_assist( |
180 | introduce_variable, | 194 | introduce_variable, |
@@ -185,7 +199,7 @@ fn foo() { | |||
185 | }", | 199 | }", |
186 | " | 200 | " |
187 | fn foo() { | 201 | fn foo() { |
188 | let <|>var_name = { let x = 0; x }; | 202 | let $0var_name = { let x = 0; x }; |
189 | something_else(); | 203 | something_else(); |
190 | }", | 204 | }", |
191 | ); | 205 | ); |
@@ -201,7 +215,7 @@ fn foo() { | |||
201 | }", | 215 | }", |
202 | " | 216 | " |
203 | fn foo() { | 217 | fn foo() { |
204 | let <|>var_name = 1; | 218 | let $0var_name = 1; |
205 | var_name + 1; | 219 | var_name + 1; |
206 | }", | 220 | }", |
207 | ); | 221 | ); |
@@ -209,7 +223,7 @@ fn foo() { | |||
209 | 223 | ||
210 | #[test] | 224 | #[test] |
211 | fn test_introduce_var_last_expr() { | 225 | fn test_introduce_var_last_expr() { |
212 | covers!(test_introduce_var_last_expr); | 226 | mark::check!(test_introduce_var_last_expr); |
213 | check_assist( | 227 | check_assist( |
214 | introduce_variable, | 228 | introduce_variable, |
215 | " | 229 | " |
@@ -218,7 +232,7 @@ fn foo() { | |||
218 | }", | 232 | }", |
219 | " | 233 | " |
220 | fn foo() { | 234 | fn foo() { |
221 | let <|>var_name = 1 + 1; | 235 | let $0var_name = 1 + 1; |
222 | bar(var_name) | 236 | bar(var_name) |
223 | }", | 237 | }", |
224 | ); | 238 | ); |
@@ -230,7 +244,7 @@ fn foo() { | |||
230 | }", | 244 | }", |
231 | " | 245 | " |
232 | fn foo() { | 246 | fn foo() { |
233 | let <|>var_name = bar(1 + 1); | 247 | let $0var_name = bar(1 + 1); |
234 | var_name | 248 | var_name |
235 | }", | 249 | }", |
236 | ) | 250 | ) |
@@ -253,7 +267,7 @@ fn main() { | |||
253 | fn main() { | 267 | fn main() { |
254 | let x = true; | 268 | let x = true; |
255 | let tuple = match x { | 269 | let tuple = match x { |
256 | true => { let <|>var_name = 2 + 2; (var_name, true) } | 270 | true => { let $0var_name = 2 + 2; (var_name, true) } |
257 | _ => (0, false) | 271 | _ => (0, false) |
258 | }; | 272 | }; |
259 | } | 273 | } |
@@ -283,7 +297,7 @@ fn main() { | |||
283 | let tuple = match x { | 297 | let tuple = match x { |
284 | true => { | 298 | true => { |
285 | let y = 1; | 299 | let y = 1; |
286 | let <|>var_name = 2 + y; | 300 | let $0var_name = 2 + y; |
287 | (var_name, true) | 301 | (var_name, true) |
288 | } | 302 | } |
289 | _ => (0, false) | 303 | _ => (0, false) |
@@ -304,7 +318,7 @@ fn main() { | |||
304 | ", | 318 | ", |
305 | " | 319 | " |
306 | fn main() { | 320 | fn main() { |
307 | let lambda = |x: u32| { let <|>var_name = x * 2; var_name }; | 321 | let lambda = |x: u32| { let $0var_name = x * 2; var_name }; |
308 | } | 322 | } |
309 | ", | 323 | ", |
310 | ); | 324 | ); |
@@ -321,7 +335,7 @@ fn main() { | |||
321 | ", | 335 | ", |
322 | " | 336 | " |
323 | fn main() { | 337 | fn main() { |
324 | let lambda = |x: u32| { let <|>var_name = x * 2; var_name }; | 338 | let lambda = |x: u32| { let $0var_name = x * 2; var_name }; |
325 | } | 339 | } |
326 | ", | 340 | ", |
327 | ); | 341 | ); |
@@ -338,7 +352,7 @@ fn main() { | |||
338 | ", | 352 | ", |
339 | " | 353 | " |
340 | fn main() { | 354 | fn main() { |
341 | let <|>var_name = Some(true); | 355 | let $0var_name = Some(true); |
342 | let o = var_name; | 356 | let o = var_name; |
343 | } | 357 | } |
344 | ", | 358 | ", |
@@ -356,7 +370,7 @@ fn main() { | |||
356 | ", | 370 | ", |
357 | " | 371 | " |
358 | fn main() { | 372 | fn main() { |
359 | let <|>var_name = bar.foo(); | 373 | let $0var_name = bar.foo(); |
360 | let v = var_name; | 374 | let v = var_name; |
361 | } | 375 | } |
362 | ", | 376 | ", |
@@ -374,7 +388,7 @@ fn foo() -> u32 { | |||
374 | ", | 388 | ", |
375 | " | 389 | " |
376 | fn foo() -> u32 { | 390 | fn foo() -> u32 { |
377 | let <|>var_name = 2 + 2; | 391 | let $0var_name = 2 + 2; |
378 | return var_name; | 392 | return var_name; |
379 | } | 393 | } |
380 | ", | 394 | ", |
@@ -396,7 +410,7 @@ fn foo() -> u32 { | |||
396 | fn foo() -> u32 { | 410 | fn foo() -> u32 { |
397 | 411 | ||
398 | 412 | ||
399 | let <|>var_name = 2 + 2; | 413 | let $0var_name = 2 + 2; |
400 | return var_name; | 414 | return var_name; |
401 | } | 415 | } |
402 | ", | 416 | ", |
@@ -413,7 +427,7 @@ fn foo() -> u32 { | |||
413 | " | 427 | " |
414 | fn foo() -> u32 { | 428 | fn foo() -> u32 { |
415 | 429 | ||
416 | let <|>var_name = 2 + 2; | 430 | let $0var_name = 2 + 2; |
417 | return var_name; | 431 | return var_name; |
418 | } | 432 | } |
419 | ", | 433 | ", |
@@ -438,7 +452,7 @@ fn foo() -> u32 { | |||
438 | // bar | 452 | // bar |
439 | 453 | ||
440 | 454 | ||
441 | let <|>var_name = 2 + 2; | 455 | let $0var_name = 2 + 2; |
442 | return var_name; | 456 | return var_name; |
443 | } | 457 | } |
444 | ", | 458 | ", |
@@ -459,7 +473,7 @@ fn main() { | |||
459 | " | 473 | " |
460 | fn main() { | 474 | fn main() { |
461 | let result = loop { | 475 | let result = loop { |
462 | let <|>var_name = 2 + 2; | 476 | let $0var_name = 2 + 2; |
463 | break var_name; | 477 | break var_name; |
464 | }; | 478 | }; |
465 | } | 479 | } |
@@ -478,7 +492,7 @@ fn main() { | |||
478 | ", | 492 | ", |
479 | " | 493 | " |
480 | fn main() { | 494 | fn main() { |
481 | let <|>var_name = 0f32 as u32; | 495 | let $0var_name = 0f32 as u32; |
482 | let v = var_name; | 496 | let v = var_name; |
483 | } | 497 | } |
484 | ", | 498 | ", |
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/merge_imports.rs b/crates/ra_assists/src/handlers/merge_imports.rs index ac3e53c27..972d16241 100644 --- a/crates/ra_assists/src/handlers/merge_imports.rs +++ b/crates/ra_assists/src/handlers/merge_imports.rs | |||
@@ -58,8 +58,6 @@ pub(crate) fn merge_imports(acc: &mut Assists, ctx: &AssistContext) -> Option<() | |||
58 | let target = tree.syntax().text_range(); | 58 | let target = tree.syntax().text_range(); |
59 | acc.add(AssistId("merge_imports"), "Merge imports", target, |builder| { | 59 | acc.add(AssistId("merge_imports"), "Merge imports", target, |builder| { |
60 | builder.rewrite(rewriter); | 60 | builder.rewrite(rewriter); |
61 | // FIXME: we only need because our diff is imprecise | ||
62 | builder.set_cursor(offset); | ||
63 | }) | 61 | }) |
64 | } | 62 | } |
65 | 63 | ||
@@ -142,7 +140,7 @@ use std::fmt<|>::Debug; | |||
142 | use std::fmt::Display; | 140 | use std::fmt::Display; |
143 | ", | 141 | ", |
144 | r" | 142 | r" |
145 | use std::fmt<|>::{Debug, Display}; | 143 | use std::fmt::{Debug, Display}; |
146 | ", | 144 | ", |
147 | ) | 145 | ) |
148 | } | 146 | } |
@@ -156,7 +154,7 @@ use std::fmt::Debug; | |||
156 | use std::fmt<|>::Display; | 154 | use std::fmt<|>::Display; |
157 | ", | 155 | ", |
158 | r" | 156 | r" |
159 | use std::fmt:<|>:{Display, Debug}; | 157 | use std::fmt::{Display, Debug}; |
160 | ", | 158 | ", |
161 | ); | 159 | ); |
162 | } | 160 | } |
@@ -169,7 +167,7 @@ use std::fmt:<|>:{Display, Debug}; | |||
169 | use std::{fmt<|>::Debug, fmt::Display}; | 167 | use std::{fmt<|>::Debug, fmt::Display}; |
170 | ", | 168 | ", |
171 | r" | 169 | r" |
172 | use std::{fmt<|>::{Debug, Display}}; | 170 | use std::{fmt::{Debug, Display}}; |
173 | ", | 171 | ", |
174 | ); | 172 | ); |
175 | check_assist( | 173 | check_assist( |
@@ -178,7 +176,7 @@ use std::{fmt<|>::{Debug, Display}}; | |||
178 | use std::{fmt::Debug, fmt<|>::Display}; | 176 | use std::{fmt::Debug, fmt<|>::Display}; |
179 | ", | 177 | ", |
180 | r" | 178 | r" |
181 | use std::{fmt::<|>{Display, Debug}}; | 179 | use std::{fmt::{Display, Debug}}; |
182 | ", | 180 | ", |
183 | ); | 181 | ); |
184 | } | 182 | } |
@@ -192,7 +190,7 @@ use std<|>::cell::*; | |||
192 | use std::str; | 190 | use std::str; |
193 | ", | 191 | ", |
194 | r" | 192 | r" |
195 | use std<|>::{cell::*, str}; | 193 | use std::{cell::*, str}; |
196 | ", | 194 | ", |
197 | ) | 195 | ) |
198 | } | 196 | } |
@@ -206,7 +204,7 @@ use std<|>::cell::*; | |||
206 | use std::str::*; | 204 | use std::str::*; |
207 | ", | 205 | ", |
208 | r" | 206 | r" |
209 | use std<|>::{cell::*, str::*}; | 207 | use std::{cell::*, str::*}; |
210 | ", | 208 | ", |
211 | ) | 209 | ) |
212 | } | 210 | } |
@@ -222,7 +220,7 @@ use foo::baz; | |||
222 | /// Doc comment | 220 | /// Doc comment |
223 | ", | 221 | ", |
224 | r" | 222 | r" |
225 | use foo<|>::{bar, baz}; | 223 | use foo::{bar, baz}; |
226 | 224 | ||
227 | /// Doc comment | 225 | /// Doc comment |
228 | ", | 226 | ", |
@@ -241,7 +239,7 @@ use { | |||
241 | ", | 239 | ", |
242 | r" | 240 | r" |
243 | use { | 241 | use { |
244 | foo<|>::{bar, baz}, | 242 | foo::{bar, baz}, |
245 | }; | 243 | }; |
246 | ", | 244 | ", |
247 | ); | 245 | ); |
@@ -255,7 +253,7 @@ use { | |||
255 | ", | 253 | ", |
256 | r" | 254 | r" |
257 | use { | 255 | use { |
258 | foo::{bar<|>, baz}, | 256 | foo::{bar, baz}, |
259 | }; | 257 | }; |
260 | ", | 258 | ", |
261 | ); | 259 | ); |
@@ -272,7 +270,7 @@ use foo::<|>{ | |||
272 | }; | 270 | }; |
273 | ", | 271 | ", |
274 | r" | 272 | r" |
275 | use foo::{<|> | 273 | use foo::{ |
276 | FooBar, | 274 | FooBar, |
277 | bar::baz}; | 275 | bar::baz}; |
278 | ", | 276 | ", |
diff --git a/crates/ra_assists/src/handlers/merge_match_arms.rs b/crates/ra_assists/src/handlers/merge_match_arms.rs index d4e38aa6a..ca04ec671 100644 --- a/crates/ra_assists/src/handlers/merge_match_arms.rs +++ b/crates/ra_assists/src/handlers/merge_match_arms.rs | |||
@@ -3,7 +3,7 @@ use std::iter::successors; | |||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | algo::neighbor, | 4 | algo::neighbor, |
5 | ast::{self, AstNode}, | 5 | ast::{self, AstNode}, |
6 | Direction, TextSize, | 6 | Direction, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::{AssistContext, AssistId, Assists, TextRange}; | 9 | use crate::{AssistContext, AssistId, Assists, TextRange}; |
@@ -41,17 +41,6 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option | |||
41 | let current_expr = current_arm.expr()?; | 41 | let current_expr = current_arm.expr()?; |
42 | let current_text_range = current_arm.syntax().text_range(); | 42 | let current_text_range = current_arm.syntax().text_range(); |
43 | 43 | ||
44 | enum CursorPos { | ||
45 | InExpr(TextSize), | ||
46 | InPat(TextSize), | ||
47 | } | ||
48 | let cursor_pos = ctx.offset(); | ||
49 | let cursor_pos = if current_expr.syntax().text_range().contains(cursor_pos) { | ||
50 | CursorPos::InExpr(current_text_range.end() - cursor_pos) | ||
51 | } else { | ||
52 | CursorPos::InPat(cursor_pos) | ||
53 | }; | ||
54 | |||
55 | // We check if the following match arms match this one. We could, but don't, | 44 | // We check if the following match arms match this one. We could, but don't, |
56 | // compare to the previous match arm as well. | 45 | // compare to the previous match arm as well. |
57 | let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) | 46 | let arms_to_merge = successors(Some(current_arm), |it| neighbor(it, Direction::Next)) |
@@ -87,10 +76,6 @@ pub(crate) fn merge_match_arms(acc: &mut Assists, ctx: &AssistContext) -> Option | |||
87 | let start = arms_to_merge.first().unwrap().syntax().text_range().start(); | 76 | let start = arms_to_merge.first().unwrap().syntax().text_range().start(); |
88 | let end = arms_to_merge.last().unwrap().syntax().text_range().end(); | 77 | let end = arms_to_merge.last().unwrap().syntax().text_range().end(); |
89 | 78 | ||
90 | edit.set_cursor(match cursor_pos { | ||
91 | CursorPos::InExpr(back_offset) => start + TextSize::of(&arm) - back_offset, | ||
92 | CursorPos::InPat(offset) => offset, | ||
93 | }); | ||
94 | edit.replace(TextRange::new(start, end), arm); | 79 | edit.replace(TextRange::new(start, end), arm); |
95 | }) | 80 | }) |
96 | } | 81 | } |
@@ -132,7 +117,7 @@ mod tests { | |||
132 | fn main() { | 117 | fn main() { |
133 | let x = X::A; | 118 | let x = X::A; |
134 | let y = match x { | 119 | let y = match x { |
135 | X::A | X::B => { 1i32<|> } | 120 | X::A | X::B => { 1i32 } |
136 | X::C => { 2i32 } | 121 | X::C => { 2i32 } |
137 | } | 122 | } |
138 | } | 123 | } |
@@ -164,7 +149,7 @@ mod tests { | |||
164 | fn main() { | 149 | fn main() { |
165 | let x = X::A; | 150 | let x = X::A; |
166 | let y = match x { | 151 | let y = match x { |
167 | X::A | X::B | X::C | X::D => {<|> 1i32 }, | 152 | X::A | X::B | X::C | X::D => { 1i32 }, |
168 | X::E => { 2i32 }, | 153 | X::E => { 2i32 }, |
169 | } | 154 | } |
170 | } | 155 | } |
@@ -197,7 +182,7 @@ mod tests { | |||
197 | let x = X::A; | 182 | let x = X::A; |
198 | let y = match x { | 183 | let y = match x { |
199 | X::A => { 1i32 }, | 184 | X::A => { 1i32 }, |
200 | _ => { 2i<|>32 } | 185 | _ => { 2i32 } |
201 | } | 186 | } |
202 | } | 187 | } |
203 | "#, | 188 | "#, |
@@ -226,7 +211,7 @@ mod tests { | |||
226 | 211 | ||
227 | fn main() { | 212 | fn main() { |
228 | match X::A { | 213 | match X::A { |
229 | X::A<|> | X::B | X::C => 92, | 214 | X::A | X::B | X::C => 92, |
230 | X::D => 62, | 215 | X::D => 62, |
231 | _ => panic!(), | 216 | _ => panic!(), |
232 | } | 217 | } |
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/move_guard.rs b/crates/ra_assists/src/handlers/move_guard.rs index fc0335b57..7edcf0748 100644 --- a/crates/ra_assists/src/handlers/move_guard.rs +++ b/crates/ra_assists/src/handlers/move_guard.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | use ra_syntax::{ | 1 | use ra_syntax::{ |
2 | ast, | 2 | ast::{AstNode, IfExpr, MatchArm}, |
3 | ast::{AstNode, AstToken, IfExpr, MatchArm}, | 3 | SyntaxKind::WHITESPACE, |
4 | TextSize, | ||
5 | }; | 4 | }; |
6 | 5 | ||
7 | use crate::{AssistContext, AssistId, Assists}; | 6 | use crate::{AssistContext, AssistId, Assists}; |
@@ -42,24 +41,15 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) -> | |||
42 | 41 | ||
43 | let target = guard.syntax().text_range(); | 42 | let target = guard.syntax().text_range(); |
44 | acc.add(AssistId("move_guard_to_arm_body"), "Move guard to arm body", target, |edit| { | 43 | acc.add(AssistId("move_guard_to_arm_body"), "Move guard to arm body", target, |edit| { |
45 | let offseting_amount = match space_before_guard.and_then(|it| it.into_token()) { | 44 | match space_before_guard { |
46 | Some(tok) => { | 45 | Some(element) if element.kind() == WHITESPACE => { |
47 | if ast::Whitespace::cast(tok.clone()).is_some() { | 46 | edit.delete(element.text_range()); |
48 | let ele = tok.text_range(); | ||
49 | edit.delete(ele); | ||
50 | ele.len() | ||
51 | } else { | ||
52 | TextSize::from(0) | ||
53 | } | ||
54 | } | 47 | } |
55 | _ => TextSize::from(0), | 48 | _ => (), |
56 | }; | 49 | }; |
57 | 50 | ||
58 | edit.delete(guard.syntax().text_range()); | 51 | edit.delete(guard.syntax().text_range()); |
59 | edit.replace_node_and_indent(arm_expr.syntax(), buf); | 52 | edit.replace_node_and_indent(arm_expr.syntax(), buf); |
60 | edit.set_cursor( | ||
61 | arm_expr.syntax().text_range().start() + TextSize::from(3) - offseting_amount, | ||
62 | ); | ||
63 | }) | 53 | }) |
64 | } | 54 | } |
65 | 55 | ||
@@ -124,7 +114,6 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex | |||
124 | } | 114 | } |
125 | 115 | ||
126 | edit.insert(match_pat.syntax().text_range().end(), buf); | 116 | edit.insert(match_pat.syntax().text_range().end(), buf); |
127 | edit.set_cursor(match_pat.syntax().text_range().end() + TextSize::from(1)); | ||
128 | }, | 117 | }, |
129 | ) | 118 | ) |
130 | } | 119 | } |
@@ -172,7 +161,7 @@ mod tests { | |||
172 | let t = 'a'; | 161 | let t = 'a'; |
173 | let chars = "abcd"; |