diff options
Diffstat (limited to 'crates')
212 files changed, 4433 insertions, 3147 deletions
diff --git a/crates/assists/src/assist_config.rs b/crates/assists/src/assist_config.rs index c458d9054..4fe8ea761 100644 --- a/crates/assists/src/assist_config.rs +++ b/crates/assists/src/assist_config.rs | |||
@@ -4,8 +4,7 @@ | |||
4 | //! module, and we use to statically check that we only produce snippet | 4 | //! module, and we use to statically check that we only produce snippet |
5 | //! assists if we are allowed to. | 5 | //! assists if we are allowed to. |
6 | 6 | ||
7 | use hir::PrefixKind; | 7 | use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; |
8 | use ide_db::helpers::insert_use::MergeBehavior; | ||
9 | 8 | ||
10 | use crate::AssistKind; | 9 | use crate::AssistKind; |
11 | 10 | ||
@@ -16,35 +15,8 @@ pub struct AssistConfig { | |||
16 | pub insert_use: InsertUseConfig, | 15 | pub insert_use: InsertUseConfig, |
17 | } | 16 | } |
18 | 17 | ||
19 | impl AssistConfig { | ||
20 | pub fn allow_snippets(&mut self, yes: bool) { | ||
21 | self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } | ||
22 | } | ||
23 | } | ||
24 | |||
25 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
26 | pub struct SnippetCap { | ||
27 | _private: (), | ||
28 | } | ||
29 | |||
30 | impl Default for AssistConfig { | ||
31 | fn default() -> Self { | ||
32 | AssistConfig { | ||
33 | snippet_cap: Some(SnippetCap { _private: () }), | ||
34 | allowed: None, | ||
35 | insert_use: InsertUseConfig::default(), | ||
36 | } | ||
37 | } | ||
38 | } | ||
39 | |||
40 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | 18 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] |
41 | pub struct InsertUseConfig { | 19 | pub struct InsertUseConfig { |
42 | pub merge: Option<MergeBehavior>, | 20 | pub merge: Option<MergeBehavior>, |
43 | pub prefix_kind: PrefixKind, | 21 | pub prefix_kind: hir::PrefixKind, |
44 | } | ||
45 | |||
46 | impl Default for InsertUseConfig { | ||
47 | fn default() -> Self { | ||
48 | InsertUseConfig { merge: Some(MergeBehavior::Full), prefix_kind: PrefixKind::Plain } | ||
49 | } | ||
50 | } | 22 | } |
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 4f59d39a9..91cc63427 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs | |||
@@ -4,7 +4,10 @@ use std::mem; | |||
4 | 4 | ||
5 | use algo::find_covering_element; | 5 | use algo::find_covering_element; |
6 | use hir::Semantics; | 6 | use hir::Semantics; |
7 | use ide_db::base_db::{AnchoredPathBuf, FileId, FileRange}; | 7 | use ide_db::{ |
8 | base_db::{AnchoredPathBuf, FileId, FileRange}, | ||
9 | helpers::SnippetCap, | ||
10 | }; | ||
8 | use ide_db::{ | 11 | use ide_db::{ |
9 | label::Label, | 12 | label::Label, |
10 | source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, | 13 | source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, |
@@ -17,10 +20,7 @@ use syntax::{ | |||
17 | }; | 20 | }; |
18 | use text_edit::{TextEdit, TextEditBuilder}; | 21 | use text_edit::{TextEdit, TextEditBuilder}; |
19 | 22 | ||
20 | use crate::{ | 23 | use crate::{assist_config::AssistConfig, Assist, AssistId, AssistKind, GroupLabel}; |
21 | assist_config::{AssistConfig, SnippetCap}, | ||
22 | Assist, AssistId, AssistKind, GroupLabel, | ||
23 | }; | ||
24 | 24 | ||
25 | /// `AssistContext` allows to apply an assist or check if it could be applied. | 25 | /// `AssistContext` allows to apply an assist or check if it could be applied. |
26 | /// | 26 | /// |
diff --git a/crates/assists/src/handlers/add_explicit_type.rs b/crates/assists/src/handlers/add_explicit_type.rs index 563cbf505..cb1548cef 100644 --- a/crates/assists/src/handlers/add_explicit_type.rs +++ b/crates/assists/src/handlers/add_explicit_type.rs | |||
@@ -12,7 +12,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
12 | // | 12 | // |
13 | // ``` | 13 | // ``` |
14 | // fn main() { | 14 | // fn main() { |
15 | // let x<|> = 92; | 15 | // let x$0 = 92; |
16 | // } | 16 | // } |
17 | // ``` | 17 | // ``` |
18 | // -> | 18 | // -> |
@@ -81,21 +81,17 @@ mod tests { | |||
81 | 81 | ||
82 | #[test] | 82 | #[test] |
83 | fn add_explicit_type_target() { | 83 | fn add_explicit_type_target() { |
84 | check_assist_target(add_explicit_type, "fn f() { let a<|> = 1; }", "a"); | 84 | check_assist_target(add_explicit_type, "fn f() { let a$0 = 1; }", "a"); |
85 | } | 85 | } |
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(add_explicit_type, "fn f() { let a<|> = 1; }", "fn f() { let a: i32 = 1; }"); | 89 | check_assist(add_explicit_type, "fn f() { let a$0 = 1; }", "fn f() { let a: i32 = 1; }"); |
90 | } | 90 | } |
91 | 91 | ||
92 | #[test] | 92 | #[test] |
93 | fn add_explicit_type_works_for_underscore() { | 93 | fn add_explicit_type_works_for_underscore() { |
94 | check_assist( | 94 | check_assist(add_explicit_type, "fn f() { let a$0: _ = 1; }", "fn f() { let a: i32 = 1; }"); |
95 | add_explicit_type, | ||
96 | "fn f() { let a<|>: _ = 1; }", | ||
97 | "fn f() { let a: i32 = 1; }", | ||
98 | ); | ||
99 | } | 95 | } |
100 | 96 | ||
101 | #[test] | 97 | #[test] |
@@ -109,7 +105,7 @@ mod tests { | |||
109 | } | 105 | } |
110 | 106 | ||
111 | fn f() { | 107 | fn f() { |
112 | let a<|>: Option<_> = Option::Some(1); | 108 | let a$0: Option<_> = Option::Some(1); |
113 | }"#, | 109 | }"#, |
114 | r#" | 110 | r#" |
115 | enum Option<T> { | 111 | enum Option<T> { |
@@ -127,7 +123,7 @@ mod tests { | |||
127 | fn add_explicit_type_works_for_macro_call() { | 123 | fn add_explicit_type_works_for_macro_call() { |
128 | check_assist( | 124 | check_assist( |
129 | add_explicit_type, | 125 | add_explicit_type, |
130 | r"macro_rules! v { () => {0u64} } fn f() { let a<|> = v!(); }", | 126 | r"macro_rules! v { () => {0u64} } fn f() { let a$0 = v!(); }", |
131 | r"macro_rules! v { () => {0u64} } fn f() { let a: u64 = v!(); }", | 127 | r"macro_rules! v { () => {0u64} } fn f() { let a: u64 = v!(); }", |
132 | ); | 128 | ); |
133 | } | 129 | } |
@@ -136,31 +132,31 @@ mod tests { | |||
136 | fn add_explicit_type_works_for_macro_call_recursive() { | 132 | fn add_explicit_type_works_for_macro_call_recursive() { |
137 | check_assist( | 133 | check_assist( |
138 | add_explicit_type, | 134 | add_explicit_type, |
139 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a<|> = v!(); }"#, | 135 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a$0 = v!(); }"#, |
140 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a: u64 = v!(); }"#, | 136 | r#"macro_rules! u { () => {0u64} } macro_rules! v { () => {u!()} } fn f() { let a: u64 = v!(); }"#, |
141 | ); | 137 | ); |
142 | } | 138 | } |
143 | 139 | ||
144 | #[test] | 140 | #[test] |
145 | fn add_explicit_type_not_applicable_if_ty_not_inferred() { | 141 | fn add_explicit_type_not_applicable_if_ty_not_inferred() { |
146 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|> = None; }"); | 142 | check_assist_not_applicable(add_explicit_type, "fn f() { let a$0 = None; }"); |
147 | } | 143 | } |
148 | 144 | ||
149 | #[test] | 145 | #[test] |
150 | fn add_explicit_type_not_applicable_if_ty_already_specified() { | 146 | fn add_explicit_type_not_applicable_if_ty_already_specified() { |
151 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|>: i32 = 1; }"); | 147 | check_assist_not_applicable(add_explicit_type, "fn f() { let a$0: i32 = 1; }"); |
152 | } | 148 | } |
153 | 149 | ||
154 | #[test] | 150 | #[test] |
155 | fn add_explicit_type_not_applicable_if_specified_ty_is_tuple() { | 151 | fn add_explicit_type_not_applicable_if_specified_ty_is_tuple() { |
156 | check_assist_not_applicable(add_explicit_type, "fn f() { let a<|>: (i32, i32) = (3, 4); }"); | 152 | check_assist_not_applicable(add_explicit_type, "fn f() { let a$0: (i32, i32) = (3, 4); }"); |
157 | } | 153 | } |
158 | 154 | ||
159 | #[test] | 155 | #[test] |
160 | fn add_explicit_type_not_applicable_if_cursor_after_equals() { | 156 | fn add_explicit_type_not_applicable_if_cursor_after_equals() { |
161 | check_assist_not_applicable( | 157 | check_assist_not_applicable( |
162 | add_explicit_type, | 158 | add_explicit_type, |
163 | "fn f() {let a =<|> match 1 {2 => 3, 3 => 5};}", | 159 | "fn f() {let a =$0 match 1 {2 => 3, 3 => 5};}", |
164 | ) | 160 | ) |
165 | } | 161 | } |
166 | 162 | ||
@@ -168,7 +164,7 @@ mod tests { | |||
168 | fn add_explicit_type_not_applicable_if_cursor_before_let() { | 164 | fn add_explicit_type_not_applicable_if_cursor_before_let() { |
169 | check_assist_not_applicable( | 165 | check_assist_not_applicable( |
170 | add_explicit_type, | 166 | add_explicit_type, |
171 | "fn f() <|>{let a = match 1 {2 => 3, 3 => 5};}", | 167 | "fn f() $0{let a = match 1 {2 => 3, 3 => 5};}", |
172 | ) | 168 | ) |
173 | } | 169 | } |
174 | 170 | ||
@@ -178,7 +174,7 @@ mod tests { | |||
178 | add_explicit_type, | 174 | add_explicit_type, |
179 | r#" | 175 | r#" |
180 | fn main() { | 176 | fn main() { |
181 | let multiply_by_two<|> = |i| i * 3; | 177 | let multiply_by_two$0 = |i| i * 3; |
182 | let six = multiply_by_two(2); | 178 | let six = multiply_by_two(2); |
183 | }"#, | 179 | }"#, |
184 | ) | 180 | ) |
@@ -195,7 +191,7 @@ struct Test<K, T = u8> { | |||
195 | } | 191 | } |
196 | 192 | ||
197 | fn main() { | 193 | fn main() { |
198 | let test<|> = Test { t: 23u8, k: 33 }; | 194 | let test$0 = Test { t: 23u8, k: 33 }; |
199 | }"#, | 195 | }"#, |
200 | r#" | 196 | r#" |
201 | struct Test<K, T = u8> { | 197 | struct Test<K, T = u8> { |
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs index 7df05b841..63cea754d 100644 --- a/crates/assists/src/handlers/add_missing_impl_members.rs +++ b/crates/assists/src/handlers/add_missing_impl_members.rs | |||
@@ -20,7 +20,7 @@ use crate::{ | |||
20 | // fn bar(&self) {} | 20 | // fn bar(&self) {} |
21 | // } | 21 | // } |
22 | // | 22 | // |
23 | // impl Trait<u32> for () {<|> | 23 | // impl Trait<u32> for () {$0 |
24 | // | 24 | // |
25 | // } | 25 | // } |
26 | // ``` | 26 | // ``` |
@@ -63,7 +63,7 @@ pub(crate) fn add_missing_impl_members(acc: &mut Assists, ctx: &AssistContext) - | |||
63 | // | 63 | // |
64 | // impl Trait for () { | 64 | // impl Trait for () { |
65 | // type X = (); | 65 | // type X = (); |
66 | // fn foo(&self) {}<|> | 66 | // fn foo(&self) {}$0 |
67 | // | 67 | // |
68 | // } | 68 | // } |
69 | // ``` | 69 | // ``` |
@@ -166,7 +166,7 @@ struct S; | |||
166 | 166 | ||
167 | impl Foo for S { | 167 | impl Foo for S { |
168 | fn bar(&self) {} | 168 | fn bar(&self) {} |
169 | <|> | 169 | $0 |
170 | }"#, | 170 | }"#, |
171 | r#" | 171 | r#" |
172 | trait Foo { | 172 | trait Foo { |
@@ -214,7 +214,7 @@ struct S; | |||
214 | 214 | ||
215 | impl Foo for S { | 215 | impl Foo for S { |
216 | fn bar(&self) {} | 216 | fn bar(&self) {} |
217 | <|> | 217 | $0 |
218 | }"#, | 218 | }"#, |
219 | r#" | 219 | r#" |
220 | trait Foo { | 220 | trait Foo { |
@@ -242,7 +242,7 @@ impl Foo for S { | |||
242 | r#" | 242 | r#" |
243 | trait Foo { fn foo(&self); } | 243 | trait Foo { fn foo(&self); } |
244 | struct S; | 244 | struct S; |
245 | impl Foo for S { <|> }"#, | 245 | impl Foo for S { $0 }"#, |
246 | r#" | 246 | r#" |
247 | trait Foo { fn foo(&self); } | 247 | trait Foo { fn foo(&self); } |
248 | struct S; | 248 | struct S; |
@@ -261,7 +261,7 @@ impl Foo for S { | |||
261 | r#" | 261 | r#" |
262 | trait Foo { fn foo(&self); } | 262 | trait Foo { fn foo(&self); } |
263 | struct S; | 263 | struct S; |
264 | impl Foo for S<|>"#, | 264 | impl Foo for S$0"#, |
265 | r#" | 265 | r#" |
266 | trait Foo { fn foo(&self); } | 266 | trait Foo { fn foo(&self); } |
267 | struct S; | 267 | struct S; |
@@ -280,7 +280,7 @@ impl Foo for S { | |||
280 | r#" | 280 | r#" |
281 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 281 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
282 | struct S; | 282 | struct S; |
283 | impl Foo<u32> for S { <|> }"#, | 283 | impl Foo<u32> for S { $0 }"#, |
284 | r#" | 284 | r#" |
285 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 285 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
286 | struct S; | 286 | struct S; |
@@ -299,7 +299,7 @@ impl Foo<u32> for S { | |||
299 | r#" | 299 | r#" |
300 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 300 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
301 | struct S; | 301 | struct S; |
302 | impl<U> Foo<U> for S { <|> }"#, | 302 | impl<U> Foo<U> for S { $0 }"#, |
303 | r#" | 303 | r#" |
304 | trait Foo<T> { fn foo(&self, t: T) -> &T; } | 304 | trait Foo<T> { fn foo(&self, t: T) -> &T; } |
305 | struct S; | 305 | struct S; |
@@ -318,7 +318,7 @@ impl<U> Foo<U> for S { | |||
318 | r#" | 318 | r#" |
319 | trait Foo { fn foo(&self); } | 319 | trait Foo { fn foo(&self); } |
320 | struct S; | 320 | struct S; |
321 | impl Foo for S {}<|>"#, | 321 | impl Foo for S {}$0"#, |
322 | r#" | 322 | r#" |
323 | trait Foo { fn foo(&self); } | 323 | trait Foo { fn foo(&self); } |
324 | struct S; | 324 | struct S; |
@@ -340,7 +340,7 @@ mod foo { | |||
340 | trait Foo { fn foo(&self, bar: Bar); } | 340 | trait Foo { fn foo(&self, bar: Bar); } |
341 | } | 341 | } |
342 | struct S; | 342 | struct S; |
343 | impl foo::Foo for S { <|> }"#, | 343 | impl foo::Foo for S { $0 }"#, |
344 | r#" | 344 | r#" |
345 | mod foo { | 345 | mod foo { |
346 | pub struct Bar; | 346 | pub struct Bar; |
@@ -370,7 +370,7 @@ mod foo { | |||
370 | use foo::bar; | 370 | use foo::bar; |
371 | 371 | ||
372 | struct S; | 372 | struct S; |
373 | impl bar::Foo for S { <|> }"#, | 373 | impl bar::Foo for S { $0 }"#, |
374 | r#" | 374 | r#" |
375 | mod foo { | 375 | mod foo { |
376 | pub mod bar { | 376 | pub mod bar { |
@@ -400,7 +400,7 @@ mod foo { | |||
400 | trait Foo { fn foo(&self, bar: Bar<u32>); } | 400 | trait Foo { fn foo(&self, bar: Bar<u32>); } |
401 | } | 401 | } |
402 | struct S; | 402 | struct S; |
403 | impl foo::Foo for S { <|> }"#, | 403 | impl foo::Foo for S { $0 }"#, |
404 | r#" | 404 | r#" |
405 | mod foo { | 405 | mod foo { |
406 | pub struct Bar<T>; | 406 | pub struct Bar<T>; |
@@ -425,7 +425,7 @@ mod foo { | |||
425 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } | 425 | trait Foo<T> { fn foo(&self, bar: Bar<T>); } |
426 | } | 426 | } |
427 | struct S; | 427 | struct S; |
428 | impl foo::Foo<u32> for S { <|> }"#, | 428 | impl foo::Foo<u32> for S { $0 }"#, |
429 | r#" | 429 | r#" |
430 | mod foo { | 430 | mod foo { |
431 | pub struct Bar<T>; | 431 | pub struct Bar<T>; |
@@ -452,7 +452,7 @@ mod foo { | |||
452 | } | 452 | } |
453 | struct Param; | 453 | struct Param; |
454 | struct S; | 454 | struct S; |
455 | impl foo::Foo<Param> for S { <|> }"#, | 455 | impl foo::Foo<Param> for S { $0 }"#, |
456 | r#" | 456 | r#" |
457 | mod foo { | 457 | mod foo { |
458 | trait Foo<T> { fn foo(&self, bar: T); } | 458 | trait Foo<T> { fn foo(&self, bar: T); } |
@@ -479,7 +479,7 @@ mod foo { | |||
479 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } | 479 | trait Foo { fn foo(&self, bar: Bar<u32>::Assoc); } |
480 | } | 480 | } |
481 | struct S; | 481 | struct S; |
482 | impl foo::Foo for S { <|> }"#, | 482 | impl foo::Foo for S { $0 }"#, |
483 | r#" | 483 | r#" |
484 | mod foo { | 484 | mod foo { |
485 | pub struct Bar<T>; | 485 | pub struct Bar<T>; |
@@ -506,7 +506,7 @@ mod foo { | |||
506 | trait Foo { fn foo(&self, bar: Bar<Baz>); } | 506 | trait Foo { fn foo(&self, bar: Bar<Baz>); } |
507 | } | 507 | } |
508 | struct S; | 508 | struct S; |
509 | impl foo::Foo for S { <|> }"#, | 509 | impl foo::Foo for S { $0 }"#, |
510 | r#" | 510 | r#" |
511 | mod foo { | 511 | mod foo { |
512 | pub struct Bar<T>; | 512 | pub struct Bar<T>; |
@@ -532,7 +532,7 @@ mod foo { | |||
532 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } | 532 | trait Foo { fn foo(&self, bar: dyn Fn(u32) -> i32); } |
533 | } | 533 | } |
534 | struct S; | 534 | struct S; |
535 | impl foo::Foo for S { <|> }"#, | 535 | impl foo::Foo for S { $0 }"#, |
536 | r#" | 536 | r#" |
537 | mod foo { | 537 | mod foo { |
538 | pub trait Fn<Args> { type Output; } | 538 | pub trait Fn<Args> { type Output; } |
@@ -554,7 +554,7 @@ impl foo::Foo for S { | |||
554 | r#" | 554 | r#" |
555 | trait Foo; | 555 | trait Foo; |
556 | struct S; | 556 | struct S; |
557 | impl Foo for S { <|> }"#, | 557 | impl Foo for S { $0 }"#, |
558 | ) | 558 | ) |
559 | } | 559 | } |
560 | 560 | ||
@@ -568,7 +568,7 @@ trait Foo { | |||
568 | fn valid(some: u32) -> bool { false } | 568 | fn valid(some: u32) -> bool { false } |
569 | } | 569 | } |
570 | struct S; | 570 | struct S; |
571 | impl Foo for S { <|> }"#, | 571 | impl Foo for S { $0 }"#, |
572 | ) | 572 | ) |
573 | } | 573 | } |
574 | 574 | ||
@@ -586,7 +586,7 @@ trait Foo { | |||
586 | fn foo(&self); | 586 | fn foo(&self); |
587 | } | 587 | } |
588 | struct S; | 588 | struct S; |
589 | impl Foo for S {}<|>"#, | 589 | impl Foo for S {}$0"#, |
590 | r#" | 590 | r#" |
591 | #[doc(alias = "test alias")] | 591 | #[doc(alias = "test alias")] |
592 | trait Foo { | 592 | trait Foo { |
@@ -621,7 +621,7 @@ trait Foo { | |||
621 | fn foo(some: u32) -> bool; | 621 | fn foo(some: u32) -> bool; |
622 | } | 622 | } |
623 | struct S; | 623 | struct S; |
624 | impl Foo for S { <|> }"#, | 624 | impl Foo for S { $0 }"#, |
625 | r#" | 625 | r#" |
626 | trait Foo { | 626 | trait Foo { |
627 | type Output; | 627 | type Output; |
@@ -648,7 +648,7 @@ trait Foo<T = Self> { | |||
648 | } | 648 | } |
649 | 649 | ||
650 | struct S; | 650 | struct S; |
651 | impl Foo for S { <|> }"#, | 651 | impl Foo for S { $0 }"#, |
652 | r#" | 652 | r#" |
653 | trait Foo<T = Self> { | 653 | trait Foo<T = Self> { |
654 | fn bar(&self, other: &T); | 654 | fn bar(&self, other: &T); |
@@ -673,7 +673,7 @@ trait Foo<T1, T2 = Self> { | |||
673 | } | 673 | } |
674 | 674 | ||
675 | struct S<T>; | 675 | struct S<T>; |
676 | impl Foo<T> for S<T> { <|> }"#, | 676 | impl Foo<T> for S<T> { $0 }"#, |
677 | r#" | 677 | r#" |
678 | trait Foo<T1, T2 = Self> { | 678 | trait Foo<T1, T2 = Self> { |
679 | fn bar(&self, this: &T1, that: &T2); | 679 | fn bar(&self, this: &T1, that: &T2); |
@@ -697,7 +697,7 @@ trait Tr { | |||
697 | type Ty: Copy + 'static; | 697 | type Ty: Copy + 'static; |
698 | } | 698 | } |
699 | 699 | ||
700 | impl Tr for ()<|> { | 700 | impl Tr for ()$0 { |
701 | }"#, | 701 | }"#, |
702 | r#" | 702 | r#" |
703 | trait Tr { | 703 | trait Tr { |
@@ -719,7 +719,7 @@ trait Tr { | |||
719 | fn foo(); | 719 | fn foo(); |
720 | } | 720 | } |
721 | 721 | ||
722 | impl Tr for ()<|> { | 722 | impl Tr for ()$0 { |
723 | +++ | 723 | +++ |
724 | }"#, | 724 | }"#, |
725 | r#" | 725 | r#" |
@@ -745,7 +745,7 @@ trait Tr { | |||
745 | fn foo(); | 745 | fn foo(); |
746 | } | 746 | } |
747 | 747 | ||
748 | impl Tr for ()<|> { | 748 | impl Tr for ()$0 { |
749 | // very important | 749 | // very important |
750 | }"#, | 750 | }"#, |
751 | r#" | 751 | r#" |
@@ -771,7 +771,7 @@ trait Test { | |||
771 | fn foo(&self, x: crate) | 771 | fn foo(&self, x: crate) |
772 | } | 772 | } |
773 | impl Test for () { | 773 | impl Test for () { |
774 | <|> | 774 | $0 |
775 | } | 775 | } |
776 | "#, | 776 | "#, |
777 | r#" | 777 | r#" |
@@ -796,7 +796,7 @@ trait Foo<BAR> { | |||
796 | fn foo(&self, bar: BAR); | 796 | fn foo(&self, bar: BAR); |
797 | } | 797 | } |
798 | impl Foo for () { | 798 | impl Foo for () { |
799 | <|> | 799 | $0 |
800 | } | 800 | } |
801 | "#, | 801 | "#, |
802 | r#" | 802 | r#" |
diff --git a/crates/assists/src/handlers/add_turbo_fish.rs b/crates/assists/src/handlers/add_turbo_fish.rs index 1f486c013..8e9ea4fad 100644 --- a/crates/assists/src/handlers/add_turbo_fish.rs +++ b/crates/assists/src/handlers/add_turbo_fish.rs | |||
@@ -14,7 +14,7 @@ use crate::{ | |||
14 | // ``` | 14 | // ``` |
15 | // fn make<T>() -> T { todo!() } | 15 | // fn make<T>() -> T { todo!() } |
16 | // fn main() { | 16 | // fn main() { |
17 | // let x = make<|>(); | 17 | // let x = make$0(); |
18 | // } | 18 | // } |
19 | // ``` | 19 | // ``` |
20 | // -> | 20 | // -> |
@@ -77,7 +77,7 @@ mod tests { | |||
77 | r#" | 77 | r#" |
78 | fn make<T>() -> T {} | 78 | fn make<T>() -> T {} |
79 | fn main() { | 79 | fn main() { |
80 | make<|>(); | 80 | make$0(); |
81 | } | 81 | } |
82 | "#, | 82 | "#, |
83 | r#" | 83 | r#" |
@@ -97,7 +97,7 @@ fn main() { | |||
97 | r#" | 97 | r#" |
98 | fn make<T>() -> T {} | 98 | fn make<T>() -> T {} |
99 | fn main() { | 99 | fn main() { |
100 | make()<|>; | 100 | make()$0; |
101 | } | 101 | } |
102 | "#, | 102 | "#, |
103 | r#" | 103 | r#" |
@@ -119,7 +119,7 @@ impl S { | |||
119 | fn make<T>(&self) -> T {} | 119 | fn make<T>(&self) -> T {} |
120 | } | 120 | } |
121 | fn main() { | 121 | fn main() { |
122 | S.make<|>(); | 122 | S.make$0(); |
123 | } | 123 | } |
124 | "#, | 124 | "#, |
125 | r#" | 125 | r#" |
@@ -142,7 +142,7 @@ fn main() { | |||
142 | r#" | 142 | r#" |
143 | fn make<T>() -> T {} | 143 | fn make<T>() -> T {} |
144 | fn main() { | 144 | fn main() { |
145 | make<|>::<()>(); | 145 | make$0::<()>(); |
146 | } | 146 | } |
147 | "#, | 147 | "#, |
148 | ); | 148 | ); |
@@ -156,7 +156,7 @@ fn main() { | |||
156 | r#" | 156 | r#" |
157 | fn make() -> () {} | 157 | fn make() -> () {} |
158 | fn main() { | 158 | fn main() { |
159 | make<|>(); | 159 | make$0(); |
160 | } | 160 | } |
161 | "#, | 161 | "#, |
162 | ); | 162 | ); |
diff --git a/crates/assists/src/handlers/apply_demorgan.rs b/crates/assists/src/handlers/apply_demorgan.rs index 1a6fdafda..ed4d11455 100644 --- a/crates/assists/src/handlers/apply_demorgan.rs +++ b/crates/assists/src/handlers/apply_demorgan.rs | |||
@@ -12,7 +12,7 @@ use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKin | |||
12 | // | 12 | // |
13 | // ``` | 13 | // ``` |
14 | // fn main() { | 14 | // fn main() { |
15 | // if x != 4 ||<|> !y {} | 15 | // if x != 4 ||$0 !y {} |
16 | // } | 16 | // } |
17 | // ``` | 17 | // ``` |
18 | // -> | 18 | // -> |
@@ -68,26 +68,26 @@ mod tests { | |||
68 | 68 | ||
69 | #[test] | 69 | #[test] |
70 | fn demorgan_turns_and_into_or() { | 70 | fn demorgan_turns_and_into_or() { |
71 | check_assist(apply_demorgan, "fn f() { !x &&<|> !x }", "fn f() { !(x || x) }") | 71 | check_assist(apply_demorgan, "fn f() { !x &&$0 !x }", "fn f() { !(x || x) }") |
72 | } | 72 | } |
73 | 73 | ||
74 | #[test] | 74 | #[test] |
75 | fn demorgan_turns_or_into_and() { | 75 | fn demorgan_turns_or_into_and() { |
76 | check_assist(apply_demorgan, "fn f() { !x ||<|> !x }", "fn f() { !(x && x) }") | 76 | check_assist(apply_demorgan, "fn f() { !x ||$0 !x }", "fn f() { !(x && x) }") |
77 | } | 77 | } |
78 | 78 | ||
79 | #[test] | 79 | #[test] |
80 | fn demorgan_removes_inequality() { | 80 | fn demorgan_removes_inequality() { |
81 | check_assist(apply_demorgan, "fn f() { x != x ||<|> !x }", "fn f() { !(x == x && x) }") | 81 | check_assist(apply_demorgan, "fn f() { x != x ||$0 !x }", "fn f() { !(x == x && x) }") |
82 | } | 82 | } |
83 | 83 | ||
84 | #[test] | 84 | #[test] |
85 | fn demorgan_general_case() { | 85 | fn demorgan_general_case() { |
86 | check_assist(apply_demorgan, "fn f() { x ||<|> x }", "fn f() { !(!x && !x) }") | 86 | check_assist(apply_demorgan, "fn f() { x ||$0 x }", "fn f() { !(!x && !x) }") |
87 | } | 87 | } |
88 | 88 | ||
89 | #[test] | 89 | #[test] |
90 | fn demorgan_doesnt_apply_with_cursor_not_on_op() { | 90 | fn demorgan_doesnt_apply_with_cursor_not_on_op() { |
91 | check_assist_not_applicable(apply_demorgan, "fn f() { <|> !x || !x }") | 91 | check_assist_not_applicable(apply_demorgan, "fn f() { $0 !x || !x }") |
92 | } | 92 | } |
93 | } | 93 | } |
diff --git a/crates/assists/src/handlers/auto_import.rs b/crates/assists/src/handlers/auto_import.rs index bd5bba646..55620f0f3 100644 --- a/crates/assists/src/handlers/auto_import.rs +++ b/crates/assists/src/handlers/auto_import.rs | |||
@@ -70,7 +70,7 @@ use crate::{ | |||
70 | // | 70 | // |
71 | // ``` | 71 | // ``` |
72 | // fn main() { | 72 | // fn main() { |
73 | // let map = HashMap<|>::new(); | 73 | // let map = HashMap$0::new(); |
74 | // } | 74 | // } |
75 | // # pub mod std { pub mod collections { pub struct HashMap { } } } | 75 | // # pub mod std { pub mod collections { pub struct HashMap { } } } |
76 | // ``` | 76 | // ``` |
@@ -151,7 +151,7 @@ mod tests { | |||
151 | 151 | ||
152 | use std::fmt; | 152 | use std::fmt; |
153 | 153 | ||
154 | <|>Formatter | 154 | $0Formatter |
155 | ", | 155 | ", |
156 | r" | 156 | r" |
157 | mod std { | 157 | mod std { |
@@ -172,7 +172,7 @@ mod tests { | |||
172 | check_assist( | 172 | check_assist( |
173 | auto_import, | 173 | auto_import, |
174 | r" | 174 | r" |
175 | <|>PubStruct | 175 | $0PubStruct |
176 | 176 | ||
177 | pub mod PubMod { | 177 | pub mod PubMod { |
178 | pub struct PubStruct; | 178 | pub struct PubStruct; |
@@ -198,7 +198,7 @@ mod tests { | |||
198 | macro_rules! foo { | 198 | macro_rules! foo { |
199 | ($i:ident) => { fn foo(a: $i) {} } | 199 | ($i:ident) => { fn foo(a: $i) {} } |
200 | } | 200 | } |
201 | foo!(Pub<|>Struct); | 201 | foo!(Pub$0Struct); |
202 | 202 | ||
203 | pub mod PubMod { | 203 | pub mod PubMod { |
204 | pub struct PubStruct; | 204 | pub struct PubStruct; |
@@ -227,7 +227,7 @@ mod tests { | |||
227 | use PubMod::PubStruct1; | 227 | use PubMod::PubStruct1; |
228 | 228 | ||
229 | struct Test { | 229 | struct Test { |
230 | test: Pub<|>Struct2<u8>, | 230 | test: Pub$0Struct2<u8>, |
231 | } | 231 | } |
232 | 232 | ||
233 | pub mod PubMod { | 233 | pub mod PubMod { |
@@ -259,7 +259,7 @@ mod tests { | |||
259 | check_assist( | 259 | check_assist( |
260 | auto_import, | 260 | auto_import, |
261 | r" | 261 | r" |
262 | PubSt<|>ruct | 262 | PubSt$0ruct |
263 | 263 | ||
264 | pub mod PubMod1 { | 264 | pub mod PubMod1 { |
265 | pub struct PubStruct; | 265 | pub struct PubStruct; |
@@ -296,7 +296,7 @@ mod tests { | |||
296 | r" | 296 | r" |
297 | use PubMod::PubStruct; | 297 | use PubMod::PubStruct; |
298 | 298 | ||
299 | PubStruct<|> | 299 | PubStruct$0 |
300 | 300 | ||
301 | pub mod PubMod { | 301 | pub mod PubMod { |
302 | pub struct PubStruct; | 302 | pub struct PubStruct; |
@@ -310,7 +310,7 @@ mod tests { | |||
310 | check_assist_not_applicable( | 310 | check_assist_not_applicable( |
311 | auto_import, | 311 | auto_import, |
312 | r" | 312 | r" |
313 | PrivateStruct<|> | 313 | PrivateStruct$0 |
314 | 314 | ||
315 | pub mod PubMod { | 315 | pub mod PubMod { |
316 | struct PrivateStruct; | 316 | struct PrivateStruct; |
@@ -324,7 +324,7 @@ mod tests { | |||
324 | check_assist_not_applicable( | 324 | check_assist_not_applicable( |
325 | auto_import, | 325 | auto_import, |
326 | " | 326 | " |
327 | PubStruct<|>", | 327 | PubStruct$0", |
328 | ); | 328 | ); |
329 | } | 329 | } |
330 | 330 | ||
@@ -333,7 +333,7 @@ mod tests { | |||
333 | check_assist_not_applicable( | 333 | check_assist_not_applicable( |
334 | auto_import, | 334 | auto_import, |
335 | r" | 335 | r" |
336 | use PubStruct<|>; | 336 | use PubStruct$0; |
337 | 337 | ||
338 | pub mod PubMod { | 338 | pub mod PubMod { |
339 | pub struct PubStruct; | 339 | pub struct PubStruct; |
@@ -346,7 +346,7 @@ mod tests { | |||
346 | check_assist( | 346 | check_assist( |
347 | auto_import, | 347 | auto_import, |
348 | r" | 348 | r" |
349 | test_function<|> | 349 | test_function$0 |
350 | 350 | ||
351 | pub mod PubMod { | 351 | pub mod PubMod { |
352 | pub fn test_function() {}; | 352 | pub fn test_function() {}; |
@@ -377,7 +377,7 @@ macro_rules! foo { | |||
377 | 377 | ||
378 | //- /main.rs crate:main deps:crate_with_macro | 378 | //- /main.rs crate:main deps:crate_with_macro |
379 | fn main() { | 379 | fn main() { |
380 | foo<|> | 380 | foo$0 |
381 | } | 381 | } |
382 | ", | 382 | ", |
383 | r"use crate_with_macro::foo; | 383 | r"use crate_with_macro::foo; |
@@ -395,7 +395,7 @@ fn main() { | |||
395 | auto_import, | 395 | auto_import, |
396 | r" | 396 | r" |
397 | struct AssistInfo { | 397 | struct AssistInfo { |
398 | group_label: Option<<|>GroupLabel>, | 398 | group_label: Option<$0GroupLabel>, |
399 | } | 399 | } |
400 | 400 | ||
401 | mod m { pub struct GroupLabel; } | 401 | mod m { pub struct GroupLabel; } |
@@ -419,7 +419,7 @@ fn main() { | |||
419 | 419 | ||
420 | use mod1::mod2; | 420 | use mod1::mod2; |
421 | fn main() { | 421 | fn main() { |
422 | mod2::mod3::TestStruct<|> | 422 | mod2::mod3::TestStruct$0 |
423 | } | 423 | } |
424 | ", | 424 | ", |
425 | ); | 425 | ); |
@@ -436,7 +436,7 @@ fn main() { | |||
436 | 436 | ||
437 | use test_mod::test_function; | 437 | use test_mod::test_function; |
438 | fn main() { | 438 | fn main() { |
439 | test_function<|> | 439 | test_function$0 |
440 | } | 440 | } |
441 | ", | 441 | ", |
442 | ); | 442 | ); |
@@ -455,7 +455,7 @@ fn main() { | |||
455 | } | 455 | } |
456 | 456 | ||
457 | fn main() { | 457 | fn main() { |
458 | TestStruct::test_function<|> | 458 | TestStruct::test_function$0 |
459 | } | 459 | } |
460 | ", | 460 | ", |
461 | r" | 461 | r" |
@@ -488,7 +488,7 @@ fn main() { | |||
488 | } | 488 | } |
489 | 489 | ||
490 | fn main() { | 490 | fn main() { |
491 | TestStruct::TEST_CONST<|> | 491 | TestStruct::TEST_CONST$0 |
492 | } | 492 | } |
493 | ", | 493 | ", |
494 | r" | 494 | r" |
@@ -524,7 +524,7 @@ fn main() { | |||
524 | } | 524 | } |
525 | 525 | ||
526 | fn main() { | 526 | fn main() { |
527 | test_mod::TestStruct::test_function<|> | 527 | test_mod::TestStruct::test_function$0 |
528 | } | 528 | } |
529 | ", | 529 | ", |
530 | r" | 530 | r" |
@@ -573,7 +573,7 @@ fn main() { | |||
573 | 573 | ||
574 | use test_mod::TestTrait2; | 574 | use test_mod::TestTrait2; |
575 | fn main() { | 575 | fn main() { |
576 | test_mod::TestEnum::test_function<|>; | 576 | test_mod::TestEnum::test_function$0; |
577 | } | 577 | } |
578 | ", | 578 | ", |
579 | ) | 579 | ) |
@@ -595,7 +595,7 @@ fn main() { | |||
595 | } | 595 | } |
596 | 596 | ||
597 | fn main() { | 597 | fn main() { |
598 | test_mod::TestStruct::TEST_CONST<|> | 598 | test_mod::TestStruct::TEST_CONST$0 |
599 | } | 599 | } |
600 | ", | 600 | ", |
601 | r" | 601 | r" |
@@ -644,7 +644,7 @@ fn main() { | |||
644 | 644 | ||
645 | use test_mod::TestTrait2; | 645 | use test_mod::TestTrait2; |
646 | fn main() { | 646 | fn main() { |
647 | test_mod::TestEnum::TEST_CONST<|>; | 647 | test_mod::TestEnum::TEST_CONST$0; |
648 | } | 648 | } |
649 | ", | 649 | ", |
650 | ) | 650 | ) |
@@ -667,7 +667,7 @@ fn main() { | |||
667 | 667 | ||
668 | fn main() { | 668 | fn main() { |
669 | let test_struct = test_mod::TestStruct {}; | 669 | let test_struct = test_mod::TestStruct {}; |
670 | test_struct.test_meth<|>od() | 670 | test_struct.test_meth$0od() |
671 | } | 671 | } |
672 | ", | 672 | ", |
673 | r" | 673 | r" |
@@ -699,7 +699,7 @@ fn main() { | |||
699 | //- /main.rs crate:main deps:dep | 699 | //- /main.rs crate:main deps:dep |
700 | fn main() { | 700 | fn main() { |
701 | let test_struct = dep::test_mod::TestStruct {}; | 701 | let test_struct = dep::test_mod::TestStruct {}; |
702 | test_struct.test_meth<|>od() | 702 | test_struct.test_meth$0od() |
703 | } | 703 | } |
704 | //- /dep.rs crate:dep | 704 | //- /dep.rs crate:dep |
705 | pub mod test_mod { | 705 | pub mod test_mod { |
@@ -730,7 +730,7 @@ fn main() { | |||
730 | r" | 730 | r" |
731 | //- /main.rs crate:main deps:dep | 731 | //- /main.rs crate:main deps:dep |
732 | fn main() { | 732 | fn main() { |
733 | dep::test_mod::TestStruct::test_func<|>tion | 733 | dep::test_mod::TestStruct::test_func$0tion |
734 | } | 734 | } |
735 | //- /dep.rs crate:dep | 735 | //- /dep.rs crate:dep |
736 | pub mod test_mod { | 736 | pub mod test_mod { |
@@ -760,7 +760,7 @@ fn main() { | |||
760 | r" | 760 | r" |
761 | //- /main.rs crate:main deps:dep | 761 | //- /main.rs crate:main deps:dep |
762 | fn main() { | 762 | fn main() { |
763 | dep::test_mod::TestStruct::CONST<|> | 763 | dep::test_mod::TestStruct::CONST$0 |
764 | } | 764 | } |
765 | //- /dep.rs crate:dep | 765 | //- /dep.rs crate:dep |
766 | pub mod test_mod { | 766 | pub mod test_mod { |
@@ -791,7 +791,7 @@ fn main() { | |||
791 | //- /main.rs crate:main deps:dep | 791 | //- /main.rs crate:main deps:dep |
792 | fn main() { | 792 | fn main() { |
793 | let test_struct = dep::test_mod::TestStruct {}; | 793 | let test_struct = dep::test_mod::TestStruct {}; |
794 | test_struct.test_func<|>tion() | 794 | test_struct.test_func$0tion() |
795 | } | 795 | } |
796 | //- /dep.rs crate:dep | 796 | //- /dep.rs crate:dep |
797 | pub mod test_mod { | 797 | pub mod test_mod { |
@@ -815,7 +815,7 @@ fn main() { | |||
815 | //- /main.rs crate:main deps:dep | 815 | //- /main.rs crate:main deps:dep |
816 | fn main() { | 816 | fn main() { |
817 | let test_struct = dep::test_mod::TestStruct {}; | 817 | let test_struct = dep::test_mod::TestStruct {}; |
818 | test_struct.test_meth<|>od() | 818 | test_struct.test_meth$0od() |
819 | } | 819 | } |
820 | //- /dep.rs crate:dep | 820 | //- /dep.rs crate:dep |
821 | pub mod test_mod { | 821 | pub mod test_mod { |
@@ -858,7 +858,7 @@ fn main() { | |||
858 | use test_mod::TestTrait2; | 858 | use test_mod::TestTrait2; |
859 | fn main() { | 859 | fn main() { |
860 | let one = test_mod::TestEnum::One; | 860 | let one = test_mod::TestEnum::One; |
861 | one.test<|>_method(); | 861 | one.test$0_method(); |
862 | } | 862 | } |
863 | ", | 863 | ", |
864 | ) | 864 | ) |
@@ -874,7 +874,7 @@ pub struct Struct; | |||
874 | 874 | ||
875 | //- /main.rs crate:main deps:dep | 875 | //- /main.rs crate:main deps:dep |
876 | fn main() { | 876 | fn main() { |
877 | Struct<|> | 877 | Struct$0 |
878 | } | 878 | } |
879 | ", | 879 | ", |
880 | r"use dep::Struct; | 880 | r"use dep::Struct; |
@@ -902,7 +902,7 @@ pub fn panic_fmt() {} | |||
902 | //- /main.rs crate:main deps:dep | 902 | //- /main.rs crate:main deps:dep |
903 | struct S; | 903 | struct S; |
904 | 904 | ||
905 | impl f<|>mt::Display for S {} | 905 | impl f$0mt::Display for S {} |
906 | ", | 906 | ", |
907 | r"use dep::fmt; | 907 | r"use dep::fmt; |
908 | 908 | ||
@@ -930,7 +930,7 @@ mac!(); | |||
930 | 930 | ||
931 | //- /main.rs crate:main deps:dep | 931 | //- /main.rs crate:main deps:dep |
932 | fn main() { | 932 | fn main() { |
933 | Cheese<|>; | 933 | Cheese$0; |
934 | } | 934 | } |
935 | ", | 935 | ", |
936 | r"use dep::Cheese; | 936 | r"use dep::Cheese; |
@@ -954,7 +954,7 @@ pub struct fmt; | |||
954 | 954 | ||
955 | //- /main.rs crate:main deps:dep | 955 | //- /main.rs crate:main deps:dep |
956 | fn main() { | 956 | fn main() { |
957 | FMT<|>; | 957 | FMT$0; |
958 | } | 958 | } |
959 | ", | 959 | ", |
960 | r"use dep::FMT; | 960 | r"use dep::FMT; |
diff --git a/crates/assists/src/handlers/change_visibility.rs b/crates/assists/src/handlers/change_visibility.rs index 22d7c95d9..ac8c44124 100644 --- a/crates/assists/src/handlers/change_visibility.rs +++ b/crates/assists/src/handlers/change_visibility.rs | |||
@@ -13,7 +13,7 @@ use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists}; | |||
13 | // Adds or changes existing visibility specifier. | 13 | // Adds or changes existing visibility specifier. |
14 | // | 14 | // |
15 | // ``` | 15 | // ``` |
16 | // <|>fn frobnicate() {} | 16 | // $0fn frobnicate() {} |
17 | // ``` | 17 | // ``` |
18 | // -> | 18 | // -> |
19 | // ``` | 19 | // ``` |
@@ -118,23 +118,23 @@ mod tests { | |||
118 | 118 | ||
119 | #[test] | 119 | #[test] |
120 | fn change_visibility_adds_pub_crate_to_items() { | 120 | fn change_visibility_adds_pub_crate_to_items() { |
121 | check_assist(change_visibility, "<|>fn foo() {}", "pub(crate) fn foo() {}"); | 121 | check_assist(change_visibility, "$0fn foo() {}", "pub(crate) fn foo() {}"); |
122 | check_assist(change_visibility, "f<|>n foo() {}", "pub(crate) fn foo() {}"); | 122 | check_assist(change_visibility, "f$0n foo() {}", "pub(crate) fn foo() {}"); |
123 | check_assist(change_visibility, "<|>struct Foo {}", "pub(crate) struct Foo {}"); | 123 | check_assist(change_visibility, "$0struct Foo {}", "pub(crate) struct Foo {}"); |
124 | check_assist(change_visibility, "<|>mod foo {}", "pub(crate) mod foo {}"); | 124 | check_assist(change_visibility, "$0mod foo {}", "pub(crate) mod foo {}"); |
125 | check_assist(change_visibility, "<|>trait Foo {}", "pub(crate) trait Foo {}"); | 125 | check_assist(change_visibility, "$0trait Foo {}", "pub(crate) trait Foo {}"); |
126 | check_assist(change_visibility, "m<|>od {}", "pub(crate) mod {}"); | 126 | check_assist(change_visibility, "m$0od {}", "pub(crate) mod {}"); |
127 | check_assist(change_visibility, "unsafe f<|>n foo() {}", "pub(crate) unsafe fn foo() {}"); | 127 | check_assist(change_visibility, "unsafe f$0n foo() {}", "pub(crate) unsafe fn foo() {}"); |
128 | } | 128 | } |
129 | 129 | ||
130 | #[test] | 130 | #[test] |
131 | fn change_visibility_works_with_struct_fields() { | 131 | fn change_visibility_works_with_struct_fields() { |
132 | check_assist( | 132 | check_assist( |
133 | change_visibility, | 133 | change_visibility, |
134 | r"struct S { <|>field: u32 }", | 134 | r"struct S { $0field: u32 }", |
135 | r"struct S { pub(crate) field: u32 }", | 135 | r"struct S { pub(crate) field: u32 }", |
136 | ); | 136 | ); |
137 | check_assist(change_visibility, r"struct S ( <|>u32 )", r"struct S ( pub(crate) u32 )"); | 137 | check_assist(change_visibility, r"struct S ( $0u32 )", r"struct S ( pub(crate) u32 )"); |
138 | } | 138 | } |
139 | 139 | ||
140 | #[test] | 140 | #[test] |
@@ -142,33 +142,33 @@ mod tests { | |||
142 | mark::check!(change_visibility_field_false_positive); | 142 | mark::check!(change_visibility_field_false_positive); |
143 | check_assist_not_applicable( | 143 | check_assist_not_applicable( |
144 | change_visibility, | 144 | change_visibility, |
145 | r"struct S { field: [(); { let <|>x = ();}] }", | 145 | r"struct S { field: [(); { let $0x = ();}] }", |
146 | ) | 146 | ) |
147 | } | 147 | } |
148 | 148 | ||
149 | #[test] | 149 | #[test] |
150 | fn change_visibility_pub_to_pub_crate() { | 150 | fn change_visibility_pub_to_pub_crate() { |
151 | check_assist(change_visibility, "<|>pub fn foo() {}", "pub(crate) fn foo() {}") | 151 | check_assist(change_visibility, "$0pub fn foo() {}", "pub(crate) fn foo() {}") |
152 | } | 152 | } |
153 | 153 | ||
154 | #[test] | 154 | #[test] |
155 | fn change_visibility_pub_crate_to_pub() { | 155 | fn change_visibility_pub_crate_to_pub() { |
156 | check_assist(change_visibility, "<|>pub(crate) fn foo() {}", "pub fn foo() {}") | 156 | check_assist(change_visibility, "$0pub(crate) fn foo() {}", "pub fn foo() {}") |
157 | } | 157 | } |
158 | 158 | ||
159 | #[test] | 159 | #[test] |
160 | fn change_visibility_const() { | 160 | fn change_visibility_const() { |
161 | check_assist(change_visibility, "<|>const FOO = 3u8;", "pub(crate) const FOO = 3u8;"); | 161 | check_assist(change_visibility, "$0const FOO = 3u8;", "pub(crate) const FOO = 3u8;"); |
162 | } | 162 | } |
163 | 163 | ||
164 | #[test] | 164 | #[test] |
165 | fn change_visibility_static() { | 165 | fn change_visibility_static() { |
166 | check_assist(change_visibility, "<|>static FOO = 3u8;", "pub(crate) static FOO = 3u8;"); | 166 | check_assist(change_visibility, "$0static FOO = 3u8;", "pub(crate) static FOO = 3u8;"); |
167 | } | 167 | } |
168 | 168 | ||
169 | #[test] | 169 | #[test] |
170 | fn change_visibility_type_alias() { | 170 | fn change_visibility_type_alias() { |
171 | check_assist(change_visibility, "<|>type T = ();", "pub(crate) type T = ();"); | 171 | check_assist(change_visibility, "$0type T = ();", "pub(crate) type T = ();"); |
172 | } | 172 | } |
173 | 173 | ||
174 | #[test] | 174 | #[test] |
@@ -181,7 +181,7 @@ mod tests { | |||
181 | // comments | 181 | // comments |
182 | 182 | ||
183 | #[derive(Debug)] | 183 | #[derive(Debug)] |
184 | <|>struct Foo; | 184 | $0struct Foo; |
185 | ", | 185 | ", |
186 | r" | 186 | r" |
187 | /// docs | 187 | /// docs |
@@ -199,14 +199,14 @@ mod tests { | |||
199 | check_assist_not_applicable( | 199 | check_assist_not_applicable( |
200 | change_visibility, | 200 | change_visibility, |
201 | r"mod foo { pub enum Foo {Foo1} } | 201 | r"mod foo { pub enum Foo {Foo1} } |
202 | fn main() { foo::Foo::Foo1<|> } ", | 202 | fn main() { foo::Foo::Foo1$0 } ", |
203 | ); | 203 | ); |
204 | } | 204 | } |
205 | 205 | ||
206 | #[test] | 206 | #[test] |
207 | fn change_visibility_target() { | 207 | fn change_visibility_target() { |
208 | check_assist_target(change_visibility, "<|>fn foo() {}", "fn"); | 208 | check_assist_target(change_visibility, "$0fn foo() {}", "fn"); |
209 | check_assist_target(change_visibility, "pub(crate)<|> fn foo() {}", "pub(crate)"); | 209 | check_assist_target(change_visibility, "pub(crate)$0 fn foo() {}", "pub(crate)"); |
210 | check_assist_target(change_visibility, "struct S { <|>field: u32 }", "field"); | 210 | check_assist_target(change_visibility, "struct S { $0field: u32 }", "field"); |
211 | } | 211 | } |
212 | } | 212 | } |
diff --git a/crates/assists/src/handlers/convert_integer_literal.rs b/crates/assists/src/handlers/convert_integer_literal.rs index 667115382..a8a819cfc 100644 --- a/crates/assists/src/handlers/convert_integer_literal.rs +++ b/crates/assists/src/handlers/convert_integer_literal.rs | |||
@@ -7,7 +7,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, GroupLabel}; | |||
7 | // Converts the base of integer literals to other bases. | 7 | // Converts the base of integer literals to other bases. |
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // const _: i32 = 10<|>; | 10 | // const _: i32 = 10$0; |
11 | // ``` | 11 | // ``` |
12 | // -> | 12 | // -> |
13 | // ``` | 13 | // ``` |
@@ -65,47 +65,47 @@ mod tests { | |||
65 | 65 | ||
66 | #[test] | 66 | #[test] |
67 | fn binary_target() { | 67 | fn binary_target() { |
68 | check_assist_target(convert_integer_literal, "const _: i32 = 0b1010<|>;", "0b1010"); | 68 | check_assist_target(convert_integer_literal, "const _: i32 = 0b1010$0;", "0b1010"); |
69 | } | 69 | } |
70 | 70 | ||
71 | #[test] | 71 | #[test] |
72 | fn octal_target() { | 72 | fn octal_target() { |
73 | check_assist_target(convert_integer_literal, "const _: i32 = 0o12<|>;", "0o12"); | 73 | check_assist_target(convert_integer_literal, "const _: i32 = 0o12$0;", "0o12"); |
74 | } | 74 | } |
75 | 75 | ||
76 | #[test] | 76 | #[test] |
77 | fn decimal_target() { | 77 | fn decimal_target() { |
78 | check_assist_target(convert_integer_literal, "const _: i32 = 10<|>;", "10"); | 78 | check_assist_target(convert_integer_literal, "const _: i32 = 10$0;", "10"); |
79 | } | 79 | } |
80 | 80 | ||
81 | #[test] | 81 | #[test] |
82 | fn hexadecimal_target() { | 82 | fn hexadecimal_target() { |
83 | check_assist_target(convert_integer_literal, "const _: i32 = 0xA<|>;", "0xA"); | 83 | check_assist_target(convert_integer_literal, "const _: i32 = 0xA$0;", "0xA"); |
84 | } | 84 | } |
85 | 85 | ||
86 | #[test] | 86 | #[test] |
87 | fn binary_target_with_underscores() { | 87 | fn binary_target_with_underscores() { |
88 | check_assist_target(convert_integer_literal, "const _: i32 = 0b10_10<|>;", "0b10_10"); | 88 | check_assist_target(convert_integer_literal, "const _: i32 = 0b10_10$0;", "0b10_10"); |
89 | } | 89 | } |
90 | 90 | ||
91 | #[test] | 91 | #[test] |
92 | fn octal_target_with_underscores() { | 92 | fn octal_target_with_underscores() { |
93 | check_assist_target(convert_integer_literal, "const _: i32 = 0o1_2<|>;", "0o1_2"); | 93 | check_assist_target(convert_integer_literal, "const _: i32 = 0o1_2$0;", "0o1_2"); |
94 | } | 94 | } |
95 | 95 | ||
96 | #[test] | 96 | #[test] |
97 | fn decimal_target_with_underscores() { | 97 | fn decimal_target_with_underscores() { |
98 | check_assist_target(convert_integer_literal, "const _: i32 = 1_0<|>;", "1_0"); | 98 | check_assist_target(convert_integer_literal, "const _: i32 = 1_0$0;", "1_0"); |
99 | } | 99 | } |
100 | 100 | ||
101 | #[test] | 101 | #[test] |
102 | fn hexadecimal_target_with_underscores() { | 102 | fn hexadecimal_target_with_underscores() { |
103 | check_assist_target(convert_integer_literal, "const _: i32 = 0x_A<|>;", "0x_A"); | 103 | check_assist_target(convert_integer_literal, "const _: i32 = 0x_A$0;", "0x_A"); |
104 | } | 104 | } |
105 | 105 | ||
106 | #[test] | 106 | #[test] |
107 | fn convert_decimal_integer() { | 107 | fn convert_decimal_integer() { |
108 | let before = "const _: i32 = 1000<|>;"; | 108 | let before = "const _: i32 = 1000$0;"; |
109 | 109 | ||
110 | check_assist_by_label( | 110 | check_assist_by_label( |
111 | convert_integer_literal, | 111 | convert_integer_literal, |
@@ -131,7 +131,7 @@ mod tests { | |||
131 | 131 | ||
132 | #[test] | 132 | #[test] |
133 | fn convert_hexadecimal_integer() { | 133 | fn convert_hexadecimal_integer() { |
134 | let before = "const _: i32 = 0xFF<|>;"; | 134 | let before = "const _: i32 = 0xFF$0;"; |
135 | 135 | ||
136 | check_assist_by_label( | 136 | check_assist_by_label( |
137 | convert_integer_literal, | 137 | convert_integer_literal, |
@@ -157,7 +157,7 @@ mod tests { | |||
157 | 157 | ||
158 | #[test] | 158 | #[test] |
159 | fn convert_binary_integer() { | 159 | fn convert_binary_integer() { |
160 | let before = "const _: i32 = 0b11111111<|>;"; | 160 | let before = "const _: i32 = 0b11111111$0;"; |
161 | 161 | ||
162 | check_assist_by_label( | 162 | check_assist_by_label( |
163 | convert_integer_literal, | 163 | convert_integer_literal, |
@@ -183,7 +183,7 @@ mod tests { | |||
183 | 183 | ||
184 | #[test] | 184 | #[test] |
185 | fn convert_octal_integer() { | 185 | fn convert_octal_integer() { |
186 | let before = "const _: i32 = 0o377<|>;"; | 186 | let before = "const _: i32 = 0o377$0;"; |
187 | 187 | ||
188 | check_assist_by_label( | 188 | check_assist_by_label( |
189 | convert_integer_literal, | 189 | convert_integer_literal, |
@@ -209,7 +209,7 @@ mod tests { | |||
209 | 209 | ||
210 | #[test] | 210 | #[test] |
211 | fn convert_integer_with_underscores() { | 211 | fn convert_integer_with_underscores() { |
212 | let before = "const _: i32 = 1_00_0<|>;"; | 212 | let before = "const _: i32 = 1_00_0$0;"; |
213 | 213 | ||
214 | check_assist_by_label( | 214 | check_assist_by_label( |
215 | convert_integer_literal, | 215 | convert_integer_literal, |
@@ -235,7 +235,7 @@ mod tests { | |||
235 | 235 | ||
236 | #[test] | 236 | #[test] |
237 | fn convert_integer_with_suffix() { | 237 | fn convert_integer_with_suffix() { |
238 | let before = "const _: i32 = 1000i32<|>;"; | 238 | let before = "const _: i32 = 1000i32$0;"; |
239 | 239 | ||
240 | check_assist_by_label( | 240 | check_assist_by_label( |
241 | convert_integer_literal, | 241 | convert_integer_literal, |
@@ -262,7 +262,7 @@ mod tests { | |||
262 | #[test] | 262 | #[test] |
263 | fn convert_overflowing_literal() { | 263 | fn convert_overflowing_literal() { |
264 | let before = "const _: i32 = | 264 | let before = "const _: i32 = |
265 | 111111111111111111111111111111111111111111111111111111111111111111111111<|>;"; | 265 | 111111111111111111111111111111111111111111111111111111111111111111111111$0;"; |
266 | check_assist_not_applicable(convert_integer_literal, before); | 266 | check_assist_not_applicable(convert_integer_literal, before); |
267 | } | 267 | } |
268 | } | 268 | } |
diff --git a/crates/assists/src/handlers/early_return.rs b/crates/assists/src/handlers/early_return.rs index 7bcc318a9..8bbbb7ed5 100644 --- a/crates/assists/src/handlers/early_return.rs +++ b/crates/assists/src/handlers/early_return.rs | |||
@@ -24,7 +24,7 @@ use crate::{ | |||
24 | // | 24 | // |
25 | // ``` | 25 | // ``` |
26 | // fn main() { | 26 | // fn main() { |
27 | // <|>if cond { | 27 | // $0if cond { |
28 | // foo(); | 28 | // foo(); |
29 | // bar(); | 29 | // bar(); |
30 | // } | 30 | // } |
@@ -69,7 +69,7 @@ pub(crate) fn convert_to_guarded_return(acc: &mut Assists, ctx: &AssistContext) | |||
69 | 69 | ||
70 | let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?; | 70 | let parent_block = if_expr.syntax().parent()?.ancestors().find_map(ast::BlockExpr::cast)?; |
71 | 71 | ||
72 | if parent_block.expr()? != if_expr.clone().into() { | 72 | if parent_block.tail_expr()? != if_expr.clone().into() { |
73 | return None; | 73 | return None; |
74 | } | 74 | } |
75 | 75 | ||
@@ -200,7 +200,7 @@ mod tests { | |||
200 | r#" | 200 | r#" |
201 | fn main() { | 201 | fn main() { |
202 | bar(); | 202 | bar(); |
203 | if<|> true { | 203 | if$0 true { |
204 | foo(); | 204 | foo(); |
205 | 205 | ||
206 | //comment | 206 | //comment |
@@ -230,7 +230,7 @@ mod tests { | |||
230 | r#" | 230 | r#" |
231 | fn main(n: Option<String>) { | 231 | fn main(n: Option<String>) { |
232 | bar(); | 232 | bar(); |
233 | if<|> let Some(n) = n { | 233 | if$0 let Some(n) = n { |
234 | foo(n); | 234 | foo(n); |
235 | 235 | ||
236 | //comment | 236 | //comment |
@@ -260,7 +260,7 @@ mod tests { | |||
260 | convert_to_guarded_return, | 260 | convert_to_guarded_return, |
261 | r#" | 261 | r#" |
262 | fn main() { | 262 | fn main() { |
263 | if<|> let Ok(x) = Err(92) { | 263 | if$0 let Ok(x) = Err(92) { |
264 | foo(x); | 264 | foo(x); |
265 | } | 265 | } |
266 | } | 266 | } |
@@ -284,7 +284,7 @@ mod tests { | |||
284 | r#" | 284 | r#" |
285 | fn main(n: Option<String>) { | 285 | fn main(n: Option<String>) { |
286 | bar(); | 286 | bar(); |
287 | if<|> let Ok(n) = n { | 287 | if$0 let Ok(n) = n { |
288 | foo(n); | 288 | foo(n); |
289 | 289 | ||
290 | //comment | 290 | //comment |
@@ -315,7 +315,7 @@ mod tests { | |||
315 | r#" | 315 | r#" |
316 | fn main() { | 316 | fn main() { |
317 | while true { | 317 | while true { |
318 | if<|> true { | 318 | if$0 true { |
319 | foo(); | 319 | foo(); |
320 | bar(); | 320 | bar(); |
321 | } | 321 | } |
@@ -343,7 +343,7 @@ mod tests { | |||
343 | r#" | 343 | r#" |
344 | fn main() { | 344 | fn main() { |
345 | while true { | 345 | while true { |
346 | if<|> let Some(n) = n { | 346 | if$0 let Some(n) = n { |
347 | foo(n); | 347 | foo(n); |
348 | bar(); | 348 | bar(); |
349 | } | 349 | } |
@@ -372,7 +372,7 @@ mod tests { | |||
372 | r#" | 372 | r#" |
373 | fn main() { | 373 | fn main() { |
374 | loop { | 374 | loop { |
375 | if<|> true { | 375 | if$0 true { |
376 | foo(); | 376 | foo(); |
377 | bar(); | 377 | bar(); |
378 | } | 378 | } |
@@ -400,7 +400,7 @@ mod tests { | |||
400 | r#" | 400 | r#" |
401 | fn main() { | 401 | fn main() { |
402 | loop { | 402 | loop { |
403 | if<|> let Some(n) = n { | 403 | if$0 let Some(n) = n { |
404 | foo(n); | 404 | foo(n); |
405 | bar(); | 405 | bar(); |
406 | } | 406 | } |
@@ -428,7 +428,7 @@ mod tests { | |||
428 | convert_to_guarded_return, | 428 | convert_to_guarded_return, |
429 | r#" | 429 | r#" |
430 | fn main() { | 430 | fn main() { |
431 | if<|> true { | 431 | if$0 true { |
432 | return; | 432 | return; |
433 | } | 433 | } |
434 | } | 434 | } |
@@ -443,7 +443,7 @@ mod tests { | |||
443 | r#" | 443 | r#" |
444 | fn main() { | 444 | fn main() { |
445 | loop { | 445 | loop { |
446 | if<|> true { | 446 | if$0 true { |
447 | continue; | 447 | continue; |
448 | } | 448 | } |
449 | } | 449 | } |
@@ -458,7 +458,7 @@ mod tests { | |||
458 | convert_to_guarded_return, | 458 | convert_to_guarded_return, |
459 | r#" | 459 | r#" |
460 | fn main() { | 460 | fn main() { |
461 | if<|> true { | 461 | if$0 true { |
462 | return | 462 | return |
463 | } | 463 | } |
464 | } | 464 | } |
@@ -472,7 +472,7 @@ mod tests { | |||
472 | convert_to_guarded_return, | 472 | convert_to_guarded_return, |
473 | r#" | 473 | r#" |
474 | fn main() { | 474 | fn main() { |
475 | if<|> true { | 475 | if$0 true { |
476 | foo(); | 476 | foo(); |
477 | } else { | 477 | } else { |
478 | bar() | 478 | bar() |
@@ -488,7 +488,7 @@ mod tests { | |||
488 | convert_to_guarded_return, | 488 | convert_to_guarded_return, |
489 | r#" | 489 | r#" |
490 | fn main() { | 490 | fn main() { |
491 | if<|> true { | 491 | if$0 true { |
492 | foo(); | 492 | foo(); |
493 | } | 493 | } |
494 | bar(); | 494 | bar(); |
@@ -504,7 +504,7 @@ mod tests { | |||
504 | r#" | 504 | r#" |
505 | fn main() { | 505 | fn main() { |
506 | if false { | 506 | if false { |
507 | if<|> true { | 507 | if$0 true { |
508 | foo(); | 508 | foo(); |
509 | } | 509 | } |
510 | } | 510 | } |
diff --git a/crates/assists/src/handlers/expand_glob_import.rs b/crates/assists/src/handlers/expand_glob_import.rs index f51a9a4ad..5fe617ba4 100644 --- a/crates/assists/src/handlers/expand_glob_import.rs +++ b/crates/assists/src/handlers/expand_glob_import.rs | |||
@@ -25,7 +25,7 @@ use crate::{ | |||
25 | // pub struct Baz; | 25 | // pub struct Baz; |
26 | // } | 26 | // } |
27 | // | 27 | // |
28 | // use foo::*<|>; | 28 | // use foo::*$0; |
29 | // | 29 | // |
30 | // fn qux(bar: Bar, baz: Baz) {} | 30 | // fn qux(bar: Bar, baz: Baz) {} |
31 | // ``` | 31 | // ``` |
@@ -201,7 +201,7 @@ fn is_mod_visible_from(ctx: &AssistContext, module: Module, from: Module) -> boo | |||
201 | // } | 201 | // } |
202 | // | 202 | // |
203 | // ↓ --------------- | 203 | // ↓ --------------- |
204 | // use foo::*<|>; | 204 | // use foo::*$0; |
205 | // use baz::Baz; | 205 | // use baz::Baz; |
206 | // ↑ --------------- | 206 | // ↑ --------------- |
207 | fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>> { | 207 | fn find_imported_defs(ctx: &AssistContext, star: SyntaxToken) -> Option<Vec<Def>> { |
@@ -303,7 +303,7 @@ mod foo { | |||
303 | pub fn f() {} | 303 | pub fn f() {} |
304 | } | 304 | } |
305 | 305 | ||
306 | use foo::*<|>; | 306 | use foo::*$0; |
307 | 307 | ||
308 | fn qux(bar: Bar, baz: Baz) { | 308 | fn qux(bar: Bar, baz: Baz) { |
309 | f(); | 309 | f(); |
@@ -340,7 +340,7 @@ mod foo { | |||
340 | pub fn f() {} | 340 | pub fn f() {} |
341 | } | 341 | } |
342 | 342 | ||
343 | use foo::{*<|>, f}; | 343 | use foo::{*$0, f}; |
344 | 344 | ||
345 | fn qux(bar: Bar, baz: Baz) { | 345 | fn qux(bar: Bar, baz: Baz) { |
346 | f(); | 346 | f(); |
@@ -378,7 +378,7 @@ mod foo { | |||
378 | } | 378 | } |
379 | 379 | ||
380 | use foo::Bar; | 380 | use foo::Bar; |
381 | use foo::{*<|>, f}; | 381 | use foo::{*$0, f}; |
382 | 382 | ||
383 | fn qux(bar: Bar, baz: Baz) { | 383 | fn qux(bar: Bar, baz: Baz) { |
384 | f(); | 384 | f(); |
@@ -422,7 +422,7 @@ mod foo { | |||
422 | } | 422 | } |
423 | } | 423 | } |
424 | 424 | ||
425 | use foo::{bar::{*<|>, f}, baz::*}; | 425 | use foo::{bar::{*$0, f}, baz::*}; |
426 | 426 | ||
427 | fn qux(bar: Bar, baz: Baz) { | 427 | fn qux(bar: Bar, baz: Baz) { |
428 | f(); | 428 | f(); |
@@ -470,7 +470,7 @@ mod foo { | |||
470 | } | 470 | } |
471 | } | 471 | } |
472 | 472 | ||
473 | use foo::{bar::{Bar, Baz, f}, baz::*<|>}; | 473 | use foo::{bar::{Bar, Baz, f}, baz::*$0}; |
474 | 474 | ||
475 | fn qux(bar: Bar, baz: Baz) { | 475 | fn qux(bar: Bar, baz: Baz) { |
476 | f(); | 476 | f(); |
@@ -529,7 +529,7 @@ mod foo { | |||
529 | 529 | ||
530 | use foo::{ | 530 | use foo::{ |
531 | bar::{*, f}, | 531 | bar::{*, f}, |
532 | baz::{g, qux::*<|>} | 532 | baz::{g, qux::*$0} |
533 | }; | 533 | }; |
534 | 534 | ||
535 | fn qux(bar: Bar, baz: Baz) { | 535 | fn qux(bar: Bar, baz: Baz) { |
@@ -605,7 +605,7 @@ mod foo { | |||
605 | 605 | ||
606 | use foo::{ | 606 | use foo::{ |
607 | bar::{*, f}, | 607 | bar::{*, f}, |
608 | baz::{g, qux::{h, q::*<|>}} | 608 | baz::{g, qux::{h, q::*$0}} |
609 | }; | 609 | }; |
610 | 610 | ||
611 | fn qux(bar: Bar, baz: Baz) { | 611 | fn qux(bar: Bar, baz: Baz) { |
@@ -681,7 +681,7 @@ mod foo { | |||
681 | 681 | ||
682 | use foo::{ | 682 | use foo::{ |
683 | bar::{*, f}, | 683 | bar::{*, f}, |
684 | baz::{g, qux::{q::j, *<|>}} | 684 | baz::{g, qux::{q::j, *$0}} |
685 | }; | 685 | }; |
686 | 686 | ||
687 | fn qux(bar: Bar, baz: Baz) { | 687 | fn qux(bar: Bar, baz: Baz) { |
@@ -747,7 +747,7 @@ fn qux(bar: Bar, baz: Baz) { | |||
747 | // pub fn baz() {} | 747 | // pub fn baz() {} |
748 | 748 | ||
749 | // //- /main.rs crate:main deps:foo | 749 | // //- /main.rs crate:main deps:foo |
750 | // use foo::*<|>; | 750 | // use foo::*$0; |
751 | 751 | ||
752 | // fn main() { | 752 | // fn main() { |
753 | // bar!(); | 753 | // bar!(); |
@@ -777,7 +777,7 @@ pub trait Tr { | |||
777 | impl Tr for () {} | 777 | impl Tr for () {} |
778 | 778 | ||
779 | //- /main.rs crate:main deps:foo | 779 | //- /main.rs crate:main deps:foo |
780 | use foo::*<|>; | 780 | use foo::*$0; |
781 | 781 | ||
782 | fn main() { | 782 | fn main() { |
783 | ().method(); | 783 | ().method(); |
@@ -807,7 +807,7 @@ pub trait Tr2 { | |||
807 | impl Tr2 for () {} | 807 | impl Tr2 for () {} |
808 | 808 | ||
809 | //- /main.rs crate:main deps:foo | 809 | //- /main.rs crate:main deps:foo |
810 | use foo::*<|>; | 810 | use foo::*$0; |
811 | 811 | ||
812 | fn main() { | 812 | fn main() { |
813 | ().method(); | 813 | ().method(); |
@@ -834,7 +834,7 @@ mod foo { | |||
834 | } | 834 | } |
835 | } | 835 | } |
836 | 836 | ||
837 | use foo::bar::*<|>; | 837 | use foo::bar::*$0; |
838 | 838 | ||
839 | fn baz(bar: Bar) {} | 839 | fn baz(bar: Bar) {} |
840 | ", | 840 | ", |
@@ -851,7 +851,7 @@ mod foo { | |||
851 | } | 851 | } |
852 | } | 852 | } |
853 | 853 | ||
854 | use foo::bar::baz::*<|>; | 854 | use foo::bar::baz::*$0; |
855 | 855 | ||
856 | fn qux(baz: Baz) {} | 856 | fn qux(baz: Baz) {} |
857 | ", | 857 | ", |
@@ -869,7 +869,7 @@ fn qux(baz: Baz) {} | |||
869 | pub struct Qux; | 869 | pub struct Qux; |
870 | } | 870 | } |
871 | 871 | ||
872 | use foo::Bar<|>; | 872 | use foo::Bar$0; |
873 | 873 | ||
874 | fn qux(bar: Bar, baz: Baz) {} | 874 | fn qux(bar: Bar, baz: Baz) {} |
875 | ", | 875 | ", |
@@ -885,7 +885,7 @@ mod foo { | |||
885 | pub struct Bar; | 885 | pub struct Bar; |
886 | } | 886 | } |
887 | 887 | ||
888 | use foo::{*<|>}; | 888 | use foo::{*$0}; |
889 | 889 | ||
890 | struct Baz { | 890 | struct Baz { |
891 | bar: Bar | 891 | bar: Bar |
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs index 030b9cd0c..40028fc01 100644 --- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs +++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs | |||
@@ -21,7 +21,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
21 | // Extracts a struct from enum variant. | 21 | // Extracts a struct from enum variant. |
22 | // | 22 | // |
23 | // ``` | 23 | // ``` |
24 | // enum A { <|>One(u32, u32) } | 24 | // enum A { $0One(u32, u32) } |
25 | // ``` | 25 | // ``` |
26 | // -> | 26 | // -> |
27 | // ``` | 27 | // ``` |
@@ -117,10 +117,14 @@ fn existing_definition(db: &RootDatabase, variant_name: &ast::Name, variant: &Va | |||
117 | .into_iter() | 117 | .into_iter() |
118 | .filter(|(_, def)| match def { | 118 | .filter(|(_, def)| match def { |
119 | // only check type-namespace | 119 | // only check type-namespace |
120 | hir::ScopeDef::ModuleDef(def) => matches!(def, | 120 | hir::ScopeDef::ModuleDef(def) => matches!( |
121 | ModuleDef::Module(_) | ModuleDef::Adt(_) | | 121 | def, |
122 | ModuleDef::Variant(_) | ModuleDef::Trait(_) | | 122 | ModuleDef::Module(_) |
123 | ModuleDef::TypeAlias(_) | ModuleDef::BuiltinType(_) | 123 | | ModuleDef::Adt(_) |
124 | | ModuleDef::Variant(_) | ||
125 | | ModuleDef::Trait(_) | ||
126 | | ModuleDef::TypeAlias(_) | ||
127 | | ModuleDef::BuiltinType(_) | ||
124 | ), | 128 | ), |
125 | _ => false, | 129 | _ => false, |
126 | }) | 130 | }) |
@@ -247,7 +251,7 @@ mod tests { | |||
247 | fn test_extract_struct_several_fields_tuple() { | 251 | fn test_extract_struct_several_fields_tuple() { |
248 | check_assist( | 252 | check_assist( |
249 | extract_struct_from_enum_variant, | 253 | extract_struct_from_enum_variant, |
250 | "enum A { <|>One(u32, u32) }", | 254 | "enum A { $0One(u32, u32) }", |
251 | r#"struct One(pub u32, pub u32); | 255 | r#"struct One(pub u32, pub u32); |
252 | 256 | ||
253 | enum A { One(One) }"#, | 257 | enum A { One(One) }"#, |
@@ -258,7 +262,7 @@ enum A { One(One) }"#, | |||
258 | fn test_extract_struct_several_fields_named() { | 262 | fn test_extract_struct_several_fields_named() { |
259 | check_assist( | 263 | check_assist( |
260 | extract_struct_from_enum_variant, | 264 | extract_struct_from_enum_variant, |
261 | "enum A { <|>One { foo: u32, bar: u32 } }", | 265 | "enum A { $0One { foo: u32, bar: u32 } }", |
262 | r#"struct One{ pub foo: u32, pub bar: u32 } | 266 | r#"struct One{ pub foo: u32, pub bar: u32 } |
263 | 267 | ||
264 | enum A { One(One) }"#, | 268 | enum A { One(One) }"#, |
@@ -269,7 +273,7 @@ enum A { One(One) }"#, | |||
269 | fn test_extract_struct_one_field_named() { | 273 | fn test_extract_struct_one_field_named() { |
270 | check_assist( | 274 | check_assist( |
271 | extract_struct_from_enum_variant, | 275 | extract_struct_from_enum_variant, |
272 | "enum A { <|>One { foo: u32 } }", | 276 | "enum A { $0One { foo: u32 } }", |
273 | r#"struct One{ pub foo: u32 } | 277 | r#"struct One{ pub foo: u32 } |
274 | 278 | ||
275 | enum A { One(One) }"#, | 279 | enum A { One(One) }"#, |
@@ -281,7 +285,7 @@ enum A { One(One) }"#, | |||
281 | check_assist( | 285 | check_assist( |
282 | extract_struct_from_enum_variant, | 286 | extract_struct_from_enum_variant, |
283 | r#"const One: () = (); | 287 | r#"const One: () = (); |
284 | enum A { <|>One(u32, u32) }"#, | 288 | enum A { $0One(u32, u32) }"#, |
285 | r#"const One: () = (); | 289 | r#"const One: () = (); |
286 | struct One(pub u32, pub u32); | 290 | struct One(pub u32, pub u32); |
287 | 291 | ||
@@ -293,7 +297,7 @@ enum A { One(One) }"#, | |||
293 | fn test_extract_struct_pub_visibility() { | 297 | fn test_extract_struct_pub_visibility() { |
294 | check_assist( | 298 | check_assist( |
295 | extract_struct_from_enum_variant, | 299 | extract_struct_from_enum_variant, |
296 | "pub enum A { <|>One(u32, u32) }", | 300 | "pub enum A { $0One(u32, u32) }", |
297 | r#"pub struct One(pub u32, pub u32); | 301 | r#"pub struct One(pub u32, pub u32); |
298 | 302 | ||
299 | pub enum A { One(One) }"#, | 303 | pub enum A { One(One) }"#, |
@@ -315,7 +319,7 @@ pub enum A { One(One) }"#, | |||
315 | } | 319 | } |
316 | 320 | ||
317 | pub enum MyEnum { | 321 | pub enum MyEnum { |
318 | <|>MyField(u8, u8), | 322 | $0MyField(u8, u8), |
319 | } | 323 | } |
320 | } | 324 | } |
321 | } | 325 | } |
@@ -357,7 +361,7 @@ fn another_fn() { | |||
357 | extract_struct_from_enum_variant, | 361 | extract_struct_from_enum_variant, |
358 | r#" | 362 | r#" |
359 | enum E { | 363 | enum E { |
360 | <|>V { i: i32, j: i32 } | 364 | $0V { i: i32, j: i32 } |
361 | } | 365 | } |
362 | 366 | ||
363 | fn f() { | 367 | fn f() { |
@@ -385,7 +389,7 @@ fn f() { | |||
385 | r#" | 389 | r#" |
386 | //- /main.rs | 390 | //- /main.rs |
387 | enum E { | 391 | enum E { |
388 | <|>V(i32, i32) | 392 | $0V(i32, i32) |
389 | } | 393 | } |
390 | mod foo; | 394 | mod foo; |
391 | 395 | ||
@@ -420,7 +424,7 @@ fn f() { | |||
420 | r#" | 424 | r#" |
421 | //- /main.rs | 425 | //- /main.rs |
422 | enum E { | 426 | enum E { |
423 | <|>V { i: i32, j: i32 } | 427 | $0V { i: i32, j: i32 } |
424 | } | 428 | } |
425 | mod foo; | 429 | mod foo; |
426 | 430 | ||
@@ -453,7 +457,7 @@ fn f() { | |||
453 | check_assist( | 457 | check_assist( |
454 | extract_struct_from_enum_variant, | 458 | extract_struct_from_enum_variant, |
455 | r#" | 459 | r#" |
456 | enum A { <|>One { a: u32, b: u32 } } | 460 | enum A { $0One { a: u32, b: u32 } } |
457 | 461 | ||
458 | struct B(A); | 462 | struct B(A); |
459 | 463 | ||
@@ -483,29 +487,29 @@ fn foo() { | |||
483 | 487 | ||
484 | #[test] | 488 | #[test] |
485 | fn test_extract_enum_not_applicable_for_element_with_no_fields() { | 489 | fn test_extract_enum_not_applicable_for_element_with_no_fields() { |
486 | check_not_applicable("enum A { <|>One }"); | 490 | check_not_applicable("enum A { $0One }"); |
487 | } | 491 | } |
488 | 492 | ||
489 | #[test] | 493 | #[test] |
490 | fn test_extract_enum_not_applicable_if_struct_exists() { | 494 | fn test_extract_enum_not_applicable_if_struct_exists() { |
491 | check_not_applicable( | 495 | check_not_applicable( |
492 | r#"struct One; | 496 | r#"struct One; |
493 | enum A { <|>One(u8, u32) }"#, | 497 | enum A { $0One(u8, u32) }"#, |
494 | ); | 498 | ); |
495 | } | 499 | } |
496 | 500 | ||
497 | #[test] | 501 | #[test] |
498 | fn test_extract_not_applicable_one_field() { | 502 | fn test_extract_not_applicable_one_field() { |
499 | check_not_applicable(r"enum A { <|>One(u32) }"); | 503 | check_not_applicable(r"enum A { $0One(u32) }"); |
500 | } | 504 | } |
501 | 505 | ||
502 | #[test] | 506 | #[test] |
503 | fn test_extract_not_applicable_no_field_tuple() { | 507 | fn test_extract_not_applicable_no_field_tuple() { |
504 | check_not_applicable(r"enum A { <|>None() }"); | 508 | check_not_applicable(r"enum A { $0None() }"); |
505 | } | 509 | } |
506 | 510 | ||
507 | #[test] | 511 | #[test] |
508 | fn test_extract_not_applicable_no_field_named() { | 512 | fn test_extract_not_applicable_no_field_named() { |
509 | check_not_applicable(r"enum A { <|>None {} }"); | 513 | check_not_applicable(r"enum A { $0None {} }"); |
510 | } | 514 | } |
511 | } | 515 | } |
diff --git a/crates/assists/src/handlers/extract_variable.rs b/crates/assists/src/handlers/extract_variable.rs index 9957012fe..98f3dc6ca 100644 --- a/crates/assists/src/handlers/extract_variable.rs +++ b/crates/assists/src/handlers/extract_variable.rs | |||
@@ -16,7 +16,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
16 | // | 16 | // |
17 | // ``` | 17 | // ``` |
18 | // fn main() { | 18 | // fn main() { |
19 | // <|>(1 + 2)<|> * 4; | 19 | // $0(1 + 2)$0 * 4; |
20 | // } | 20 | // } |
21 | // ``` | 21 | // ``` |
22 | // -> | 22 | // -> |
@@ -139,7 +139,7 @@ impl Anchor { | |||
139 | fn from(to_extract: &ast::Expr) -> Option<Anchor> { | 139 | fn from(to_extract: &ast::Expr) -> Option<Anchor> { |
140 | to_extract.syntax().ancestors().find_map(|node| { | 140 | to_extract.syntax().ancestors().find_map(|node| { |
141 | if let Some(expr) = | 141 | if let Some(expr) = |
142 | node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.expr()) | 142 | node.parent().and_then(ast::BlockExpr::cast).and_then(|it| it.tail_expr()) |
143 | { | 143 | { |
144 | if expr.syntax() == &node { | 144 | if expr.syntax() == &node { |
145 | mark::hit!(test_extract_var_last_expr); | 145 | mark::hit!(test_extract_var_last_expr); |
@@ -187,7 +187,7 @@ mod tests { | |||
187 | extract_variable, | 187 | extract_variable, |
188 | r#" | 188 | r#" |
189 | fn foo() { | 189 | fn foo() { |
190 | foo(<|>1 + 1<|>); | 190 | foo($01 + 1$0); |
191 | }"#, | 191 | }"#, |
192 | r#" | 192 | r#" |
193 | fn foo() { | 193 | fn foo() { |
@@ -200,7 +200,7 @@ fn foo() { | |||
200 | #[test] | 200 | #[test] |
201 | fn extract_var_in_comment_is_not_applicable() { | 201 | fn extract_var_in_comment_is_not_applicable() { |
202 | mark::check!(extract_var_in_comment_is_not_applicable); | 202 | mark::check!(extract_var_in_comment_is_not_applicable); |
203 | check_assist_not_applicable(extract_variable, "fn main() { 1 + /* <|>comment<|> */ 1; }"); | 203 | check_assist_not_applicable(extract_variable, "fn main() { 1 + /* $0comment$0 */ 1; }"); |
204 | } | 204 | } |
205 | 205 | ||
206 | #[test] | 206 | #[test] |
@@ -210,7 +210,7 @@ fn foo() { | |||
210 | extract_variable, | 210 | extract_variable, |
211 | r#" | 211 | r#" |
212 | fn foo() { | 212 | fn foo() { |
213 | <|>1 + 1<|>; | 213 | $01 + 1$0; |
214 | }"#, | 214 | }"#, |
215 | r#" | 215 | r#" |
216 | fn foo() { | 216 | fn foo() { |
@@ -221,7 +221,7 @@ fn foo() { | |||
221 | extract_variable, | 221 | extract_variable, |
222 | " | 222 | " |
223 | fn foo() { | 223 | fn foo() { |
224 | <|>{ let x = 0; x }<|> | 224 | $0{ let x = 0; x }$0 |
225 | something_else(); | 225 | something_else(); |
226 | }", | 226 | }", |
227 | " | 227 | " |
@@ -238,7 +238,7 @@ fn foo() { | |||
238 | extract_variable, | 238 | extract_variable, |
239 | " | 239 | " |
240 | fn foo() { | 240 | fn foo() { |
241 | <|>1<|> + 1; | 241 | $01$0 + 1; |
242 | }", | 242 | }", |
243 | " | 243 | " |
244 | fn foo() { | 244 | fn foo() { |
@@ -255,7 +255,7 @@ fn foo() { | |||
255 | extract_variable, | 255 | extract_variable, |
256 | r#" | 256 | r#" |
257 | fn foo() { | 257 | fn foo() { |
258 | bar(<|>1 + 1<|>) | 258 | bar($01 + 1$0) |
259 | } | 259 | } |
260 | "#, | 260 | "#, |
261 | r#" | 261 | r#" |
@@ -269,7 +269,7 @@ fn foo() { | |||
269 | extract_variable, | 269 | extract_variable, |
270 | r#" | 270 | r#" |
271 | fn foo() { | 271 | fn foo() { |
272 | <|>bar(1 + 1)<|> | 272 | $0bar(1 + 1)$0 |
273 | } | 273 | } |
274 | "#, | 274 | "#, |
275 | r#" | 275 | r#" |
@@ -289,7 +289,7 @@ fn foo() { | |||
289 | fn main() { | 289 | fn main() { |
290 | let x = true; | 290 | let x = true; |
291 | let tuple = match x { | 291 | let tuple = match x { |
292 | true => (<|>2 + 2<|>, true) | 292 | true => ($02 + 2$0, true) |
293 | _ => (0, false) | 293 | _ => (0, false) |
294 | }; | 294 | }; |
295 | } | 295 | } |
@@ -316,7 +316,7 @@ fn main() { | |||
316 | let tuple = match x { | 316 | let tuple = match x { |
317 | true => { | 317 | true => { |
318 | let y = 1; | 318 | let y = 1; |
319 | (<|>2 + y<|>, true) | 319 | ($02 + y$0, true) |
320 | } | 320 | } |
321 | _ => (0, false) | 321 | _ => (0, false) |
322 | }; | 322 | }; |
@@ -344,7 +344,7 @@ fn main() { | |||
344 | extract_variable, | 344 | extract_variable, |
345 | " | 345 | " |
346 | fn main() { | 346 | fn main() { |
347 | let lambda = |x: u32| <|>x * 2<|>; | 347 | let lambda = |x: u32| $0x * 2$0; |
348 | } | 348 | } |
349 | ", | 349 | ", |
350 | " | 350 | " |
@@ -361,7 +361,7 @@ fn main() { | |||
361 | extract_variable, | 361 | extract_variable, |
362 | " | 362 | " |
363 | fn main() { | 363 | fn main() { |
364 | let lambda = |x: u32| { <|>x * 2<|> }; | 364 | let lambda = |x: u32| { $0x * 2$0 }; |
365 | } | 365 | } |
366 | ", | 366 | ", |
367 | " | 367 | " |
@@ -378,7 +378,7 @@ fn main() { | |||
378 | extract_variable, | 378 | extract_variable, |
379 | " | 379 | " |
380 | fn main() { | 380 | fn main() { |
381 | let o = <|>Some(true)<|>; | 381 | let o = $0Some(true)$0; |
382 | } | 382 | } |
383 | ", | 383 | ", |
384 | " | 384 | " |
@@ -396,7 +396,7 @@ fn main() { | |||
396 | extract_variable, | 396 | extract_variable, |
397 | " | 397 | " |
398 | fn main() { | 398 | fn main() { |
399 | let v = <|>bar.foo()<|>; | 399 | let v = $0bar.foo()$0; |
400 | } | 400 | } |
401 | ", | 401 | ", |
402 | " | 402 | " |
@@ -414,7 +414,7 @@ fn main() { | |||
414 | extract_variable, | 414 | extract_variable, |
415 | " | 415 | " |
416 | fn foo() -> u32 { | 416 | fn foo() -> u32 { |
417 | <|>return 2 + 2<|>; | 417 | $0return 2 + 2$0; |
418 | } | 418 | } |
419 | ", | 419 | ", |
420 | " | 420 | " |
@@ -434,7 +434,7 @@ fn foo() -> u32 { | |||
434 | fn foo() -> u32 { | 434 | fn foo() -> u32 { |
435 | 435 | ||
436 | 436 | ||
437 | <|>return 2 + 2<|>; | 437 | $0return 2 + 2$0; |
438 | } | 438 | } |
439 | ", | 439 | ", |
440 | " | 440 | " |
@@ -452,7 +452,7 @@ fn foo() -> u32 { | |||
452 | " | 452 | " |
453 | fn foo() -> u32 { | 453 | fn foo() -> u32 { |
454 | 454 | ||
455 | <|>return 2 + 2<|>; | 455 | $0return 2 + 2$0; |
456 | } | 456 | } |
457 | ", | 457 | ", |
458 | " | 458 | " |
@@ -473,7 +473,7 @@ fn foo() -> u32 { | |||
473 | // bar | 473 | // bar |
474 | 474 | ||
475 | 475 | ||
476 | <|>return 2 + 2<|>; | 476 | $0return 2 + 2$0; |
477 | } | 477 | } |
478 | ", | 478 | ", |
479 | " | 479 | " |
@@ -497,7 +497,7 @@ fn foo() -> u32 { | |||
497 | " | 497 | " |
498 | fn main() { | 498 | fn main() { |
499 | let result = loop { | 499 | let result = loop { |
500 | <|>break 2 + 2<|>; | 500 | $0break 2 + 2$0; |
501 | }; | 501 | }; |
502 | } | 502 | } |
503 | ", | 503 | ", |
@@ -518,7 +518,7 @@ fn main() { | |||
518 | extract_variable, | 518 | extract_variable, |
519 | " | 519 | " |
520 | fn main() { | 520 | fn main() { |
521 | let v = <|>0f32 as u32<|>; | 521 | let v = $00f32 as u32$0; |
522 | } | 522 | } |
523 | ", | 523 | ", |
524 | " | 524 | " |
@@ -540,7 +540,7 @@ struct S { | |||
540 | } | 540 | } |
541 | 541 | ||
542 | fn main() { | 542 | fn main() { |
543 | S { foo: <|>1 + 1<|> } | 543 | S { foo: $01 + 1$0 } |
544 | } | 544 | } |
545 | "#, | 545 | "#, |
546 | r#" | 546 | r#" |
@@ -558,18 +558,18 @@ fn main() { | |||
558 | 558 | ||
559 | #[test] | 559 | #[test] |
560 | fn test_extract_var_for_return_not_applicable() { | 560 | fn test_extract_var_for_return_not_applicable() { |
561 | check_assist_not_applicable(extract_variable, "fn foo() { <|>return<|>; } "); | 561 | check_assist_not_applicable(extract_variable, "fn foo() { $0return$0; } "); |
562 | } | 562 | } |
563 | 563 | ||
564 | #[test] | 564 | #[test] |
565 | fn test_extract_var_for_break_not_applicable() { | 565 | fn test_extract_var_for_break_not_applicable() { |
566 | check_assist_not_applicable(extract_variable, "fn main() { loop { <|>break<|>; }; }"); | 566 | check_assist_not_applicable(extract_variable, "fn main() { loop { $0break$0; }; }"); |
567 | } | 567 | } |
568 | 568 | ||
569 | // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic | 569 | // FIXME: This is not quite correct, but good enough(tm) for the sorting heuristic |
570 | #[test] | 570 | #[test] |
571 | fn extract_var_target() { | 571 | fn extract_var_target() { |
572 | check_assist_target(extract_variable, "fn foo() -> u32 { <|>return 2 + 2<|>; }", "2 + 2"); | 572 | check_assist_target(extract_variable, "fn foo() -> u32 { $0return 2 + 2$0; }", "2 + 2"); |
573 | 573 | ||
574 | check_assist_target( | 574 | check_assist_target( |
575 | extract_variable, | 575 | extract_variable, |
@@ -577,7 +577,7 @@ fn main() { | |||
577 | fn main() { | 577 | fn main() { |
578 | let x = true; | 578 | let x = true; |
579 | let tuple = match x { | 579 | let tuple = match x { |
580 | true => (<|>2 + 2<|>, true) | 580 | true => ($02 + 2$0, true) |
581 | _ => (0, false) | 581 | _ => (0, false) |
582 | }; | 582 | }; |
583 | } | 583 | } |
diff --git a/crates/assists/src/handlers/fill_match_arms.rs b/crates/assists/src/handlers/fill_match_arms.rs index f9a62b9fa..da47187e4 100644 --- a/crates/assists/src/handlers/fill_match_arms.rs +++ b/crates/assists/src/handlers/fill_match_arms.rs | |||
@@ -21,7 +21,7 @@ use crate::{ | |||
21 | // | 21 | // |
22 | // fn handle(action: Action) { | 22 | // fn handle(action: Action) { |
23 | // match action { | 23 | // match action { |
24 | // <|> | 24 | // $0 |
25 | // } | 25 | // } |
26 | // } | 26 | // } |
27 | // ``` | 27 | // ``` |
@@ -231,7 +231,7 @@ mod tests { | |||
231 | Cs(i32, Option<i32>), | 231 | Cs(i32, Option<i32>), |
232 | } | 232 | } |
233 | fn main() { | 233 | fn main() { |
234 | match A::As<|> { | 234 | match A::As$0 { |
235 | A::As, | 235 | A::As, |
236 | A::Bs{x,y:Some(_)} => {} | 236 | A::Bs{x,y:Some(_)} => {} |
237 | A::Cs(_, Some(_)) => {} | 237 | A::Cs(_, Some(_)) => {} |
@@ -249,7 +249,7 @@ mod tests { | |||
249 | fill_match_arms, | 249 | fill_match_arms, |
250 | r#" | 250 | r#" |
251 | fn main() { | 251 | fn main() { |
252 | match (0, false)<|> { | 252 | match (0, false)$0 { |
253 | } | 253 | } |
254 | } | 254 | } |
255 | "#, | 255 | "#, |
@@ -267,7 +267,7 @@ mod tests { | |||
267 | Cs(i32, Option<i32>), | 267 | Cs(i32, Option<i32>), |
268 | } | 268 | } |
269 | fn main() { | 269 | fn main() { |
270 | match A::As<|> { | 270 | match A::As$0 { |
271 | A::Bs { x, y: Some(_) } => {} | 271 | A::Bs { x, y: Some(_) } => {} |
272 | A::Cs(_, Some(_)) => {} | 272 | A::Cs(_, Some(_)) => {} |
273 | } | 273 | } |
@@ -297,7 +297,7 @@ mod tests { | |||
297 | r#" | 297 | r#" |
298 | enum A { As, Bs, Cs(Option<i32>) } | 298 | enum A { As, Bs, Cs(Option<i32>) } |
299 | fn main() { | 299 | fn main() { |
300 | match A::As<|> { | 300 | match A::As$0 { |
301 | A::Cs(_) | A::Bs => {} | 301 | A::Cs(_) | A::Bs => {} |
302 | } | 302 | } |
303 | } | 303 | } |
@@ -322,7 +322,7 @@ fn main() { | |||
322 | enum A { As, Bs, Cs, Ds(String), Es(B) } | 322 | enum A { As, Bs, Cs, Ds(String), Es(B) } |
323 | enum B { Xs, Ys } | 323 | enum B { Xs, Ys } |
324 | fn main() { | 324 | fn main() { |
325 | match A::As<|> { | 325 | match A::As$0 { |
326 | A::Bs if 0 < 1 => {} | 326 | A::Bs if 0 < 1 => {} |
327 | A::Ds(_value) => { let x = 1; } | 327 | A::Ds(_value) => { let x = 1; } |
328 | A::Es(B::Xs) => (), | 328 | A::Es(B::Xs) => (), |
@@ -352,7 +352,7 @@ fn main() { | |||
352 | r#" | 352 | r#" |
353 | enum A { As, Bs, Cs(Option<i32>) } | 353 | enum A { As, Bs, Cs(Option<i32>) } |
354 | fn main() { | 354 | fn main() { |
355 | match A::As<|> { | 355 | match A::As$0 { |
356 | A::As(_) => {} | 356 | A::As(_) => {} |
357 | a @ A::Bs(_) => {} | 357 | a @ A::Bs(_) => {} |
358 | } | 358 | } |
@@ -380,7 +380,7 @@ enum A { As, Bs, Cs(String), Ds(String, String), Es { x: usize, y: usize } } | |||
380 | 380 | ||
381 | fn main() { | 381 | fn main() { |
382 | let a = A::As; | 382 | let a = A::As; |
383 | match a<|> {} | 383 | match a$0 {} |
384 | } | 384 | } |
385 | "#, | 385 | "#, |
386 | r#" | 386 | r#" |
@@ -411,7 +411,7 @@ fn main() { | |||
411 | fn main() { | 411 | fn main() { |
412 | let a = A::One; | 412 | let a = A::One; |
413 | let b = B::One; | 413 | let b = B::One; |
414 | match (a<|>, b) {} | 414 | match (a$0, b) {} |
415 | } | 415 | } |
416 | "#, | 416 | "#, |
417 | r#" | 417 | r#" |
@@ -443,7 +443,7 @@ fn main() { | |||
443 | fn main() { | 443 | fn main() { |
444 | let a = A::One; | 444 | let a = A::One; |
445 | let b = B::One; | 445 | let b = B::One; |
446 | match (&a<|>, &b) {} | 446 | match (&a$0, &b) {} |
447 | } | 447 | } |
448 | "#, | 448 | "#, |
449 | r#" | 449 | r#" |
@@ -475,7 +475,7 @@ fn main() { | |||
475 | fn main() { | 475 | fn main() { |
476 | let a = A::One; | 476 | let a = A::One; |
477 | let b = B::One; | 477 | let b = B::One; |
478 | match (a<|>, b) { | 478 | match (a$0, b) { |
479 | (A::Two, B::One) => {} | 479 | (A::Two, B::One) => {} |
480 | } | 480 | } |
481 | } | 481 | } |
@@ -494,7 +494,7 @@ fn main() { | |||
494 | fn main() { | 494 | fn main() { |
495 | let a = A::One; | 495 | let a = A::One; |
496 | let b = B::One; | 496 | let b = B::One; |
497 | match (a<|>, b) { | 497 | match (a$0, b) { |
498 | (A::Two, B::One) => {} | 498 | (A::Two, B::One) => {} |
499 | (A::One, B::One) => {} | 499 | (A::One, B::One) => {} |
500 | (A::One, B::Two) => {} | 500 | (A::One, B::Two) => {} |
@@ -517,7 +517,7 @@ fn main() { | |||
517 | 517 | ||
518 | fn main() { | 518 | fn main() { |
519 | let a = A::One; | 519 | let a = A::One; |
520 | match (a<|>, ) { | 520 | match (a$0, ) { |
521 | } | 521 | } |
522 | } | 522 | } |
523 | "#, | 523 | "#, |
@@ -532,7 +532,7 @@ fn main() { | |||
532 | enum A { As } | 532 | enum A { As } |
533 | 533 | ||
534 | fn foo(a: &A) { | 534 | fn foo(a: &A) { |
535 | match a<|> { | 535 | match a$0 { |
536 | } | 536 | } |
537 | } | 537 | } |
538 | "#, | 538 | "#, |
@@ -555,7 +555,7 @@ fn main() { | |||
555 | } | 555 | } |
556 | 556 | ||
557 | fn foo(a: &mut A) { | 557 | fn foo(a: &mut A) { |
558 | match a<|> { | 558 | match a$0 { |
559 | } | 559 | } |
560 | } | 560 | } |
561 | "#, | 561 | "#, |
@@ -581,7 +581,7 @@ fn main() { | |||
581 | enum E { X, Y } | 581 | enum E { X, Y } |
582 | 582 | ||
583 | fn main() { | 583 | fn main() { |
584 | match E::X<|> {} | 584 | match E::X$0 {} |
585 | } | 585 | } |
586 | "#, | 586 | "#, |
587 | "match E::X {}", | 587 | "match E::X {}", |
@@ -597,7 +597,7 @@ fn main() { | |||
597 | 597 | ||
598 | fn main() { | 598 | fn main() { |
599 | match E::X { | 599 | match E::X { |
600 | <|>_ => {} | 600 | $0_ => {} |
601 | } | 601 | } |
602 | } | 602 | } |
603 | "#, | 603 | "#, |
@@ -624,7 +624,7 @@ fn main() { | |||
624 | 624 | ||
625 | fn main() { | 625 | fn main() { |
626 | match X { | 626 | match X { |
627 | <|> | 627 | $0 |
628 | } | 628 | } |
629 | } | 629 | } |
630 | "#, | 630 | "#, |
@@ -650,7 +650,7 @@ fn main() { | |||
650 | enum A { One, Two } | 650 | enum A { One, Two } |
651 | fn foo(a: A) { | 651 | fn foo(a: A) { |
652 | match a { | 652 | match a { |
653 | // foo bar baz<|> | 653 | // foo bar baz$0 |
654 | A::One => {} | 654 | A::One => {} |
655 | // This is where the rest should be | 655 | // This is where the rest should be |
656 | } | 656 | } |
@@ -678,7 +678,7 @@ fn main() { | |||
678 | enum A { One, Two } | 678 | enum A { One, Two } |
679 | fn foo(a: A) { | 679 | fn foo(a: A) { |
680 | match a { | 680 | match a { |
681 | // foo bar baz<|> | 681 | // foo bar baz$0 |
682 | } | 682 | } |
683 | } | 683 | } |
684 | "#, | 684 | "#, |
@@ -702,7 +702,7 @@ fn main() { | |||
702 | r#" | 702 | r#" |
703 | enum A { One, Two, } | 703 | enum A { One, Two, } |
704 | fn foo(a: A) { | 704 | fn foo(a: A) { |
705 | match a<|> { | 705 | match a$0 { |
706 | _ => (), | 706 | _ => (), |
707 | } | 707 | } |
708 | } | 708 | } |
@@ -724,7 +724,7 @@ fn main() { | |||
724 | mark::check!(option_order); | 724 | mark::check!(option_order); |
725 | let before = r#" | 725 | let before = r#" |
726 | fn foo(opt: Option<i32>) { | 726 | fn foo(opt: Option<i32>) { |
727 | match opt<|> { | 727 | match opt$0 { |
728 | } | 728 | } |
729 | } | 729 | } |
730 | "#; | 730 | "#; |
diff --git a/crates/assists/src/handlers/fix_visibility.rs b/crates/assists/src/handlers/fix_visibility.rs index de1e8f0bf..6c7824e55 100644 --- a/crates/assists/src/handlers/fix_visibility.rs +++ b/crates/assists/src/handlers/fix_visibility.rs | |||
@@ -18,7 +18,7 @@ use crate::{utils::vis_offset, AssistContext, AssistId, AssistKind, Assists}; | |||
18 | // fn frobnicate() {} | 18 | // fn frobnicate() {} |
19 | // } | 19 | // } |
20 | // fn main() { | 20 | // fn main() { |
21 | // m::frobnicate<|>() {} | 21 | // m::frobnicate$0() {} |
22 | // } | 22 | // } |
23 | // ``` | 23 | // ``` |
24 | // -> | 24 | // -> |
@@ -97,7 +97,6 @@ fn add_vis_to_referenced_record_field(acc: &mut Assists, ctx: &AssistContext) -> | |||
97 | let parent_name = parent.name(ctx.db()); | 97 | let parent_name = parent.name(ctx.db()); |
98 | let target_module = parent.module(ctx.db()); | 98 | let target_module = parent.module(ctx.db()); |
99 | 99 | ||
100 | #[allow(deprecated)] | ||
101 | let in_file_source = record_field_def.source(ctx.db())?; | 100 | let in_file_source = record_field_def.source(ctx.db())?; |
102 | let (offset, current_visibility, target) = match in_file_source.value { | 101 | let (offset, current_visibility, target) = match in_file_source.value { |
103 | hir::FieldSource::Named(it) => { | 102 | hir::FieldSource::Named(it) => { |
@@ -219,14 +218,14 @@ mod tests { | |||
219 | check_assist( | 218 | check_assist( |
220 | fix_visibility, | 219 | fix_visibility, |
221 | r"mod foo { fn foo() {} } | 220 | r"mod foo { fn foo() {} } |
222 | fn main() { foo::foo<|>() } ", | 221 | fn main() { foo::foo$0() } ", |
223 | r"mod foo { $0pub(crate) fn foo() {} } | 222 | r"mod foo { $0pub(crate) fn foo() {} } |
224 | fn main() { foo::foo() } ", | 223 | fn main() { foo::foo() } ", |
225 | ); | 224 | ); |
226 | check_assist_not_applicable( | 225 | check_assist_not_applicable( |
227 | fix_visibility, | 226 | fix_visibility, |
228 | r"mod foo { pub fn foo() {} } | 227 | r"mod foo { pub fn foo() {} } |
229 | fn main() { foo::foo<|>() } ", | 228 | fn main() { foo::foo$0() } ", |
230 | ) | 229 | ) |
231 | } | 230 | } |
232 | 231 | ||
@@ -235,38 +234,38 @@ mod tests { | |||
235 | check_assist( | 234 | check_assist( |
236 | fix_visibility, | 235 | fix_visibility, |
237 | r"mod foo { struct Foo; } | 236 | r"mod foo { struct Foo; } |
238 | fn main() { foo::Foo<|> } ", | 237 | fn main() { foo::Foo$0 } ", |
239 | r"mod foo { $0pub(crate) struct Foo; } | 238 | r"mod foo { $0pub(crate) struct Foo; } |
240 | fn main() { foo::Foo } ", | 239 | fn main() { foo::Foo } ", |
241 | ); | 240 | ); |
242 | check_assist_not_applicable( | 241 | check_assist_not_applicable( |
243 | fix_visibility, | 242 | fix_visibility, |
244 | r"mod foo { pub struct Foo; } | 243 | r"mod foo { pub struct Foo; } |
245 | fn main() { foo::Foo<|> } ", | 244 | fn main() { foo::Foo$0 } ", |
246 | ); | 245 | ); |
247 | check_assist( | 246 | check_assist( |
248 | fix_visibility, | 247 | fix_visibility, |
249 | r"mod foo { enum Foo; } | 248 | r"mod foo { enum Foo; } |
250 | fn main() { foo::Foo<|> } ", | 249 | fn main() { foo::Foo$0 } ", |
251 | r"mod foo { $0pub(crate) enum Foo; } | 250 | r"mod foo { $0pub(crate) enum Foo; } |
252 | fn main() { foo::Foo } ", | 251 | fn main() { foo::Foo } ", |
253 | ); | 252 | ); |
254 | check_assist_not_applicable( | 253 | check_assist_not_applicable( |
255 | fix_visibility, | 254 | fix_visibility, |
256 | r"mod foo { pub enum Foo; } | 255 | r"mod foo { pub enum Foo; } |
257 | fn main() { foo::Foo<|> } ", | 256 | fn main() { foo::Foo$0 } ", |
258 | ); | 257 | ); |
259 | check_assist( | 258 | check_assist( |
260 | fix_visibility, | 259 | fix_visibility, |
261 | r"mod foo { union Foo; } | 260 | r"mod foo { union Foo; } |
262 | fn main() { foo::Foo<|> } ", | 261 | fn main() { foo::Foo$0 } ", |
263 | r"mod foo { $0pub(crate) union Foo; } | 262 | r"mod foo { $0pub(crate) union Foo; } |
264 | fn main() { foo::Foo } ", | 263 | fn main() { foo::Foo } ", |
265 | ); | 264 | ); |
266 | check_assist_not_applicable( | 265 | check_assist_not_applicable( |
267 | fix_visibility, | 266 | fix_visibility, |
268 | r"mod foo { pub union Foo; } | 267 | r"mod foo { pub union Foo; } |
269 | fn main() { foo::Foo<|> } ", | 268 | fn main() { foo::Foo$0 } ", |
270 | ); | 269 | ); |
271 | } | 270 | } |
272 | 271 | ||
@@ -277,7 +276,7 @@ mod tests { | |||
277 | r" | 276 | r" |
278 | //- /main.rs | 277 | //- /main.rs |
279 | mod foo; | 278 | mod foo; |
280 | fn main() { foo::Foo<|> } | 279 | fn main() { foo::Foo$0 } |
281 | 280 | ||
282 | //- /foo.rs | 281 | //- /foo.rs |
283 | struct Foo; | 282 | struct Foo; |
@@ -292,7 +291,7 @@ struct Foo; | |||
292 | check_assist( | 291 | check_assist( |
293 | fix_visibility, | 292 | fix_visibility, |
294 | r"mod foo { pub struct Foo { bar: (), } } | 293 | r"mod foo { pub struct Foo { bar: (), } } |
295 | fn main() { foo::Foo { <|>bar: () }; } ", | 294 | fn main() { foo::Foo { $0bar: () }; } ", |
296 | r"mod foo { pub struct Foo { $0pub(crate) bar: (), } } | 295 | r"mod foo { pub struct Foo { $0pub(crate) bar: (), } } |
297 | fn main() { foo::Foo { bar: () }; } ", | 296 | fn main() { foo::Foo { bar: () }; } ", |
298 | ); | 297 | ); |
@@ -301,7 +300,7 @@ struct Foo; | |||
301 | r" | 300 | r" |
302 | //- /lib.rs | 301 | //- /lib.rs |
303 | mod foo; | 302 | mod foo; |
304 | fn main() { foo::Foo { <|>bar: () }; } | 303 | fn main() { foo::Foo { $0bar: () }; } |
305 | //- /foo.rs | 304 | //- /foo.rs |
306 | pub struct Foo { bar: () } | 305 | pub struct Foo { bar: () } |
307 | ", | 306 | ", |
@@ -311,14 +310,14 @@ pub struct Foo { bar: () } | |||
311 | check_assist_not_applicable( | 310 | check_assist_not_applicable( |
312 | fix_visibility, | 311 | fix_visibility, |
313 | r"mod foo { pub struct Foo { pub bar: (), } } | 312 | r"mod foo { pub struct Foo { pub bar: (), } } |
314 | fn main() { foo::Foo { <|>bar: () }; } ", | 313 | fn main() { foo::Foo { $0bar: () }; } ", |
315 | ); | 314 | ); |
316 | check_assist_not_applicable( | 315 | check_assist_not_applicable( |
317 | fix_visibility, | 316 | fix_visibility, |
318 | r" | 317 | r" |
319 | //- /lib.rs | 318 | //- /lib.rs |
320 | mod foo; | 319 | mod foo; |
321 | fn main() { foo::Foo { <|>bar: () }; } | 320 | fn main() { foo::Foo { $0bar: () }; } |
322 | //- /foo.rs | 321 | //- /foo.rs |
323 | pub struct Foo { pub bar: () } | 322 | pub struct Foo { pub bar: () } |
324 | ", | 323 | ", |
@@ -332,14 +331,14 @@ pub struct Foo { pub bar: () } | |||
332 | check_assist_not_applicable( | 331 | check_assist_not_applicable( |
333 | fix_visibility, | 332 | fix_visibility, |
334 | r"mod foo { pub enum Foo { Bar { bar: () } } } | 333 | r"mod foo { pub enum Foo { Bar { bar: () } } } |
335 | fn main() { foo::Foo::Bar { <|>bar: () }; } ", | 334 | fn main() { foo::Foo::Bar { $0bar: () }; } ", |
336 | ); | 335 | ); |
337 | check_assist_not_applicable( | 336 | check_assist_not_applicable( |
338 | fix_visibility, | 337 | fix_visibility, |
339 | r" | 338 | r" |
340 | //- /lib.rs | 339 | //- /lib.rs |
341 | mod foo; | 340 | mod foo; |
342 | fn main() { foo::Foo::Bar { <|>bar: () }; } | 341 | fn main() { foo::Foo::Bar { $0bar: () }; } |
343 | //- /foo.rs | 342 | //- /foo.rs |
344 | pub enum Foo { Bar { bar: () } } | 343 | pub enum Foo { Bar { bar: () } } |
345 | ", | 344 | ", |
@@ -347,14 +346,14 @@ pub enum Foo { Bar { bar: () } } | |||
347 | check_assist_not_applicable( | 346 | check_assist_not_applicable( |
348 | fix_visibility, | 347 | fix_visibility, |
349 | r"mod foo { pub struct Foo { pub bar: (), } } | 348 | r"mod foo { pub struct Foo { pub bar: (), } } |
350 | fn main() { foo::Foo { <|>bar: () }; } ", | 349 | fn main() { foo::Foo { $0bar: () }; } ", |
351 | ); | 350 | ); |
352 | check_assist_not_applicable( | 351 | check_assist_not_applicable( |
353 | fix_visibility, | 352 | fix_visibility, |
354 | r" | 353 | r" |
355 | //- /lib.rs | 354 | //- /lib.rs |
356 | mod foo; | 355 | mod foo; |
357 | fn main() { foo::Foo { <|>bar: () }; } | 356 | fn main() { foo::Foo { $0bar: () }; } |
358 | //- /foo.rs | 357 | //- /foo.rs |
359 | pub struct Foo { pub bar: () } | 358 | pub struct Foo { pub bar: () } |
360 | ", | 359 | ", |
@@ -368,7 +367,7 @@ pub struct Foo { pub bar: () } | |||
368 | check_assist( | 367 | check_assist( |
369 | fix_visibility, | 368 | fix_visibility, |
370 | r"mod foo { pub union Foo { bar: (), } } | 369 | r"mod foo { pub union Foo { bar: (), } } |
371 | fn main() { foo::Foo { <|>bar: () }; } ", | 370 | fn main() { foo::Foo { $0bar: () }; } ", |
372 | r"mod foo { pub union Foo { $0pub(crate) bar: (), } } | 371 | r"mod foo { pub union Foo { $0pub(crate) bar: (), } } |
373 | fn main() { foo::Foo { bar: () }; } ", | 372 | fn main() { foo::Foo { bar: () }; } ", |
374 | ); | 373 | ); |
@@ -377,7 +376,7 @@ pub struct Foo { pub bar: () } | |||
377 | r" | 376 | r" |
378 | //- /lib.rs | 377 | //- /lib.rs |
379 | mod foo; | 378 | mod foo; |
380 | fn main() { foo::Foo { <|>bar: () }; } | 379 | fn main() { foo::Foo { $0bar: () }; } |
381 | //- /foo.rs | 380 | //- /foo.rs |
382 | pub union Foo { bar: () } | 381 | pub union Foo { bar: () } |
383 | ", | 382 | ", |
@@ -387,14 +386,14 @@ pub union Foo { bar: () } | |||
387 | check_assist_not_applicable( | 386 | check_assist_not_applicable( |
388 | fix_visibility, | 387 | fix_visibility, |
389 | r"mod foo { pub union Foo { pub bar: (), } } | 388 | r"mod foo { pub union Foo { pub bar: (), } } |
390 | fn main() { foo::Foo { <|>bar: () }; } ", | 389 | fn main() { foo::Foo { $0bar: () }; } ", |
391 | ); | 390 | ); |
392 | check_assist_not_applicable( | 391 | check_assist_not_applicable( |
393 | fix_visibility, | 392 | fix_visibility, |
394 | r" | 393 | r" |
395 | //- /lib.rs | 394 | //- /lib.rs |
396 | mod foo; | 395 | mod foo; |
397 | fn main() { foo::Foo { <|>bar: () }; } | 396 | fn main() { foo::Foo { $0bar: () }; } |
398 | //- /foo.rs | 397 | //- /foo.rs |
399 | pub union Foo { pub bar: () } | 398 | pub union Foo { pub bar: () } |
400 | ", | 399 | ", |
@@ -406,14 +405,14 @@ pub union Foo { pub bar: () } | |||
406 | check_assist( | 405 | check_assist( |
407 | fix_visibility, | 406 | fix_visibility, |
408 | r"mod foo { const FOO: () = (); } | 407 | r"mod foo { const FOO: () = (); } |
409 | fn main() { foo::FOO<|> } ", | 408 | fn main() { foo::FOO$0 } ", |
410 | r"mod foo { $0pub(crate) const FOO: () = (); } | 409 | r"mod foo { $0pub(crate) const FOO: () = (); } |
411 | fn main() { foo::FOO } ", | 410 | fn main() { foo::FOO } ", |
412 | ); | 411 | ); |
413 | check_assist_not_applicable( | 412 | check_assist_not_applicable( |
414 | fix_visibility, | 413 | fix_visibility, |
415 | r"mod foo { pub const FOO: () = (); } | 414 | r"mod foo { pub const FOO: () = (); } |
416 | fn main() { foo::FOO<|> } ", | 415 | fn main() { foo::FOO$0 } ", |
417 | ); | 416 | ); |
418 | } | 417 | } |
419 | 418 | ||
@@ -422,14 +421,14 @@ pub union Foo { pub bar: () } | |||
422 | check_assist( | 421 | check_assist( |
423 | fix_visibility, | 422 | fix_visibility, |
424 | r"mod foo { static FOO: () = (); } | 423 | r"mod foo { static FOO: () = (); } |
425 | fn main() { foo::FOO<|> } ", | 424 | fn main() { foo::FOO$0 } ", |
426 | r"mod foo { $0pub(crate) static FOO: () = (); } | 425 | r"mod foo { $0pub(crate) static FOO: () = (); } |
427 | fn main() { foo::FOO } ", | 426 | fn main() { foo::FOO } ", |
428 | ); | 427 | ); |
429 | check_assist_not_applicable( | 428 | check_assist_not_applicable( |
430 | fix_visibility, | 429 | fix_visibility, |
431 | r"mod foo { pub static FOO: () = (); } | 430 | r"mod foo { pub static FOO: () = (); } |
432 | fn main() { foo::FOO<|> } ", | 431 | fn main() { foo::FOO$0 } ", |
433 | ); | 432 | ); |
434 | } | 433 | } |
435 | 434 | ||
@@ -438,14 +437,14 @@ pub union Foo { pub bar: () } | |||
438 | check_assist( | 437 | check_assist( |
439 | fix_visibility, | 438 | fix_visibility, |
440 | r"mod foo { trait Foo { fn foo(&self) {} } } | 439 | r"mod foo { trait Foo { fn foo(&self) {} } } |
441 | fn main() { let x: &dyn foo::<|>Foo; } ", | 440 | fn main() { let x: &dyn foo::$0Foo; } ", |
442 | r"mod foo { $0pub(crate) trait Foo { fn foo(&self) {} } } | 441 | r"mod foo { $0pub(crate) trait Foo { fn foo(&self) {} } } |
443 | fn main() { let x: &dyn foo::Foo; } ", | 442 | fn main() { let x: &dyn foo::Foo; } ", |
444 | ); | 443 | ); |
445 | check_assist_not_applicable( | 444 | check_assist_not_applicable( |
446 | fix_visibility, | 445 | fix_visibility, |
447 | r"mod foo { pub trait Foo { fn foo(&self) {} } } | 446 | r"mod foo { pub trait Foo { fn foo(&self) {} } } |
448 | fn main() { let x: &dyn foo::Foo<|>; } ", | 447 | fn main() { let x: &dyn foo::Foo$0; } ", |
449 | ); | 448 | ); |
450 | } | 449 | } |
451 | 450 | ||
@@ -454,14 +453,14 @@ pub union Foo { pub bar: () } | |||
454 | check_assist( | 453 | check_assist( |
455 | fix_visibility, | 454 | fix_visibility, |
456 | r"mod foo { type Foo = (); } | 455 | r"mod foo { type Foo = (); } |
457 | fn main() { let x: foo::Foo<|>; } ", | 456 | fn main() { let x: foo::Foo$0; } ", |
458 | r"mod foo { $0pub(crate) type Foo = (); } | 457 | r"mod foo { $0pub(crate) type Foo = (); } |
459 | fn main() { let x: foo::Foo; } ", | 458 | fn main() { let x: foo::Foo; } ", |
460 | ); | 459 | ); |
461 | check_assist_not_applicable( | 460 | check_assist_not_applicable( |
462 | fix_visibility, | 461 | fix_visibility, |
463 | r"mod foo { pub type Foo = (); } | 462 | r"mod foo { pub type Foo = (); } |
464 | fn main() { let x: foo::Foo<|>; } ", | 463 | fn main() { let x: foo::Foo$0; } ", |
465 | ); | 464 | ); |
466 | } | 465 | } |
467 | 466 | ||
@@ -470,7 +469,7 @@ pub union Foo { pub bar: () } | |||
470 | check_assist( | 469 | check_assist( |
471 | fix_visibility, | 470 | fix_visibility, |
472 | r"mod foo { mod bar { fn bar() {} } } | 471 | r"mod foo { mod bar { fn bar() {} } } |
473 | fn main() { foo::bar<|>::bar(); } ", | 472 | fn main() { foo::bar$0::bar(); } ", |
474 | r"mod foo { $0pub(crate) mod bar { fn bar() {} } } | 473 | r"mod foo { $0pub(crate) mod bar { fn bar() {} } } |
475 | fn main() { foo::bar::bar(); } ", | 474 | fn main() { foo::bar::bar(); } ", |
476 | ); | 475 | ); |
@@ -480,7 +479,7 @@ pub union Foo { pub bar: () } | |||
480 | r" | 479 | r" |
481 | //- /main.rs | 480 | //- /main.rs |
482 | mod foo; | 481 | mod foo; |
483 | fn main() { foo::bar<|>::baz(); } | 482 | fn main() { foo::bar$0::baz(); } |
484 | 483 | ||
485 | //- /foo.rs | 484 | //- /foo.rs |
486 | mod bar { | 485 | mod bar { |
@@ -496,7 +495,7 @@ mod bar { | |||
496 | check_assist_not_applicable( | 495 | check_assist_not_applicable( |
497 | fix_visibility, | 496 | fix_visibility, |
498 | r"mod foo { pub mod bar { pub fn bar() {} } } | 497 | r"mod foo { pub mod bar { pub fn bar() {} } } |
499 | fn main() { foo::bar<|>::bar(); } ", | 498 | fn main() { foo::bar$0::bar(); } ", |
500 | ); | 499 | ); |
501 | } | 500 | } |
502 | 501 | ||
@@ -507,7 +506,7 @@ mod bar { | |||
507 | r" | 506 | r" |
508 | //- /main.rs | 507 | //- /main.rs |
509 | mod foo; | 508 | mod foo; |
510 | fn main() { foo::bar<|>::baz(); } | 509 | fn main() { foo::bar$0::baz(); } |
511 | 510 | ||
512 | //- /foo.rs | 511 | //- /foo.rs |
513 | mod bar; | 512 | mod bar; |
@@ -526,7 +525,7 @@ pub fn baz() {} | |||
526 | r" | 525 | r" |
527 | //- /main.rs | 526 | //- /main.rs |
528 | mod foo; | 527 | mod foo; |
529 | fn main() { foo::bar<|>>::baz(); } | 528 | fn main() { foo::bar$0>::baz(); } |
530 | 529 | ||
531 | //- /foo.rs | 530 | //- /foo.rs |
532 | mod bar { | 531 | mod bar { |
@@ -546,7 +545,7 @@ mod bar { | |||
546 | fix_visibility, | 545 | fix_visibility, |
547 | r" | 546 | r" |
548 | //- /main.rs crate:a deps:foo | 547 | //- /main.rs crate:a deps:foo |
549 | foo::Bar<|> | 548 | foo::Bar$0 |
550 | //- /lib.rs crate:foo | 549 | //- /lib.rs crate:foo |
551 | struct Bar; | 550 | struct Bar; |
552 | ", | 551 | ", |
@@ -561,7 +560,7 @@ struct Bar; | |||
561 | fix_visibility, | 560 | fix_visibility, |
562 | r" | 561 | r" |
563 | //- /main.rs crate:a deps:foo | 562 | //- /main.rs crate:a deps:foo |
564 | foo::Bar<|> | 563 | foo::Bar$0 |
565 | //- /lib.rs crate:foo | 564 | //- /lib.rs crate:foo |
566 | pub(crate) struct Bar; | 565 | pub(crate) struct Bar; |
567 | ", | 566 | ", |
@@ -573,7 +572,7 @@ pub(crate) struct Bar; | |||
573 | r" | 572 | r" |
574 | //- /main.rs crate:a deps:foo | 573 | //- /main.rs crate:a deps:foo |
575 | fn main() { | 574 | fn main() { |
576 | foo::Foo { <|>bar: () }; | 575 | foo::Foo { $0bar: () }; |
577 | } | 576 | } |
578 | //- /lib.rs crate:foo | 577 | //- /lib.rs crate:foo |
579 | pub struct Foo { pub(crate) bar: () } | 578 | pub struct Foo { pub(crate) bar: () } |
@@ -594,7 +593,7 @@ pub struct Foo { pub(crate) bar: () } | |||
594 | use bar::Baz; | 593 | use bar::Baz; |
595 | mod bar { pub(super) struct Baz; } | 594 | mod bar { pub(super) struct Baz; } |
596 | } | 595 | } |
597 | foo::Baz<|> | 596 | foo::Baz$0 |
598 | ", | 597 | ", |
599 | r" | 598 | r" |
600 | mod foo { | 599 | mod foo { |
diff --git a/crates/assists/src/handlers/flip_binexpr.rs b/crates/assists/src/handlers/flip_binexpr.rs index 404f06133..209e5d43c 100644 --- a/crates/assists/src/handlers/flip_binexpr.rs +++ b/crates/assists/src/handlers/flip_binexpr.rs | |||
@@ -8,7 +8,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // fn main() { | 10 | // fn main() { |
11 | // let _ = 90 +<|> 2; | 11 | // let _ = 90 +$0 2; |
12 | // } | 12 | // } |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
@@ -77,42 +77,34 @@ mod tests { | |||
77 | 77 | ||
78 | #[test] | 78 | #[test] |
79 | fn flip_binexpr_target_is_the_op() { | 79 | fn flip_binexpr_target_is_the_op() { |
80 | check_assist_target(flip_binexpr, "fn f() { let res = 1 ==<|> 2; }", "==") | 80 | check_assist_target(flip_binexpr, "fn f() { let res = 1 ==$0 2; }", "==") |
81 | } | 81 | } |
82 | 82 | ||
83 | #[test] | 83 | #[test] |
84 | fn flip_binexpr_not_applicable_for_assignment() { | 84 | fn flip_binexpr_not_applicable_for_assignment() { |
85 | check_assist_not_applicable(flip_binexpr, "fn f() { let mut _x = 1; _x +=<|> 2 }") | 85 | check_assist_not_applicable(flip_binexpr, "fn f() { let mut _x = 1; _x +=$0 2 }") |
86 | } | 86 | } |
87 | 87 | ||
88 | #[test] | 88 | #[test] |
89 | fn flip_binexpr_works_for_eq() { | 89 | fn flip_binexpr_works_for_eq() { |
90 | check_assist( | 90 | check_assist(flip_binexpr, "fn f() { let res = 1 ==$0 2; }", "fn f() { let res = 2 == 1; }") |
91 | flip_binexpr, | ||
92 | "fn f() { let res = 1 ==<|> 2; }", | ||
93 | "fn f() { let res = 2 == 1; }", | ||
94 | ) | ||
95 | } | 91 | } |
96 | 92 | ||
97 | #[test] | 93 | #[test] |
98 | fn flip_binexpr_works_for_gt() { | 94 | fn flip_binexpr_works_for_gt() { |
99 | check_assist(flip_binexpr, "fn f() { let res = 1 ><|> 2; }", "fn f() { let res = 2 < 1; }") | 95 | check_assist(flip_binexpr, "fn f() { let res = 1 >$0 2; }", "fn f() { let res = 2 < 1; }") |
100 | } | 96 | } |
101 | 97 | ||
102 | #[test] | 98 | #[test] |
103 | fn flip_binexpr_works_for_lteq() { | 99 | fn flip_binexpr_works_for_lteq() { |
104 | check_assist( | 100 | check_assist(flip_binexpr, "fn f() { let res = 1 <=$0 2; }", "fn f() { let res = 2 >= 1; }") |
105 | flip_binexpr, | ||
106 | "fn f() { let res = 1 <=<|> 2; }", | ||
107 | "fn f() { let res = 2 >= 1; }", | ||
108 | ) | ||
109 | } | 101 | } |
110 | 102 | ||
111 | #[test] | 103 | #[test] |
112 | fn flip_binexpr_works_for_complex_expr() { | 104 | fn flip_binexpr_works_for_complex_expr() { |
113 | check_assist( | 105 | check_assist( |
114 | flip_binexpr, | 106 | flip_binexpr, |
115 | "fn f() { let res = (1 + 1) ==<|> (2 + 2); }", | 107 | "fn f() { let res = (1 + 1) ==$0 (2 + 2); }", |
116 | "fn f() { let res = (2 + 2) == (1 + 1); }", | 108 | "fn f() { let res = (2 + 2) == (1 + 1); }", |
117 | ) | 109 | ) |
118 | } | 110 | } |
@@ -125,7 +117,7 @@ mod tests { | |||
125 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { | 117 | fn dyn_eq(&self, other: &dyn Diagnostic) -> bool { |
126 | match other.downcast_ref::<Self>() { | 118 | match other.downcast_ref::<Self>() { |
127 | None => false, | 119 | None => false, |
128 | Some(it) => it ==<|> self, | 120 | Some(it) => it ==$0 self, |
129 | } | 121 | } |
130 | } | 122 | } |
131 | "#, | 123 | "#, |
diff --git a/crates/assists/src/handlers/flip_comma.rs b/crates/assists/src/handlers/flip_comma.rs index 64b4b1a76..18cf64a34 100644 --- a/crates/assists/src/handlers/flip_comma.rs +++ b/crates/assists/src/handlers/flip_comma.rs | |||
@@ -8,7 +8,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // fn main() { | 10 | // fn main() { |
11 | // ((1, 2),<|> (3, 4)); | 11 | // ((1, 2),$0 (3, 4)); |
12 | // } | 12 | // } |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
@@ -49,14 +49,14 @@ mod tests { | |||
49 | fn flip_comma_works_for_function_parameters() { | 49 | fn flip_comma_works_for_function_parameters() { |
50 | check_assist( | 50 | check_assist( |
51 | flip_comma, | 51 | flip_comma, |
52 | "fn foo(x: i32,<|> y: Result<(), ()>) {}", | 52 | r#"fn foo(x: i32,$0 y: Result<(), ()>) {}"#, |
53 | "fn foo(y: Result<(), ()>, x: i32) {}", | 53 | r#"fn foo(y: Result<(), ()>, x: i32) {}"#, |
54 | ) | 54 | ) |
55 | } | 55 | } |
56 | 56 | ||
57 | #[test] | 57 | #[test] |
58 | fn flip_comma_target() { | 58 | fn flip_comma_target() { |
59 | check_assist_target(flip_comma, "fn foo(x: i32,<|> y: Result<(), ()>) {}", ",") | 59 | check_assist_target(flip_comma, r#"fn foo(x: i32,$0 y: Result<(), ()>) {}"#, ",") |
60 | } | 60 | } |
61 | 61 | ||
62 | #[test] | 62 | #[test] |
@@ -68,7 +68,7 @@ mod tests { | |||
68 | check_assist_target( | 68 | check_assist_target( |
69 | flip_comma, | 69 | flip_comma, |
70 | "pub enum Test { \ | 70 | "pub enum Test { \ |
71 | A,<|> \ | 71 | A,$0 \ |
72 | }", | 72 | }", |
73 | ",", | 73 | ",", |
74 | ); | 74 | ); |
@@ -76,7 +76,7 @@ mod tests { | |||
76 | check_assist_target( | 76 | check_assist_target( |
77 | flip_comma, | 77 | flip_comma, |
78 | "pub struct Test { \ | 78 | "pub struct Test { \ |
79 | foo: usize,<|> \ | 79 | foo: usize,$0 \ |
80 | }", | 80 | }", |
81 | ",", | 81 | ",", |
82 | ); | 82 | ); |
diff --git a/crates/assists/src/handlers/flip_trait_bound.rs b/crates/assists/src/handlers/flip_trait_bound.rs index 92ee42181..d419d263e 100644 --- a/crates/assists/src/handlers/flip_trait_bound.rs +++ b/crates/assists/src/handlers/flip_trait_bound.rs | |||
@@ -11,7 +11,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
11 | // Flips two trait bounds. | 11 | // Flips two trait bounds. |
12 | // | 12 | // |
13 | // ``` | 13 | // ``` |
14 | // fn foo<T: Clone +<|> Copy>() { } | 14 | // fn foo<T: Clone +$0 Copy>() { } |
15 | // ``` | 15 | // ``` |
16 | // -> | 16 | // -> |
17 | // ``` | 17 | // ``` |
@@ -52,19 +52,19 @@ mod tests { | |||
52 | 52 | ||
53 | #[test] | 53 | #[test] |
54 | fn flip_trait_bound_assist_available() { | 54 | fn flip_trait_bound_assist_available() { |
55 | check_assist_target(flip_trait_bound, "struct S<T> where T: A <|>+ B + C { }", "+") | 55 | check_assist_target(flip_trait_bound, "struct S<T> where T: A $0+ B + C { }", "+") |
56 | } | 56 | } |
57 | 57 | ||
58 | #[test] | 58 | #[test] |
59 | fn flip_trait_bound_not_applicable_for_single_trait_bound() { | 59 | fn flip_trait_bound_not_applicable_for_single_trait_bound() { |
60 | check_assist_not_applicable(flip_trait_bound, "struct S<T> where T: <|>A { }") | 60 | check_assist_not_applicable(flip_trait_bound, "struct S<T> where T: $0A { }") |
61 | } | 61 | } |
62 | 62 | ||
63 | #[test] | 63 | #[test] |
64 | fn flip_trait_bound_works_for_struct() { | 64 | fn flip_trait_bound_works_for_struct() { |
65 | check_assist( | 65 | check_assist( |
66 | flip_trait_bound, | 66 | flip_trait_bound, |
67 | "struct S<T> where T: A <|>+ B { }", | 67 | "struct S<T> where T: A $0+ B { }", |
68 | "struct S<T> where T: B + A { }", | 68 | "struct S<T> where T: B + A { }", |
69 | ) | 69 | ) |
70 | } | 70 | } |
@@ -73,21 +73,21 @@ mod tests { | |||
73 | fn flip_trait_bound_works_for_trait_impl() { | 73 | fn flip_trait_bound_works_for_trait_impl() { |
74 | check_assist( | 74 | check_assist( |
75 | flip_trait_bound, | 75 | flip_trait_bound, |
76 | "impl X for S<T> where T: A +<|> B { }", | 76 | "impl X for S<T> where T: A +$0 B { }", |
77 | "impl X for S<T> where T: B + A { }", | 77 | "impl X for S<T> where T: B + A { }", |
78 | ) | 78 | ) |
79 | } | 79 | } |
80 | 80 | ||
81 | #[test] | 81 | #[test] |
82 | fn flip_trait_bound_works_for_fn() { | 82 | fn flip_trait_bound_works_for_fn() { |
83 | check_assist(flip_trait_bound, "fn f<T: A <|>+ B>(t: T) { }", "fn f<T: B + A>(t: T) { }") | 83 | check_assist(flip_trait_bound, "fn f<T: A $0+ B>(t: T) { }", "fn f<T: B + A>(t: T) { }") |
84 | } | 84 | } |
85 | 85 | ||
86 | #[test] | 86 | #[test] |
87 | fn flip_trait_bound_works_for_fn_where_clause() { | 87 | fn flip_trait_bound_works_for_fn_where_clause() { |
88 | check_assist( | 88 | check_assist( |
89 | flip_trait_bound, | 89 | flip_trait_bound, |
90 | "fn f<T>(t: T) where T: A +<|> B { }", | 90 | "fn f<T>(t: T) where T: A +$0 B { }", |
91 | "fn f<T>(t: T) where T: B + A { }", | 91 | "fn f<T>(t: T) where T: B + A { }", |
92 | ) | 92 | ) |
93 | } | 93 | } |
@@ -96,7 +96,7 @@ mod tests { | |||
96 | fn flip_trait_bound_works_for_lifetime() { | 96 | fn flip_trait_bound_works_for_lifetime() { |
97 | check_assist( | 97 | check_assist( |
98 | flip_trait_bound, | 98 | flip_trait_bound, |
99 | "fn f<T>(t: T) where T: A <|>+ 'static { }", | 99 | "fn f<T>(t: T) where T: A $0+ 'static { }", |
100 | "fn f<T>(t: T) where T: 'static + A { }", | 100 | "fn f<T>(t: T) where T: 'static + A { }", |
101 | ) | 101 | ) |
102 | } | 102 | } |
@@ -105,7 +105,7 @@ mod tests { | |||
105 | fn flip_trait_bound_works_for_complex_bounds() { | 105 | fn flip_trait_bound_works_for_complex_bounds() { |
106 | check_assist( | 106 | check_assist( |
107 | flip_trait_bound, | 107 | flip_trait_bound, |
108 | "struct S<T> where T: A<T> <|>+ b_mod::B<T> + C<T> { }", | 108 | "struct S<T> where T: A<T> $0+ b_mod::B<T> + C<T> { }", |
109 | "struct S<T> where T: b_mod::B<T> + A<T> + C<T> { }", | 109 | "struct S<T> where T: b_mod::B<T> + A<T> + C<T> { }", |
110 | ) | 110 | ) |
111 | } | 111 | } |
@@ -114,7 +114,7 @@ mod tests { | |||
114 | fn flip_trait_bound_works_for_long_bounds() { | 114 | fn flip_trait_bound_works_for_long_bounds() { |
115 | check_assist( | 115 | check_assist( |
116 | flip_trait_bound, | 116 | flip_trait_bound, |
117 | "struct S<T> where T: A + B + C + D + E + F +<|> G + H + I + J { }", | 117 | "struct S<T> where T: A + B + C + D + E + F +$0 G + H + I + J { }", |
118 | "struct S<T> where T: A + B + C + D + E + G + F + H + I + J { }", | 118 | "struct S<T> where T: A + B + C + D + E + G + F + H + I + J { }", |
119 | ) | 119 | ) |
120 | } | 120 | } |
diff --git a/crates/assists/src/handlers/generate_default_from_enum_variant.rs b/crates/assists/src/handlers/generate_default_from_enum_variant.rs index bcea46735..6a2ab9596 100644 --- a/crates/assists/src/handlers/generate_default_from_enum_variant.rs +++ b/crates/assists/src/handlers/generate_default_from_enum_variant.rs | |||
@@ -12,7 +12,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
12 | // ``` | 12 | // ``` |
13 | // enum Version { | 13 | // enum Version { |
14 | // Undefined, | 14 | // Undefined, |
15 | // Minor<|>, | 15 | // Minor$0, |
16 | // Major, | 16 | // Major, |
17 | // } | 17 | // } |
18 | // ``` | 18 | // ``` |
@@ -108,7 +108,7 @@ mod tests { | |||
108 | r#" | 108 | r#" |
109 | enum Variant { | 109 | enum Variant { |
110 | Undefined, | 110 | Undefined, |
111 | Minor<|>, | 111 | Minor$0, |
112 | Major, | 112 | Major, |
113 | }"#, | 113 | }"#, |
114 | r#"enum Variant { | 114 | r#"enum Variant { |
@@ -132,7 +132,7 @@ impl Default for Variant { | |||
132 | r#" | 132 | r#" |
133 | enum Variant { | 133 | enum Variant { |
134 | Undefined, | 134 | Undefined, |
135 | Minor<|>, | 135 | Minor$0, |
136 | Major, | 136 | Major, |
137 | } | 137 | } |
138 | 138 | ||
@@ -151,7 +151,7 @@ impl Default for Variant { | |||
151 | r#" | 151 | r#" |
152 | enum Variant { | 152 | enum Variant { |
153 | Undefined, | 153 | Undefined, |
154 | Minor(u32)<|>, | 154 | Minor(u32)$0, |
155 | Major, | 155 | Major, |
156 | }"#, | 156 | }"#, |
157 | ); | 157 | ); |
@@ -161,7 +161,7 @@ enum Variant { | |||
161 | fn test_generate_default_from_variant_with_one_variant() { | 161 | fn test_generate_default_from_variant_with_one_variant() { |
162 | check_assist( | 162 | check_assist( |
163 | generate_default_from_enum_variant, | 163 | generate_default_from_enum_variant, |
164 | r#"enum Variant { Undefi<|>ned }"#, | 164 | r#"enum Variant { Undefi$0ned }"#, |
165 | r#" | 165 | r#" |
166 | enum Variant { Undefined } | 166 | enum Variant { Undefined } |
167 | 167 | ||
diff --git a/crates/assists/src/handlers/generate_derive.rs b/crates/assists/src/handlers/generate_derive.rs index 314504e15..f876b7684 100644 --- a/crates/assists/src/handlers/generate_derive.rs +++ b/crates/assists/src/handlers/generate_derive.rs | |||
@@ -13,7 +13,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
13 | // ``` | 13 | // ``` |
14 | // struct Point { | 14 | // struct Point { |
15 | // x: u32, | 15 | // x: u32, |
16 | // y: u32,<|> | 16 | // y: u32,$0 |
17 | // } | 17 | // } |
18 | // ``` | 18 | // ``` |
19 | // -> | 19 | // -> |
@@ -76,12 +76,12 @@ mod tests { | |||
76 | fn add_derive_new() { | 76 | fn add_derive_new() { |
77 | check_assist( | 77 | check_assist( |
78 | generate_derive, | 78 | generate_derive, |
79 | "struct Foo { a: i32, <|>}", | 79 | "struct Foo { a: i32, $0}", |
80 | "#[derive($0)]\nstruct Foo { a: i32, }", | 80 | "#[derive($0)]\nstruct Foo { a: i32, }", |
81 | ); | 81 | ); |
82 | check_assist( | 82 | check_assist( |
83 | generate_derive, | 83 | generate_derive, |
84 | "struct Foo { <|> a: i32, }", | 84 | "struct Foo { $0 a: i32, }", |
85 | "#[derive($0)]\nstruct Foo { a: i32, }", | 85 | "#[derive($0)]\nstruct Foo { a: i32, }", |
86 | ); | 86 | ); |
87 | } | 87 | } |
@@ -90,7 +90,7 @@ mod tests { | |||
90 | fn add_derive_existing() { | 90 | fn add_derive_existing() { |
91 | check_assist( | 91 | check_assist( |
92 | generate_derive, | 92 | generate_derive, |
93 | "#[derive(Clone)]\nstruct Foo { a: i32<|>, }", | 93 | "#[derive(Clone)]\nstruct Foo { a: i32$0, }", |
94 | "#[derive(Clone$0)]\nstruct Foo { a: i32, }", | 94 | "#[derive(Clone$0)]\nstruct Foo { a: i32, }", |
95 | ); | 95 | ); |
96 | } | 96 | } |
@@ -102,7 +102,7 @@ mod tests { | |||
102 | " | 102 | " |
103 | /// `Foo` is a pretty important struct. | 103 | /// `Foo` is a pretty important struct. |
104 | /// It does stuff. | 104 | /// It does stuff. |
105 | struct Foo { a: i32<|>, } | 105 | struct Foo { a: i32$0, } |
106 | ", | 106 | ", |
107 | " | 107 | " |
108 | /// `Foo` is a pretty important struct. | 108 | /// `Foo` is a pretty important struct. |
@@ -121,7 +121,7 @@ struct Foo { a: i32, } | |||
121 | struct SomeThingIrrelevant; | 121 | struct SomeThingIrrelevant; |
122 | /// `Foo` is a pretty important struct. | 122 | /// `Foo` is a pretty important struct. |
123 | /// It does stuff. | 123 | /// It does stuff. |
124 | struct Foo { a: i32<|>, } | 124 | struct Foo { a: i32$0, } |
125 | struct EvenMoreIrrelevant; | 125 | struct EvenMoreIrrelevant; |
126 | ", | 126 | ", |
127 | "/// `Foo` is a pretty important struct. | 127 | "/// `Foo` is a pretty important struct. |
diff --git a/crates/assists/src/handlers/generate_from_impl_for_enum.rs b/crates/assists/src/handlers/generate_from_impl_for_enum.rs index 3c374e5d9..d9af6ab11 100644 --- a/crates/assists/src/handlers/generate_from_impl_for_enum.rs +++ b/crates/assists/src/handlers/generate_from_impl_for_enum.rs | |||
@@ -10,7 +10,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
10 | // Adds a From impl for an enum variant with one tuple field. | 10 | // Adds a From impl for an enum variant with one tuple field. |
11 | // | 11 | // |
12 | // ``` | 12 | // ``` |
13 | // enum A { <|>One(u32) } | 13 | // enum A { $0One(u32) } |
14 | // ``` | 14 | // ``` |
15 | // -> | 15 | // -> |
16 | // ``` | 16 | // ``` |
@@ -101,7 +101,7 @@ mod tests { | |||
101 | fn test_generate_from_impl_for_enum() { | 101 | fn test_generate_from_impl_for_enum() { |
102 | check_assist( | 102 | check_assist( |
103 | generate_from_impl_for_enum, | 103 | generate_from_impl_for_enum, |
104 | "enum A { <|>One(u32) }", | 104 | "enum A { $0One(u32) }", |
105 | r#"enum A { One(u32) } | 105 | r#"enum A { One(u32) } |
106 | 106 | ||
107 | impl From<u32> for A { | 107 | impl From<u32> for A { |
@@ -116,7 +116,7 @@ impl From<u32> for A { | |||
116 | fn test_generate_from_impl_for_enum_complicated_path() { | 116 | fn test_generate_from_impl_for_enum_complicated_path() { |
117 | check_assist( | 117 | check_assist( |
118 | generate_from_impl_for_enum, | 118 | generate_from_impl_for_enum, |
119 | r#"enum A { <|>One(foo::bar::baz::Boo) }"#, | 119 | r#"enum A { $0One(foo::bar::baz::Boo) }"#, |
120 | r#"enum A { One(foo::bar::baz::Boo) } | 120 | r#"enum A { One(foo::bar::baz::Boo) } |
121 | 121 | ||
122 | impl From<foo::bar::baz::Boo> for A { | 122 | impl From<foo::bar::baz::Boo> for A { |
@@ -135,17 +135,17 @@ impl From<foo::bar::baz::Boo> for A { | |||
135 | 135 | ||
136 | #[test] | 136 | #[test] |
137 | fn test_add_from_impl_no_element() { | 137 | fn test_add_from_impl_no_element() { |
138 | check_not_applicable("enum A { <|>One }"); | 138 | check_not_applicable("enum A { $0One }"); |
139 | } | 139 | } |
140 | 140 | ||
141 | #[test] | 141 | #[test] |
142 | fn test_add_from_impl_more_than_one_element_in_tuple() { | 142 | fn test_add_from_impl_more_than_one_element_in_tuple() { |
143 | check_not_applicable("enum A { <|>One(u32, String) }"); | 143 | check_not_applicable("enum A { $0One(u32, String) }"); |
144 | } | 144 | } |
145 | 145 | ||
146 | #[test] | 146 | #[test] |
147 | fn test_add_from_impl_struct_variant() { | 147 | fn test_add_from_impl_struct_variant() { |
148 | check_not_applicable("enum A { <|>One { x: u32 } }"); | 148 | check_not_applicable("enum A { $0One { x: u32 } }"); |
149 | } | 149 | } |
150 | 150 | ||
151 | #[test] | 151 | #[test] |
@@ -153,7 +153,7 @@ impl From<foo::bar::baz::Boo> for A { | |||
153 | mark::check!(test_add_from_impl_already_exists); | 153 | mark::check!(test_add_from_impl_already_exists); |
154 | check_not_applicable( | 154 | check_not_applicable( |
155 | r#" | 155 | r#" |
156 | enum A { <|>One(u32), } | 156 | enum A { $0One(u32), } |
157 | 157 | ||
158 | impl From<u32> for A { | 158 | impl From<u32> for A { |
159 | fn from(v: u32) -> Self { | 159 | fn from(v: u32) -> Self { |
@@ -168,7 +168,7 @@ impl From<u32> for A { | |||
168 | fn test_add_from_impl_different_variant_impl_exists() { | 168 | fn test_add_from_impl_different_variant_impl_exists() { |
169 | check_assist( | 169 | check_assist( |
170 | generate_from_impl_for_enum, | 170 | generate_from_impl_for_enum, |
171 | r#"enum A { <|>One(u32), Two(String), } | 171 | r#"enum A { $0One(u32), Two(String), } |
172 | 172 | ||
173 | impl From<String> for A { | 173 | impl From<String> for A { |
174 | fn from(v: String) -> Self { | 174 | fn from(v: String) -> Self { |
diff --git a/crates/assists/src/handlers/generate_function.rs b/crates/assists/src/handlers/generate_function.rs index f4cf155b6..06ac85f67 100644 --- a/crates/assists/src/handlers/generate_function.rs +++ b/crates/assists/src/handlers/generate_function.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | use hir::HirDisplay; | 1 | use hir::HirDisplay; |
2 | use ide_db::base_db::FileId; | 2 | use ide_db::{base_db::FileId, helpers::SnippetCap}; |
3 | use rustc_hash::{FxHashMap, FxHashSet}; | 3 | use rustc_hash::{FxHashMap, FxHashSet}; |
4 | use syntax::{ | 4 | use syntax::{ |
5 | ast::{ | 5 | ast::{ |
@@ -11,7 +11,6 @@ use syntax::{ | |||
11 | }; | 11 | }; |
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | assist_config::SnippetCap, | ||
15 | utils::{render_snippet, Cursor}, | 14 | utils::{render_snippet, Cursor}, |
16 | AssistContext, AssistId, AssistKind, Assists, | 15 | AssistContext, AssistId, AssistKind, Assists, |
17 | }; | 16 | }; |
@@ -24,7 +23,7 @@ use crate::{ | |||
24 | // struct Baz; | 23 | // struct Baz; |
25 | // fn baz() -> Baz { Baz } | 24 | // fn baz() -> Baz { Baz } |
26 | // fn foo() { | 25 | // fn foo() { |
27 | // bar<|>("", baz()); | 26 | // bar$0("", baz()); |
28 | // } | 27 | // } |
29 | // | 28 | // |
30 | // ``` | 29 | // ``` |
@@ -343,7 +342,7 @@ mod tests { | |||
343 | generate_function, | 342 | generate_function, |
344 | r" | 343 | r" |
345 | fn foo() { | 344 | fn foo() { |
346 | bar<|>(); | 345 | bar$0(); |
347 | } | 346 | } |
348 | ", | 347 | ", |
349 | r" | 348 | r" |
@@ -367,7 +366,7 @@ fn bar() ${0:-> ()} { | |||
367 | r" | 366 | r" |
368 | impl Foo { | 367 | impl Foo { |
369 | fn foo() { | 368 | fn foo() { |
370 | bar<|>(); | 369 | bar$0(); |
371 | } | 370 | } |
372 | } | 371 | } |
373 | ", | 372 | ", |
@@ -392,7 +391,7 @@ fn bar() ${0:-> ()} { | |||
392 | generate_function, | 391 | generate_function, |
393 | r" | 392 | r" |
394 | fn foo1() { | 393 | fn foo1() { |
395 | bar<|>(); | 394 | bar$0(); |
396 | } | 395 | } |
397 | 396 | ||
398 | fn foo2() {} | 397 | fn foo2() {} |
@@ -418,7 +417,7 @@ fn foo2() {} | |||
418 | r" | 417 | r" |
419 | mod baz { | 418 | mod baz { |
420 | fn foo() { | 419 | fn foo() { |
421 | bar<|>(); | 420 | bar$0(); |
422 | } | 421 | } |
423 | } | 422 | } |
424 | ", | 423 | ", |
@@ -444,7 +443,7 @@ mod baz { | |||
444 | struct Baz; | 443 | struct Baz; |
445 | fn baz() -> Baz { todo!() } | 444 | fn baz() -> Baz { todo!() } |
446 | fn foo() { | 445 | fn foo() { |
447 | bar<|>(baz()); | 446 | bar$0(baz()); |
448 | } | 447 | } |
449 | ", | 448 | ", |
450 | r" | 449 | r" |
@@ -469,7 +468,7 @@ fn bar(baz: Baz) ${0:-> ()} { | |||
469 | struct Baz; | 468 | struct Baz; |
470 | impl Baz { | 469 | impl Baz { |
471 | fn foo(&self) -> Baz { | 470 | fn foo(&self) -> Baz { |
472 | ba<|>r(self.baz()) | 471 | ba$0r(self.baz()) |
473 | } | 472 | } |
474 | fn baz(&self) -> Baz { | 473 | fn baz(&self) -> Baz { |
475 | Baz | 474 | Baz |
@@ -500,7 +499,7 @@ fn bar(baz: Baz) ${0:-> ()} { | |||
500 | generate_function, | 499 | generate_function, |
501 | r#" | 500 | r#" |
502 | fn foo() { | 501 | fn foo() { |
503 | <|>bar("bar") | 502 | $0bar("bar") |
504 | } | 503 | } |
505 | "#, | 504 | "#, |
506 | r#" | 505 | r#" |
@@ -521,7 +520,7 @@ fn bar(arg: &str) ${0:-> ()} { | |||
521 | generate_function, | 520 | generate_function, |
522 | r#" | 521 | r#" |
523 | fn foo() { | 522 | fn foo() { |
524 | <|>bar('x') | 523 | $0bar('x') |
525 | } | 524 | } |
526 | "#, | 525 | "#, |
527 | r#" | 526 | r#" |
@@ -542,7 +541,7 @@ fn bar(arg: char) ${0:-> ()} { | |||
542 | generate_function, | 541 | generate_function, |
543 | r" | 542 | r" |
544 | fn foo() { | 543 | fn foo() { |
545 | <|>bar(42) | 544 | $0bar(42) |
546 | } | 545 | } |
547 | ", | 546 | ", |
548 | r" | 547 | r" |
@@ -563,7 +562,7 @@ fn bar(arg: i32) ${0:-> ()} { | |||
563 | generate_function, | 562 | generate_function, |
564 | r" | 563 | r" |
565 | fn foo() { | 564 | fn foo() { |
566 | <|>bar(42 as u8) | 565 | $0bar(42 as u8) |
567 | } | 566 | } |
568 | ", | 567 | ", |
569 | r" | 568 | r" |
@@ -587,7 +586,7 @@ fn bar(arg: u8) ${0:-> ()} { | |||
587 | r" | 586 | r" |
588 | fn foo() { | 587 | fn foo() { |
589 | let x = 42; | 588 | let x = 42; |
590 | bar<|>(x as u8) | 589 | bar$0(x as u8) |
591 | } | 590 | } |
592 | ", | 591 | ", |
593 | r" | 592 | r" |
@@ -610,7 +609,7 @@ fn bar(x: u8) ${0:-> ()} { | |||
610 | r" | 609 | r" |
611 | fn foo() { | 610 | fn foo() { |
612 | let worble = (); | 611 | let worble = (); |
613 | <|>bar(worble) | 612 | $0bar(worble) |
614 | } | 613 | } |
615 | ", | 614 | ", |
616 | r" | 615 | r" |
@@ -636,7 +635,7 @@ fn foo() -> impl Foo { | |||
636 | todo!() | 635 | todo!() |
637 | } | 636 | } |
638 | fn baz() { | 637 | fn baz() { |
639 | <|>bar(foo()) | 638 | $0bar(foo()) |
640 | } | 639 | } |
641 | ", | 640 | ", |
642 | r" | 641 | r" |
@@ -664,7 +663,7 @@ struct Baz; | |||
664 | fn baz() -> Baz { todo!() } | 663 | fn baz() -> Baz { todo!() } |
665 | 664 | ||
666 | fn foo() { | 665 | fn foo() { |
667 | bar<|>(&baz()) | 666 | bar$0(&baz()) |
668 | } | 667 | } |
669 | ", | 668 | ", |
670 | r" | 669 | r" |
@@ -692,7 +691,7 @@ mod Baz { | |||
692 | pub fn baz() -> Bof { Bof } | 691 | pub fn baz() -> Bof { Bof } |
693 | } | 692 | } |
694 | fn foo() { | 693 | fn foo() { |
695 | <|>bar(Baz::baz()) | 694 | $0bar(Baz::baz()) |
696 | } | 695 | } |
697 | ", | 696 | ", |
698 | r" | 697 | r" |
@@ -719,7 +718,7 @@ fn bar(baz: Baz::Bof) ${0:-> ()} { | |||
719 | generate_function, | 718 | generate_function, |
720 | r" | 719 | r" |
721 | fn foo<T>(t: T) { | 720 | fn foo<T>(t: T) { |
722 | <|>bar(t) | 721 | $0bar(t) |
723 | } | 722 | } |
724 | ", | 723 | ", |
725 | r" | 724 | r" |
@@ -746,7 +745,7 @@ impl Baz { | |||
746 | fn new() -> Self { Baz } | 745 | fn new() -> Self { Baz } |
747 | } | 746 | } |
748 | fn foo() { | 747 | fn foo() { |
749 | <|>bar(Baz::new); | 748 | $0bar(Baz::new); |
750 | } | 749 | } |
751 | ", | 750 | ", |
752 | r" | 751 | r" |
@@ -774,7 +773,7 @@ fn bar(arg: fn() -> Baz) ${0:-> ()} { | |||
774 | r" | 773 | r" |
775 | fn foo() { | 774 | fn foo() { |
776 | let closure = |x: i64| x - 1; | 775 | let closure = |x: i64| x - 1; |
777 | <|>bar(closure) | 776 | $0bar(closure) |
778 | } | 777 | } |
779 | ", | 778 | ", |
780 | r" | 779 | r" |
@@ -796,7 +795,7 @@ fn bar(closure: impl Fn(i64) -> i64) ${0:-> ()} { | |||
796 | generate_function, | 795 | generate_function, |
797 | r" | 796 | r" |
798 | fn foo() { | 797 | fn foo() { |
799 | <|>bar(baz) | 798 | $0bar(baz) |
800 | } | 799 | } |
801 | ", | 800 | ", |
802 | r" | 801 | r" |
@@ -819,7 +818,7 @@ fn bar(baz: ()) ${0:-> ()} { | |||
819 | struct Baz; | 818 | struct Baz; |
820 | fn baz() -> Baz { Baz } | 819 | fn baz() -> Baz { Baz } |
821 | fn foo() { | 820 | fn foo() { |
822 | <|>bar(baz(), baz()) | 821 | $0bar(baz(), baz()) |
823 | } | 822 | } |
824 | ", | 823 | ", |
825 | r" | 824 | r" |
@@ -844,7 +843,7 @@ fn bar(baz_1: Baz, baz_2: Baz) ${0:-> ()} { | |||
844 | struct Baz; | 843 | struct Baz; |
845 | fn baz() -> Baz { Baz } | 844 | fn baz() -> Baz { Baz } |
846 | fn foo() { | 845 | fn foo() { |
847 | <|>bar(baz(), baz(), "foo", "bar") | 846 | $0bar(baz(), baz(), "foo", "bar") |
848 | } | 847 | } |
849 | "#, | 848 | "#, |
850 | r#" | 849 | r#" |
@@ -869,7 +868,7 @@ fn bar(baz_1: Baz, baz_2: Baz, arg_1: &str, arg_2: &str) ${0:-> ()} { | |||
869 | mod bar {} | 868 | mod bar {} |
870 | 869 | ||
871 | fn foo() { | 870 | fn foo() { |
872 | bar::my_fn<|>() | 871 | bar::my_fn$0() |
873 | } | 872 | } |
874 | ", | 873 | ", |
875 | r" | 874 | r" |
@@ -900,7 +899,7 @@ mod foo { | |||
900 | fn bar() { | 899 | fn bar() { |
901 | use foo::Foo; | 900 | use foo::Foo; |
902 | let foo = Foo; | 901 | let foo = Foo; |
903 | baz<|>(foo) | 902 | baz$0(foo) |
904 | } | 903 | } |
905 | ", | 904 | ", |
906 | " | 905 | " |
@@ -930,7 +929,7 @@ mod bar { | |||
930 | } | 929 | } |
931 | 930 | ||
932 | fn foo() { | 931 | fn foo() { |
933 | bar::my_fn<|>() | 932 | bar::my_fn$0() |
934 | } | 933 | } |
935 | ", | 934 | ", |
936 | r" | 935 | r" |
@@ -959,7 +958,7 @@ mod bar { | |||
959 | } | 958 | } |
960 | 959 | ||
961 | fn foo() { | 960 | fn foo() { |
962 | bar::baz::my_fn<|>() | 961 | bar::baz::my_fn$0() |
963 | } | 962 | } |
964 | ", | 963 | ", |
965 | r" | 964 | r" |
@@ -987,7 +986,7 @@ fn foo() { | |||
987 | mod foo; | 986 | mod foo; |
988 | 987 | ||
989 | fn main() { | 988 | fn main() { |
990 | foo::bar<|>() | 989 | foo::bar$0() |
991 | } | 990 | } |
992 | //- /foo.rs | 991 | //- /foo.rs |
993 | ", | 992 | ", |
@@ -1006,7 +1005,7 @@ pub(crate) fn bar() ${0:-> ()} { | |||
1006 | generate_function, | 1005 | generate_function, |
1007 | r" | 1006 | r" |
1008 | fn foo() { | 1007 | fn foo() { |
1009 | bar<|>(); | 1008 | bar$0(); |
1010 | } | 1009 | } |
1011 | 1010 | ||
1012 | fn bar() {} | 1011 | fn bar() {} |
@@ -1023,7 +1022,7 @@ fn bar() {} | |||
1023 | generate_function, | 1022 | generate_function, |
1024 | r" | 1023 | r" |
1025 | fn foo() { | 1024 | fn foo() { |
1026 | bar(b<|>az); | 1025 | bar(b$0az); |
1027 | } | 1026 | } |
1028 | 1027 | ||
1029 | fn bar(baz: ()) {} | 1028 | fn bar(baz: ()) {} |
@@ -1040,7 +1039,7 @@ fn bar(baz: ()) {} | |||
1040 | struct Foo; | 1039 | struct Foo; |
1041 | impl Foo { | 1040 | impl Foo { |
1042 | fn foo(&self) { | 1041 | fn foo(&self) { |
1043 | self.bar()<|>; | 1042 | self.bar()$0; |
1044 | } | 1043 | } |
1045 | } | 1044 | } |
1046 | ", | 1045 | ", |
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs index 960af5ab3..9af45192b 100644 --- a/crates/assists/src/handlers/generate_impl.rs +++ b/crates/assists/src/handlers/generate_impl.rs | |||
@@ -10,7 +10,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
10 | // | 10 | // |
11 | // ``` | 11 | // ``` |
12 | // struct Ctx<T: Clone> { | 12 | // struct Ctx<T: Clone> { |
13 | // data: T,<|> | 13 | // data: T,$0 |
14 | // } | 14 | // } |
15 | // ``` | 15 | // ``` |
16 | // -> | 16 | // -> |
@@ -87,24 +87,24 @@ mod tests { | |||
87 | fn test_add_impl() { | 87 | fn test_add_impl() { |
88 | check_assist( | 88 | check_assist( |
89 | generate_impl, | 89 | generate_impl, |
90 | "struct Foo {<|>}\n", | 90 | "struct Foo {$0}\n", |
91 | "struct Foo {}\n\nimpl Foo {\n $0\n}\n", | 91 | "struct Foo {}\n\nimpl Foo {\n $0\n}\n", |
92 | ); | 92 | ); |
93 | check_assist( | 93 | check_assist( |
94 | generate_impl, | 94 | generate_impl, |
95 | "struct Foo<T: Clone> {<|>}", | 95 | "struct Foo<T: Clone> {$0}", |
96 | "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}", | 96 | "struct Foo<T: Clone> {}\n\nimpl<T: Clone> Foo<T> {\n $0\n}", |
97 | ); | 97 | ); |
98 | check_assist( | 98 | check_assist( |
99 | generate_impl, | 99 | generate_impl, |
100 | "struct Foo<'a, T: Foo<'a>> {<|>}", | 100 | "struct Foo<'a, T: Foo<'a>> {$0}", |
101 | "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", | 101 | "struct Foo<'a, T: Foo<'a>> {}\n\nimpl<'a, T: Foo<'a>> Foo<'a, T> {\n $0\n}", |
102 | ); | 102 | ); |
103 | check_assist( | 103 | check_assist( |
104 | generate_impl, | 104 | generate_impl, |
105 | r#" | 105 | r#" |
106 | #[cfg(feature = "foo")] | 106 | #[cfg(feature = "foo")] |
107 | struct Foo<'a, T: Foo<'a>> {<|>}"#, | 107 | struct Foo<'a, T: Foo<'a>> {$0}"#, |
108 | r#" | 108 | r#" |
109 | #[cfg(feature = "foo")] | 109 | #[cfg(feature = "foo")] |
110 | struct Foo<'a, T: Foo<'a>> {} | 110 | struct Foo<'a, T: Foo<'a>> {} |
@@ -119,7 +119,7 @@ mod tests { | |||
119 | generate_impl, | 119 | generate_impl, |
120 | r#" | 120 | r#" |
121 | #[cfg(not(feature = "foo"))] | 121 | #[cfg(not(feature = "foo"))] |
122 | struct Foo<'a, T: Foo<'a>> {<|>}"#, | 122 | struct Foo<'a, T: Foo<'a>> {$0}"#, |
123 | r#" | 123 | r#" |
124 | #[cfg(not(feature = "foo"))] | 124 | #[cfg(not(feature = "foo"))] |
125 | struct Foo<'a, T: Foo<'a>> {} | 125 | struct Foo<'a, T: Foo<'a>> {} |
@@ -138,7 +138,7 @@ mod tests { | |||
138 | " | 138 | " |
139 | struct SomeThingIrrelevant; | 139 | struct SomeThingIrrelevant; |
140 | /// Has a lifetime parameter | 140 | /// Has a lifetime parameter |
141 | struct Foo<'a, T: Foo<'a>> {<|>} | 141 | struct Foo<'a, T: Foo<'a>> {$0} |
142 | struct EvenMoreIrrelevant; | 142 | struct EvenMoreIrrelevant; |
143 | ", | 143 | ", |
144 | "/// Has a lifetime parameter | 144 | "/// Has a lifetime parameter |
diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs index c5fec4e0a..5c52b2bc8 100644 --- a/crates/assists/src/handlers/generate_new.rs +++ b/crates/assists/src/handlers/generate_new.rs | |||
@@ -14,7 +14,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
14 | // | 14 | // |
15 | // ``` | 15 | // ``` |
16 | // struct Ctx<T: Clone> { | 16 | // struct Ctx<T: Clone> { |
17 | // data: T,<|> | 17 | // data: T,$0 |
18 | // } | 18 | // } |
19 | // ``` | 19 | // ``` |
20 | // -> | 20 | // -> |
@@ -182,7 +182,7 @@ mod tests { | |||
182 | // Check output of generation | 182 | // Check output of generation |
183 | check_assist( | 183 | check_assist( |
184 | generate_new, | 184 | generate_new, |
185 | "struct Foo {<|>}", | 185 | "struct Foo {$0}", |
186 | "struct Foo {} | 186 | "struct Foo {} |
187 | 187 | ||
188 | impl Foo { | 188 | impl Foo { |
@@ -192,7 +192,7 @@ impl Foo { | |||
192 | ); | 192 | ); |
193 | check_assist( | 193 | check_assist( |
194 | generate_new, | 194 | generate_new, |
195 | "struct Foo<T: Clone> {<|>}", | 195 | "struct Foo<T: Clone> {$0}", |
196 | "struct Foo<T: Clone> {} | 196 | "struct Foo<T: Clone> {} |
197 | 197 | ||
198 | impl<T: Clone> Foo<T> { | 198 | impl<T: Clone> Foo<T> { |
@@ -202,7 +202,7 @@ impl<T: Clone> Foo<T> { | |||
202 | ); | 202 | ); |
203 | check_assist( | 203 | check_assist( |
204 | generate_new, | 204 | generate_new, |
205 | "struct Foo<'a, T: Foo<'a>> {<|>}", | 205 | "struct Foo<'a, T: Foo<'a>> {$0}", |
206 | "struct Foo<'a, T: Foo<'a>> {} | 206 | "struct Foo<'a, T: Foo<'a>> {} |
207 | 207 | ||
208 | impl<'a, T: Foo<'a>> Foo<'a, T> { | 208 | impl<'a, T: Foo<'a>> Foo<'a, T> { |
@@ -212,7 +212,7 @@ impl<'a, T: Foo<'a>> Foo<'a, T> { | |||
212 | ); | 212 | ); |
213 | check_assist( | 213 | check_assist( |
214 | generate_new, | 214 | generate_new, |
215 | "struct Foo { baz: String <|>}", | 215 | "struct Foo { baz: String $0}", |
216 | "struct Foo { baz: String } | 216 | "struct Foo { baz: String } |
217 | 217 | ||
218 | impl Foo { | 218 | impl Foo { |
@@ -222,7 +222,7 @@ impl Foo { | |||
222 | ); | 222 | ); |
223 | check_assist( | 223 | check_assist( |
224 | generate_new, | 224 | generate_new, |
225 | "struct Foo { baz: String, qux: Vec<i32> <|>}", | 225 | "struct Foo { baz: String, qux: Vec<i32> $0}", |
226 | "struct Foo { baz: String, qux: Vec<i32> } | 226 | "struct Foo { baz: String, qux: Vec<i32> } |
227 | 227 | ||
228 | impl Foo { | 228 | impl Foo { |
@@ -234,7 +234,7 @@ impl Foo { | |||
234 | // Check that visibility modifiers don't get brought in for fields | 234 | // Check that visibility modifiers don't get brought in for fields |
235 | check_assist( | 235 | check_assist( |
236 | generate_new, | 236 | generate_new, |
237 | "struct Foo { pub baz: String, pub qux: Vec<i32> <|>}", | 237 | "struct Foo { pub baz: String, pub qux: Vec<i32> $0}", |
238 | "struct Foo { pub baz: String, pub qux: Vec<i32> } | 238 | "struct Foo { pub baz: String, pub qux: Vec<i32> } |
239 | 239 | ||
240 | impl Foo { | 240 | impl Foo { |
@@ -246,7 +246,7 @@ impl Foo { | |||
246 | // Check that it reuses existing impls | 246 | // Check that it reuses existing impls |
247 | check_assist( | 247 | check_assist( |
248 | generate_new, | 248 | generate_new, |
249 | "struct Foo {<|>} | 249 | "struct Foo {$0} |
250 | 250 | ||
251 | impl Foo {} | 251 | impl Foo {} |
252 | ", | 252 | ", |
@@ -259,7 +259,7 @@ impl Foo { | |||
259 | ); | 259 | ); |
260 | check_assist( | 260 | check_assist( |
261 | generate_new, | 261 | generate_new, |
262 | "struct Foo {<|>} | 262 | "struct Foo {$0} |
263 | 263 | ||
264 | impl Foo { | 264 | impl Foo { |
265 | fn qux(&self) {} | 265 | fn qux(&self) {} |
@@ -277,7 +277,7 @@ impl Foo { | |||
277 | 277 | ||
278 | check_assist( | 278 | check_assist( |
279 | generate_new, | 279 | generate_new, |
280 | "struct Foo {<|>} | 280 | "struct Foo {$0} |
281 | 281 | ||
282 | impl Foo { | 282 | impl Foo { |
283 | fn qux(&self) {} | 283 | fn qux(&self) {} |
@@ -302,7 +302,7 @@ impl Foo { | |||
302 | // Check visibility of new fn based on struct | 302 | // Check visibility of new fn based on struct |
303 | check_assist( | 303 | check_assist( |
304 | generate_new, | 304 | generate_new, |
305 | "pub struct Foo {<|>}", | 305 | "pub struct Foo {$0}", |
306 | "pub struct Foo {} | 306 | "pub struct Foo {} |
307 | 307 | ||
308 | impl Foo { | 308 | impl Foo { |
@@ -312,7 +312,7 @@ impl Foo { | |||
312 | ); | 312 | ); |
313 | check_assist( | 313 | check_assist( |
314 | generate_new, | 314 | generate_new, |
315 | "pub(crate) struct Foo {<|>}", | 315 | "pub(crate) struct Foo {$0}", |
316 | "pub(crate) struct Foo {} | 316 | "pub(crate) struct Foo {} |
317 | 317 | ||
318 | impl Foo { | 318 | impl Foo { |
@@ -327,7 +327,7 @@ impl Foo { | |||
327 | check_assist_not_applicable( | 327 | check_assist_not_applicable( |
328 | generate_new, | 328 | generate_new, |
329 | " | 329 | " |
330 | struct Foo {<|>} | 330 | struct Foo {$0} |
331 | 331 | ||
332 | impl Foo { | 332 | impl Foo { |
333 | fn new() -> Self { | 333 | fn new() -> Self { |
@@ -339,7 +339,7 @@ impl Foo { | |||
339 | check_assist_not_applicable( | 339 | check_assist_not_applicable( |
340 | generate_new, | 340 | generate_new, |
341 | " | 341 | " |
342 | struct Foo {<|>} | 342 | struct Foo {$0} |
343 | 343 | ||
344 | impl Foo { | 344 | impl Foo { |
345 | fn New() -> Self { | 345 | fn New() -> Self { |
@@ -356,7 +356,7 @@ impl Foo { | |||
356 | " | 356 | " |
357 | struct SomeThingIrrelevant; | 357 | struct SomeThingIrrelevant; |
358 | /// Has a lifetime parameter | 358 | /// Has a lifetime parameter |
359 | struct Foo<'a, T: Foo<'a>> {<|>} | 359 | struct Foo<'a, T: Foo<'a>> {$0} |
360 | struct EvenMoreIrrelevant; | 360 | struct EvenMoreIrrelevant; |
361 | ", | 361 | ", |
362 | "/// Has a lifetime parameter | 362 | "/// Has a lifetime parameter |
@@ -381,7 +381,7 @@ impl<N: AstNode> AstId<N> { | |||
381 | } | 381 | } |
382 | 382 | ||
383 | pub struct Source<T> { | 383 | pub struct Source<T> { |
384 | pub file_id: HirFileId,<|> | 384 | pub file_id: HirFileId,$0 |
385 | pub ast: T, | 385 | pub ast: T, |
386 | } | 386 | } |
387 | 387 | ||
diff --git a/crates/assists/src/handlers/infer_function_return_type.rs b/crates/assists/src/handlers/infer_function_return_type.rs index aa584eb03..5279af1f3 100644 --- a/crates/assists/src/handlers/infer_function_return_type.rs +++ b/crates/assists/src/handlers/infer_function_return_type.rs | |||
@@ -10,7 +10,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
10 | // type specified. This assists is useable in a functions or closures tail expression or return type position. | 10 | // type specified. This assists is useable in a functions or closures tail expression or return type position. |
11 | // | 11 | // |
12 | // ``` | 12 | // ``` |
13 | // fn foo() { 4<|>2i32 } | 13 | // fn foo() { 4$02i32 } |
14 | // ``` | 14 | // ``` |
15 | // -> | 15 | // -> |
16 | // ``` | 16 | // ``` |
@@ -89,7 +89,7 @@ fn extract_tail(ctx: &AssistContext) -> Option<(FnType, ast::Expr, InsertOrRepla | |||
89 | let body = closure.body()?; | 89 | let body = closure.body()?; |
90 | let body_start = body.syntax().first_token()?.text_range().start(); | 90 | let body_start = body.syntax().first_token()?.text_range().start(); |
91 | let (tail_expr, wrap_expr) = match body { | 91 | let (tail_expr, wrap_expr) = match body { |
92 | ast::Expr::BlockExpr(block) => (block.expr()?, false), | 92 | ast::Expr::BlockExpr(block) => (block.tail_expr()?, false), |
93 | body => (body, true), | 93 | body => (body, true), |
94 | }; | 94 | }; |
95 | 95 | ||
@@ -101,7 +101,7 @@ fn extract_tail(ctx: &AssistContext) -> Option<(FnType, ast::Expr, InsertOrRepla | |||
101 | let action = ret_ty_to_action(func.ret_type(), rparen_pos)?; | 101 | let action = ret_ty_to_action(func.ret_type(), rparen_pos)?; |
102 | 102 | ||
103 | let body = func.body()?; | 103 | let body = func.body()?; |
104 | let tail_expr = body.expr()?; | 104 | let tail_expr = body.tail_expr()?; |
105 | 105 | ||
106 | let ret_range_end = body.l_curly_token()?.text_range().start(); | 106 | let ret_range_end = body.l_curly_token()?.text_range().start(); |
107 | let ret_range = TextRange::new(rparen_pos, ret_range_end); | 107 | let ret_range = TextRange::new(rparen_pos, ret_range_end); |
@@ -131,7 +131,7 @@ mod tests { | |||
131 | mark::check!(existing_infer_ret_type); | 131 | mark::check!(existing_infer_ret_type); |
132 | check_assist( | 132 | check_assist( |
133 | infer_function_return_type, | 133 | infer_function_return_type, |
134 | r#"fn foo() -> <|>_ { | 134 | r#"fn foo() -> $0_ { |
135 | 45 | 135 | 45 |
136 | }"#, | 136 | }"#, |
137 | r#"fn foo() -> i32 { | 137 | r#"fn foo() -> i32 { |
@@ -146,7 +146,7 @@ mod tests { | |||
146 | check_assist( | 146 | check_assist( |
147 | infer_function_return_type, | 147 | infer_function_return_type, |
148 | r#"fn foo() { | 148 | r#"fn foo() { |
149 | || -> _ {<|>45}; | 149 | || -> _ {$045}; |
150 | }"#, | 150 | }"#, |
151 | r#"fn foo() { | 151 | r#"fn foo() { |
152 | || -> i32 {45}; | 152 | || -> i32 {45}; |
@@ -159,7 +159,7 @@ mod tests { | |||
159 | mark::check!(cursor_in_ret_position); | 159 | mark::check!(cursor_in_ret_position); |
160 | check_assist( | 160 | check_assist( |
161 | infer_function_return_type, | 161 | infer_function_return_type, |
162 | r#"fn foo() <|>{ | 162 | r#"fn foo() $0{ |
163 | 45 | 163 | 45 |
164 | }"#, | 164 | }"#, |
165 | r#"fn foo() -> i32 { | 165 | r#"fn foo() -> i32 { |
@@ -174,7 +174,7 @@ mod tests { | |||
174 | check_assist( | 174 | check_assist( |
175 | infer_function_return_type, | 175 | infer_function_return_type, |
176 | r#"fn foo() { | 176 | r#"fn foo() { |
177 | || <|>45 | 177 | || $045 |
178 | }"#, | 178 | }"#, |
179 | r#"fn foo() { | 179 | r#"fn foo() { |
180 | || -> i32 {45} | 180 | || -> i32 {45} |
@@ -188,7 +188,7 @@ mod tests { | |||
188 | check_assist( | 188 | check_assist( |
189 | infer_function_return_type, | 189 | infer_function_return_type, |
190 | r#"fn foo() { | 190 | r#"fn foo() { |
191 | 45<|> | 191 | 45$0 |
192 | }"#, | 192 | }"#, |
193 | r#"fn foo() -> i32 { | 193 | r#"fn foo() -> i32 { |
194 | 45 | 194 | 45 |
@@ -202,7 +202,7 @@ mod tests { | |||
202 | infer_function_return_type, | 202 | infer_function_return_type, |
203 | r#"fn foo() { | 203 | r#"fn foo() { |
204 | if true { | 204 | if true { |
205 | 3<|> | 205 | 3$0 |
206 | } else { | 206 | } else { |
207 | 5 | 207 | 5 |
208 | } | 208 | } |
@@ -223,7 +223,7 @@ mod tests { | |||
223 | check_assist_not_applicable( | 223 | check_assist_not_applicable( |
224 | infer_function_return_type, | 224 | infer_function_return_type, |
225 | r#"fn foo() -> i32 { | 225 | r#"fn foo() -> i32 { |
226 | ( 45<|> + 32 ) * 123 | 226 | ( 45$0 + 32 ) * 123 |
227 | }"#, | 227 | }"#, |
228 | ); | 228 | ); |
229 | } | 229 | } |
@@ -233,7 +233,7 @@ mod tests { | |||
233 | check_assist_not_applicable( | 233 | check_assist_not_applicable( |
234 | infer_function_return_type, | 234 | infer_function_return_type, |
235 | r#"fn foo() { | 235 | r#"fn foo() { |
236 | let x = <|>3; | 236 | let x = $03; |
237 | ( 45 + 32 ) * 123 | 237 | ( 45 + 32 ) * 123 |
238 | }"#, | 238 | }"#, |
239 | ); | 239 | ); |
@@ -244,7 +244,7 @@ mod tests { | |||
244 | check_assist_not_applicable( | 244 | check_assist_not_applicable( |
245 | infer_function_return_type, | 245 | infer_function_return_type, |
246 | r#"fn foo() { | 246 | r#"fn foo() { |
247 | (<|>) | 247 | ($0) |
248 | }"#, | 248 | }"#, |
249 | ); | 249 | ); |
250 | } | 250 | } |
@@ -256,7 +256,7 @@ mod tests { | |||
256 | infer_function_return_type, | 256 | infer_function_return_type, |
257 | r#"fn foo() { | 257 | r#"fn foo() { |
258 | |x: i32| { | 258 | |x: i32| { |
259 | x<|> | 259 | x$0 |
260 | }; | 260 | }; |
261 | }"#, | 261 | }"#, |
262 | r#"fn foo() { | 262 | r#"fn foo() { |
@@ -272,7 +272,7 @@ mod tests { | |||
272 | check_assist( | 272 | check_assist( |
273 | infer_function_return_type, | 273 | infer_function_return_type, |
274 | r#"fn foo() { | 274 | r#"fn foo() { |
275 | |x: i32| { x<|> }; | 275 | |x: i32| { x$0 }; |
276 | }"#, | 276 | }"#, |
277 | r#"fn foo() { | 277 | r#"fn foo() { |
278 | |x: i32| -> i32 { x }; | 278 | |x: i32| -> i32 { x }; |
@@ -286,7 +286,7 @@ mod tests { | |||
286 | check_assist( | 286 | check_assist( |
287 | infer_function_return_type, | 287 | infer_function_return_type, |
288 | r#"fn foo() { | 288 | r#"fn foo() { |
289 | |x: i32| x<|>; | 289 | |x: i32| x$0; |
290 | }"#, | 290 | }"#, |
291 | r#"fn foo() { | 291 | r#"fn foo() { |
292 | |x: i32| -> i32 {x}; | 292 | |x: i32| -> i32 {x}; |
@@ -301,7 +301,7 @@ mod tests { | |||
301 | r#"fn foo() { | 301 | r#"fn foo() { |
302 | || { | 302 | || { |
303 | if true { | 303 | if true { |
304 | 3<|> | 304 | 3$0 |
305 | } else { | 305 | } else { |
306 | 5 | 306 | 5 |
307 | } | 307 | } |
@@ -325,7 +325,7 @@ mod tests { | |||
325 | check_assist_not_applicable( | 325 | check_assist_not_applicable( |
326 | infer_function_return_type, | 326 | infer_function_return_type, |
327 | r#"fn foo() { | 327 | r#"fn foo() { |
328 | || -> i32 { 3<|> } | 328 | || -> i32 { 3$0 } |
329 | }"#, | 329 | }"#, |
330 | ); | 330 | ); |
331 | } | 331 | } |
@@ -336,7 +336,7 @@ mod tests { | |||
336 | infer_function_return_type, | 336 | infer_function_return_type, |
337 | r#"fn foo() { | 337 | r#"fn foo() { |
338 | || -> i32 { | 338 | || -> i32 { |
339 | let x = 3<|>; | 339 | let x = 3$0; |
340 | 6 | 340 | 6 |
341 | } | 341 | } |
342 | }"#, | 342 | }"#, |
diff --git a/crates/assists/src/handlers/inline_function.rs b/crates/assists/src/handlers/inline_function.rs new file mode 100644 index 000000000..6ec99b09b --- /dev/null +++ b/crates/assists/src/handlers/inline_function.rs | |||
@@ -0,0 +1,202 @@ | |||
1 | use ast::make; | ||
2 | use hir::{HasSource, PathResolution}; | ||
3 | use syntax::{ | ||
4 | ast::{self, edit::AstNodeEdit, ArgListOwner}, | ||
5 | AstNode, | ||
6 | }; | ||
7 | use test_utils::mark; | ||
8 | |||
9 | use crate::{ | ||
10 | assist_context::{AssistContext, Assists}, | ||
11 | AssistId, AssistKind, | ||
12 | }; | ||
13 | |||
14 | // Assist: inline_function | ||
15 | // | ||
16 | // Inlines a function body. | ||
17 | // | ||
18 | // ``` | ||
19 | // fn add(a: u32, b: u32) -> u32 { a + b } | ||
20 | // fn main() { | ||
21 | // let x = add$0(1, 2); | ||
22 | // } | ||
23 | // ``` | ||
24 | // -> | ||
25 | // ``` | ||
26 | // fn add(a: u32, b: u32) -> u32 { a + b } | ||
27 | // fn main() { | ||
28 | // let x = { | ||
29 | // let a = 1; | ||
30 | // let b = 2; | ||
31 | // a + b | ||
32 | // }; | ||
33 | // } | ||
34 | // ``` | ||
35 | pub(crate) fn inline_function(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | ||
36 | let path_expr: ast::PathExpr = ctx.find_node_at_offset()?; | ||
37 | let call = path_expr.syntax().parent().and_then(ast::CallExpr::cast)?; | ||
38 | let path = path_expr.path()?; | ||
39 | |||
40 | let function = match ctx.sema.resolve_path(&path)? { | ||
41 | PathResolution::Def(hir::ModuleDef::Function(f)) => f, | ||
42 | _ => return None, | ||
43 | }; | ||
44 | |||
45 | let function_source = function.source(ctx.db())?; | ||
46 | let arguments: Vec<_> = call.arg_list()?.args().collect(); | ||
47 | let parameters = function_parameter_patterns(&function_source.value)?; | ||
48 | |||
49 | if arguments.len() != parameters.len() { | ||
50 | // Can't inline the function because they've passed the wrong number of | ||
51 | // arguments to this function | ||
52 | mark::hit!(inline_function_incorrect_number_of_arguments); | ||
53 | return None; | ||
54 | } | ||
55 | |||
56 | let new_bindings = parameters.into_iter().zip(arguments); | ||
57 | |||
58 | let body = function_source.value.body()?; | ||
59 | |||
60 | acc.add( | ||
61 | AssistId("inline_function", AssistKind::RefactorInline), | ||
62 | format!("Inline `{}`", path), | ||
63 | call.syntax().text_range(), | ||
64 | |builder| { | ||
65 | let mut statements: Vec<ast::Stmt> = Vec::new(); | ||
66 | |||
67 | for (pattern, value) in new_bindings { | ||
68 | statements.push(make::let_stmt(pattern, Some(value)).into()); | ||
69 | } | ||
70 | |||
71 | statements.extend(body.statements()); | ||
72 | |||
73 | let original_indentation = call.indent_level(); | ||
74 | let replacement = make::block_expr(statements, body.tail_expr()) | ||
75 | .reset_indent() | ||
76 | .indent(original_indentation); | ||
77 | |||
78 | builder.replace_ast(ast::Expr::CallExpr(call), ast::Expr::BlockExpr(replacement)); | ||
79 | }, | ||
80 | ) | ||
81 | } | ||
82 | |||
83 | fn function_parameter_patterns(value: &ast::Fn) -> Option<Vec<ast::Pat>> { | ||
84 | let mut patterns = Vec::new(); | ||
85 | |||
86 | for param in value.param_list()?.params() { | ||
87 | let pattern = param.pat()?; | ||
88 | patterns.push(pattern); | ||
89 | } | ||
90 | |||
91 | Some(patterns) | ||
92 | } | ||
93 | |||
94 | #[cfg(test)] | ||
95 | mod tests { | ||
96 | use crate::tests::{check_assist, check_assist_not_applicable}; | ||
97 | |||
98 | use super::*; | ||
99 | |||
100 | #[test] | ||
101 | fn no_args_or_return_value_gets_inlined_without_block() { | ||
102 | check_assist( | ||
103 | inline_function, | ||
104 | r#" | ||
105 | fn foo() { println!("Hello, World!"); } | ||
106 | fn main() { | ||
107 | fo$0o(); | ||
108 | } | ||
109 | "#, | ||
110 | r#" | ||
111 | fn foo() { println!("Hello, World!"); } | ||
112 | fn main() { | ||
113 | { | ||
114 | println!("Hello, World!"); | ||
115 | }; | ||
116 | } | ||
117 | "#, | ||
118 | ); | ||
119 | } | ||
120 | |||
121 | #[test] | ||
122 | fn args_with_side_effects() { | ||
123 | check_assist( | ||
124 | inline_function, | ||
125 | r#" | ||
126 | fn foo(name: String) { println!("Hello, {}!", name); } | ||
127 | fn main() { | ||
128 | foo$0(String::from("Michael")); | ||
129 | } | ||
130 | "#, | ||
131 | r#" | ||
132 | fn foo(name: String) { println!("Hello, {}!", name); } | ||
133 | fn main() { | ||
134 | { | ||
135 | let name = String::from("Michael"); | ||
136 | println!("Hello, {}!", name); | ||
137 | }; | ||
138 | } | ||
139 | "#, | ||
140 | ); | ||
141 | } | ||
142 | |||
143 | #[test] | ||
144 | fn method_inlining_isnt_supported() { | ||
145 | check_assist_not_applicable( | ||
146 | inline_function, | ||
147 | r" | ||
148 | struct Foo; | ||
149 | impl Foo { fn bar(&self) {} } | ||
150 | |||
151 | fn main() { Foo.bar$0(); } | ||
152 | ", | ||
153 | ); | ||
154 | } | ||
155 | |||
156 | #[test] | ||
157 | fn not_applicable_when_incorrect_number_of_parameters_are_provided() { | ||
158 | mark::check!(inline_function_incorrect_number_of_arguments); | ||
159 | check_assist_not_applicable( | ||
160 | inline_function, | ||
161 | r#" | ||
162 | fn add(a: u32, b: u32) -> u32 { a + b } | ||
163 | fn main() { let x = add$0(42); } | ||
164 | "#, | ||
165 | ); | ||
166 | } | ||
167 | |||
168 | #[test] | ||
169 | fn function_with_multiple_statements() { | ||
170 | check_assist( | ||
171 | inline_function, | ||
172 | r#" | ||
173 | fn foo(a: u32, b: u32) -> u32 { | ||
174 | let x = a + b; | ||
175 | let y = x - b; | ||
176 | x * y | ||
177 | } | ||
178 | |||
179 | fn main() { | ||
180 | let x = foo$0(1, 2); | ||
181 | } | ||
182 | "#, | ||
183 | r#" | ||
184 | fn foo(a: u32, b: u32) -> u32 { | ||
185 | let x = a + b; | ||
186 | let y = x - b; | ||
187 | x * y | ||
188 | } | ||
189 | |||
190 | fn main() { | ||
191 | let x = { | ||
192 | let a = 1; | ||
193 | let b = 2; | ||
194 | let x = a + b; | ||
195 | let y = x - b; | ||
196 | x * y | ||
197 | }; | ||
198 | } | ||
199 | "#, | ||
200 | ); | ||
201 | } | ||
202 | } | ||
diff --git a/crates/assists/src/handlers/inline_local_variable.rs b/crates/assists/src/handlers/inline_local_variable.rs index 587eb5feb..d559be9cb 100644 --- a/crates/assists/src/handlers/inline_local_variable.rs +++ b/crates/assists/src/handlers/inline_local_variable.rs | |||
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | // | 16 | // |
17 | // ``` | 17 | // ``` |
18 | // fn main() { | 18 | // fn main() { |
19 | // let x<|> = 1 + 2; | 19 | // let x$0 = 1 + 2; |
20 | // x * 4; | 20 | // x * 4; |
21 | // } | 21 | // } |
22 | // ``` | 22 | // ``` |
@@ -146,7 +146,7 @@ mod tests { | |||
146 | r" | 146 | r" |
147 | fn bar(a: usize) {} | 147 | fn bar(a: usize) {} |
148 | fn foo() { | 148 | fn foo() { |
149 | let a<|> = 1; | 149 | let a$0 = 1; |
150 | a + 1; | 150 | a + 1; |
151 | if a > 10 { | 151 | if a > 10 { |
152 | } | 152 | } |
@@ -180,7 +180,7 @@ fn foo() { | |||
180 | r" | 180 | r" |
181 | fn bar(a: usize) {} | 181 | fn bar(a: usize) {} |
182 | fn foo() { | 182 | fn foo() { |
183 | let a<|> = 1 + 1; | 183 | let a$0 = 1 + 1; |
184 | a + 1; | 184 | a + 1; |
185 | if a > 10 { | 185 | if a > 10 { |
186 | } | 186 | } |
@@ -214,7 +214,7 @@ fn foo() { | |||
214 | r" | 214 | r" |
215 | fn bar(a: usize) {} | 215 | fn bar(a: usize) {} |
216 | fn foo() { | 216 | fn foo() { |
217 | let a<|> = bar(1); | 217 | let a$0 = bar(1); |
218 | a + 1; | 218 | a + 1; |
219 | if a > 10 { | 219 | if a > 10 { |
220 | } | 220 | } |
@@ -248,7 +248,7 @@ fn foo() { | |||
248 | r" | 248 | r" |
249 | fn bar(a: usize): usize { a } | 249 | fn bar(a: usize): usize { a } |
250 | fn foo() { | 250 | fn foo() { |
251 | let a<|> = bar(1) as u64; | 251 | let a$0 = bar(1) as u64; |
252 | a + 1; | 252 | a + 1; |
253 | if a > 10 { | 253 | if a > 10 { |
254 | } | 254 | } |
@@ -281,7 +281,7 @@ fn foo() { | |||
281 | inline_local_variable, | 281 | inline_local_variable, |
282 | r" | 282 | r" |
283 | fn foo() { | 283 | fn foo() { |
284 | let a<|> = { 10 + 1 }; | 284 | let a$0 = { 10 + 1 }; |
285 | a + 1; | 285 | a + 1; |
286 | if a > 10 { | 286 | if a > 10 { |
287 | } | 287 | } |
@@ -313,7 +313,7 @@ fn foo() { | |||
313 | inline_local_variable, | 313 | inline_local_variable, |
314 | r" | 314 | r" |
315 | fn foo() { | 315 | fn foo() { |
316 | let a<|> = ( 10 + 1 ); | 316 | let a$0 = ( 10 + 1 ); |
317 | a + 1; | 317 | a + 1; |
318 | if a > 10 { | 318 | if a > 10 { |
319 | } | 319 | } |
@@ -346,7 +346,7 @@ fn foo() { | |||
346 | inline_local_variable, | 346 | inline_local_variable, |
347 | r" | 347 | r" |
348 | fn foo() { | 348 | fn foo() { |
349 | let mut a<|> = 1 + 1; | 349 | let mut a$0 = 1 + 1; |
350 | a + 1; | 350 | a + 1; |
351 | }", | 351 | }", |
352 | ); | 352 | ); |
@@ -358,7 +358,7 @@ fn foo() { | |||
358 | inline_local_variable, | 358 | inline_local_variable, |
359 | r" | 359 | r" |
360 | fn foo() { | 360 | fn foo() { |
361 | let a<|> = bar(10 + 1); | 361 | let a$0 = bar(10 + 1); |
362 | let b = a * 10; | 362 | let b = a * 10; |
363 | let c = a as usize; | 363 | let c = a as usize; |
364 | }", | 364 | }", |
@@ -377,7 +377,7 @@ fn foo() { | |||
377 | r" | 377 | r" |
378 | fn foo() { | 378 | fn foo() { |
379 | let x = vec![1, 2, 3]; | 379 | let x = vec![1, 2, 3]; |
380 | let a<|> = x[0]; | 380 | let a$0 = x[0]; |
381 | let b = a * 10; | 381 | let b = a * 10; |
382 | let c = a as usize; | 382 | let c = a as usize; |
383 | }", | 383 | }", |
@@ -397,7 +397,7 @@ fn foo() { | |||
397 | r" | 397 | r" |
398 | fn foo() { | 398 | fn foo() { |
399 | let bar = vec![1]; | 399 | let bar = vec![1]; |
400 | let a<|> = bar.len(); | 400 | let a$0 = bar.len(); |
401 | let b = a * 10; | 401 | let b = a * 10; |
402 | let c = a as usize; | 402 | let c = a as usize; |
403 | }", | 403 | }", |
@@ -421,7 +421,7 @@ struct Bar { | |||
421 | 421 | ||
422 | fn foo() { | 422 | fn foo() { |
423 | let bar = Bar { foo: 1 }; | 423 | let bar = Bar { foo: 1 }; |
424 | let a<|> = bar.foo; | 424 | let a$0 = bar.foo; |
425 | let b = a * 10; | 425 | let b = a * 10; |
426 | let c = a as usize; | 426 | let c = a as usize; |
427 | }", | 427 | }", |
@@ -445,7 +445,7 @@ fn foo() { | |||
445 | r" | 445 | r" |
446 | fn foo() -> Option<usize> { | 446 | fn foo() -> Option<usize> { |
447 | let bar = Some(1); | 447 | let bar = Some(1); |
448 | let a<|> = bar?; | 448 | let a$0 = bar?; |
449 | let b = a * 10; | 449 | let b = a * 10; |
450 | let c = a as usize; | 450 | let c = a as usize; |
451 | None | 451 | None |
@@ -467,7 +467,7 @@ fn foo() -> Option<usize> { | |||
467 | r" | 467 | r" |
468 | fn foo() { | 468 | fn foo() { |
469 | let bar = 10; | 469 | let bar = 10; |
470 | let a<|> = &bar; | 470 | let a$0 = &bar; |
471 | let b = a * 10; | 471 | let b = a * 10; |
472 | }", | 472 | }", |
473 | r" | 473 | r" |
@@ -484,7 +484,7 @@ fn foo() { | |||
484 | inline_local_variable, | 484 | inline_local_variable, |
485 | r" | 485 | r" |
486 | fn foo() { | 486 | fn foo() { |
487 | let a<|> = (10, 20); | 487 | let a$0 = (10, 20); |
488 | let b = a[0]; | 488 | let b = a[0]; |
489 | }", | 489 | }", |
490 | r" | 490 | r" |
@@ -500,7 +500,7 @@ fn foo() { | |||
500 | inline_local_variable, | 500 | inline_local_variable, |
501 | r" | 501 | r" |
502 | fn foo() { | 502 | fn foo() { |
503 | let a<|> = [1, 2, 3]; | 503 | let a$0 = [1, 2, 3]; |
504 | let b = a.len(); | 504 | let b = a.len(); |
505 | }", | 505 | }", |
506 | r" | 506 | r" |
@@ -516,7 +516,7 @@ fn foo() { | |||
516 | inline_local_variable, | 516 | inline_local_variable, |
517 | r" | 517 | r" |
518 | fn foo() { | 518 | fn foo() { |
519 | let a<|> = (10 + 20); | 519 | let a$0 = (10 + 20); |
520 | let b = a * 10; | 520 | let b = a * 10; |
521 | let c = a as usize; | 521 | let c = a as usize; |
522 | }", | 522 | }", |
@@ -535,7 +535,7 @@ fn foo() { | |||
535 | r" | 535 | r" |
536 | fn foo() { | 536 | fn foo() { |
537 | let d = 10; | 537 | let d = 10; |
538 | let a<|> = d; | 538 | let a$0 = d; |
539 | let b = a * 10; | 539 | let b = a * 10; |
540 | let c = a as usize; | 540 | let c = a as usize; |
541 | }", | 541 | }", |
@@ -554,7 +554,7 @@ fn foo() { | |||
554 | inline_local_variable, | 554 | inline_local_variable, |
555 | r" | 555 | r" |
556 | fn foo() { | 556 | fn foo() { |
557 | let a<|> = { 10 }; | 557 | let a$0 = { 10 }; |
558 | let b = a * 10; | 558 | let b = a * 10; |
559 | let c = a as usize; | 559 | let c = a as usize; |
560 | }", | 560 | }", |
@@ -572,7 +572,7 @@ fn foo() { | |||
572 | inline_local_variable, | 572 | inline_local_variable, |
573 | r" | 573 | r" |
574 | fn foo() { | 574 | fn foo() { |
575 | let a<|> = 10 + 20; | 575 | let a$0 = 10 + 20; |
576 | let b = a * 10; | 576 | let b = a * 10; |
577 | let c = (a, 20); | 577 | let c = (a, 20); |
578 | let d = [a, 10]; | 578 | let d = [a, 10]; |
@@ -594,7 +594,7 @@ fn foo() { | |||
594 | inline_local_variable, | 594 | inline_local_variable, |
595 | r" | 595 | r" |
596 | fn foo() { | 596 | fn foo() { |
597 | let a<|> = vec![10, 20]; | 597 | let a$0 = vec![10, 20]; |
598 | for i in a {} | 598 | for i in a {} |
599 | }", | 599 | }", |
600 | r" | 600 | r" |
@@ -610,7 +610,7 @@ fn foo() { | |||
610 | inline_local_variable, | 610 | inline_local_variable, |
611 | r" | 611 | r" |
612 | fn foo() { | 612 | fn foo() { |
613 | let a<|> = 1 > 0; | 613 | let a$0 = 1 > 0; |
614 | while a {} | 614 | while a {} |
615 | }", | 615 | }", |
616 | r" | 616 | r" |
@@ -626,7 +626,7 @@ fn foo() { | |||
626 | inline_local_variable, | 626 | inline_local_variable, |
627 | r" | 627 | r" |
628 | fn foo() { | 628 | fn foo() { |
629 | let a<|> = 1 + 1; | 629 | let a$0 = 1 + 1; |
630 | loop { | 630 | loop { |
631 | break a; | 631 | break a; |
632 | } | 632 | } |
@@ -646,7 +646,7 @@ fn foo() { | |||
646 | inline_local_variable, | 646 | inline_local_variable, |
647 | r" | 647 | r" |
648 | fn foo() { | 648 | fn foo() { |
649 | let a<|> = 1 > 0; | 649 | let a$0 = 1 > 0; |
650 | return a; | 650 | return a; |
651 | }", | 651 | }", |
652 | r" | 652 | r" |
@@ -662,7 +662,7 @@ fn foo() { | |||
662 | inline_local_variable, | 662 | inline_local_variable, |
663 | r" | 663 | r" |
664 | fn foo() { | 664 | fn foo() { |
665 | let a<|> = 1 > 0; | 665 | let a$0 = 1 > 0; |
666 | match a {} | 666 | match a {} |
667 | }", | 667 | }", |
668 | r" | 668 | r" |
@@ -680,7 +680,7 @@ fn foo() { | |||
680 | r" | 680 | r" |
681 | struct S { foo: i32} | 681 | struct S { foo: i32} |
682 | fn main() { | 682 | fn main() { |
683 | let <|>foo = 92; | 683 | let $0foo = 92; |
684 | S { foo } | 684 | S { foo } |
685 | } | 685 | } |
686 | ", | 686 | ", |
@@ -700,7 +700,7 @@ fn main() { | |||
700 | inline_local_variable, | 700 | inline_local_variable, |
701 | r" | 701 | r" |
702 | fn foo() { | 702 | fn foo() { |
703 | let <|>a = 0; | 703 | let $0a = 0; |
704 | } | 704 | } |
705 | ", | 705 | ", |
706 | ) | 706 | ) |
@@ -713,7 +713,7 @@ fn foo() { | |||
713 | inline_local_variable, | 713 | inline_local_variable, |
714 | r" | 714 | r" |
715 | fn main() { | 715 | fn main() { |
716 | let x = <|>1 + 2; | 716 | let x = $01 + 2; |
717 | x * 4; | 717 | x * 4; |
718 | } | 718 | } |
719 | ", | 719 | ", |
diff --git a/crates/assists/src/handlers/introduce_named_lifetime.rs b/crates/assists/src/handlers/introduce_named_lifetime.rs index ab8fe3ea9..3f5f44d69 100644 --- a/crates/assists/src/handlers/introduce_named_lifetime.rs +++ b/crates/assists/src/handlers/introduce_named_lifetime.rs | |||
@@ -14,7 +14,7 @@ static ASSIST_LABEL: &str = "Introduce named lifetime"; | |||
14 | // Change an anonymous lifetime to a named lifetime. | 14 | // Change an anonymous lifetime to a named lifetime. |
15 | // | 15 | // |
16 | // ``` | 16 | // ``` |
17 | // impl Cursor<'_<|>> { | 17 | // impl Cursor<'_$0> { |
18 | // fn node(self) -> &SyntaxNode { | 18 | // fn node(self) -> &SyntaxNode { |
19 | // match self { | 19 | // match self { |
20 | // Cursor::Replace(node) | Cursor::Before(node) => node, | 20 | // Cursor::Replace(node) | Cursor::Before(node) => node, |
@@ -33,7 +33,7 @@ static ASSIST_LABEL: &str = "Introduce named lifetime"; | |||
33 | // } | 33 | // } |
34 | // ``` | 34 | // ``` |
35 | // FIXME: How can we handle renaming any one of multiple anonymous lifetimes? | 35 | // FIXME: How can we handle renaming any one of multiple anonymous lifetimes? |
36 | // FIXME: should also add support for the case fun(f: &Foo) -> &<|>Foo | 36 | // FIXME: should also add support for the case fun(f: &Foo) -> &$0Foo |
37 | pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 37 | pub(crate) fn introduce_named_lifetime(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
38 | let lifetime = | 38 | let lifetime = |
39 | ctx.find_node_at_offset::<ast::Lifetime>().filter(|lifetime| lifetime.text() == "'_")?; | 39 | ctx.find_node_at_offset::<ast::Lifetime>().filter(|lifetime| lifetime.text() == "'_")?; |
@@ -150,7 +150,7 @@ mod tests { | |||
150 | fn test_example_case() { | 150 | fn test_example_case() { |
151 | check_assist( | 151 | check_assist( |
152 | introduce_named_lifetime, | 152 | introduce_named_lifetime, |
153 | r#"impl Cursor<'_<|>> { | 153 | r#"impl Cursor<'_$0> { |
154 | fn node(self) -> &SyntaxNode { | 154 | fn node(self) -> &SyntaxNode { |
155 | match self { | 155 | match self { |
156 | Cursor::Replace(node) | Cursor::Before(node) => node, | 156 | Cursor::Replace(node) | Cursor::Before(node) => node, |
@@ -171,7 +171,7 @@ mod tests { | |||
171 | fn test_example_case_simplified() { | 171 | fn test_example_case_simplified() { |
172 | check_assist( | 172 | check_assist( |
173 | introduce_named_lifetime, | 173 | introduce_named_lifetime, |
174 | r#"impl Cursor<'_<|>> {"#, | 174 | r#"impl Cursor<'_$0> {"#, |
175 | r#"impl<'a> Cursor<'a> {"#, | 175 | r#"impl<'a> Cursor<'a> {"#, |
176 | ); | 176 | ); |
177 | } | 177 | } |
@@ -180,7 +180,7 @@ mod tests { | |||
180 | fn test_example_case_cursor_after_tick() { | 180 | fn test_example_case_cursor_after_tick() { |
181 | check_assist( | 181 | check_assist( |
182 | introduce_named_lifetime, | 182 | introduce_named_lifetime, |
183 | r#"impl Cursor<'<|>_> {"#, | 183 | r#"impl Cursor<'$0_> {"#, |
184 | r#"impl<'a> Cursor<'a> {"#, | 184 | r#"impl<'a> Cursor<'a> {"#, |
185 | ); | 185 | ); |
186 | } | 186 | } |
@@ -189,7 +189,7 @@ mod tests { | |||
189 | fn test_impl_with_other_type_param() { | 189 | fn test_impl_with_other_type_param() { |
190 | check_assist( | 190 | check_assist( |
191 | introduce_named_lifetime, | 191 | introduce_named_lifetime, |
192 | "impl<I> fmt::Display for SepByBuilder<'_<|>, I> | 192 | "impl<I> fmt::Display for SepByBuilder<'_$0, I> |
193 | where | 193 | where |
194 | I: Iterator, | 194 | I: Iterator, |
195 | I::Item: fmt::Display, | 195 | I::Item: fmt::Display, |
@@ -206,28 +206,28 @@ mod tests { | |||
206 | fn test_example_case_cursor_before_tick() { | 206 | fn test_example_case_cursor_before_tick() { |
207 | check_assist( | 207 | check_assist( |
208 | introduce_named_lifetime, | 208 | introduce_named_lifetime, |
209 | r#"impl Cursor<<|>'_> {"#, | 209 | r#"impl Cursor<$0'_> {"#, |
210 | r#"impl<'a> Cursor<'a> {"#, | 210 | r#"impl<'a> Cursor<'a> {"#, |
211 | ); | 211 | ); |
212 | } | 212 | } |
213 | 213 | ||
214 | #[test] | 214 | #[test] |
215 | fn test_not_applicable_cursor_position() { | 215 | fn test_not_applicable_cursor_position() { |
216 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'_><|> {"#); | 216 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'_>$0 {"#); |
217 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<|><'_> {"#); | 217 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor$0<'_> {"#); |
218 | } | 218 | } |
219 | 219 | ||
220 | #[test] | 220 | #[test] |
221 | fn test_not_applicable_lifetime_already_name() { | 221 | fn test_not_applicable_lifetime_already_name() { |
222 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'a<|>> {"#); | 222 | check_assist_not_applicable(introduce_named_lifetime, r#"impl Cursor<'a$0> {"#); |
223 | check_assist_not_applicable(introduce_named_lifetime, r#"fn my_fun<'a>() -> X<'a<|>>"#); | 223 | check_assist_not_applicable(introduce_named_lifetime, r#"fn my_fun<'a>() -> X<'a$0>"#); |
224 | } | 224 | } |
225 | 225 | ||
226 | #[test] | 226 | #[test] |
227 | fn test_with_type_parameter() { | 227 | fn test_with_type_parameter() { |
228 | check_assist( | 228 | check_assist( |
229 | introduce_named_lifetime, | 229 | introduce_named_lifetime, |
230 | r#"impl<T> Cursor<T, '_<|>>"#, | 230 | r#"impl<T> Cursor<T, '_$0>"#, |
231 | r#"impl<T, 'a> Cursor<T, 'a>"#, | 231 | r#"impl<T, 'a> Cursor<T, 'a>"#, |
232 | ); | 232 | ); |
233 | } | 233 | } |
@@ -236,7 +236,7 @@ mod tests { | |||
236 | fn test_with_existing_lifetime_name_conflict() { | 236 | fn test_with_existing_lifetime_name_conflict() { |
237 | check_assist( | 237 | check_assist( |
238 | introduce_named_lifetime, | 238 | introduce_named_lifetime, |
239 | r#"impl<'a, 'b> Cursor<'a, 'b, '_<|>>"#, | 239 | r#"impl<'a, 'b> Cursor<'a, 'b, '_$0>"#, |
240 | r#"impl<'a, 'b, 'c> Cursor<'a, 'b, 'c>"#, | 240 | r#"impl<'a, 'b, 'c> Cursor<'a, 'b, 'c>"#, |
241 | ); | 241 | ); |
242 | } | 242 | } |
@@ -245,7 +245,7 @@ mod tests { | |||
245 | fn test_function_return_value_anon_lifetime_param() { | 245 | fn test_function_return_value_anon_lifetime_param() { |
246 | check_assist( | 246 | check_assist( |
247 | introduce_named_lifetime, | 247 | introduce_named_lifetime, |
248 | r#"fn my_fun() -> X<'_<|>>"#, | 248 | r#"fn my_fun() -> X<'_$0>"#, |
249 | r#"fn my_fun<'a>() -> X<'a>"#, | 249 | r#"fn my_fun<'a>() -> X<'a>"#, |
250 | ); | 250 | ); |
251 | } | 251 | } |
@@ -254,7 +254,7 @@ mod tests { | |||
254 | fn test_function_return_value_anon_reference_lifetime() { | 254 | fn test_function_return_value_anon_reference_lifetime() { |
255 | check_assist( | 255 | check_assist( |
256 | introduce_named_lifetime, | 256 | introduce_named_lifetime, |
257 | r#"fn my_fun() -> &'_<|> X"#, | 257 | r#"fn my_fun() -> &'_$0 X"#, |
258 | r#"fn my_fun<'a>() -> &'a X"#, | 258 | r#"fn my_fun<'a>() -> &'a X"#, |
259 | ); | 259 | ); |
260 | } | 260 | } |
@@ -263,7 +263,7 @@ mod tests { | |||
263 | fn test_function_param_anon_lifetime() { | 263 | fn test_function_param_anon_lifetime() { |
264 | check_assist( | 264 | check_assist( |
265 | introduce_named_lifetime, | 265 | introduce_named_lifetime, |
266 | r#"fn my_fun(x: X<'_<|>>)"#, | 266 | r#"fn my_fun(x: X<'_$0>)"#, |
267 | r#"fn my_fun<'a>(x: X<'a>)"#, | 267 | r#"fn my_fun<'a>(x: X<'a>)"#, |
268 | ); | 268 | ); |
269 | } | 269 | } |
@@ -272,7 +272,7 @@ mod tests { | |||
272 | fn test_function_add_lifetime_to_params() { | 272 | fn test_function_add_lifetime_to_params() { |
273 | check_assist( | 273 | check_assist( |
274 | introduce_named_lifetime, | 274 | introduce_named_lifetime, |
275 | r#"fn my_fun(f: &Foo) -> X<'_<|>>"#, | 275 | r#"fn my_fun(f: &Foo) -> X<'_$0>"#, |
276 | r#"fn my_fun<'a>(f: &'a Foo) -> X<'a>"#, | 276 | r#"fn my_fun<'a>(f: &'a Foo) -> X<'a>"#, |
277 | ); | 277 | ); |
278 | } | 278 | } |
@@ -281,7 +281,7 @@ mod tests { | |||
281 | fn test_function_add_lifetime_to_params_in_presence_of_other_lifetime() { | 281 | fn test_function_add_lifetime_to_params_in_presence_of_other_lifetime() { |
282 | check_assist( | 282 | check_assist( |
283 | introduce_named_lifetime, | 283 | introduce_named_lifetime, |
284 | r#"fn my_fun<'other>(f: &Foo, b: &'other Bar) -> X<'_<|>>"#, | 284 | r#"fn my_fun<'other>(f: &Foo, b: &'other Bar) -> X<'_$0>"#, |
285 | r#"fn my_fun<'other, 'a>(f: &'a Foo, b: &'other Bar) -> X<'a>"#, | 285 | r#"fn my_fun<'other, 'a>(f: &'a Foo, b: &'other Bar) -> X<'a>"#, |
286 | ); | 286 | ); |
287 | } | 287 | } |
@@ -291,7 +291,7 @@ mod tests { | |||
291 | // this is not permitted under lifetime elision rules | 291 | // this is not permitted under lifetime elision rules |
292 | check_assist_not_applicable( | 292 | check_assist_not_applicable( |
293 | introduce_named_lifetime, | 293 | introduce_named_lifetime, |
294 | r#"fn my_fun(f: &Foo, b: &Bar) -> X<'_<|>>"#, | 294 | r#"fn my_fun(f: &Foo, b: &Bar) -> X<'_$0>"#, |
295 | ); | 295 | ); |
296 | } | 296 | } |
297 | 297 | ||
@@ -299,7 +299,7 @@ mod tests { | |||
299 | fn test_function_add_lifetime_to_self_ref_param() { | 299 | fn test_function_add_lifetime_to_self_ref_param() { |
300 | check_assist( | 300 | check_assist( |
301 | introduce_named_lifetime, | 301 | introduce_named_lifetime, |
302 | r#"fn my_fun<'other>(&self, f: &Foo, b: &'other Bar) -> X<'_<|>>"#, | 302 | r#"fn my_fun<'other>(&self, f: &Foo, b: &'other Bar) -> X<'_$0>"#, |
303 | r#"fn my_fun<'other, 'a>(&'a self, f: &Foo, b: &'other Bar) -> X<'a>"#, | 303 | r#"fn my_fun<'other, 'a>(&'a self, f: &Foo, b: &'other Bar) -> X<'a>"#, |
304 | ); | 304 | ); |
305 | } | 305 | } |
@@ -308,7 +308,7 @@ mod tests { | |||
308 | fn test_function_add_lifetime_to_param_with_non_ref_self() { | 308 | fn test_function_add_lifetime_to_param_with_non_ref_self() { |
309 | check_assist( | 309 | check_assist( |
310 | introduce_named_lifetime, | 310 | introduce_named_lifetime, |
311 | r#"fn my_fun<'other>(self, f: &Foo, b: &'other Bar) -> X<'_<|>>"#, | 311 | r#"fn my_fun<'other>(self, f: &Foo, b: &'other Bar) -> X<'_$0>"#, |
312 | r#"fn my_fun<'other, 'a>(self, f: &'a Foo, b: &'other Bar) -> X<'a>"#, | 312 | r#"fn my_fun<'other, 'a>(self, f: &'a Foo, b: &'other Bar) -> X<'a>"#, |
313 | ); | 313 | ); |
314 | } | 314 | } |
diff --git a/crates/assists/src/handlers/invert_if.rs b/crates/assists/src/handlers/invert_if.rs index f9c33b3f7..5b69dafd4 100644 --- a/crates/assists/src/handlers/invert_if.rs +++ b/crates/assists/src/handlers/invert_if.rs | |||
@@ -18,7 +18,7 @@ use crate::{ | |||
18 | // | 18 | // |
19 | // ``` | 19 | // ``` |
20 | // fn main() { | 20 | // fn main() { |
21 | // if<|> !y { A } else { B } | 21 | // if$0 !y { A } else { B } |
22 | // } | 22 | // } |
23 | // ``` | 23 | // ``` |
24 | // -> | 24 | // -> |
@@ -72,7 +72,7 @@ mod tests { | |||
72 | fn invert_if_composite_condition() { | 72 | fn invert_if_composite_condition() { |
73 | check_assist( | 73 | check_assist( |
74 | invert_if, | 74 | invert_if, |
75 | "fn f() { i<|>f x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", | 75 | "fn f() { i$0f x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", |
76 | "fn f() { if !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", | 76 | "fn f() { if !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", |
77 | ) | 77 | ) |
78 | } | 78 | } |
@@ -81,7 +81,7 @@ mod tests { | |||
81 | fn invert_if_remove_not_parentheses() { | 81 | fn invert_if_remove_not_parentheses() { |
82 | check_assist( | 82 | check_assist( |
83 | invert_if, | 83 | invert_if, |
84 | "fn f() { i<|>f !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", | 84 | "fn f() { i$0f !(x == 3 || x == 4 || x == 5) { 3 * 2 } else { 1 } }", |
85 | "fn f() { if x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", | 85 | "fn f() { if x == 3 || x == 4 || x == 5 { 1 } else { 3 * 2 } }", |
86 | ) | 86 | ) |
87 | } | 87 | } |
@@ -90,7 +90,7 @@ mod tests { | |||
90 | fn invert_if_remove_inequality() { | 90 | fn invert_if_remove_inequality() { |
91 | check_assist( | 91 | check_assist( |
92 | invert_if, | 92 | invert_if, |
93 | "fn f() { i<|>f x != 3 { 1 } else { 3 + 2 } }", | 93 | "fn f() { i$0f x != 3 { 1 } else { 3 + 2 } }", |
94 | "fn f() { if x == 3 { 3 + 2 } else { 1 } }", | 94 | "fn f() { if x == 3 { 3 + 2 } else { 1 } }", |
95 | ) | 95 | ) |
96 | } | 96 | } |
@@ -99,7 +99,7 @@ mod tests { | |||
99 | fn invert_if_remove_not() { | 99 | fn invert_if_remove_not() { |
100 | check_assist( | 100 | check_assist( |
101 | invert_if, | 101 | invert_if, |
102 | "fn f() { <|>if !cond { 3 * 2 } else { 1 } }", | 102 | "fn f() { $0if !cond { 3 * 2 } else { 1 } }", |
103 | "fn f() { if cond { 1 } else { 3 * 2 } }", | 103 | "fn f() { if cond { 1 } else { 3 * 2 } }", |
104 | ) | 104 | ) |
105 | } | 105 | } |
@@ -108,21 +108,21 @@ mod tests { | |||
108 | fn invert_if_general_case() { | 108 | fn invert_if_general_case() { |
109 | check_assist( | 109 | check_assist( |
110 | invert_if, | 110 | invert_if, |
111 | "fn f() { i<|>f cond { 3 * 2 } else { 1 } }", | 111 | "fn f() { i$0f cond { 3 * 2 } else { 1 } }", |
112 | "fn f() { if !cond { 1 } else { 3 * 2 } }", | 112 | "fn f() { if !cond { 1 } else { 3 * 2 } }", |
113 | ) | 113 | ) |
114 | } | 114 | } |
115 | 115 | ||
116 | #[test] | 116 | #[test] |
117 | fn invert_if_doesnt_apply_with_cursor_not_on_if() { | 117 | fn invert_if_doesnt_apply_with_cursor_not_on_if() { |
118 | check_assist_not_applicable(invert_if, "fn f() { if !<|>cond { 3 * 2 } else { 1 } }") | 118 | check_assist_not_applicable(invert_if, "fn f() { if !$0cond { 3 * 2 } else { 1 } }") |
119 | } | 119 | } |
120 | 120 | ||
121 | #[test] | 121 | #[test] |
122 | fn invert_if_doesnt_apply_with_if_let() { | 122 | fn invert_if_doesnt_apply_with_if_let() { |
123 | check_assist_not_applicable( | 123 | check_assist_not_applicable( |
124 | invert_if, | 124 | invert_if, |
125 | "fn f() { i<|>f let Some(_) = Some(1) { 1 } else { 0 } }", | 125 | "fn f() { i$0f let Some(_) = Some(1) { 1 } else { 0 } }", |
126 | ) | 126 | ) |
127 | } | 127 | } |
128 | 128 | ||
@@ -130,7 +130,7 @@ mod tests { | |||
130 | fn invert_if_option_case() { | 130 | fn invert_if_option_case() { |
131 | check_assist( | 131 | check_assist( |
132 | invert_if, | 132 | invert_if, |
133 | "fn f() { if<|> doc_style.is_some() { Class::DocComment } else { Class::Comment } }", | 133 | "fn f() { if$0 doc_style.is_some() { Class::DocComment } else { Class::Comment } }", |
134 | "fn f() { if doc_style.is_none() { Class::Comment } else { Class::DocComment } }", | 134 | "fn f() { if doc_style.is_none() { Class::Comment } else { Class::DocComment } }", |
135 | ) | 135 | ) |
136 | } | 136 | } |
@@ -139,7 +139,7 @@ mod tests { | |||
139 | fn invert_if_result_case() { | 139 | fn invert_if_result_case() { |
140 | check_assist( | 140 | check_assist( |
141 | invert_if, | 141 | invert_if, |
142 | "fn f() { i<|>f doc_style.is_err() { Class::Err } else { Class::Ok } }", | 142 | "fn f() { i$0f doc_style.is_err() { Class::Err } else { Class::Ok } }", |
143 | "fn f() { if doc_style.is_ok() { Class::Ok } else { Class::Err } }", | 143 | "fn f() { if doc_style.is_ok() { Class::Ok } else { Class::Err } }", |
144 | ) | 144 | ) |
145 | } | 145 | } |
diff --git a/crates/assists/src/handlers/merge_imports.rs b/crates/assists/src/handlers/merge_imports.rs index 2f0dc7831..7bd7e1e36 100644 --- a/crates/assists/src/handlers/merge_imports.rs +++ b/crates/assists/src/handlers/merge_imports.rs | |||
@@ -15,7 +15,7 @@ use crate::{ | |||
15 | // Merges two imports with a common prefix. | 15 | // Merges two imports with a common prefix. |
16 | // | 16 | // |
17 | // ``` | 17 | // ``` |
18 | // use std::<|>fmt::Formatter; | 18 | // use std::$0fmt::Formatter; |
19 | // use std::io; | 19 | // use std::io; |
20 | // ``` | 20 | // ``` |
21 | // -> | 21 | // -> |
@@ -75,7 +75,7 @@ mod tests { | |||
75 | check_assist( | 75 | check_assist( |
76 | merge_imports, | 76 | merge_imports, |
77 | r" | 77 | r" |
78 | use std::fmt<|>::{Display, Debug}; | 78 | use std::fmt$0::{Display, Debug}; |
79 | use std::fmt::{Display, Debug}; | 79 | use std::fmt::{Display, Debug}; |
80 | ", | 80 | ", |
81 | r" | 81 | r" |
@@ -89,7 +89,7 @@ use std::fmt::{Debug, Display}; | |||
89 | check_assist( | 89 | check_assist( |
90 | merge_imports, | 90 | merge_imports, |
91 | r" | 91 | r" |
92 | use std::fmt<|>::Debug; | 92 | use std::fmt$0::Debug; |
93 | use std::fmt::Display; | 93 | use std::fmt::Display; |
94 | ", | 94 | ", |
95 | r" | 95 | r" |
@@ -104,7 +104,7 @@ use std::fmt::{Debug, Display}; | |||
104 | merge_imports, | 104 | merge_imports, |
105 | r" | 105 | r" |
106 | use std::fmt::Debug; | 106 | use std::fmt::Debug; |
107 | use std::fmt<|>::Display; | 107 | use std::fmt$0::Display; |
108 | ", | 108 | ", |
109 | r" | 109 | r" |
110 | use std::fmt::{Debug, Display}; | 110 | use std::fmt::{Debug, Display}; |
@@ -117,7 +117,7 @@ use std::fmt::{Debug, Display}; | |||
117 | check_assist( | 117 | check_assist( |
118 | merge_imports, | 118 | merge_imports, |
119 | r" | 119 | r" |
120 | use std::fmt<|>; | 120 | use std::fmt$0; |
121 | use std::fmt::Display; | 121 | use std::fmt::Display; |
122 | ", | 122 | ", |
123 | r" | 123 | r" |
@@ -131,7 +131,7 @@ use std::fmt::{self, Display}; | |||
131 | check_assist( | 131 | check_assist( |
132 | merge_imports, | 132 | merge_imports, |
133 | r" | 133 | r" |
134 | use std::{fmt, <|>fmt::Display}; | 134 | use std::{fmt, $0fmt::Display}; |
135 | ", | 135 | ", |
136 | r" | 136 | r" |
137 | use std::{fmt::{self, Display}}; | 137 | use std::{fmt::{self, Display}}; |
@@ -144,7 +144,7 @@ use std::{fmt::{self, Display}}; | |||
144 | check_assist_not_applicable( | 144 | check_assist_not_applicable( |
145 | merge_imports, | 145 | merge_imports, |
146 | r" | 146 | r" |
147 | pub use std::fmt<|>::Debug; | 147 | pub use std::fmt$0::Debug; |
148 | use std::fmt::Display; | 148 | use std::fmt::Display; |
149 | ", | 149 | ", |
150 | ); | 150 | ); |
@@ -155,7 +155,7 @@ use std::fmt::Display; | |||
155 | check_assist_not_applicable( | 155 | check_assist_not_applicable( |
156 | merge_imports, | 156 | merge_imports, |
157 | r" | 157 | r" |
158 | use std::fmt<|>::Debug; | 158 | use std::fmt$0::Debug; |
159 | pub use std::fmt::Display; | 159 | pub use std::fmt::Display; |
160 | ", | 160 | ", |
161 | ); | 161 | ); |
@@ -166,7 +166,7 @@ pub use std::fmt::Display; | |||
166 | check_assist_not_applicable( | 166 | check_assist_not_applicable( |
167 | merge_imports, | 167 | merge_imports, |
168 | r" | 168 | r" |
169 | pub(crate) use std::fmt<|>::Debug; | 169 | pub(crate) use std::fmt$0::Debug; |
170 | pub use std::fmt::Display; | 170 | pub use std::fmt::Display; |
171 | ", | 171 | ", |
172 | ); | 172 | ); |
@@ -177,7 +177,7 @@ pub use std::fmt::Display; | |||
177 | check_assist_not_applicable( | 177 | check_assist_not_applicable( |
178 | merge_imports, | 178 | merge_imports, |
179 | r" | 179 | r" |
180 | pub use std::fmt<|>::Debug; | 180 | pub use std::fmt$0::Debug; |
181 | pub(crate) use std::fmt::Display; | 181 | pub(crate) use std::fmt::Display; |
182 | ", | 182 | ", |
183 | ); | 183 | ); |
@@ -188,7 +188,7 @@ pub(crate) use std::fmt::Display; | |||
188 | check_assist( | 188 | check_assist( |
189 | merge_imports, | 189 | merge_imports, |
190 | r" | 190 | r" |
191 | pub use std::fmt<|>::Debug; | 191 | pub use std::fmt$0::Debug; |
192 | pub use std::fmt::Display; | 192 | pub use std::fmt::Display; |
193 | ", | 193 | ", |
194 | r" | 194 | r" |
@@ -202,7 +202,7 @@ pub use std::fmt::{Debug, Display}; | |||
202 | check_assist( | 202 | check_assist( |
203 | merge_imports, | 203 | merge_imports, |
204 | r" | 204 | r" |
205 | pub(crate) use std::fmt<|>::Debug; | 205 | pub(crate) use std::fmt$0::Debug; |
206 | pub(crate) use std::fmt::Display; | 206 | pub(crate) use std::fmt::Display; |
207 | ", | 207 | ", |
208 | r" | 208 | r" |
@@ -216,7 +216,7 @@ pub(crate) use std::fmt::{Debug, Display}; | |||
216 | check_assist( | 216 | check_assist( |
217 | merge_imports, | 217 | merge_imports, |
218 | r" | 218 | r" |
219 | use std::{fmt<|>::Debug, fmt::Display}; | 219 | use std::{fmt$0::Debug, fmt::Display}; |
220 | ", | 220 | ", |
221 | r" | 221 | r" |
222 | use std::{fmt::{Debug, Display}}; | 222 | use std::{fmt::{Debug, Display}}; |
@@ -229,7 +229,7 @@ use std::{fmt::{Debug, Display}}; | |||
229 | check_assist( | 229 | check_assist( |
230 | merge_imports, | 230 | merge_imports, |
231 | r" | 231 | r" |
232 | use std::{fmt::Debug, fmt<|>::Display}; | 232 | use std::{fmt::Debug, fmt$0::Display}; |
233 | ", | 233 | ", |
234 | r" | 234 | r" |
235 | use std::{fmt::{Debug, Display}}; | 235 | use std::{fmt::{Debug, Display}}; |
@@ -242,7 +242,7 @@ use std::{fmt::{Debug, Display}}; | |||
242 | check_assist( | 242 | check_assist( |
243 | merge_imports, | 243 | merge_imports, |
244 | r" | 244 | r" |
245 | use std<|>::cell::*; | 245 | use std$0::cell::*; |
246 | use std::str; | 246 | use std::str; |
247 | ", | 247 | ", |
248 | r" | 248 | r" |
@@ -256,7 +256,7 @@ use std::{cell::*, str}; | |||
256 | check_assist( | 256 | check_assist( |
257 | merge_imports, | 257 | merge_imports, |
258 | r" | 258 | r" |
259 | use std<|>::cell::*; | 259 | use std$0::cell::*; |
260 | use std::str::*; | 260 | use std::str::*; |
261 | ", | 261 | ", |
262 | r" | 262 | r" |
@@ -270,7 +270,7 @@ use std::{cell::*, str::*}; | |||
270 | check_assist( | 270 | check_assist( |
271 | merge_imports, | 271 | merge_imports, |
272 | r" | 272 | r" |
273 | use foo<|>::bar; | 273 | use foo$0::bar; |
274 | use foo::baz; | 274 | use foo::baz; |
275 | 275 | ||
276 | /// Doc comment | 276 | /// Doc comment |
@@ -289,7 +289,7 @@ use foo::{bar, baz}; | |||
289 | merge_imports, | 289 | merge_imports, |
290 | r" | 290 | r" |
291 | use { | 291 | use { |
292 | foo<|>::bar, | 292 | foo$0::bar, |
293 | foo::baz, | 293 | foo::baz, |
294 | }; | 294 | }; |
295 | ", | 295 | ", |
@@ -304,7 +304,7 @@ use { | |||
304 | r" | 304 | r" |
305 | use { | 305 | use { |
306 | foo::baz, | 306 | foo::baz, |
307 | foo<|>::bar, | 307 | foo$0::bar, |
308 | }; | 308 | }; |
309 | ", | 309 | ", |
310 | r" | 310 | r" |
@@ -321,7 +321,7 @@ use { | |||
321 | merge_imports, | 321 | merge_imports, |
322 | r" | 322 | r" |
323 | use foo::bar::baz; | 323 | use foo::bar::baz; |
324 | use foo::<|>{ | 324 | use foo::$0{ |
325 | FooBar, | 325 | FooBar, |
326 | }; | 326 | }; |
327 | ", | 327 | ", |
@@ -336,7 +336,7 @@ use foo::{FooBar, bar::baz}; | |||
336 | check_assist_not_applicable( | 336 | check_assist_not_applicable( |
337 | merge_imports, | 337 | merge_imports, |
338 | r" | 338 | r" |
339 | use std::<|> | 339 | use std::$0 |
340 | fn main() {}", | 340 | fn main() {}", |
341 | ); | 341 | ); |
342 | } | 342 | } |
diff --git a/crates/assists/src/handlers/merge_match_arms.rs b/crates/assists/src/handlers/merge_match_arms.rs index c347eb40e..9bf076cb9 100644 --- a/crates/assists/src/handlers/merge_match_arms.rs +++ b/crates/assists/src/handlers/merge_match_arms.rs | |||
@@ -17,7 +17,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists, TextRange}; | |||
17 | // | 17 | // |
18 | // fn handle(action: Action) { | 18 | // fn handle(action: Action) { |
19 | // match action { | 19 | // match action { |
20 | // <|>Action::Move(..) => foo(), | 20 | // $0Action::Move(..) => foo(), |
21 | // Action::Stop => foo(), | 21 | // Action::Stop => foo(), |
22 | // } | 22 | // } |
23 | // } | 23 | // } |
@@ -106,7 +106,7 @@ mod tests { | |||
106 | fn main() { | 106 | fn main() { |
107 | let x = X::A; | 107 | let x = X::A; |
108 | let y = match x { | 108 | let y = match x { |
109 | X::A => { 1i32<|> } | 109 | X::A => { 1i32$0 } |
110 | X::B => { 1i32 } | 110 | X::B => { 1i32 } |
111 | X::C => { 2i32 } | 111 | X::C => { 2i32 } |
112 | } | 112 | } |
@@ -138,7 +138,7 @@ mod tests { | |||
138 | fn main() { | 138 | fn main() { |
139 | let x = X::A; | 139 | let x = X::A; |
140 | let y = match x { | 140 | let y = match x { |
141 | X::A | X::B => {<|> 1i32 }, | 141 | X::A | X::B => {$0 1i32 }, |
142 | X::C | X::D => { 1i32 }, | 142 | X::C | X::D => { 1i32 }, |
143 | X::E => { 2i32 }, | 143 | X::E => { 2i32 }, |
144 | } | 144 | } |
@@ -171,7 +171,7 @@ mod tests { | |||
171 | let x = X::A; | 171 | let x = X::A; |
172 | let y = match x { | 172 | let y = match x { |
173 | X::A => { 1i32 }, | 173 | X::A => { 1i32 }, |
174 | X::B => { 2i<|>32 }, | 174 | X::B => { 2i$032 }, |
175 | _ => { 2i32 } | 175 | _ => { 2i32 } |
176 | } | 176 | } |
177 | } | 177 | } |
@@ -200,7 +200,7 @@ mod tests { | |||
200 | 200 | ||
201 | fn main() { | 201 | fn main() { |
202 | match X::A { | 202 | match X::A { |
203 | X::A<|> => 92, | 203 | X::A$0 => 92, |
204 | X::B => 92, | 204 | X::B => 92, |
205 | X::C => 92, | 205 | X::C => 92, |
206 | X::D => 62, | 206 | X::D => 62, |
@@ -237,7 +237,7 @@ mod tests { | |||
237 | fn main() { | 237 | fn main() { |
238 | let x = X::A; | 238 | let x = X::A; |
239 | let y = match x { | 239 | let y = match x { |
240 | X::A(a) if a > 5 => { <|>1i32 }, | 240 | X::A(a) if a > 5 => { $01i32 }, |
241 | X::B => { 1i32 }, | 241 | X::B => { 1i32 }, |
242 | X::C => { 2i32 } | 242 | X::C => { 2i32 } |
243 | } | 243 | } |
diff --git a/crates/assists/src/handlers/move_bounds.rs b/crates/assists/src/handlers/move_bounds.rs index e2e461520..cf260c6f8 100644 --- a/crates/assists/src/handlers/move_bounds.rs +++ b/crates/assists/src/handlers/move_bounds.rs | |||
@@ -12,7 +12,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
12 | // Moves inline type bounds to a where clause. | 12 | // Moves inline type bounds to a where clause. |
13 | // | 13 | // |
14 | // ``` | 14 | // ``` |
15 | // fn apply<T, U, <|>F: FnOnce(T) -> U>(f: F, x: T) -> U { | 15 | // fn apply<T, U, $0F: FnOnce(T) -> U>(f: F, x: T) -> U { |
16 | // f(x) | 16 | // f(x) |
17 | // } | 17 | // } |
18 | // ``` | 18 | // ``` |
@@ -103,7 +103,7 @@ mod tests { | |||
103 | check_assist( | 103 | check_assist( |
104 | move_bounds_to_where_clause, | 104 | move_bounds_to_where_clause, |
105 | r#" | 105 | r#" |
106 | fn foo<T: u32, <|>F: FnOnce(T) -> T>() {} | 106 | fn foo<T: u32, $0F: FnOnce(T) -> T>() {} |
107 | "#, | 107 | "#, |
108 | r#" | 108 | r#" |
109 | fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {} | 109 | fn foo<T, F>() where T: u32, F: FnOnce(T) -> T {} |
@@ -116,7 +116,7 @@ mod tests { | |||
116 | check_assist( | 116 | check_assist( |
117 | move_bounds_to_where_clause, | 117 | move_bounds_to_where_clause, |
118 | r#" | 118 | r#" |
119 | impl<U: u32, <|>T> A<U, T> {} | 119 | impl<U: u32, $0T> A<U, T> {} |
120 | "#, | 120 | "#, |
121 | r#" | 121 | r#" |
122 | impl<U, T> A<U, T> where U: u32 {} | 122 | impl<U, T> A<U, T> where U: u32 {} |
@@ -129,7 +129,7 @@ mod tests { | |||
129 | check_assist( | 129 | check_assist( |
130 | move_bounds_to_where_clause, | 130 | move_bounds_to_where_clause, |
131 | r#" | 131 | r#" |
132 | struct A<<|>T: Iterator<Item = u32>> {} | 132 | struct A<$0T: Iterator<Item = u32>> {} |
133 | "#, | 133 | "#, |
134 | r#" | 134 | r#" |
135 | struct A<T> where T: Iterator<Item = u32> {} | 135 | struct A<T> where T: Iterator<Item = u32> {} |
@@ -142,7 +142,7 @@ mod tests { | |||
142 | check_assist( | 142 | check_assist( |
143 | move_bounds_to_where_clause, | 143 | move_bounds_to_where_clause, |
144 | r#" | 144 | r#" |
145 | struct Pair<<|>T: u32>(T, T); | 145 | struct Pair<$0T: u32>(T, T); |
146 | "#, | 146 | "#, |
147 | r#" | 147 | r#" |
148 | struct Pair<T>(T, T) where T: u32; | 148 | struct Pair<T>(T, T) where T: u32; |
diff --git a/crates/assists/src/handlers/move_guard.rs b/crates/assists/src/handlers/move_guard.rs index eaffd80ce..3f22302a9 100644 --- a/crates/assists/src/handlers/move_guard.rs +++ b/crates/assists/src/handlers/move_guard.rs | |||
@@ -14,7 +14,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
14 | // | 14 | // |
15 | // fn handle(action: Action) { | 15 | // fn handle(action: Action) { |
16 | // match action { | 16 | // match action { |
17 | // Action::Move { distance } <|>if distance > 10 => foo(), | 17 | // Action::Move { distance } $0if distance > 10 => foo(), |
18 | // _ => (), | 18 | // _ => (), |
19 | // } | 19 | // } |
20 | // } | 20 | // } |
@@ -74,7 +74,7 @@ pub(crate) fn move_guard_to_arm_body(acc: &mut Assists, ctx: &AssistContext) -> | |||
74 | // | 74 | // |
75 | // fn handle(action: Action) { | 75 | // fn handle(action: Action) { |
76 | // match action { | 76 | // match action { |
77 | // Action::Move { distance } => <|>if distance > 10 { foo() }, | 77 | // Action::Move { distance } => $0if distance > 10 { foo() }, |
78 | // _ => (), | 78 | // _ => (), |
79 | // } | 79 | // } |
80 | // } | 80 | // } |
@@ -98,7 +98,7 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex | |||
98 | let mut replace_node = None; | 98 | let mut replace_node = None; |
99 | let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| { | 99 | let if_expr: IfExpr = IfExpr::cast(arm_body.syntax().clone()).or_else(|| { |
100 | let block_expr = BlockExpr::cast(arm_body.syntax().clone())?; | 100 | let block_expr = BlockExpr::cast(arm_body.syntax().clone())?; |
101 | if let Expr::IfExpr(e) = block_expr.expr()? { | 101 | if let Expr::IfExpr(e) = block_expr.tail_expr()? { |
102 | replace_node = Some(block_expr.syntax().clone()); | 102 | replace_node = Some(block_expr.syntax().clone()); |
103 | Some(e) | 103 | Some(e) |
104 | } else { | 104 | } else { |
@@ -128,7 +128,7 @@ pub(crate) fn move_arm_cond_to_match_guard(acc: &mut Assists, ctx: &AssistContex | |||
128 | |edit| { | 128 | |edit| { |
129 | let then_only_expr = then_block.statements().next().is_none(); | 129 | let then_only_expr = then_block.statements().next().is_none(); |
130 | 130 | ||
131 | match &then_block.expr() { | 131 | match &then_block.tail_expr() { |
132 | Some(then_expr) if then_only_expr => { | 132 | Some(then_expr) if then_only_expr => { |
133 | edit.replace(replace_node.text_range(), then_expr.syntax().text()) | 133 | edit.replace(replace_node.text_range(), then_expr.syntax().text()) |
134 | } | 134 | } |
@@ -158,7 +158,7 @@ mod tests { | |||
158 | r#" | 158 | r#" |
159 | fn main() { | 159 | fn main() { |
160 | match 92 { | 160 | match 92 { |
161 | x <|>if x > 10 => false, | 161 | x $0if x > 10 => false, |
162 | _ => true | 162 | _ => true |
163 | } | 163 | } |
164 | } | 164 | } |
@@ -174,7 +174,7 @@ fn main() { | |||
174 | r#" | 174 | r#" |
175 | fn main() { | 175 | fn main() { |
176 | match 92 { | 176 | match 92 { |
177 | x <|>if x > 10 => false, | 177 | x $0if x > 10 => false, |
178 | _ => true | 178 | _ => true |
179 | } | 179 | } |
180 | } | 180 | } |
@@ -199,7 +199,7 @@ fn main() { | |||
199 | r#" | 199 | r#" |
200 | fn main() { | 200 | fn main() { |
201 | match 92 { | 201 | match 92 { |
202 | <|>x @ 4 | x @ 5 if x > 5 => true, | 202 | $0x @ 4 | x @ 5 if x > 5 => true, |
203 | _ => false | 203 | _ => false |
204 | } | 204 | } |
205 | } | 205 | } |
@@ -224,7 +224,7 @@ fn main() { | |||
224 | r#" | 224 | r#" |
225 | fn main() { | 225 | fn main() { |
226 | match 92 { | 226 | match 92 { |
227 | x => if x > 10 { <|>false }, | 227 | x => if x > 10 { $0false }, |
228 | _ => true | 228 | _ => true |
229 | } | 229 | } |
230 | } | 230 | } |
@@ -248,7 +248,7 @@ fn main() { | |||
248 | fn main() { | 248 | fn main() { |
249 | match 92 { | 249 | match 92 { |
250 | x => { | 250 | x => { |
251 | <|>if x > 10 { | 251 | $0if x > 10 { |
252 | false | 252 | false |
253 | } | 253 | } |
254 | }, | 254 | }, |
@@ -274,7 +274,7 @@ fn main() { | |||
274 | r#" | 274 | r#" |
275 | fn main() { | 275 | fn main() { |
276 | match 92 { | 276 | match 92 { |
277 | x => if let 62 = x { <|>false }, | 277 | x => if let 62 = x { $0false }, |
278 | _ => true | 278 | _ => true |
279 | } | 279 | } |
280 | } | 280 | } |
@@ -289,7 +289,7 @@ fn main() { | |||
289 | r#" | 289 | r#" |
290 | fn main() { | 290 | fn main() { |
291 | match 92 { | 291 | match 92 { |
292 | x => if x > 10 { <|> }, | 292 | x => if x > 10 { $0 }, |
293 | _ => true | 293 | _ => true |
294 | } | 294 | } |
295 | } | 295 | } |
@@ -313,7 +313,7 @@ fn main() { | |||
313 | fn main() { | 313 | fn main() { |
314 | match 92 { | 314 | match 92 { |
315 | x => if x > 10 { | 315 | x => if x > 10 { |
316 | 92;<|> | 316 | 92;$0 |
317 | false | 317 | false |
318 | }, | 318 | }, |
319 | _ => true | 319 | _ => true |
@@ -343,7 +343,7 @@ fn main() { | |||
343 | match 92 { | 343 | match 92 { |
344 | x => { | 344 | x => { |
345 | if x > 10 { | 345 | if x > 10 { |
346 | 92;<|> | 346 | 92;$0 |
347 | false | 347 | false |
348 | } | 348 | } |
349 | } | 349 | } |
diff --git a/crates/assists/src/handlers/extract_module_to_file.rs b/crates/assists/src/handlers/move_module_to_file.rs index 50bf67ef7..9d8579f47 100644 --- a/crates/assists/src/handlers/extract_module_to_file.rs +++ b/crates/assists/src/handlers/move_module_to_file.rs | |||
@@ -2,17 +2,18 @@ use ast::edit::IndentLevel; | |||
2 | use ide_db::base_db::AnchoredPathBuf; | 2 | use ide_db::base_db::AnchoredPathBuf; |
3 | use syntax::{ | 3 | use syntax::{ |
4 | ast::{self, edit::AstNodeEdit, NameOwner}, | 4 | ast::{self, edit::AstNodeEdit, NameOwner}, |
5 | AstNode, | 5 | AstNode, TextRange, |
6 | }; | 6 | }; |
7 | use test_utils::mark; | ||
7 | 8 | ||
8 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 9 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
9 | 10 | ||
10 | // Assist: extract_module_to_file | 11 | // Assist: move_module_to_file |
11 | // | 12 | // |
12 | // This assist extract module to file. | 13 | // Moves inline module's contents to a separate file. |
13 | // | 14 | // |
14 | // ``` | 15 | // ``` |
15 | // mod foo {<|> | 16 | // mod $0foo { |
16 | // fn t() {} | 17 | // fn t() {} |
17 | // } | 18 | // } |
18 | // ``` | 19 | // ``` |
@@ -20,19 +21,24 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
20 | // ``` | 21 | // ``` |
21 | // mod foo; | 22 | // mod foo; |
22 | // ``` | 23 | // ``` |
23 | pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 24 | pub(crate) fn move_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
24 | let module_ast = ctx.find_node_at_offset::<ast::Module>()?; | 25 | let module_ast = ctx.find_node_at_offset::<ast::Module>()?; |
26 | let module_items = module_ast.item_list()?; | ||
27 | |||
28 | let l_curly_offset = module_items.syntax().text_range().start(); | ||
29 | if l_curly_offset <= ctx.offset() { | ||
30 | mark::hit!(available_before_curly); | ||
31 | return None; | ||
32 | } | ||
33 | let target = TextRange::new(module_ast.syntax().text_range().start(), l_curly_offset); | ||
34 | |||
25 | let module_name = module_ast.name()?; | 35 | let module_name = module_ast.name()?; |
26 | 36 | ||
27 | let module_def = ctx.sema.to_def(&module_ast)?; | 37 | let module_def = ctx.sema.to_def(&module_ast)?; |
28 | let parent_module = module_def.parent(ctx.db())?; | 38 | let parent_module = module_def.parent(ctx.db())?; |
29 | 39 | ||
30 | let module_items = module_ast.item_list()?; | ||
31 | let target = module_ast.syntax().text_range(); | ||
32 | let anchor_file_id = ctx.frange.file_id; | ||
33 | |||
34 | acc.add( | 40 | acc.add( |
35 | AssistId("extract_module_to_file", AssistKind::RefactorExtract), | 41 | AssistId("move_module_to_file", AssistKind::RefactorExtract), |
36 | "Extract module to file", | 42 | "Extract module to file", |
37 | target, | 43 | target, |
38 | |builder| { | 44 | |builder| { |
@@ -53,9 +59,9 @@ pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> | |||
53 | items | 59 | items |
54 | }; | 60 | }; |
55 | 61 | ||
56 | builder.replace(target, format!("mod {};", module_name)); | 62 | builder.replace(module_ast.syntax().text_range(), format!("mod {};", module_name)); |
57 | 63 | ||
58 | let dst = AnchoredPathBuf { anchor: anchor_file_id, path }; | 64 | let dst = AnchoredPathBuf { anchor: ctx.frange.file_id, path }; |
59 | builder.create_file(dst, contents); | 65 | builder.create_file(dst, contents); |
60 | }, | 66 | }, |
61 | ) | 67 | ) |
@@ -63,16 +69,16 @@ pub(crate) fn extract_module_to_file(acc: &mut Assists, ctx: &AssistContext) -> | |||
63 | 69 | ||
64 | #[cfg(test)] | 70 | #[cfg(test)] |
65 | mod tests { | 71 | mod tests { |
66 | use crate::tests::check_assist; | 72 | use crate::tests::{check_assist, check_assist_not_applicable}; |
67 | 73 | ||
68 | use super::*; | 74 | use super::*; |
69 | 75 | ||
70 | #[test] | 76 | #[test] |
71 | fn extract_from_root() { | 77 | fn extract_from_root() { |
72 | check_assist( | 78 | check_assist( |
73 | extract_module_to_file, | 79 | move_module_to_file, |
74 | r#" | 80 | r#" |
75 | mod tests {<|> | 81 | mod $0tests { |
76 | #[test] fn t() {} | 82 | #[test] fn t() {} |
77 | } | 83 | } |
78 | "#, | 84 | "#, |
@@ -88,12 +94,12 @@ mod tests; | |||
88 | #[test] | 94 | #[test] |
89 | fn extract_from_submodule() { | 95 | fn extract_from_submodule() { |
90 | check_assist( | 96 | check_assist( |
91 | extract_module_to_file, | 97 | move_module_to_file, |
92 | r#" | 98 | r#" |
93 | //- /main.rs | 99 | //- /main.rs |
94 | mod submod; | 100 | mod submod; |
95 | //- /submod.rs | 101 | //- /submod.rs |
96 | mod inner<|> { | 102 | $0mod inner { |
97 | fn f() {} | 103 | fn f() {} |
98 | } | 104 | } |
99 | fn g() {} | 105 | fn g() {} |
@@ -111,12 +117,12 @@ fn f() {} | |||
111 | #[test] | 117 | #[test] |
112 | fn extract_from_mod_rs() { | 118 | fn extract_from_mod_rs() { |
113 | check_assist( | 119 | check_assist( |
114 | extract_module_to_file, | 120 | move_module_to_file, |
115 | r#" | 121 | r#" |
116 | //- /main.rs | 122 | //- /main.rs |
117 | mod submodule; | 123 | mod submodule; |
118 | //- /submodule/mod.rs | 124 | //- /submodule/mod.rs |
119 | mod inner<|> { | 125 | mod inner$0 { |
120 | fn f() {} | 126 | fn f() {} |
121 | } | 127 | } |
122 | fn g() {} | 128 | fn g() {} |
@@ -130,4 +136,10 @@ fn f() {} | |||
130 | "#, | 136 | "#, |
131 | ); | 137 | ); |
132 | } | 138 | } |
139 | |||
140 | #[test] | ||
141 | fn available_before_curly() { | ||
142 | mark::check!(available_before_curly); | ||
143 | check_assist_not_applicable(move_module_to_file, r#"mod m { $0 }"#); | ||
144 | } | ||
133 | } | 145 | } |
diff --git a/crates/assists/src/handlers/extract_assignment.rs b/crates/assists/src/handlers/pull_assignment_up.rs index 281cf5d24..13e1cb754 100644 --- a/crates/assists/src/handlers/extract_assignment.rs +++ b/crates/assists/src/handlers/pull_assignment_up.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use hir::AsName; | ||
2 | use syntax::{ | 1 | use syntax::{ |
3 | ast::{self, edit::AstNodeEdit, make}, | 2 | ast::{self, edit::AstNodeEdit, make}, |
4 | AstNode, | 3 | AstNode, |
@@ -10,16 +9,16 @@ use crate::{ | |||
10 | AssistId, AssistKind, | 9 | AssistId, AssistKind, |
11 | }; | 10 | }; |
12 | 11 | ||
13 | // Assist: extract_assignment | 12 | // Assist: pull_assignment_up |
14 | // | 13 | // |
15 | // Extracts variable assigment to outside an if or match statement. | 14 | // Extracts variable assignment to outside an if or match statement. |
16 | // | 15 | // |
17 | // ``` | 16 | // ``` |
18 | // fn main() { | 17 | // fn main() { |
19 | // let mut foo = 6; | 18 | // let mut foo = 6; |
20 | // | 19 | // |
21 | // if true { | 20 | // if true { |
22 | // <|>foo = 5; | 21 | // $0foo = 5; |
23 | // } else { | 22 | // } else { |
24 | // foo = 4; | 23 | // foo = 4; |
25 | // } | 24 | // } |
@@ -37,16 +36,24 @@ use crate::{ | |||
37 | // }; | 36 | // }; |
38 | // } | 37 | // } |
39 | // ``` | 38 | // ``` |
40 | pub(crate) fn extract_assigment(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | 39 | pub(crate) fn pull_assignment_up(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { |
41 | let name = ctx.find_node_at_offset::<ast::NameRef>()?.as_name(); | 40 | let assign_expr = ctx.find_node_at_offset::<ast::BinExpr>()?; |
41 | let name_expr = if assign_expr.op_kind()? == ast::BinOp::Assignment { | ||
42 | assign_expr.lhs()? | ||
43 | } else { | ||
44 | return None; | ||
45 | }; | ||
42 | 46 | ||
43 | let (old_stmt, new_stmt) = if let Some(if_expr) = ctx.find_node_at_offset::<ast::IfExpr>() { | 47 | let (old_stmt, new_stmt) = if let Some(if_expr) = ctx.find_node_at_offset::<ast::IfExpr>() { |
44 | ( | 48 | ( |
45 | ast::Expr::cast(if_expr.syntax().to_owned())?, | 49 | ast::Expr::cast(if_expr.syntax().to_owned())?, |
46 | exprify_if(&if_expr, &name)?.indent(if_expr.indent_level()), | 50 | exprify_if(&if_expr, &ctx.sema, &name_expr)?.indent(if_expr.indent_level()), |
47 | ) | 51 | ) |
48 | } else if let Some(match_expr) = ctx.find_node_at_offset::<ast::MatchExpr>() { | 52 | } else if let Some(match_expr) = ctx.find_node_at_offset::<ast::MatchExpr>() { |
49 | (ast::Expr::cast(match_expr.syntax().to_owned())?, exprify_match(&match_expr, &name)?) | 53 | ( |
54 | ast::Expr::cast(match_expr.syntax().to_owned())?, | ||
55 | exprify_match(&match_expr, &ctx.sema, &name_expr)?, | ||
56 | ) | ||
50 | } else { | 57 | } else { |
51 | return None; | 58 | return None; |
52 | }; | 59 | }; |
@@ -54,22 +61,26 @@ pub(crate) fn extract_assigment(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
54 | let expr_stmt = make::expr_stmt(new_stmt); | 61 | let expr_stmt = make::expr_stmt(new_stmt); |
55 | 62 | ||
56 | acc.add( | 63 | acc.add( |
57 | AssistId("extract_assignment", AssistKind::RefactorExtract), | 64 | AssistId("pull_assignment_up", AssistKind::RefactorExtract), |
58 | "Extract assignment", | 65 | "Pull assignment up", |
59 | old_stmt.syntax().text_range(), | 66 | old_stmt.syntax().text_range(), |
60 | move |edit| { | 67 | move |edit| { |
61 | edit.replace(old_stmt.syntax().text_range(), format!("{} = {};", name, expr_stmt)); | 68 | edit.replace(old_stmt.syntax().text_range(), format!("{} = {};", name_expr, expr_stmt)); |
62 | }, | 69 | }, |
63 | ) | 70 | ) |
64 | } | 71 | } |
65 | 72 | ||
66 | fn exprify_match(match_expr: &ast::MatchExpr, name: &hir::Name) -> Option<ast::Expr> { | 73 | fn exprify_match( |
74 | match_expr: &ast::MatchExpr, | ||
75 | sema: &hir::Semantics<ide_db::RootDatabase>, | ||
76 | name: &ast::Expr, | ||
77 | ) -> Option<ast::Expr> { | ||
67 | let new_arm_list = match_expr | 78 | let new_arm_list = match_expr |
68 | .match_arm_list()? | 79 | .match_arm_list()? |
69 | .arms() | 80 | .arms() |
70 | .map(|arm| { | 81 | .map(|arm| { |
71 | if let ast::Expr::BlockExpr(block) = arm.expr()? { | 82 | if let ast::Expr::BlockExpr(block) = arm.expr()? { |
72 | let new_block = exprify_block(&block, name)?.indent(block.indent_level()); | 83 | let new_block = exprify_block(&block, sema, name)?.indent(block.indent_level()); |
73 | Some(arm.replace_descendant(block, new_block)) | 84 | Some(arm.replace_descendant(block, new_block)) |
74 | } else { | 85 | } else { |
75 | None | 86 | None |
@@ -82,22 +93,32 @@ fn exprify_match(match_expr: &ast::MatchExpr, name: &hir::Name) -> Option<ast::E | |||
82 | Some(make::expr_match(match_expr.expr()?, new_arm_list)) | 93 | Some(make::expr_match(match_expr.expr()?, new_arm_list)) |
83 | } | 94 | } |
84 | 95 | ||
85 | fn exprify_if(statement: &ast::IfExpr, name: &hir::Name) -> Option<ast::Expr> { | 96 | fn exprify_if( |
86 | let then_branch = exprify_block(&statement.then_branch()?, name)?; | 97 | statement: &ast::IfExpr, |
98 | sema: &hir::Semantics<ide_db::RootDatabase>, | ||
99 | name: &ast::Expr, | ||
100 | ) -> Option<ast::Expr> { | ||
101 | let then_branch = exprify_block(&statement.then_branch()?, sema, name)?; | ||
87 | let else_branch = match statement.else_branch()? { | 102 | let else_branch = match statement.else_branch()? { |
88 | ast::ElseBranch::Block(ref block) => ast::ElseBranch::Block(exprify_block(block, name)?), | 103 | ast::ElseBranch::Block(ref block) => { |
104 | ast::ElseBranch::Block(exprify_block(block, sema, name)?) | ||
105 | } | ||
89 | ast::ElseBranch::IfExpr(expr) => { | 106 | ast::ElseBranch::IfExpr(expr) => { |
90 | mark::hit!(test_extract_assigment_chained_if); | 107 | mark::hit!(test_pull_assignment_up_chained_if); |
91 | ast::ElseBranch::IfExpr(ast::IfExpr::cast( | 108 | ast::ElseBranch::IfExpr(ast::IfExpr::cast( |
92 | exprify_if(&expr, name)?.syntax().to_owned(), | 109 | exprify_if(&expr, sema, name)?.syntax().to_owned(), |
93 | )?) | 110 | )?) |
94 | } | 111 | } |
95 | }; | 112 | }; |
96 | Some(make::expr_if(statement.condition()?, then_branch, Some(else_branch))) | 113 | Some(make::expr_if(statement.condition()?, then_branch, Some(else_branch))) |
97 | } | 114 | } |
98 | 115 | ||
99 | fn exprify_block(block: &ast::BlockExpr, name: &hir::Name) -> Option<ast::BlockExpr> { | 116 | fn exprify_block( |
100 | if block.expr().is_some() { | 117 | block: &ast::BlockExpr, |
118 | sema: &hir::Semantics<ide_db::RootDatabase>, | ||
119 | name: &ast::Expr, | ||
120 | ) -> Option<ast::BlockExpr> { | ||
121 | if block.tail_expr().is_some() { | ||
101 | return None; | 122 | return None; |
102 | } | 123 | } |
103 | 124 | ||
@@ -106,8 +127,7 @@ fn exprify_block(block: &ast::BlockExpr, name: &hir::Name) -> Option<ast::BlockE | |||
106 | 127 | ||
107 | if let ast::Stmt::ExprStmt(stmt) = stmt { | 128 | if let ast::Stmt::ExprStmt(stmt) = stmt { |
108 | if let ast::Expr::BinExpr(expr) = stmt.expr()? { | 129 | if let ast::Expr::BinExpr(expr) = stmt.expr()? { |
109 | if expr.op_kind()? == ast::BinOp::Assignment | 130 | if expr.op_kind()? == ast::BinOp::Assignment && is_equivalent(sema, &expr.lhs()?, name) |
110 | && &expr.lhs()?.name_ref()?.as_name() == name | ||
111 | { | 131 | { |
112 | // The last statement in the block is an assignment to the name we want | 132 | // The last statement in the block is an assignment to the name we want |
113 | return Some(make::block_expr(stmts, Some(expr.rhs()?))); | 133 | return Some(make::block_expr(stmts, Some(expr.rhs()?))); |
@@ -117,6 +137,29 @@ fn exprify_block(block: &ast::BlockExpr, name: &hir::Name) -> Option<ast::BlockE | |||
117 | None | 137 | None |
118 | } | 138 | } |
119 | 139 | ||
140 | fn is_equivalent( | ||
141 | sema: &hir::Semantics<ide_db::RootDatabase>, | ||
142 | expr0: &ast::Expr, | ||
143 | expr1: &ast::Expr, | ||
144 | ) -> bool { | ||
145 | match (expr0, expr1) { | ||
146 | (ast::Expr::FieldExpr(field_expr0), ast::Expr::FieldExpr(field_expr1)) => { | ||
147 | mark::hit!(test_pull_assignment_up_field_assignment); | ||
148 | sema.resolve_field(field_expr0) == sema.resolve_field(field_expr1) | ||
149 | } | ||
150 | (ast::Expr::PathExpr(path0), ast::Expr::PathExpr(path1)) => { | ||
151 | let path0 = path0.path(); | ||
152 | let path1 = path1.path(); | ||
153 | if let (Some(path0), Some(path1)) = (path0, path1) { | ||
154 | sema.resolve_path(&path0) == sema.resolve_path(&path1) | ||
155 | } else { | ||
156 | false | ||
157 | } | ||
158 | } | ||
159 | _ => false, | ||
160 | } | ||
161 | } | ||
162 | |||
120 | #[cfg(test)] | 163 | #[cfg(test)] |
121 | mod tests { | 164 | mod tests { |
122 | use super::*; | 165 | use super::*; |
@@ -124,15 +167,15 @@ mod tests { | |||
124 | use crate::tests::{check_assist, check_assist_not_applicable}; | 167 | use crate::tests::{check_assist, check_assist_not_applicable}; |
125 | 168 | ||
126 | #[test] | 169 | #[test] |
127 | fn test_extract_assignment_if() { | 170 | fn test_pull_assignment_up_if() { |
128 | check_assist( | 171 | check_assist( |
129 | extract_assigment, | 172 | pull_assignment_up, |
130 | r#" | 173 | r#" |
131 | fn foo() { | 174 | fn foo() { |
132 | let mut a = 1; | 175 | let mut a = 1; |
133 | 176 | ||
134 | if true { | 177 | if true { |
135 | <|>a = 2; | 178 | $0a = 2; |
136 | } else { | 179 | } else { |
137 | a = 3; | 180 | a = 3; |
138 | } | 181 | } |
@@ -151,16 +194,16 @@ fn foo() { | |||
151 | } | 194 | } |
152 | 195 | ||
153 | #[test] | 196 | #[test] |
154 | fn test_extract_assignment_match() { | 197 | fn test_pull_assignment_up_match() { |
155 | check_assist( | 198 | check_assist( |
156 | extract_assigment, | 199 | pull_assignment_up, |
157 | r#" | 200 | r#" |
158 | fn foo() { | 201 | fn foo() { |
159 | let mut a = 1; | 202 | let mut a = 1; |
160 | 203 | ||
161 | match 1 { | 204 | match 1 { |
162 | 1 => { | 205 | 1 => { |
163 | <|>a = 2; | 206 | $0a = 2; |
164 | }, | 207 | }, |
165 | 2 => { | 208 | 2 => { |
166 | a = 3; | 209 | a = 3; |
@@ -190,15 +233,15 @@ fn foo() { | |||
190 | } | 233 | } |
191 | 234 | ||
192 | #[test] | 235 | #[test] |
193 | fn test_extract_assignment_not_last_not_applicable() { | 236 | fn test_pull_assignment_up_not_last_not_applicable() { |
194 | check_assist_not_applicable( | 237 | check_assist_not_applicable( |
195 | extract_assigment, | 238 | pull_assignment_up, |
196 | r#" | 239 | r#" |
197 | fn foo() { | 240 | fn foo() { |
198 | let mut a = 1; | 241 | let mut a = 1; |
199 | 242 | ||
200 | if true { | 243 | if true { |
201 | <|>a = 2; | 244 | $0a = 2; |
202 | b = a; | 245 | b = a; |
203 | } else { | 246 | } else { |
204 | a = 3; | 247 | a = 3; |
@@ -208,16 +251,16 @@ fn foo() { | |||
208 | } | 251 | } |
209 | 252 | ||
210 | #[test] | 253 | #[test] |
211 | fn test_extract_assignment_chained_if() { | 254 | fn test_pull_assignment_up_chained_if() { |
212 | mark::check!(test_extract_assigment_chained_if); | 255 | mark::check!(test_pull_assignment_up_chained_if); |
213 | check_assist( | 256 | check_assist( |
214 | extract_assigment, | 257 | pull_assignment_up, |
215 | r#" | 258 | r#" |
216 | fn foo() { | 259 | fn foo() { |
217 | let mut a = 1; | 260 | let mut a = 1; |
218 | 261 | ||
219 | if true { | 262 | if true { |
220 | <|>a = 2; | 263 | $0a = 2; |
221 | } else if false { | 264 | } else if false { |
222 | a = 3; | 265 | a = 3; |
223 | } else { | 266 | } else { |
@@ -240,16 +283,16 @@ fn foo() { | |||
240 | } | 283 | } |
241 | 284 | ||
242 | #[test] | 285 | #[test] |
243 | fn test_extract_assigment_retains_stmts() { | 286 | fn test_pull_assignment_up_retains_stmts() { |
244 | check_assist( | 287 | check_assist( |
245 | extract_assigment, | 288 | pull_assignment_up, |
246 | r#" | 289 | r#" |
247 | fn foo() { | 290 | fn foo() { |
248 | let mut a = 1; | 291 | let mut a = 1; |
249 | 292 | ||
250 | if true { | 293 | if true { |
251 | let b = 2; | 294 | let b = 2; |
252 | <|>a = 2; | 295 | $0a = 2; |
253 | } else { | 296 | } else { |
254 | let b = 3; | 297 | let b = 3; |
255 | a = 3; | 298 | a = 3; |
@@ -271,15 +314,15 @@ fn foo() { | |||
271 | } | 314 | } |
272 | 315 | ||
273 | #[test] | 316 | #[test] |
274 | fn extract_assignment_let_stmt_not_applicable() { | 317 | fn pull_assignment_up_let_stmt_not_applicable() { |
275 | check_assist_not_applicable( | 318 | check_assist_not_applicable( |
276 | extract_assigment, | 319 | pull_assignment_up, |
277 | r#" | 320 | r#" |
278 | fn foo() { | 321 | fn foo() { |
279 | let mut a = 1; | 322 | let mut a = 1; |
280 | 323 | ||
281 | let b = if true { | 324 | let b = if true { |
282 | <|>a = 2 | 325 | $0a = 2 |
283 | } else { | 326 | } else { |
284 | a = 3 | 327 | a = 3 |
285 | }; | 328 | }; |
@@ -288,31 +331,31 @@ fn foo() { | |||
288 | } | 331 | } |
289 | 332 | ||
290 | #[test] | 333 | #[test] |
291 | fn extract_assignment_if_missing_assigment_not_applicable() { | 334 | fn pull_assignment_up_if_missing_assigment_not_applicable() { |
292 | check_assist_not_applicable( | 335 | check_assist_not_applicable( |
293 | extract_assigment, | 336 | pull_assignment_up, |
294 | r#" | 337 | r#" |
295 | fn foo() { | 338 | fn foo() { |
296 | let mut a = 1; | 339 | let mut a = 1; |
297 | 340 | ||
298 | if true { | 341 | if true { |
299 | <|>a = 2; | 342 | $0a = 2; |
300 | } else {} | 343 | } else {} |
301 | }"#, | 344 | }"#, |
302 | ) | 345 | ) |
303 | } | 346 | } |
304 | 347 | ||
305 | #[test] | 348 | #[test] |
306 | fn extract_assignment_match_missing_assigment_not_applicable() { | 349 | fn pull_assignment_up_match_missing_assigment_not_applicable() { |
307 | check_assist_not_applicable( | 350 | check_assist_not_applicable( |
308 | extract_assigment, | 351 | pull_assignment_up, |
309 | r#" | 352 | r#" |
310 | fn foo() { | 353 | fn foo() { |
311 | let mut a = 1; | 354 | let mut a = 1; |
312 | 355 | ||
313 | match 1 { | 356 | match 1 { |
314 | 1 => { | 357 | 1 => { |
315 | <|>a = 2; | 358 | $0a = 2; |
316 | }, | 359 | }, |
317 | 2 => { | 360 | 2 => { |
318 | a = 3; | 361 | a = 3; |
@@ -322,4 +365,36 @@ fn foo() { | |||
322 | }"#, | 365 | }"#, |
323 | ) | 366 | ) |
324 | } | 367 | } |
368 | |||
369 | #[test] | ||
370 | fn test_pull_assignment_up_field_assignment() { | ||
371 | mark::check!(test_pull_assignment_up_field_assignment); | ||
372 | check_assist( | ||
373 | pull_assignment_up, | ||
374 | r#" | ||
375 | struct A(usize); | ||
376 | |||
377 | fn foo() { | ||
378 | let mut a = A(1); | ||
379 | |||
380 | if true { | ||
381 | $0a.0 = 2; | ||
382 | } else { | ||
383 | a.0 = 3; | ||
384 | } | ||
385 | }"#, | ||
386 | r#" | ||
387 | struct A(usize); | ||
388 | |||
389 | fn foo() { | ||
390 | let mut a = A(1); | ||
391 | |||
392 | a.0 = if true { | ||
393 | 2 | ||
394 | } else { | ||
395 | 3 | ||
396 | }; | ||
397 | }"#, | ||
398 | ) | ||
399 | } | ||
325 | } | 400 | } |
diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs index 98cb09214..f7fbf37f4 100644 --- a/crates/assists/src/handlers/qualify_path.rs +++ b/crates/assists/src/handlers/qualify_path.rs | |||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | // | 22 | // |
23 | // ``` | 23 | // ``` |
24 | // fn main() { | 24 | // fn main() { |
25 | // let map = HashMap<|>::new(); | 25 | // let map = HashMap$0::new(); |
26 | // } | 26 | // } |
27 | // # pub mod std { pub mod collections { pub struct HashMap { } } } | 27 | // # pub mod std { pub mod collections { pub struct HashMap { } } } |
28 | // ``` | 28 | // ``` |
@@ -221,7 +221,7 @@ mod tests { | |||
221 | 221 | ||
222 | use std::fmt; | 222 | use std::fmt; |
223 | 223 | ||
224 | <|>Formatter | 224 | $0Formatter |
225 | ", | 225 | ", |
226 | r" | 226 | r" |
227 | mod std { | 227 | mod std { |
@@ -242,7 +242,7 @@ mod tests { | |||
242 | check_assist( | 242 | check_assist( |
243 | qualify_path, | 243 | qualify_path, |
244 | r" | 244 | r" |
245 | <|>PubStruct | 245 | $0PubStruct |
246 | 246 | ||
247 | pub mod PubMod { | 247 | pub mod PubMod { |
248 | pub struct PubStruct; | 248 | pub struct PubStruct; |
@@ -266,7 +266,7 @@ mod tests { | |||
266 | macro_rules! foo { | 266 | macro_rules! foo { |
267 | ($i:ident) => { fn foo(a: $i) {} } | 267 | ($i:ident) => { fn foo(a: $i) {} } |
268 | } | 268 | } |
269 | foo!(Pub<|>Struct); | 269 | foo!(Pub$0Struct); |
270 | 270 | ||
271 | pub mod PubMod { | 271 | pub mod PubMod { |
272 | pub struct PubStruct; | 272 | pub struct PubStruct; |
@@ -290,7 +290,7 @@ mod tests { | |||
290 | check_assist( | 290 | check_assist( |
291 | qualify_path, | 291 | qualify_path, |
292 | r" | 292 | r" |
293 | PubSt<|>ruct | 293 | PubSt$0ruct |
294 | 294 | ||
295 | pub mod PubMod1 { | 295 | pub mod PubMod1 { |
296 | pub struct PubStruct; | 296 | pub struct PubStruct; |
@@ -325,7 +325,7 @@ mod tests { | |||
325 | r" | 325 | r" |
326 | use PubMod::PubStruct; | 326 | use PubMod::PubStruct; |
327 | 327 | ||
328 | PubStruct<|> | 328 | PubStruct$0 |
329 | 329 | ||
330 | pub mod PubMod { | 330 | pub mod PubMod { |
331 | pub struct PubStruct; | 331 | pub struct PubStruct; |
@@ -339,7 +339,7 @@ mod tests { | |||
339 | check_assist_not_applicable( | 339 | check_assist_not_applicable( |
340 | qualify_path, | 340 | qualify_path, |
341 | r" | 341 | r" |
342 | PrivateStruct<|> | 342 | PrivateStruct$0 |
343 | 343 | ||
344 | pub mod PubMod { | 344 | pub mod PubMod { |
345 | struct PrivateStruct; | 345 | struct PrivateStruct; |
@@ -353,7 +353,7 @@ mod tests { | |||
353 | check_assist_not_applicable( | 353 | check_assist_not_applicable( |
354 | qualify_path, | 354 | qualify_path, |
355 | " | 355 | " |
356 | PubStruct<|>", | 356 | PubStruct$0", |
357 | ); | 357 | ); |
358 | } | 358 | } |
359 | 359 | ||
@@ -362,7 +362,7 @@ mod tests { | |||
362 | check_assist_not_applicable( | 362 | check_assist_not_applicable( |
363 | qualify_path, | 363 | qualify_path, |
364 | r" | 364 | r" |
365 | use PubStruct<|>; | 365 | use PubStruct$0; |
366 | 366 | ||
367 | pub mod PubMod { | 367 | pub mod PubMod { |
368 | pub struct PubStruct; | 368 | pub struct PubStruct; |
@@ -375,7 +375,7 @@ mod tests { | |||
375 | check_assist( | 375 | check_assist( |
376 | qualify_path, | 376 | qualify_path, |
377 | r" | 377 | r" |
378 | test_function<|> | 378 | test_function$0 |
379 | 379 | ||
380 | pub mod PubMod { | 380 | pub mod PubMod { |
381 | pub fn test_function() {}; | 381 | pub fn test_function() {}; |
@@ -404,7 +404,7 @@ macro_rules! foo { | |||
404 | 404 | ||
405 | //- /main.rs crate:main deps:crate_with_macro | 405 | //- /main.rs crate:main deps:crate_with_macro |
406 | fn main() { | 406 | fn main() { |
407 | foo<|> | 407 | foo$0 |
408 | } | 408 | } |
409 | ", | 409 | ", |
410 | r" | 410 | r" |
@@ -421,7 +421,7 @@ fn main() { | |||
421 | qualify_path, | 421 | qualify_path, |
422 | r" | 422 | r" |
423 | struct AssistInfo { | 423 | struct AssistInfo { |
424 | group_label: Option<<|>GroupLabel>, | 424 | group_label: Option<$0GroupLabel>, |
425 | } | 425 | } |
426 | 426 | ||
427 | mod m { pub struct GroupLabel; } | 427 | mod m { pub struct GroupLabel; } |
@@ -445,7 +445,7 @@ fn main() { | |||
445 | 445 | ||
446 | use mod1::mod2; | 446 | use mod1::mod2; |
447 | fn main() { | 447 | fn main() { |
448 | mod2::mod3::TestStruct<|> | 448 | mod2::mod3::TestStruct$0 |
449 | } | 449 | } |
450 | ", | 450 | ", |
451 | ); | 451 | ); |
@@ -462,7 +462,7 @@ fn main() { | |||
462 | 462 | ||
463 | use test_mod::test_function; | 463 | use test_mod::test_function; |
464 | fn main() { | 464 | fn main() { |
465 | test_function<|> | 465 | test_function$0 |
466 | } | 466 | } |
467 | ", | 467 | ", |
468 | ); | 468 | ); |
@@ -481,7 +481,7 @@ fn main() { | |||
481 | } | 481 | } |
482 | 482 | ||
483 | fn main() { | 483 | fn main() { |
484 | TestStruct::test_function<|> | 484 | TestStruct::test_function$0 |
485 | } | 485 | } |
486 | ", | 486 | ", |
487 | r" | 487 | r" |
@@ -513,7 +513,7 @@ fn main() { | |||
513 | } | 513 | } |
514 | 514 | ||
515 | fn main() { | 515 | fn main() { |
516 | TestStruct::TEST_CONST<|> | 516 | TestStruct::TEST_CONST$0 |
517 | } | 517 | } |
518 | ", | 518 | ", |
519 | r" | 519 | r" |
@@ -547,7 +547,7 @@ fn main() { | |||
547 | } | 547 | } |
548 | 548 | ||
549 | fn main() { | 549 | fn main() { |
550 | test_mod::TestStruct::test_function<|> | 550 | test_mod::TestStruct::test_function$0 |
551 | } | 551 | } |
552 | ", | 552 | ", |
553 | r" | 553 | r" |
@@ -594,7 +594,7 @@ fn main() { | |||
594 | 594 | ||
595 | use test_mod::TestTrait2; | 595 | use test_mod::TestTrait2; |
596 | fn main() { | 596 | fn main() { |
597 | test_mod::TestEnum::test_function<|>; | 597 | test_mod::TestEnum::test_function$0; |
598 | } | 598 | } |
599 | ", | 599 | ", |
600 | ) | 600 | ) |
@@ -617,7 +617,7 @@ fn main() { | |||
617 | } | 617 | } |
618 | 618 | ||
619 | fn main() { | 619 | fn main() { |
620 | test_mod::TestStruct::TEST_CONST<|> | 620 | test_mod::TestStruct::TEST_CONST$0 |
621 | } | 621 | } |
622 | ", | 622 | ", |
623 | r" | 623 | r" |
@@ -664,7 +664,7 @@ fn main() { | |||
664 | 664 | ||
665 | use test_mod::TestTrait2; | 665 | use test_mod::TestTrait2; |
666 | fn main() { | 666 | fn main() { |
667 | test_mod::TestEnum::TEST_CONST<|>; | 667 | test_mod::TestEnum::TEST_CONST$0; |
668 | } | 668 | } |
669 | ", | 669 | ", |
670 | ) | 670 | ) |
@@ -688,7 +688,7 @@ fn main() { | |||
688 | 688 | ||
689 | fn main() { | 689 | fn main() { |
690 | let test_struct = test_mod::TestStruct {}; | 690 | let test_struct = test_mod::TestStruct {}; |
691 | test_struct.test_meth<|>od() | 691 | test_struct.test_meth$0od() |
692 | } | 692 | } |
693 | ", | 693 | ", |
694 | r" | 694 | r" |
@@ -727,7 +727,7 @@ fn main() { | |||
727 | 727 | ||
728 | fn main() { | 728 | fn main() { |
729 | let test_struct = test_mod::TestStruct {}; | 729 | let test_struct = test_mod::TestStruct {}; |
730 | test_struct.test_meth<|>od(42) | 730 | test_struct.test_meth$0od(42) |
731 | } | 731 | } |
732 | ", | 732 | ", |
733 | r" | 733 | r" |
@@ -766,7 +766,7 @@ fn main() { | |||
766 | 766 | ||
767 | fn main() { | 767 | fn main() { |
768 | let test_struct = test_mod::TestStruct {}; | 768 | let test_struct = test_mod::TestStruct {}; |
769 | test_struct.test_meth<|>od() | 769 | test_struct.test_meth$0od() |
770 | } | 770 | } |
771 | ", | 771 | ", |
772 | r" | 772 | r" |
@@ -796,7 +796,7 @@ fn main() { | |||
796 | //- /main.rs crate:main deps:dep | 796 | //- /main.rs crate:main deps:dep |
797 | fn main() { | 797 | fn main() { |
798 | let test_struct = dep::test_mod::TestStruct {}; | 798 | let test_struct = dep::test_mod::TestStruct {}; |
799 | test_struct.test_meth<|>od() | 799 | test_struct.test_meth$0od() |
800 | } | 800 | } |
801 | //- /dep.rs crate:dep | 801 | //- /dep.rs crate:dep |
802 | pub mod test_mod { | 802 | pub mod test_mod { |
@@ -825,7 +825,7 @@ fn main() { | |||
825 | r" | 825 | r" |
826 | //- /main.rs crate:main deps:dep | 826 | //- /main.rs crate:main deps:dep |
827 | fn main() { | 827 | fn main() { |
828 | dep::test_mod::TestStruct::test_func<|>tion | 828 | dep::test_mod::TestStruct::test_func$0tion |
829 | } | 829 | } |
830 | //- /dep.rs crate:dep | 830 | //- /dep.rs crate:dep |
831 | pub mod test_mod { | 831 | pub mod test_mod { |
@@ -853,7 +853,7 @@ fn main() { | |||
853 | r" | 853 | r" |
854 | //- /main.rs crate:main deps:dep | 854 | //- /main.rs crate:main deps:dep |
855 | fn main() { | 855 | fn main() { |
856 | dep::test_mod::TestStruct::CONST<|> | 856 | dep::test_mod::TestStruct::CONST$0 |
857 | } | 857 | } |
858 | //- /dep.rs crate:dep | 858 | //- /dep.rs crate:dep |
859 | pub mod test_mod { | 859 | pub mod test_mod { |
@@ -882,7 +882,7 @@ fn main() { | |||
882 | //- /main.rs crate:main deps:dep | 882 | //- /main.rs crate:main deps:dep |
883 | fn main() { | 883 | fn main() { |
884 | let test_struct = dep::test_mod::TestStruct {}; | 884 | let test_struct = dep::test_mod::TestStruct {}; |
885 | test_struct.test_func<|>tion() | 885 | test_struct.test_func$0tion() |
886 | } | 886 | } |
887 | //- /dep.rs crate:dep | 887 | //- /dep.rs crate:dep |
888 | pub mod test_mod { | 888 | pub mod test_mod { |
@@ -906,7 +906,7 @@ fn main() { | |||
906 | //- /main.rs crate:main deps:dep | 906 | //- /main.rs crate:main deps:dep |
907 | fn main() { | 907 | fn main() { |
908 | let test_struct = dep::test_mod::TestStruct {}; | 908 | let test_struct = dep::test_mod::TestStruct {}; |
909 | test_struct.test_meth<|>od() | 909 | test_struct.test_meth$0od() |
910 | } | 910 | } |
911 | //- /dep.rs crate:dep | 911 | //- /dep.rs crate:dep |
912 | pub mod test_mod { | 912 | pub mod test_mod { |
@@ -949,7 +949,7 @@ fn main() { | |||
949 | use test_mod::TestTrait2; | 949 | use test_mod::TestTrait2; |
950 | fn main() { | 950 | fn main() { |
951 | let one = test_mod::TestEnum::One; | 951 | let one = test_mod::TestEnum::One; |
952 | one.test<|>_method(); | 952 | one.test$0_method(); |
953 | } | 953 | } |
954 | ", | 954 | ", |
955 | ) | 955 | ) |
@@ -965,7 +965,7 @@ pub struct Struct; | |||
965 | 965 | ||
966 | //- /main.rs crate:main deps:dep | 966 | //- /main.rs crate:main deps:dep |
967 | fn main() { | 967 | fn main() { |
968 | Struct<|> | 968 | Struct$0 |
969 | } | 969 | } |
970 | ", | 970 | ", |
971 | r" | 971 | r" |
@@ -992,7 +992,7 @@ pub fn panic_fmt() {} | |||
992 | //- /main.rs crate:main deps:dep | 992 | //- /main.rs crate:main deps:dep |
993 | struct S; | 993 | struct S; |
994 | 994 | ||
995 | impl f<|>mt::Display for S {} | 995 | impl f$0mt::Display for S {} |
996 | ", | 996 | ", |
997 | r" | 997 | r" |
998 | struct S; | 998 | struct S; |
@@ -1019,7 +1019,7 @@ mac!(); | |||
1019 | 1019 | ||
1020 | //- /main.rs crate:main deps:dep | 1020 | //- /main.rs crate:main deps:dep |
1021 | fn main() { | 1021 | fn main() { |
1022 | Cheese<|>; | 1022 | Cheese$0; |
1023 | } | 1023 | } |
1024 | ", | 1024 | ", |
1025 | r" | 1025 | r" |
@@ -1042,7 +1042,7 @@ pub struct fmt; | |||
1042 | 1042 | ||
1043 | //- /main.rs crate:main deps:dep | 1043 | //- /main.rs crate:main deps:dep |
1044 | fn main() { | 1044 | fn main() { |
1045 | FMT<|>; | 1045 | FMT$0; |
1046 | } | 1046 | } |
1047 | ", | 1047 | ", |
1048 | r" | 1048 | r" |
@@ -1062,7 +1062,7 @@ fn main() { | |||
1062 | pub mod generic { pub struct Thing<'a, T>(&'a T); } | 1062 | pub mod generic { pub struct Thing<'a, T>(&'a T); } |
1063 | 1063 | ||
1064 | //- /main.rs crate:main deps:dep | 1064 | //- /main.rs crate:main deps:dep |
1065 | fn foo() -> Thin<|>g<'static, ()> {} | 1065 | fn foo() -> Thin$0g<'static, ()> {} |
1066 | 1066 | ||
1067 | fn main() {} | 1067 | fn main() {} |
1068 | ", | 1068 | ", |
@@ -1083,7 +1083,7 @@ fn main() {} | |||
1083 | pub mod generic { pub struct Thing<'a, T>(&'a T); } | 1083 | pub mod generic { pub struct Thing<'a, T>(&'a T); } |
1084 | 1084 | ||
1085 | //- /main.rs crate:main deps:dep | 1085 | //- /main.rs crate:main deps:dep |
1086 | fn foo() -> Thin<|>g::<'static, ()> {} | 1086 | fn foo() -> Thin$0g::<'static, ()> {} |
1087 | 1087 | ||
1088 | fn main() {} | 1088 | fn main() {} |
1089 | ", | 1089 | ", |
@@ -1108,7 +1108,7 @@ fn main() {} | |||
1108 | } | 1108 | } |
1109 | 1109 | ||
1110 | fn main() { | 1110 | fn main() { |
1111 | TestStruct::<()>::TEST_CONST<|> | 1111 | TestStruct::<()>::TEST_CONST$0 |
1112 | } | 1112 | } |
1113 | ", | 1113 | ", |
1114 | r" | 1114 | r" |
@@ -1142,7 +1142,7 @@ fn main() {} | |||
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | fn main() { | 1144 | fn main() { |
1145 | test_mod::TestStruct::<()>::TEST_CONST<|> | 1145 | test_mod::TestStruct::<()>::TEST_CONST$0 |
1146 | } | 1146 | } |
1147 | ", | 1147 | ", |
1148 | r" | 1148 | r" |
@@ -1180,7 +1180,7 @@ fn main() {} | |||
1180 | 1180 | ||
1181 | fn main() { | 1181 | fn main() { |
1182 | let test_struct = test_mod::TestStruct {}; | 1182 | let test_struct = test_mod::TestStruct {}; |
1183 | test_struct.test_meth<|>od::<()>() | 1183 | test_struct.test_meth$0od::<()>() |
1184 | } | 1184 | } |
1185 | ", | 1185 | ", |
1186 | r" | 1186 | r" |
diff --git a/crates/assists/src/handlers/raw_string.rs b/crates/assists/src/handlers/raw_string.rs index 4c759cc25..be963f162 100644 --- a/crates/assists/src/handlers/raw_string.rs +++ b/crates/assists/src/handlers/raw_string.rs | |||
@@ -11,7 +11,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
11 | // | 11 | // |
12 | // ``` | 12 | // ``` |
13 | // fn main() { | 13 | // fn main() { |
14 | // "Hello,<|> World!"; | 14 | // "Hello,$0 World!"; |
15 | // } | 15 | // } |
16 | // ``` | 16 | // ``` |
17 | // -> | 17 | // -> |
@@ -53,7 +53,7 @@ pub(crate) fn make_raw_string(acc: &mut Assists, ctx: &AssistContext) -> Option< | |||
53 | // | 53 | // |
54 | // ``` | 54 | // ``` |
55 | // fn main() { | 55 | // fn main() { |
56 | // r#"Hello,<|> "World!""#; | 56 | // r#"Hello,$0 "World!""#; |
57 | // } | 57 | // } |
58 | // ``` | 58 | // ``` |
59 | // -> | 59 | // -> |
@@ -95,7 +95,7 @@ pub(crate) fn make_usual_string(acc: &mut Assists, ctx: &AssistContext) -> Optio | |||
95 | // | 95 | // |
96 | // ``` | 96 | // ``` |
97 | // fn main() { | 97 | // fn main() { |
98 | // r#"Hello,<|> World!"#; | 98 | // r#"Hello,$0 World!"#; |
99 | // } | 99 | // } |
100 | // ``` | 100 | // ``` |
101 | // -> | 101 | // -> |
@@ -123,7 +123,7 @@ pub(crate) fn add_hash(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { | |||
123 | // | 123 | // |
124 | // ``` | 124 | // ``` |
125 | // fn main() { | 125 | // fn main() { |
126 | // r#"Hello,<|> World!"#; | 126 | // r#"Hello,$0 World!"#; |
127 | // } | 127 | // } |
128 | // ``` | 128 | // ``` |
129 | // -> | 129 | // -> |
@@ -194,7 +194,7 @@ mod tests { | |||
194 | make_raw_string, | 194 | make_raw_string, |
195 | r#" | 195 | r#" |
196 | fn f() { | 196 | fn f() { |
197 | let s = <|>"random\nstring"; | 197 | let s = $0"random\nstring"; |
198 | } | 198 | } |
199 | "#, | 199 | "#, |
200 | r#""random\nstring""#, | 200 | r#""random\nstring""#, |
@@ -207,7 +207,7 @@ mod tests { | |||
207 | make_raw_string, | 207 | make_raw_string, |
208 | r#" | 208 | r#" |
209 | fn f() { | 209 | fn f() { |
210 | let s = <|>"random\nstring"; | 210 | let s = $0"random\nstring"; |
211 | } | 211 | } |
212 | "#, | 212 | "#, |
213 | r##" | 213 | r##" |
@@ -225,7 +225,7 @@ string"#; | |||
225 | make_raw_string, | 225 | make_raw_string, |
226 | r#" | 226 | r#" |
227 | fn f() { | 227 | fn f() { |
228 | format!(<|>"x = {}", 92) | 228 | format!($0"x = {}", 92) |
229 | } | 229 | } |
230 | "#, | 230 | "#, |
231 | r##" | 231 | r##" |
@@ -242,7 +242,7 @@ string"#; | |||
242 | make_raw_string, | 242 | make_raw_string, |
243 | r###" | 243 | r###" |
244 | fn f() { | 244 | fn f() { |
245 | let s = <|>"#random##\nstring"; | 245 | let s = $0"#random##\nstring"; |
246 | } | 246 | } |
247 | "###, | 247 | "###, |
248 | r####" | 248 | r####" |
@@ -260,7 +260,7 @@ string"#; | |||
260 | make_raw_string, | 260 | make_raw_string, |
261 | r###" | 261 | r###" |
262 | fn f() { | 262 | fn f() { |
263 | let s = <|>"#random\"##\nstring"; | 263 | let s = $0"#random\"##\nstring"; |
264 | } | 264 | } |
265 | "###, | 265 | "###, |
266 | r####" | 266 | r####" |
@@ -278,7 +278,7 @@ string"###; | |||
278 | make_raw_string, | 278 | make_raw_string, |
279 | r#" | 279 | r#" |
280 | fn f() { | 280 | fn f() { |
281 | let s = <|>"random string"; | 281 | let s = $0"random string"; |
282 | } | 282 | } |
283 | "#, | 283 | "#, |
284 | r##" | 284 | r##" |
@@ -295,7 +295,7 @@ string"###; | |||
295 | make_raw_string, | 295 | make_raw_string, |
296 | r#" | 296 | r#" |
297 | fn f() { | 297 | fn f() { |
298 | let s = "foo<|> | 298 | let s = "foo$0 |
299 | } | 299 | } |
300 | "#, | 300 | "#, |
301 | ) | 301 | ) |
@@ -307,7 +307,7 @@ string"###; | |||
307 | make_usual_string, | 307 | make_usual_string, |
308 | r#" | 308 | r#" |
309 | fn main() { | 309 | fn main() { |
310 | let s = r#"bar<|> | 310 | let s = r#"bar$0 |
311 | } | 311 | } |
312 | "#, | 312 | "#, |
313 | ) | 313 | ) |
@@ -319,7 +319,7 @@ string"###; | |||
319 | add_hash, | 319 | add_hash, |
320 | r#" | 320 | r#" |
321 | fn f() { | 321 | fn f() { |
322 | let s = <|>r"random string"; | 322 | let s = $0r"random string"; |
323 | } | 323 | } |
324 | "#, | 324 | "#, |
325 | r#"r"random string""#, | 325 | r#"r"random string""#, |
@@ -332,7 +332,7 @@ string"###; | |||
332 | add_hash, | 332 | add_hash, |
333 | r#" | 333 | r#" |
334 | fn f() { | 334 | fn f() { |
335 | let s = <|>r"random string"; | 335 | let s = $0r"random string"; |
336 | } | 336 | } |
337 | "#, | 337 | "#, |
338 | r##" | 338 | r##" |
@@ -349,7 +349,7 @@ string"###; | |||
349 | add_hash, | 349 | add_hash, |
350 | r##" | 350 | r##" |
351 | fn f() { | 351 | fn f() { |
352 | let s = <|>r#"random"string"#; | 352 | let s = $0r#"random"string"#; |
353 | } | 353 | } |
354 | "##, | 354 | "##, |
355 | r###" | 355 | r###" |
@@ -366,7 +366,7 @@ string"###; | |||
366 | add_hash, | 366 | add_hash, |
367 | r#" | 367 | r#" |
368 | fn f() { | 368 | fn f() { |
369 | let s = <|>"random string"; | 369 | let s = $0"random string"; |
370 | } | 370 | } |
371 | "#, | 371 | "#, |
372 | ); | 372 | ); |
@@ -378,7 +378,7 @@ string"###; | |||
378 | remove_hash, | 378 | remove_hash, |
379 | r##" | 379 | r##" |
380 | fn f() { | 380 | fn f() { |
381 | let s = <|>r#"random string"#; | 381 | let s = $0r#"random string"#; |
382 | } | 382 | } |
383 | "##, | 383 | "##, |
384 | r##"r#"random string"#"##, | 384 | r##"r#"random string"#"##, |
@@ -389,7 +389,7 @@ string"###; | |||
389 | fn remove_hash_works() { | 389 | fn remove_hash_works() { |
390 | check_assist( | 390 | check_assist( |
391 | remove_hash, | 391 | remove_hash, |
392 | r##"fn f() { let s = <|>r#"random string"#; }"##, | 392 | r##"fn f() { let s = $0r#"random string"#; }"##, |
393 | r#"fn f() { let s = r"random string"; }"#, | 393 | r#"fn f() { let s = r"random string"; }"#, |
394 | ) | 394 | ) |
395 | } | 395 | } |
@@ -401,7 +401,7 @@ string"###; | |||
401 | remove_hash, | 401 | remove_hash, |
402 | r##" | 402 | r##" |
403 | fn f() { | 403 | fn f() { |
404 | let s = <|>r#"random"str"ing"#; | 404 | let s = $0r#"random"str"ing"#; |
405 | } | 405 | } |
406 | "##, | 406 | "##, |
407 | ) | 407 | ) |
@@ -413,7 +413,7 @@ string"###; | |||
413 | remove_hash, | 413 | remove_hash, |
414 | r###" | 414 | r###" |
415 | fn f() { | 415 | fn f() { |
416 | let s = <|>r##"random string"##; | 416 | let s = $0r##"random string"##; |
417 | } | 417 | } |
418 | "###, | 418 | "###, |
419 | r##" | 419 | r##" |
@@ -426,12 +426,12 @@ string"###; | |||
426 | 426 | ||
427 | #[test] | 427 | #[test] |
428 | fn remove_hash_doesnt_work() { | 428 | fn remove_hash_doesnt_work() { |
429 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>"random string"; }"#); | 429 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = $0"random string"; }"#); |
430 | } | 430 | } |
431 | 431 | ||
432 | #[test] | 432 | #[test] |
433 | fn remove_hash_no_hash_doesnt_work() { | 433 | fn remove_hash_no_hash_doesnt_work() { |
434 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = <|>r"random string"; }"#); | 434 | check_assist_not_applicable(remove_hash, r#"fn f() { let s = $0r"random string"; }"#); |
435 | } | 435 | } |
436 | 436 | ||
437 | #[test] | 437 | #[test] |
@@ -440,7 +440,7 @@ string"###; | |||
440 | make_usual_string, | 440 | make_usual_string, |
441 | r##" | 441 | r##" |
442 | fn f() { | 442 | fn f() { |
443 | let s = <|>r#"random string"#; | 443 | let s = $0r#"random string"#; |
444 | } | 444 | } |
445 | "##, | 445 | "##, |
446 | r##"r#"random string"#"##, | 446 | r##"r#"random string"#"##, |
@@ -453,7 +453,7 @@ string"###; | |||
453 | make_usual_string, | 453 | make_usual_string, |
454 | r##" | 454 | r##" |
455 | fn f() { | 455 | fn f() { |
456 | let s = <|>r#"random string"#; | 456 | let s = $0r#"random string"#; |
457 | } | 457 | } |
458 | "##, | 458 | "##, |
459 | r#" | 459 | r#" |
@@ -470,7 +470,7 @@ string"###; | |||
470 | make_usual_string, | 470 | make_usual_string, |
471 | r##" | 471 | r##" |
472 | fn f() { | 472 | fn f() { |
473 | let s = <|>r#"random"str"ing"#; | 473 | let s = $0r#"random"str"ing"#; |
474 | } | 474 | } |
475 | "##, | 475 | "##, |
476 | r#" | 476 | r#" |
@@ -487,7 +487,7 @@ string"###; | |||
487 | make_usual_string, | 487 | make_usual_string, |
488 | r###" | 488 | r###" |
489 | fn f() { | 489 | fn f() { |
490 | let s = <|>r##"random string"##; | 490 | let s = $0r##"random string"##; |
491 | } | 491 | } |
492 | "###, | 492 | "###, |
493 | r##" | 493 | r##" |
@@ -504,7 +504,7 @@ string"###; | |||
504 | make_usual_string, | 504 | make_usual_string, |
505 | r#" | 505 | r#" |
506 | fn f() { | 506 | fn f() { |
507 | let s = <|>"random string"; | 507 | let s = $0"random string"; |
508 | } | 508 | } |
509 | "#, | 509 | "#, |
510 | ); | 510 | ); |
diff --git a/crates/assists/src/handlers/remove_dbg.rs b/crates/assists/src/handlers/remove_dbg.rs index eae6367c1..0320c2f12 100644 --- a/crates/assists/src/handlers/remove_dbg.rs +++ b/crates/assists/src/handlers/remove_dbg.rs | |||
@@ -11,7 +11,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
11 | // | 11 | // |
12 | // ``` | 12 | // ``` |
13 | // fn main() { | 13 | // fn main() { |
14 | // <|>dbg!(92); | 14 | // $0dbg!(92); |
15 | // } | 15 | // } |
16 | // ``` | 16 | // ``` |
17 | // -> | 17 | // -> |
@@ -161,19 +161,19 @@ mod tests { | |||
161 | 161 | ||
162 | #[test] | 162 | #[test] |
163 | fn test_remove_dbg() { | 163 | fn test_remove_dbg() { |
164 | check_assist(remove_dbg, "<|>dbg!(1 + 1)", "1 + 1"); | 164 | check_assist(remove_dbg, "$0dbg!(1 + 1)", "1 + 1"); |
165 | 165 | ||
166 | check_assist(remove_dbg, "dbg!<|>((1 + 1))", "(1 + 1)"); | 166 | check_assist(remove_dbg, "dbg!$0((1 + 1))", "(1 + 1)"); |
167 | 167 | ||
168 | check_assist(remove_dbg, "dbg!(1 <|>+ 1)", "1 + 1"); | 168 | check_assist(remove_dbg, "dbg!(1 $0+ 1)", "1 + 1"); |
169 | 169 | ||
170 | check_assist(remove_dbg, "let _ = <|>dbg!(1 + 1)", "let _ = 1 + 1"); | 170 | check_assist(remove_dbg, "let _ = $0dbg!(1 + 1)", "let _ = 1 + 1"); |
171 | 171 | ||
172 | check_assist( | 172 | check_assist( |
173 | remove_dbg, | 173 | remove_dbg, |
174 | " | 174 | " |
175 | fn foo(n: usize) { | 175 | fn foo(n: usize) { |
176 | if let Some(_) = dbg!(n.<|>checked_sub(4)) { | 176 | if let Some(_) = dbg!(n.$0checked_sub(4)) { |
177 | // ... | 177 | // ... |
178 | } | 178 | } |
179 | } | 179 | } |
@@ -187,20 +187,20 @@ fn foo(n: usize) { | |||
187 | ", | 187 | ", |
188 | ); | 188 | ); |
189 | 189 | ||
190 | check_assist(remove_dbg, "<|>dbg!(Foo::foo_test()).bar()", "Foo::foo_test().bar()"); | 190 | check_assist(remove_dbg, "$0dbg!(Foo::foo_test()).bar()", "Foo::foo_test().bar()"); |
191 | } | 191 | } |
192 | 192 | ||
193 | #[test] | 193 | #[test] |
194 | fn test_remove_dbg_with_brackets_and_braces() { | 194 | fn test_remove_dbg_with_brackets_and_braces() { |
195 | check_assist(remove_dbg, "dbg![<|>1 + 1]", "1 + 1"); | 195 | check_assist(remove_dbg, "dbg![$01 + 1]", "1 + 1"); |
196 | check_assist(remove_dbg, "dbg!{<|>1 + 1}", "1 + 1"); | 196 | check_assist(remove_dbg, "dbg!{$01 + 1}", "1 + 1"); |
197 | } | 197 | } |
198 | 198 | ||
199 | #[test] | 199 | #[test] |
200 | fn test_remove_dbg_not_applicable() { | 200 | fn test_remove_dbg_not_applicable() { |
201 | check_assist_not_applicable(remove_dbg, "<|>vec![1, 2, 3]"); | 201 | check_assist_not_applicable(remove_dbg, "$0vec![1, 2, 3]"); |
202 | check_assist_not_applicable(remove_dbg, "<|>dbg(5, 6, 7)"); | 202 | check_assist_not_applicable(remove_dbg, "$0dbg(5, 6, 7)"); |
203 | check_assist_not_applicable(remove_dbg, "<|>dbg!(5, 6, 7"); | 203 | check_assist_not_applicable(remove_dbg, "$0dbg!(5, 6, 7"); |
204 | } | 204 | } |
205 | 205 | ||
206 | #[test] | 206 | #[test] |
@@ -209,7 +209,7 @@ fn foo(n: usize) { | |||
209 | remove_dbg, | 209 | remove_dbg, |
210 | " | 210 | " |
211 | fn foo(n: usize) { | 211 | fn foo(n: usize) { |
212 | if let Some(_) = dbg!(n.<|>checked_sub(4)) { | 212 | if let Some(_) = dbg!(n.$0checked_sub(4)) { |
213 | // ... | 213 | // ... |
214 | } | 214 | } |
215 | } | 215 | } |
@@ -226,7 +226,7 @@ fn foo(n: usize) { | |||
226 | // the ast::MacroCall to include the semicolon at the end | 226 | // the ast::MacroCall to include the semicolon at the end |
227 | check_assist( | 227 | check_assist( |
228 | remove_dbg, | 228 | remove_dbg, |
229 | r#"let res = <|>dbg!(1 * 20); // needless comment"#, | 229 | r#"let res = $0dbg!(1 * 20); // needless comment"#, |
230 | r#"let res = 1 * 20; // needless comment"#, | 230 | r#"let res = 1 * 20; // needless comment"#, |
231 | ); | 231 | ); |
232 | } | 232 | } |
@@ -238,7 +238,7 @@ fn foo(n: usize) { | |||
238 | " | 238 | " |
239 | fn main() { | 239 | fn main() { |
240 | let mut a = 1; | 240 | let mut a = 1; |
241 | while dbg!<|>(a) < 10000 { | 241 | while dbg!$0(a) < 10000 { |
242 | a += 1; | 242 | a += 1; |
243 | } | 243 | } |
244 | } | 244 | } |
@@ -258,31 +258,31 @@ fn main() { | |||
258 | fn test_remove_dbg_keep_expression() { | 258 | fn test_remove_dbg_keep_expression() { |
259 | check_assist( | 259 | check_assist( |
260 | remove_dbg, | 260 | remove_dbg, |
261 | r#"let res = <|>dbg!(a + b).foo();"#, | 261 | r#"let res = $0dbg!(a + b).foo();"#, |
262 | r#"let res = (a + b).foo();"#, | 262 | r#"let res = (a + b).foo();"#, |
263 | ); | 263 | ); |
264 | 264 | ||
265 | check_assist(remove_dbg, r#"let res = <|>dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#); | 265 | check_assist(remove_dbg, r#"let res = $0dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#); |
266 | check_assist(remove_dbg, r#"let res = <|>dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#); | 266 | check_assist(remove_dbg, r#"let res = $0dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#); |
267 | } | 267 | } |
268 | 268 | ||
269 | #[test] | 269 | #[test] |
270 | fn test_remove_dbg_method_chaining() { | 270 | fn test_remove_dbg_method_chaining() { |
271 | check_assist( | 271 | check_assist( |
272 | remove_dbg, | 272 | remove_dbg, |
273 | r#"let res = <|>dbg!(foo().bar()).baz();"#, | 273 | r#"let res = $0dbg!(foo().bar()).baz();"#, |
274 | r#"let res = foo().bar().baz();"#, | 274 | r#"let res = foo().bar().baz();"#, |
275 | ); | 275 | ); |
276 | check_assist( | 276 | check_assist( |
277 | remove_dbg, | 277 | remove_dbg, |
278 | r#"let res = <|>dbg!(foo.bar()).baz();"#, | 278 | r#"let res = $0dbg!(foo.bar()).baz();"#, |
279 | r#"let res = foo.bar().baz();"#, | 279 | r#"let res = foo.bar().baz();"#, |
280 | ); | 280 | ); |
281 | } | 281 | } |
282 | 282 | ||
283 | #[test] | 283 | #[test] |
284 | fn test_remove_dbg_field_chaining() { | 284 | fn test_remove_dbg_field_chaining() { |
285 | check_assist(remove_dbg, r#"let res = <|>dbg!(foo.bar).baz;"#, r#"let res = foo.bar.baz;"#); | 285 | check_assist(remove_dbg, r#"let res = $0dbg!(foo.bar).baz;"#, r#"let res = foo.bar.baz;"#); |
286 | } | 286 | } |
287 | 287 | ||
288 | #[test] | 288 | #[test] |
@@ -295,7 +295,7 @@ fn square(x: u32) -> u32 { | |||
295 | } | 295 | } |
296 | 296 | ||
297 | fn main() { | 297 | fn main() { |
298 | let x = square(dbg<|>!(5 + 10)); | 298 | let x = square(dbg$0!(5 + 10)); |
299 | println!("{}", x); | 299 | println!("{}", x); |
300 | }"#, | 300 | }"#, |
301 | "dbg!(5 + 10)", | 301 | "dbg!(5 + 10)", |
@@ -309,7 +309,7 @@ fn square(x: u32) -> u32 { | |||
309 | } | 309 | } |
310 | 310 | ||
311 | fn main() { | 311 | fn main() { |
312 | let x = square(dbg<|>!(5 + 10)); | 312 | let x = square(dbg$0!(5 + 10)); |
313 | println!("{}", x); | 313 | println!("{}", x); |
314 | }"#, | 314 | }"#, |
315 | r#" | 315 | r#" |
@@ -328,7 +328,7 @@ fn main() { | |||
328 | fn test_remove_dbg_try_expr() { | 328 | fn test_remove_dbg_try_expr() { |
329 | check_assist( | 329 | check_assist( |
330 | remove_dbg, | 330 | remove_dbg, |
331 | r#"let res = <|>dbg!(result?).foo();"#, | 331 | r#"let res = $0dbg!(result?).foo();"#, |
332 | r#"let res = result?.foo();"#, | 332 | r#"let res = result?.foo();"#, |
333 | ); | 333 | ); |
334 | } | 334 | } |
@@ -337,7 +337,7 @@ fn main() { | |||
337 | fn test_remove_dbg_await_expr() { | 337 | fn test_remove_dbg_await_expr() { |
338 | check_assist( | 338 | check_assist( |
339 | remove_dbg, | 339 | remove_dbg, |
340 | r#"let res = <|>dbg!(fut.await).foo();"#, | 340 | r#"let res = $0dbg!(fut.await).foo();"#, |
341 | r#"let res = fut.await.foo();"#, | 341 | r#"let res = fut.await.foo();"#, |
342 | ); | 342 | ); |
343 | } | 343 | } |
@@ -346,7 +346,7 @@ fn main() { | |||
346 | fn test_remove_dbg_as_cast() { | 346 | fn test_remove_dbg_as_cast() { |
347 | check_assist( | 347 | check_assist( |
348 | remove_dbg, | 348 | remove_dbg, |
349 | r#"let res = <|>dbg!(3 as usize).foo();"#, | 349 | r#"let res = $0dbg!(3 as usize).foo();"#, |
350 | r#"let res = (3 as usize).foo();"#, | 350 | r#"let res = (3 as usize).foo();"#, |
351 | ); | 351 | ); |
352 | } | 352 | } |
@@ -355,12 +355,12 @@ fn main() { | |||
355 | fn test_remove_dbg_index_expr() { | 355 | fn test_remove_dbg_index_expr() { |
356 | check_assist( | 356 | check_assist( |
357 | remove_dbg, | 357 | remove_dbg, |
358 | r#"let res = <|>dbg!(array[3]).foo();"#, | 358 | r#"let res = $0dbg!(array[3]).foo();"#, |
359 | r#"let res = array[3].foo();"#, | 359 | r#"let res = array[3].foo();"#, |
360 | ); | 360 | ); |
361 | check_assist( | 361 | check_assist( |
362 | remove_dbg, | 362 | remove_dbg, |
363 | r#"let res = <|>dbg!(tuple.3).foo();"#, | 363 | r#"let res = $0dbg!(tuple.3).foo();"#, |
364 | r#"let res = tuple.3.foo();"#, | 364 | r#"let res = tuple.3.foo();"#, |
365 | ); | 365 | ); |
366 | } | 366 | } |
@@ -369,12 +369,12 @@ fn main() { | |||
369 | fn test_remove_dbg_range_expr() { | 369 | fn test_remove_dbg_range_expr() { |
370 | check_assist( | 370 | check_assist( |
371 | remove_dbg, | 371 | remove_dbg, |
372 | r#"let res = <|>dbg!(foo..bar).foo();"#, | 372 | r#"let res = $0dbg!(foo..bar).foo();"#, |
373 | r#"let res = (foo..bar).foo();"#, | 373 | r#"let res = (foo..bar).foo();"#, |
374 | ); | 374 | ); |
375 | check_assist( | 375 | check_assist( |
376 | remove_dbg, | 376 | remove_dbg, |
377 | r#"let res = <|>dbg!(foo..=bar).foo();"#, | 377 | r#"let res = $0dbg!(foo..=bar).foo();"#, |
378 | r#"let res = (foo..=bar).foo();"#, | 378 | r#"let res = (foo..=bar).foo();"#, |
379 | ); | 379 | ); |
380 | } | 380 | } |
@@ -384,7 +384,7 @@ fn main() { | |||
384 | check_assist( | 384 | check_assist( |
385 | remove_dbg, | 385 | remove_dbg, |
386 | r#"fn foo() { | 386 | r#"fn foo() { |
387 | if <|>dbg!(x || y) {} | 387 | if $0dbg!(x || y) {} |
388 | }"#, | 388 | }"#, |
389 | r#"fn foo() { | 389 | r#"fn foo() { |
390 | if x || y {} | 390 | if x || y {} |
@@ -393,7 +393,7 @@ fn main() { | |||
393 | check_assist( | 393 | check_assist( |
394 | remove_dbg, | 394 | remove_dbg, |
395 | r#"fn foo() { | 395 | r#"fn foo() { |
396 | while let foo = <|>dbg!(&x) {} | 396 | while let foo = $0dbg!(&x) {} |
397 | }"#, | 397 | }"#, |
398 | r#"fn foo() { | 398 | r#"fn foo() { |
399 | while let foo = &x {} | 399 | while let foo = &x {} |
@@ -402,7 +402,7 @@ fn main() { | |||
402 | check_assist( | 402 | check_assist( |
403 | remove_dbg, | 403 | remove_dbg, |
404 | r#"fn foo() { | 404 | r#"fn foo() { |
405 | if let foo = <|>dbg!(&x) {} | 405 | if let foo = $0dbg!(&x) {} |
406 | }"#, | 406 | }"#, |
407 | r#"fn foo() { | 407 | r#"fn foo() { |
408 | if let foo = &x {} | 408 | if let foo = &x {} |
@@ -411,7 +411,7 @@ fn main() { | |||
411 | check_assist( | 411 | check_assist( |
412 | remove_dbg, | 412 | remove_dbg, |
413 | r#"fn foo() { | 413 | r#"fn foo() { |
414 | match <|>dbg!(&x) {} | 414 | match $0dbg!(&x) {} |
415 | }"#, | 415 | }"#, |
416 | r#"fn foo() { | 416 | r#"fn foo() { |
417 | match &x {} | 417 | match &x {} |
diff --git a/crates/assists/src/handlers/remove_mut.rs b/crates/assists/src/handlers/remove_mut.rs index 575b271f7..30d36dacd 100644 --- a/crates/assists/src/handlers/remove_mut.rs +++ b/crates/assists/src/handlers/remove_mut.rs | |||
@@ -8,7 +8,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // impl Walrus { | 10 | // impl Walrus { |
11 | // fn feed(&mut<|> self, amount: u32) {} | 11 | // fn feed(&mut$0 self, amount: u32) {} |
12 | // } | 12 | // } |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
diff --git a/crates/assists/src/handlers/remove_unused_param.rs b/crates/assists/src/handlers/remove_unused_param.rs index f72dd49ed..56e8b5229 100644 --- a/crates/assists/src/handlers/remove_unused_param.rs +++ b/crates/assists/src/handlers/remove_unused_param.rs | |||
@@ -16,7 +16,7 @@ use crate::{ | |||
16 | // Removes unused function parameter. | 16 | // Removes unused function parameter. |
17 | // | 17 | // |
18 | // ``` | 18 | // ``` |
19 | // fn frobnicate(x: i32<|>) {} | 19 | // fn frobnicate(x: i32$0) {} |
20 | // | 20 | // |
21 | // fn main() { | 21 | // fn main() { |
22 | // frobnicate(92); | 22 | // frobnicate(92); |
@@ -123,7 +123,7 @@ mod tests { | |||
123 | remove_unused_param, | 123 | remove_unused_param, |
124 | r#" | 124 | r#" |
125 | fn a() { foo(9, 2) } | 125 | fn a() { foo(9, 2) } |
126 | fn foo(x: i32, <|>y: i32) { x; } | 126 | fn foo(x: i32, $0y: i32) { x; } |
127 | fn b() { foo(9, 2,) } | 127 | fn b() { foo(9, 2,) } |
128 | "#, | 128 | "#, |
129 | r#" | 129 | r#" |
@@ -139,7 +139,7 @@ fn b() { foo(9, ) } | |||
139 | check_assist( | 139 | check_assist( |
140 | remove_unused_param, | 140 | remove_unused_param, |
141 | r#" | 141 | r#" |
142 | fn foo(<|>x: i32, y: i32) { y; } | 142 | fn foo($0x: i32, y: i32) { y; } |
143 | fn a() { foo(1, 2) } | 143 | fn a() { foo(1, 2) } |
144 | fn b() { foo(1, 2,) } | 144 | fn b() { foo(1, 2,) } |
145 | "#, | 145 | "#, |
@@ -156,7 +156,7 @@ fn b() { foo(2,) } | |||
156 | check_assist( | 156 | check_assist( |
157 | remove_unused_param, | 157 | remove_unused_param, |
158 | r#" | 158 | r#" |
159 | fn foo(<|>x: i32) { 0; } | 159 | fn foo($0x: i32) { 0; } |
160 | fn a() { foo(1) } | 160 | fn a() { foo(1) } |
161 | fn b() { foo(1, ) } | 161 | fn b() { foo(1, ) } |
162 | "#, | 162 | "#, |
@@ -173,7 +173,7 @@ fn b() { foo( ) } | |||
173 | check_assist( | 173 | check_assist( |
174 | remove_unused_param, | 174 | remove_unused_param, |
175 | r#" | 175 | r#" |
176 | fn foo(x: i32, <|>y: i32, z: i32) { x; } | 176 | fn foo(x: i32, $0y: i32, z: i32) { x; } |
177 | fn a() { foo(1, 2, 3) } | 177 | fn a() { foo(1, 2, 3) } |
178 | fn b() { foo(1, 2, 3,) } | 178 | fn b() { foo(1, 2, 3,) } |
179 | "#, | 179 | "#, |
@@ -190,7 +190,7 @@ fn b() { foo(1, 3,) } | |||
190 | check_assist( | 190 | check_assist( |
191 | remove_unused_param, | 191 | remove_unused_param, |
192 | r#" | 192 | r#" |
193 | mod bar { pub fn foo(x: i32, <|>y: i32) { x; } } | 193 | mod bar { pub fn foo(x: i32, $0y: i32) { x; } } |
194 | fn b() { bar::foo(9, 2) } | 194 | fn b() { bar::foo(9, 2) } |
195 | "#, | 195 | "#, |
196 | r#" | 196 | r#" |
@@ -205,7 +205,7 @@ fn b() { bar::foo(9) } | |||
205 | check_assist( | 205 | check_assist( |
206 | remove_unused_param, | 206 | remove_unused_param, |
207 | r#" | 207 | r#" |
208 | pub fn foo<T>(x: T, <|>y: i32) { x; } | 208 | pub fn foo<T>(x: T, $0y: i32) { x; } |
209 | fn b() { foo::<i32>(9, 2) } | 209 | fn b() { foo::<i32>(9, 2) } |
210 | "#, | 210 | "#, |
211 | r#" | 211 | r#" |
@@ -220,7 +220,7 @@ fn b() { foo::<i32>(9) } | |||
220 | check_assist( | 220 | check_assist( |
221 | remove_unused_param, | 221 | remove_unused_param, |
222 | r#" | 222 | r#" |
223 | pub fn foo<T>(x: i32, <|>y: T) { x; } | 223 | pub fn foo<T>(x: i32, $0y: T) { x; } |
224 | fn b() { foo::<i32>(9, 2) } | 224 | fn b() { foo::<i32>(9, 2) } |
225 | fn b2() { foo(9, 2) } | 225 | fn b2() { foo(9, 2) } |
226 | "#, | 226 | "#, |
@@ -238,7 +238,7 @@ fn b2() { foo(9) } | |||
238 | check_assist_not_applicable( | 238 | check_assist_not_applicable( |
239 | remove_unused_param, | 239 | remove_unused_param, |
240 | r#" | 240 | r#" |
241 | fn foo(x: i32, <|>y: i32) { y; } | 241 | fn foo(x: i32, $0y: i32) { y; } |
242 | fn main() { foo(9, 2) } | 242 | fn main() { foo(9, 2) } |
243 | "#, | 243 | "#, |
244 | ); | 244 | ); |
@@ -250,7 +250,7 @@ fn main() { foo(9, 2) } | |||
250 | remove_unused_param, | 250 | remove_unused_param, |
251 | r#" | 251 | r#" |
252 | //- /main.rs | 252 | //- /main.rs |
253 | fn foo(x: i32, <|>y: i32) { x; } | 253 | fn foo(x: i32, $0y: i32) { x; } |
254 | 254 | ||
255 | mod foo; | 255 | mod foo; |
256 | 256 | ||
diff --git a/crates/assists/src/handlers/reorder_fields.rs b/crates/assists/src/handlers/reorder_fields.rs index fe5574242..fba7d6ddb 100644 --- a/crates/assists/src/handlers/reorder_fields.rs +++ b/crates/assists/src/handlers/reorder_fields.rs | |||
@@ -15,7 +15,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
15 | // | 15 | // |
16 | // ``` | 16 | // ``` |
17 | // struct Foo {foo: i32, bar: i32}; | 17 | // struct Foo {foo: i32, bar: i32}; |
18 | // const test: Foo = <|>Foo {bar: 0, foo: 1} | 18 | // const test: Foo = $0Foo {bar: 0, foo: 1} |
19 | // ``` | 19 | // ``` |
20 | // -> | 20 | // -> |
21 | // ``` | 21 | // ``` |
@@ -126,7 +126,7 @@ struct Foo { | |||
126 | bar: i32, | 126 | bar: i32, |
127 | } | 127 | } |
128 | 128 | ||
129 | const test: Foo = <|>Foo { foo: 0, bar: 0 }; | 129 | const test: Foo = $0Foo { foo: 0, bar: 0 }; |
130 | "#, | 130 | "#, |
131 | ) | 131 | ) |
132 | } | 132 | } |
@@ -137,7 +137,7 @@ const test: Foo = <|>Foo { foo: 0, bar: 0 }; | |||
137 | reorder_fields, | 137 | reorder_fields, |
138 | r#" | 138 | r#" |
139 | struct Foo {}; | 139 | struct Foo {}; |
140 | const test: Foo = <|>Foo {} | 140 | const test: Foo = $0Foo {} |
141 | "#, | 141 | "#, |
142 | ) | 142 | ) |
143 | } | 143 | } |
@@ -148,7 +148,7 @@ const test: Foo = <|>Foo {} | |||
148 | reorder_fields, | 148 | reorder_fields, |
149 | r#" | 149 | r#" |
150 | struct Foo {foo: i32, bar: i32}; | 150 | struct Foo {foo: i32, bar: i32}; |
151 | const test: Foo = <|>Foo {bar: 0, foo: 1} | 151 | const test: Foo = $0Foo {bar: 0, foo: 1} |
152 | "#, | 152 | "#, |
153 | r#" | 153 | r#" |
154 | struct Foo {foo: i32, bar: i32}; | 154 | struct Foo {foo: i32, bar: i32}; |
@@ -166,7 +166,7 @@ struct Foo { foo: i64, bar: i64, baz: i64 } | |||
166 | 166 | ||
167 | fn f(f: Foo) -> { | 167 | fn f(f: Foo) -> { |
168 | match f { | 168 | match f { |
169 | <|>Foo { baz: 0, ref mut bar, .. } => (), | 169 | $0Foo { baz: 0, ref mut bar, .. } => (), |
170 | _ => () | 170 | _ => () |
171 | } | 171 | } |
172 | } | 172 | } |
@@ -197,7 +197,7 @@ struct Foo { | |||
197 | impl Foo { | 197 | impl Foo { |
198 | fn new() -> Foo { | 198 | fn new() -> Foo { |
199 | let foo = String::new(); | 199 | let foo = String::new(); |
200 | <|>Foo { | 200 | $0Foo { |
201 | bar: foo.clone(), | 201 | bar: foo.clone(), |
202 | extra: "Extra field", | 202 | extra: "Extra field", |
203 | foo, | 203 | foo, |
diff --git a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs index cb7a5c104..bd4c1c806 100644 --- a/crates/assists/src/handlers/replace_derive_with_manual_impl.rs +++ b/crates/assists/src/handlers/replace_derive_with_manual_impl.rs | |||
@@ -22,7 +22,7 @@ use crate::{ | |||
22 | // | 22 | // |
23 | // ``` | 23 | // ``` |
24 | // # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } | 24 | // # trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } |
25 | // #[derive(Deb<|>ug, Display)] | 25 | // #[derive(Deb$0ug, Display)] |
26 | // struct S; | 26 | // struct S; |
27 | // ``` | 27 | // ``` |
28 | // -> | 28 | // -> |
@@ -219,7 +219,7 @@ mod fmt { | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | #[derive(Debu<|>g)] | 222 | #[derive(Debu$0g)] |
223 | struct Foo { | 223 | struct Foo { |
224 | bar: String, | 224 | bar: String, |
225 | } | 225 | } |
@@ -261,7 +261,7 @@ mod foo { | |||
261 | } | 261 | } |
262 | } | 262 | } |
263 | 263 | ||
264 | #[derive(<|>Bar)] | 264 | #[derive($0Bar)] |
265 | struct Foo { | 265 | struct Foo { |
266 | bar: String, | 266 | bar: String, |
267 | } | 267 | } |
@@ -300,7 +300,7 @@ impl foo::Bar for Foo { | |||
300 | check_assist( | 300 | check_assist( |
301 | replace_derive_with_manual_impl, | 301 | replace_derive_with_manual_impl, |
302 | " | 302 | " |
303 | #[derive(Debu<|>g)] | 303 | #[derive(Debu$0g)] |
304 | struct Foo { | 304 | struct Foo { |
305 | bar: String, | 305 | bar: String, |
306 | } | 306 | } |
@@ -322,7 +322,7 @@ impl Debug for Foo { | |||
322 | check_assist( | 322 | check_assist( |
323 | replace_derive_with_manual_impl, | 323 | replace_derive_with_manual_impl, |
324 | " | 324 | " |
325 | #[derive(Debug<|>)] | 325 | #[derive(Debug$0)] |
326 | pub struct Foo { | 326 | pub struct Foo { |
327 | bar: String, | 327 | bar: String, |
328 | } | 328 | } |
@@ -344,7 +344,7 @@ impl Debug for Foo { | |||
344 | check_assist( | 344 | check_assist( |
345 | replace_derive_with_manual_impl, | 345 | replace_derive_with_manual_impl, |
346 | " | 346 | " |
347 | #[derive(Display, Debug<|>, Serialize)] | 347 | #[derive(Display, Debug$0, Serialize)] |
348 | struct Foo {} | 348 | struct Foo {} |
349 | ", | 349 | ", |
350 | " | 350 | " |
@@ -363,7 +363,7 @@ impl Debug for Foo { | |||
363 | check_assist_not_applicable( | 363 | check_assist_not_applicable( |
364 | replace_derive_with_manual_impl, | 364 | replace_derive_with_manual_impl, |
365 | " | 365 | " |
366 | #[derive(<|>)] | 366 | #[derive($0)] |
367 | struct Foo {} | 367 | struct Foo {} |
368 | ", | 368 | ", |
369 | ) | 369 | ) |
@@ -374,7 +374,7 @@ struct Foo {} | |||
374 | check_assist_not_applicable( | 374 | check_assist_not_applicable( |
375 | replace_derive_with_manual_impl, | 375 | replace_derive_with_manual_impl, |
376 | " | 376 | " |
377 | #[derive<|>(Debug)] | 377 | #[derive$0(Debug)] |
378 | struct Foo {} | 378 | struct Foo {} |
379 | ", | 379 | ", |
380 | ); | 380 | ); |
@@ -382,7 +382,7 @@ struct Foo {} | |||
382 | check_assist_not_applicable( | 382 | check_assist_not_applicable( |
383 | replace_derive_with_manual_impl, | 383 | replace_derive_with_manual_impl, |
384 | " | 384 | " |
385 | #[derive(Debug)<|>] | 385 | #[derive(Debug)$0] |
386 | struct Foo {} | 386 | struct Foo {} |
387 | ", | 387 | ", |
388 | ) | 388 | ) |
@@ -393,7 +393,7 @@ struct Foo {} | |||
393 | check_assist_not_applicable( | 393 | check_assist_not_applicable( |
394 | replace_derive_with_manual_impl, | 394 | replace_derive_with_manual_impl, |
395 | " | 395 | " |
396 | #[allow(non_camel_<|>case_types)] | 396 | #[allow(non_camel_$0case_types)] |
397 | struct Foo {} | 397 | struct Foo {} |
398 | ", | 398 | ", |
399 | ) | 399 | ) |
diff --git a/crates/assists/src/handlers/replace_if_let_with_match.rs b/crates/assists/src/handlers/replace_if_let_with_match.rs index 4a355c66f..aee3397ab 100644 --- a/crates/assists/src/handlers/replace_if_let_with_match.rs +++ b/crates/assists/src/handlers/replace_if_let_with_match.rs | |||
@@ -20,7 +20,7 @@ use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, As | |||
20 | // enum Action { Move { distance: u32 }, Stop } | 20 | // enum Action { Move { distance: u32 }, Stop } |
21 | // | 21 | // |
22 | // fn handle(action: Action) { | 22 | // fn handle(action: Action) { |
23 | // <|>if let Action::Move { distance } = action { | 23 | // $0if let Action::Move { distance } = action { |
24 | // foo(distance) | 24 | // foo(distance) |
25 | // } else { | 25 | // } else { |
26 | // bar() | 26 | // bar() |
@@ -89,7 +89,7 @@ pub(crate) fn replace_if_let_with_match(acc: &mut Assists, ctx: &AssistContext) | |||
89 | // enum Action { Move { distance: u32 }, Stop } | 89 | // enum Action { Move { distance: u32 }, Stop } |
90 | // | 90 | // |
91 | // fn handle(action: Action) { | 91 | // fn handle(action: Action) { |
92 | // <|>match action { | 92 | // $0match action { |
93 | // Action::Move { distance } => foo(distance), | 93 | // Action::Move { distance } => foo(distance), |
94 | // _ => bar(), | 94 | // _ => bar(), |
95 | // } | 95 | // } |
@@ -138,7 +138,7 @@ pub(crate) fn replace_match_with_if_let(acc: &mut Assists, ctx: &AssistContext) | |||
138 | }; | 138 | }; |
139 | let else_expr = match else_expr { | 139 | let else_expr = match else_expr { |
140 | ast::Expr::BlockExpr(block) | 140 | ast::Expr::BlockExpr(block) |
141 | if block.statements().count() == 0 && block.expr().is_none() => | 141 | if block.statements().count() == 0 && block.tail_expr().is_none() => |
142 | { | 142 | { |
143 | None | 143 | None |
144 | } | 144 | } |
@@ -179,7 +179,7 @@ mod tests { | |||
179 | r#" | 179 | r#" |
180 | impl VariantData { | 180 | impl VariantData { |
181 | pub fn is_struct(&self) -> bool { | 181 | pub fn is_struct(&self) -> bool { |
182 | if <|>let VariantData::Struct(..) = *self { | 182 | if $0let VariantData::Struct(..) = *self { |
183 | true | 183 | true |
184 | } else { | 184 | } else { |
185 | false | 185 | false |
@@ -204,7 +204,7 @@ impl VariantData { | |||
204 | replace_if_let_with_match, | 204 | replace_if_let_with_match, |
205 | r#" | 205 | r#" |
206 | fn foo() { | 206 | fn foo() { |
207 | if <|>let VariantData::Struct(..) = a { | 207 | if $0let VariantData::Struct(..) = a { |
208 | bar( | 208 | bar( |
209 | 123 | 209 | 123 |
210 | ) | 210 | ) |
@@ -233,7 +233,7 @@ fn foo() { | |||
233 | r#" | 233 | r#" |
234 | impl VariantData { | 234 | impl VariantData { |
235 | pub fn is_struct(&self) -> bool { | 235 | pub fn is_struct(&self) -> bool { |
236 | if <|>let VariantData::Struct(..) = *self { | 236 | if $0let VariantData::Struct(..) = *self { |
237 | true | 237 | true |
238 | } else { | 238 | } else { |
239 | false | 239 | false |
@@ -257,7 +257,7 @@ enum Option<T> { Some(T), None } | |||
257 | use Option::*; | 257 | use Option::*; |
258 | 258 | ||
259 | fn foo(x: Option<i32>) { | 259 | fn foo(x: Option<i32>) { |
260 | <|>if let Some(x) = x { | 260 | $0if let Some(x) = x { |
261 | println!("{}", x) | 261 | println!("{}", x) |
262 | } else { | 262 | } else { |
263 | println!("none") | 263 | println!("none") |
@@ -287,7 +287,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
287 | use Result::*; | 287 | use Result::*; |
288 | 288 | ||
289 | fn foo(x: Result<i32, ()>) { | 289 | fn foo(x: Result<i32, ()>) { |
290 | <|>if let Ok(x) = x { | 290 | $0if let Ok(x) = x { |
291 | println!("{}", x) | 291 | println!("{}", x) |
292 | } else { | 292 | } else { |
293 | println!("none") | 293 | println!("none") |
@@ -315,7 +315,7 @@ fn foo(x: Result<i32, ()>) { | |||
315 | r#" | 315 | r#" |
316 | fn main() { | 316 | fn main() { |
317 | if true { | 317 | if true { |
318 | <|>if let Ok(rel_path) = path.strip_prefix(root_path) { | 318 | $0if let Ok(rel_path) = path.strip_prefix(root_path) { |
319 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | 319 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; |
320 | Some((*id, rel_path)) | 320 | Some((*id, rel_path)) |
321 | } else { | 321 | } else { |
@@ -347,7 +347,7 @@ fn main() { | |||
347 | r#" | 347 | r#" |
348 | impl VariantData { | 348 | impl VariantData { |
349 | pub fn is_struct(&self) -> bool { | 349 | pub fn is_struct(&self) -> bool { |
350 | <|>match *self { | 350 | $0match *self { |
351 | VariantData::Struct(..) => true, | 351 | VariantData::Struct(..) => true, |
352 | _ => false, | 352 | _ => false, |
353 | } | 353 | } |
@@ -372,7 +372,7 @@ impl VariantData { | |||
372 | replace_match_with_if_let, | 372 | replace_match_with_if_let, |
373 | r#" | 373 | r#" |
374 | fn foo() { | 374 | fn foo() { |
375 | <|>match a { | 375 | $0match a { |
376 | VariantData::Struct(..) => { | 376 | VariantData::Struct(..) => { |
377 | bar( | 377 | bar( |
378 | 123 | 378 | 123 |
@@ -401,7 +401,7 @@ fn foo() { | |||
401 | r#" | 401 | r#" |
402 | impl VariantData { | 402 | impl VariantData { |
403 | pub fn is_struct(&self) -> bool { | 403 | pub fn is_struct(&self) -> bool { |
404 | <|>match *self { | 404 | $0match *self { |
405 | VariantData::Struct(..) => true, | 405 | VariantData::Struct(..) => true, |
406 | _ => false, | 406 | _ => false, |
407 | } | 407 | } |
@@ -423,7 +423,7 @@ enum Option<T> { Some(T), None } | |||
423 | use Option::*; | 423 | use Option::*; |
424 | 424 | ||
425 | fn foo(x: Option<i32>) { | 425 | fn foo(x: Option<i32>) { |
426 | <|>match x { | 426 | $0match x { |
427 | Some(x) => println!("{}", x), | 427 | Some(x) => println!("{}", x), |
428 | None => println!("none"), | 428 | None => println!("none"), |
429 | } | 429 | } |
@@ -453,7 +453,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
453 | use Result::*; | 453 | use Result::*; |
454 | 454 | ||
455 | fn foo(x: Result<i32, ()>) { | 455 | fn foo(x: Result<i32, ()>) { |
456 | <|>match x { | 456 | $0match x { |
457 | Ok(x) => println!("{}", x), | 457 | Ok(x) => println!("{}", x), |
458 | Err(_) => println!("none"), | 458 | Err(_) => println!("none"), |
459 | } | 459 | } |
@@ -481,7 +481,7 @@ fn foo(x: Result<i32, ()>) { | |||
481 | r#" | 481 | r#" |
482 | fn main() { | 482 | fn main() { |
483 | if true { | 483 | if true { |
484 | <|>match path.strip_prefix(root_path) { | 484 | $0match path.strip_prefix(root_path) { |
485 | Ok(rel_path) => { | 485 | Ok(rel_path) => { |
486 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | 486 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; |
487 | Some((*id, rel_path)) | 487 | Some((*id, rel_path)) |
@@ -512,7 +512,7 @@ fn main() { | |||
512 | replace_match_with_if_let, | 512 | replace_match_with_if_let, |
513 | r#" | 513 | r#" |
514 | fn main() { | 514 | fn main() { |
515 | <|>match path.strip_prefix(root_path) { | 515 | $0match path.strip_prefix(root_path) { |
516 | Ok(rel_path) => println!("{}", rel_path), | 516 | Ok(rel_path) => println!("{}", rel_path), |
517 | _ => (), | 517 | _ => (), |
518 | } | 518 | } |
diff --git a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs index 6738bc134..ff25b61ea 100644 --- a/crates/assists/src/handlers/replace_impl_trait_with_generic.rs +++ b/crates/assists/src/handlers/replace_impl_trait_with_generic.rs | |||
@@ -7,7 +7,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
7 | // Replaces `impl Trait` function argument with the named generic. | 7 | // Replaces `impl Trait` function argument with the named generic. |
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // fn foo(bar: <|>impl Bar) {} | 10 | // fn foo(bar: $0impl Bar) {} |
11 | // ``` | 11 | // ``` |
12 | // -> | 12 | // -> |
13 | // ``` | 13 | // ``` |
@@ -56,7 +56,7 @@ mod tests { | |||
56 | check_assist( | 56 | check_assist( |
57 | replace_impl_trait_with_generic, | 57 | replace_impl_trait_with_generic, |
58 | r#" | 58 | r#" |
59 | fn foo<G>(bar: <|>impl Bar) {} | 59 | fn foo<G>(bar: $0impl Bar) {} |
60 | "#, | 60 | "#, |
61 | r#" | 61 | r#" |
62 | fn foo<G, B: Bar>(bar: B) {} | 62 | fn foo<G, B: Bar>(bar: B) {} |
@@ -69,7 +69,7 @@ mod tests { | |||
69 | check_assist( | 69 | check_assist( |
70 | replace_impl_trait_with_generic, | 70 | replace_impl_trait_with_generic, |
71 | r#" | 71 | r#" |
72 | fn foo(bar: <|>impl Bar) {} | 72 | fn foo(bar: $0impl Bar) {} |
73 | "#, | 73 | "#, |
74 | r#" | 74 | r#" |
75 | fn foo<B: Bar>(bar: B) {} | 75 | fn foo<B: Bar>(bar: B) {} |
@@ -82,7 +82,7 @@ mod tests { | |||
82 | check_assist( | 82 | check_assist( |
83 | replace_impl_trait_with_generic, | 83 | replace_impl_trait_with_generic, |
84 | r#" | 84 | r#" |
85 | fn foo<G>(foo: impl Foo, bar: <|>impl Bar) {} | 85 | fn foo<G>(foo: impl Foo, bar: $0impl Bar) {} |
86 | "#, | 86 | "#, |
87 | r#" | 87 | r#" |
88 | fn foo<G, B: Bar>(foo: impl Foo, bar: B) {} | 88 | fn foo<G, B: Bar>(foo: impl Foo, bar: B) {} |
@@ -95,7 +95,7 @@ mod tests { | |||
95 | check_assist( | 95 | check_assist( |
96 | replace_impl_trait_with_generic, | 96 | replace_impl_trait_with_generic, |
97 | r#" | 97 | r#" |
98 | fn foo<>(bar: <|>impl Bar) {} | 98 | fn foo<>(bar: $0impl Bar) {} |
99 | "#, | 99 | "#, |
100 | r#" | 100 | r#" |
101 | fn foo<B: Bar>(bar: B) {} | 101 | fn foo<B: Bar>(bar: B) {} |
@@ -109,7 +109,7 @@ mod tests { | |||
109 | replace_impl_trait_with_generic, | 109 | replace_impl_trait_with_generic, |
110 | r#" | 110 | r#" |
111 | fn foo< | 111 | fn foo< |
112 | >(bar: <|>impl Bar) {} | 112 | >(bar: $0impl Bar) {} |
113 | "#, | 113 | "#, |
114 | r#" | 114 | r#" |
115 | fn foo<B: Bar | 115 | fn foo<B: Bar |
@@ -124,7 +124,7 @@ mod tests { | |||
124 | check_assist( | 124 | check_assist( |
125 | replace_impl_trait_with_generic, | 125 | replace_impl_trait_with_generic, |
126 | r#" | 126 | r#" |
127 | fn foo<B>(bar: <|>impl Bar) {} | 127 | fn foo<B>(bar: $0impl Bar) {} |
128 | "#, | 128 | "#, |
129 | r#" | 129 | r#" |
130 | fn foo<B, C: Bar>(bar: C) {} | 130 | fn foo<B, C: Bar>(bar: C) {} |
@@ -141,7 +141,7 @@ mod tests { | |||
141 | G: Foo, | 141 | G: Foo, |
142 | F, | 142 | F, |
143 | H, | 143 | H, |
144 | >(bar: <|>impl Bar) {} | 144 | >(bar: $0impl Bar) {} |
145 | "#, | 145 | "#, |
146 | r#" | 146 | r#" |
147 | fn foo< | 147 | fn foo< |
@@ -158,7 +158,7 @@ mod tests { | |||
158 | check_assist( | 158 | check_assist( |
159 | replace_impl_trait_with_generic, | 159 | replace_impl_trait_with_generic, |
160 | r#" | 160 | r#" |
161 | fn foo(bar: <|>impl Foo + Bar) {} | 161 | fn foo(bar: $0impl Foo + Bar) {} |
162 | "#, | 162 | "#, |
163 | r#" | 163 | r#" |
164 | fn foo<F: Foo + Bar>(bar: F) {} | 164 | fn foo<F: Foo + Bar>(bar: F) {} |
diff --git a/crates/assists/src/handlers/replace_let_with_if_let.rs b/crates/assists/src/handlers/replace_let_with_if_let.rs index 5970e283c..5a27ada6b 100644 --- a/crates/assists/src/handlers/replace_let_with_if_let.rs +++ b/crates/assists/src/handlers/replace_let_with_if_let.rs | |||
@@ -20,7 +20,7 @@ use ide_db::ty_filter::TryEnum; | |||
20 | // # enum Option<T> { Some(T), None } | 20 | // # enum Option<T> { Some(T), None } |
21 | // | 21 | // |
22 | // fn main(action: Action) { | 22 | // fn main(action: Action) { |
23 | // <|>let x = compute(); | 23 | // $0let x = compute(); |
24 | // } | 24 | // } |
25 | // | 25 | // |
26 | // fn compute() -> Option<i32> { None } | 26 | // fn compute() -> Option<i32> { None } |
@@ -85,7 +85,7 @@ mod tests { | |||
85 | enum E<T> { X(T), Y(T) } | 85 | enum E<T> { X(T), Y(T) } |
86 | 86 | ||
87 | fn main() { | 87 | fn main() { |
88 | <|>let x = E::X(92); | 88 | $0let x = E::X(92); |
89 | } | 89 | } |
90 | ", | 90 | ", |
91 | r" | 91 | r" |
diff --git a/crates/assists/src/handlers/replace_qualified_name_with_use.rs b/crates/assists/src/handlers/replace_qualified_name_with_use.rs index 8193e45a8..f3bc6cf39 100644 --- a/crates/assists/src/handlers/replace_qualified_name_with_use.rs +++ b/crates/assists/src/handlers/replace_qualified_name_with_use.rs | |||
@@ -9,7 +9,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
9 | // Adds a use statement for a given fully-qualified name. | 9 | // Adds a use statement for a given fully-qualified name. |
10 | // | 10 | // |
11 | // ``` | 11 | // ``` |
12 | // fn process(map: std::collections::<|>HashMap<String, String>) {} | 12 | // fn process(map: std::collections::$0HashMap<String, String>) {} |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
15 | // ``` | 15 | // ``` |
@@ -127,7 +127,7 @@ mod tests { | |||
127 | r"use std::fs; | 127 | r"use std::fs; |
128 | 128 | ||
129 | fn main() { | 129 | fn main() { |
130 | std::f<|>s::Path | 130 | std::f$0s::Path |
131 | }", | 131 | }", |
132 | r"use std::fs; | 132 | r"use std::fs; |
133 | 133 | ||
@@ -142,7 +142,7 @@ fn main() { | |||
142 | check_assist( | 142 | check_assist( |
143 | replace_qualified_name_with_use, | 143 | replace_qualified_name_with_use, |
144 | r" | 144 | r" |
145 | std::fmt::Debug<|> | 145 | std::fmt::Debug$0 |
146 | ", | 146 | ", |
147 | r" | 147 | r" |
148 | use std::fmt::Debug; | 148 | use std::fmt::Debug; |
@@ -156,7 +156,7 @@ Debug | |||
156 | check_assist( | 156 | check_assist( |
157 | replace_qualified_name_with_use, | 157 | replace_qualified_name_with_use, |
158 | r" | 158 | r" |
159 | std::fmt::Debug<|> | 159 | std::fmt::Debug$0 |
160 | 160 | ||
161 | fn main() { | 161 | fn main() { |
162 | } | 162 | } |
@@ -180,7 +180,7 @@ fn main() { | |||
180 | fn main() { | 180 | fn main() { |
181 | } | 181 | } |
182 | 182 | ||
183 | std::fmt::Debug<|> | 183 | std::fmt::Debug$0 |
184 | ", | 184 | ", |
185 | r" | 185 | r" |
186 | use std::fmt::Debug; | 186 | use std::fmt::Debug; |
@@ -198,7 +198,7 @@ Debug | |||
198 | check_assist( | 198 | check_assist( |
199 | replace_qualified_name_with_use, | 199 | replace_qualified_name_with_use, |
200 | r" | 200 | r" |
201 | std::fmt<|>::Debug | 201 | std::fmt$0::Debug |
202 | ", | 202 | ", |
203 | r" | 203 | r" |
204 | use std::fmt; | 204 | use std::fmt; |
@@ -215,7 +215,7 @@ fmt::Debug | |||
215 | r" | 215 | r" |
216 | use stdx; | 216 | use stdx; |
217 | 217 | ||
218 | impl std::fmt::Debug<|> for Foo { | 218 | impl std::fmt::Debug$0 for Foo { |
219 | } | 219 | } |
220 | ", | 220 | ", |
221 | r" | 221 | r" |
@@ -234,7 +234,7 @@ impl Debug for Foo { | |||
234 | check_assist( | 234 | check_assist( |
235 | replace_qualified_name_with_use, | 235 | replace_qualified_name_with_use, |
236 | r" | 236 | r" |
237 | impl std::fmt::Debug<|> for Foo { | 237 | impl std::fmt::Debug$0 for Foo { |
238 | } | 238 | } |
239 | ", | 239 | ", |
240 | r" | 240 | r" |
@@ -251,7 +251,7 @@ impl Debug for Foo { | |||
251 | check_assist( | 251 | check_assist( |
252 | replace_qualified_name_with_use, | 252 | replace_qualified_name_with_use, |
253 | r" | 253 | r" |
254 | impl std::fmt::Debug<|> for Foo { | 254 | impl std::fmt::Debug$0 for Foo { |
255 | } | 255 | } |
256 | ", | 256 | ", |
257 | r" | 257 | r" |
@@ -270,7 +270,7 @@ impl Debug for Foo { | |||
270 | r" | 270 | r" |
271 | use std::fmt; | 271 | use std::fmt; |
272 | 272 | ||
273 | impl std::io<|> for Foo { | 273 | impl std::io$0 for Foo { |
274 | } | 274 | } |
275 | ", | 275 | ", |
276 | r" | 276 | r" |
@@ -289,7 +289,7 @@ impl io for Foo { | |||
289 | r" | 289 | r" |
290 | use std::fmt; | 290 | use std::fmt; |
291 | 291 | ||
292 | impl std::fmt::Debug<|> for Foo { | 292 | impl std::fmt::Debug$0 for Foo { |
293 | } | 293 | } |
294 | ", | 294 | ", |
295 | r" | 295 | r" |
@@ -308,7 +308,7 @@ impl Debug for Foo { | |||
308 | r" | 308 | r" |
309 | use std::fmt::Debug; | 309 | use std::fmt::Debug; |
310 | 310 | ||
311 | impl std::fmt<|> for Foo { | 311 | impl std::fmt$0 for Foo { |
312 | } | 312 | } |
313 | ", | 313 | ", |
314 | r" | 314 | r" |
@@ -327,7 +327,7 @@ impl fmt for Foo { | |||
327 | r" | 327 | r" |
328 | use std::fmt::{Debug, nested::{Display}}; | 328 | use std::fmt::{Debug, nested::{Display}}; |
329 | 329 | ||
330 | impl std::fmt::nested<|> for Foo { | 330 | impl std::fmt::nested$0 for Foo { |
331 | } | 331 | } |
332 | ", | 332 | ", |
333 | r" | 333 | r" |
@@ -346,7 +346,7 @@ impl nested for Foo { | |||
346 | r" | 346 | r" |
347 | use std::fmt::{Debug, nested::{self, Display}}; | 347 | use std::fmt::{Debug, nested::{self, Display}}; |
348 | 348 | ||
349 | impl std::fmt::nested<|> for Foo { | 349 | impl std::fmt::nested$0 for Foo { |
350 | } | 350 | } |
351 | ", | 351 | ", |
352 | r" | 352 | r" |
@@ -365,7 +365,7 @@ impl nested for Foo { | |||
365 | r" | 365 | r" |
366 | use std::fmt::{Debug, nested::{Display}}; | 366 | use std::fmt::{Debug, nested::{Display}}; |
367 | 367 | ||
368 | impl std::fmt::nested::Debug<|> for Foo { | 368 | impl std::fmt::nested::Debug$0 for Foo { |
369 | } | 369 | } |
370 | ", | 370 | ", |
371 | r" | 371 | r" |
@@ -384,7 +384,7 @@ impl Debug for Foo { | |||
384 | r" | 384 | r" |
385 | use std::fmt::Debug; | 385 | use std::fmt::Debug; |
386 | 386 | ||
387 | impl std::fmt::nested::Display<|> for Foo { | 387 | impl std::fmt::nested::Display$0 for Foo { |
388 | } | 388 | } |
389 | ", | 389 | ", |
390 | r" | 390 | r" |
@@ -403,7 +403,7 @@ impl Display for Foo { | |||
403 | r" | 403 | r" |
404 | use std::fmt::nested::Debug; | 404 | use std::fmt::nested::Debug; |
405 | 405 | ||
406 | impl std::fmt::Display<|> for Foo { | 406 | impl std::fmt::Display$0 for Foo { |
407 | } | 407 | } |
408 | ", | 408 | ", |
409 | r" | 409 | r" |
@@ -425,7 +425,7 @@ use crate::{ | |||
425 | AssocItem, | 425 | AssocItem, |
426 | }; | 426 | }; |
427 | 427 | ||
428 | fn foo() { crate::ty::lower<|>::trait_env() } | 428 | fn foo() { crate::ty::lower$0::trait_env() } |
429 | ", | 429 | ", |
430 | r" | 430 | r" |
431 | use crate::{AssocItem, ty::{Substs, Ty, lower}}; | 431 | use crate::{AssocItem, ty::{Substs, Ty, lower}}; |
@@ -442,7 +442,7 @@ fn foo() { lower::trait_env() } | |||
442 | r" | 442 | r" |
443 | use std::fmt as foo; | 443 | use std::fmt as foo; |
444 | 444 | ||
445 | impl foo::Debug<|> for Foo { | 445 | impl foo::Debug$0 for Foo { |
446 | } | 446 | } |
447 | ", | 447 | ", |
448 | r" | 448 | r" |
@@ -462,7 +462,7 @@ impl Debug for Foo { | |||
462 | check_assist_not_applicable( | 462 | check_assist_not_applicable( |
463 | replace_qualified_name_with_use, | 463 | replace_qualified_name_with_use, |
464 | r" | 464 | r" |
465 | impl foo<|> for Foo { | 465 | impl foo$0 for Foo { |
466 | } | 466 | } |
467 | ", | 467 | ", |
468 | ); | 468 | ); |
@@ -473,7 +473,7 @@ impl foo<|> for Foo { | |||
473 | check_assist_not_applicable( | 473 | check_assist_not_applicable( |
474 | replace_qualified_name_with_use, | 474 | replace_qualified_name_with_use, |
475 | r" | 475 | r" |
476 | use std::fmt<|>; | 476 | use std::fmt$0; |
477 | ", | 477 | ", |
478 | ); | 478 | ); |
479 | } | 479 | } |
@@ -485,7 +485,7 @@ use std::fmt<|>; | |||
485 | r" | 485 | r" |
486 | mod foo { | 486 | mod foo { |
487 | mod bar { | 487 | mod bar { |
488 | std::fmt::Debug<|> | 488 | std::fmt::Debug$0 |
489 | } | 489 | } |
490 | } | 490 | } |
491 | ", | 491 | ", |
@@ -509,7 +509,7 @@ mod foo { | |||
509 | #![allow(dead_code)] | 509 | #![allow(dead_code)] |
510 | 510 | ||
511 | fn main() { | 511 | fn main() { |
512 | std::fmt::Debug<|> | 512 | std::fmt::Debug$0 |
513 | } | 513 | } |
514 | ", | 514 | ", |
515 | r" | 515 | r" |
@@ -530,7 +530,7 @@ fn main() { | |||
530 | replace_qualified_name_with_use, | 530 | replace_qualified_name_with_use, |
531 | r" | 531 | r" |
532 | fn main() { | 532 | fn main() { |
533 | std::fmt::Debug<|>; | 533 | std::fmt::Debug$0; |
534 | let x: std::fmt::Debug = std::fmt::Debug; | 534 | let x: std::fmt::Debug = std::fmt::Debug; |
535 | } | 535 | } |
536 | ", | 536 | ", |
@@ -552,7 +552,7 @@ fn main() { | |||
552 | r" | 552 | r" |
553 | mod m { | 553 | mod m { |
554 | fn f() { | 554 | fn f() { |
555 | std::fmt::Debug<|>; | 555 | std::fmt::Debug$0; |
556 | let x: std::fmt::Debug = std::fmt::Debug; | 556 | let x: std::fmt::Debug = std::fmt::Debug; |
557 | } | 557 | } |
558 | fn g() { | 558 | fn g() { |
@@ -590,7 +590,7 @@ fn f() { | |||
590 | replace_qualified_name_with_use, | 590 | replace_qualified_name_with_use, |
591 | r" | 591 | r" |
592 | fn main() { | 592 | fn main() { |
593 | std::fmt::Debug<|>; | 593 | std::fmt::Debug$0; |
594 | } | 594 | } |
595 | 595 | ||
596 | mod sub { | 596 | mod sub { |
@@ -623,7 +623,7 @@ mod sub { | |||
623 | use std::fmt::Display; | 623 | use std::fmt::Display; |
624 | 624 | ||
625 | fn main() { | 625 | fn main() { |
626 | std::fmt<|>; | 626 | std::fmt$0; |
627 | } | 627 | } |
628 | ", | 628 | ", |
629 | r" | 629 | r" |
@@ -643,7 +643,7 @@ fn main() { | |||
643 | r" | 643 | r" |
644 | pub use std::fmt; | 644 | pub use std::fmt; |
645 | 645 | ||
646 | impl std::io<|> for Foo { | 646 | impl std::io$0 for Foo { |
647 | } | 647 | } |
648 | ", | 648 | ", |
649 | r" | 649 | r" |
@@ -663,7 +663,7 @@ impl io for Foo { | |||
663 | r" | 663 | r" |
664 | pub(crate) use std::fmt; | 664 | pub(crate) use std::fmt; |
665 | 665 | ||
666 | impl std::io<|> for Foo { | 666 | impl std::io$0 for Foo { |
667 | } | 667 | } |
668 | ", | 668 | ", |
669 | r" | 669 | r" |
diff --git a/crates/assists/src/handlers/replace_string_with_char.rs b/crates/assists/src/handlers/replace_string_with_char.rs index b4b898846..317318c24 100644 --- a/crates/assists/src/handlers/replace_string_with_char.rs +++ b/crates/assists/src/handlers/replace_string_with_char.rs | |||
@@ -8,7 +8,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
8 | // | 8 | // |
9 | // ``` | 9 | // ``` |
10 | // fn main() { | 10 | // fn main() { |
11 | // find("{<|>"); | 11 | // find("{$0"); |
12 | // } | 12 | // } |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
@@ -48,7 +48,7 @@ mod tests { | |||
48 | replace_string_with_char, | 48 | replace_string_with_char, |
49 | r#" | 49 | r#" |
50 | fn f() { | 50 | fn f() { |
51 | let s = "<|>c"; | 51 | let s = "$0c"; |
52 | } | 52 | } |
53 | "#, | 53 | "#, |
54 | r#""c""#, | 54 | r#""c""#, |
@@ -61,7 +61,7 @@ mod tests { | |||
61 | replace_string_with_char, | 61 | replace_string_with_char, |
62 | r#" | 62 | r#" |
63 | fn f() { | 63 | fn f() { |
64 | let s = "<|>c"; | 64 | let s = "$0c"; |
65 | } | 65 | } |
66 | "#, | 66 | "#, |
67 | r##" | 67 | r##" |
@@ -78,7 +78,7 @@ mod tests { | |||
78 | replace_string_with_char, | 78 | replace_string_with_char, |
79 | r#" | 79 | r#" |
80 | fn f() { | 80 | fn f() { |
81 | let s = "<|>😀"; | 81 | let s = "$0😀"; |
82 | } | 82 | } |
83 | "#, | 83 | "#, |
84 | r##" | 84 | r##" |
@@ -95,7 +95,7 @@ mod tests { | |||
95 | replace_string_with_char, | 95 | replace_string_with_char, |
96 | r#" | 96 | r#" |
97 | fn f() { | 97 | fn f() { |
98 | let s = "<|>test"; | 98 | let s = "$0test"; |
99 | } | 99 | } |
100 | "#, | 100 | "#, |
101 | ) | 101 | ) |
@@ -107,7 +107,7 @@ mod tests { | |||
107 | replace_string_with_char, | 107 | replace_string_with_char, |
108 | r#" | 108 | r#" |
109 | fn f() { | 109 | fn f() { |
110 | format!(<|>"x", 92) | 110 | format!($0"x", 92) |
111 | } | 111 | } |
112 | "#, | 112 | "#, |
113 | r##" | 113 | r##" |
@@ -124,7 +124,7 @@ mod tests { | |||
124 | replace_string_with_char, | 124 | replace_string_with_char, |
125 | r#" | 125 | r#" |
126 | fn f() { | 126 | fn f() { |
127 | find(<|>"x"); | 127 | find($0"x"); |
128 | } | 128 | } |
129 | "#, | 129 | "#, |
130 | r##" | 130 | r##" |
diff --git a/crates/assists/src/handlers/replace_unwrap_with_match.rs b/crates/assists/src/handlers/replace_unwrap_with_match.rs index f547066f0..a986a6ae8 100644 --- a/crates/assists/src/handlers/replace_unwrap_with_match.rs +++ b/crates/assists/src/handlers/replace_unwrap_with_match.rs | |||
@@ -23,7 +23,7 @@ use ide_db::ty_filter::TryEnum; | |||
23 | // enum Result<T, E> { Ok(T), Err(E) } | 23 | // enum Result<T, E> { Ok(T), Err(E) } |
24 | // fn main() { | 24 | // fn main() { |
25 | // let x: Result<i32, i32> = Result::Ok(92); | 25 | // let x: Result<i32, i32> = Result::Ok(92); |
26 | // let y = x.<|>unwrap(); | 26 | // let y = x.$0unwrap(); |
27 | // } | 27 | // } |
28 | // ``` | 28 | // ``` |
29 | // -> | 29 | // -> |
@@ -101,7 +101,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
101 | fn i<T>(a: T) -> T { a } | 101 | fn i<T>(a: T) -> T { a } |
102 | fn main() { | 102 | fn main() { |
103 | let x: Result<i32, i32> = Result::Ok(92); | 103 | let x: Result<i32, i32> = Result::Ok(92); |
104 | let y = i(x).<|>unwrap(); | 104 | let y = i(x).$0unwrap(); |
105 | } | 105 | } |
106 | ", | 106 | ", |
107 | r" | 107 | r" |
@@ -127,7 +127,7 @@ enum Option<T> { Some(T), None } | |||
127 | fn i<T>(a: T) -> T { a } | 127 | fn i<T>(a: T) -> T { a } |
128 | fn main() { | 128 | fn main() { |
129 | let x = Option::Some(92); | 129 | let x = Option::Some(92); |
130 | let y = i(x).<|>unwrap(); | 130 | let y = i(x).$0unwrap(); |
131 | } | 131 | } |
132 | ", | 132 | ", |
133 | r" | 133 | r" |
@@ -153,7 +153,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
153 | fn i<T>(a: T) -> T { a } | 153 | fn i<T>(a: T) -> T { a } |
154 | fn main() { | 154 | fn main() { |
155 | let x: Result<i32, i32> = Result::Ok(92); | 155 | let x: Result<i32, i32> = Result::Ok(92); |
156 | let y = i(x).<|>unwrap().count_zeroes(); | 156 | let y = i(x).$0unwrap().count_zeroes(); |
157 | } | 157 | } |
158 | ", | 158 | ", |
159 | r" | 159 | r" |
@@ -179,7 +179,7 @@ enum Option<T> { Some(T), None } | |||
179 | fn i<T>(a: T) -> T { a } | 179 | fn i<T>(a: T) -> T { a } |
180 | fn main() { | 180 | fn main() { |
181 | let x = Option::Some(92); | 181 | let x = Option::Some(92); |
182 | let y = i(x).<|>unwrap(); | 182 | let y = i(x).$0unwrap(); |
183 | } | 183 | } |
184 | ", | 184 | ", |
185 | r"i(x).unwrap()", | 185 | r"i(x).unwrap()", |
diff --git a/crates/assists/src/handlers/split_import.rs b/crates/assists/src/handlers/split_import.rs index ef1f6b8a1..9319a4267 100644 --- a/crates/assists/src/handlers/split_import.rs +++ b/crates/assists/src/handlers/split_import.rs | |||
@@ -9,7 +9,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
9 | // Wraps the tail of import into braces. | 9 | // Wraps the tail of import into braces. |
10 | // | 10 | // |
11 | // ``` | 11 | // ``` |
12 | // use std::<|>collections::HashMap; | 12 | // use std::$0collections::HashMap; |
13 | // ``` | 13 | // ``` |
14 | // -> | 14 | // -> |
15 | // ``` | 15 | // ``` |
@@ -43,7 +43,7 @@ mod tests { | |||
43 | fn test_split_import() { | 43 | fn test_split_import() { |
44 | check_assist( | 44 | check_assist( |
45 | split_import, | 45 | split_import, |
46 | "use crate::<|>db::RootDatabase;", | 46 | "use crate::$0db::RootDatabase;", |
47 | "use crate::{db::RootDatabase};", | 47 | "use crate::{db::RootDatabase};", |
48 | ) | 48 | ) |
49 | } | 49 | } |
@@ -52,19 +52,19 @@ mod tests { | |||
52 | fn split_import_works_with_trees() { | 52 | fn split_import_works_with_trees() { |
53 | check_assist( | 53 | check_assist( |
54 | split_import, | 54 | split_import, |
55 | "use crate:<|>:db::{RootDatabase, FileSymbol}", | 55 | "use crate:$0:db::{RootDatabase, FileSymbol}", |
56 | "use crate::{db::{RootDatabase, FileSymbol}}", | 56 | "use crate::{db::{RootDatabase, FileSymbol}}", |
57 | ) | 57 | ) |
58 | } | 58 | } |
59 | 59 | ||
60 | #[test] | 60 | #[test] |
61 | fn split_import_target() { | 61 | fn split_import_target() { |
62 | check_assist_target(split_import, "use crate::<|>db::{RootDatabase, FileSymbol}", "::"); | 62 | check_assist_target(split_import, "use crate::$0db::{RootDatabase, FileSymbol}", "::"); |
63 | } | 63 | } |
64 | 64 | ||
65 | #[test] | 65 | #[test] |
66 | fn issue4044() { | 66 | fn issue4044() { |
67 | check_assist_not_applicable(split_import, "use crate::<|>:::self;") | 67 | check_assist_not_applicable(split_import, "use crate::$0:::self;") |
68 | } | 68 | } |
69 | 69 | ||
70 | #[test] | 70 | #[test] |
@@ -72,7 +72,7 @@ mod tests { | |||
72 | check_assist_not_applicable( | 72 | check_assist_not_applicable( |
73 | split_import, | 73 | split_import, |
74 | r" | 74 | r" |
75 | use std::<|> | 75 | use std::$0 |
76 | fn main() {}", | 76 | fn main() {}", |
77 | ); | 77 | ); |
78 | } | 78 | } |
diff --git a/crates/assists/src/handlers/toggle_ignore.rs b/crates/assists/src/handlers/toggle_ignore.rs index 14b420421..33e12a7d0 100644 --- a/crates/assists/src/handlers/toggle_ignore.rs +++ b/crates/assists/src/handlers/toggle_ignore.rs | |||
@@ -10,7 +10,7 @@ use crate::{utils::test_related_attribute, AssistContext, AssistId, AssistKind, | |||
10 | // Adds `#[ignore]` attribute to the test. | 10 | // Adds `#[ignore]` attribute to the test. |
11 | // | 11 | // |
12 | // ``` | 12 | // ``` |
13 | // <|>#[test] | 13 | // $0#[test] |
14 | // fn arithmetics { | 14 | // fn arithmetics { |
15 | // assert_eq!(2 + 2, 5); | 15 | // assert_eq!(2 + 2, 5); |
16 | // } | 16 | // } |
@@ -69,7 +69,7 @@ mod tests { | |||
69 | check_assist( | 69 | check_assist( |
70 | toggle_ignore, | 70 | toggle_ignore, |
71 | r#" | 71 | r#" |
72 | #[test<|>] | 72 | #[test$0] |
73 | fn test() {} | 73 | fn test() {} |
74 | "#, | 74 | "#, |
75 | r#" | 75 | r#" |
@@ -85,7 +85,7 @@ mod tests { | |||
85 | check_assist( | 85 | check_assist( |
86 | toggle_ignore, | 86 | toggle_ignore, |
87 | r#" | 87 | r#" |
88 | #[test<|>] | 88 | #[test$0] |
89 | #[ignore] | 89 | #[ignore] |
90 | fn test() {} | 90 | fn test() {} |
91 | "#, | 91 | "#, |
diff --git a/crates/assists/src/handlers/unwrap_block.rs b/crates/assists/src/handlers/unwrap_block.rs index 676db7137..ed6f6177d 100644 --- a/crates/assists/src/handlers/unwrap_block.rs +++ b/crates/assists/src/handlers/unwrap_block.rs | |||
@@ -14,7 +14,7 @@ use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, As | |||
14 | // | 14 | // |
15 | // ``` | 15 | // ``` |
16 | // fn foo() { | 16 | // fn foo() { |
17 | // if true {<|> | 17 | // if true {$0 |
18 | // println!("foo"); | 18 | // println!("foo"); |
19 | // } | 19 | // } |
20 | // } | 20 | // } |
@@ -124,7 +124,7 @@ mod tests { | |||
124 | unwrap_block, | 124 | unwrap_block, |
125 | r#" | 125 | r#" |
126 | fn main() { | 126 | fn main() { |
127 | <|>{ | 127 | $0{ |
128 | 92 | 128 | 92 |
129 | } | 129 | } |
130 | } | 130 | } |
@@ -143,7 +143,7 @@ fn main() { | |||
143 | unwrap_block, | 143 | unwrap_block, |
144 | r#" | 144 | r#" |
145 | fn main() { | 145 | fn main() { |
146 | <|>{ | 146 | $0{ |
147 | 92; | 147 | 92; |
148 | } | 148 | } |
149 | () | 149 | () |
@@ -161,7 +161,7 @@ fn main() { | |||
161 | unwrap_block, | 161 | unwrap_block, |
162 | r#" | 162 | r#" |
163 | fn main() { | 163 | fn main() { |
164 | <|>{ | 164 | $0{ |
165 | 92 | 165 | 92 |
166 | } | 166 | } |
167 | () | 167 | () |
@@ -183,7 +183,7 @@ fn main() { | |||
183 | r#" | 183 | r#" |
184 | fn main() { | 184 | fn main() { |
185 | bar(); | 185 | bar(); |
186 | if true {<|> | 186 | if true {$0 |
187 | foo(); | 187 | foo(); |
188 | 188 | ||
189 | //comment | 189 | //comment |
@@ -217,7 +217,7 @@ fn main() { | |||
217 | 217 | ||
218 | //comment | 218 | //comment |
219 | bar(); | 219 | bar(); |
220 | } else {<|> | 220 | } else {$0 |
221 | println!("bar"); | 221 | println!("bar"); |
222 | } | 222 | } |
223 | } | 223 | } |
@@ -249,7 +249,7 @@ fn main() { | |||
249 | 249 | ||
250 | //comment | 250 | //comment |
251 | //bar(); | 251 | //bar(); |
252 | } else if false {<|> | 252 | } else if false {$0 |
253 | println!("bar"); | 253 | println!("bar"); |
254 | } else { | 254 | } else { |
255 | println!("foo"); | 255 | println!("foo"); |
@@ -285,7 +285,7 @@ fn main() { | |||
285 | //bar(); | 285 | //bar(); |
286 | } else if false { | 286 | } else if false { |
287 | println!("bar"); | 287 | println!("bar"); |
288 | } else if true {<|> | 288 | } else if true {$0 |
289 | println!("foo"); | 289 | println!("foo"); |
290 | } | 290 | } |
291 | } | 291 | } |
@@ -323,7 +323,7 @@ fn main() { | |||
323 | println!("bar"); | 323 | println!("bar"); |
324 | } else if true { | 324 | } else if true { |
325 | println!("foo"); | 325 | println!("foo"); |
326 | } else {<|> | 326 | } else {$0 |
327 | println!("else"); | 327 | println!("else"); |
328 | } | 328 | } |
329 | } | 329 | } |
@@ -361,7 +361,7 @@ fn main() { | |||
361 | //bar(); | 361 | //bar(); |
362 | } else if false { | 362 | } else if false { |
363 | println!("bar"); | 363 | println!("bar"); |
364 | } else if true {<|> | 364 | } else if true {$0 |
365 | println!("foo"); | 365 | println!("foo"); |
366 | } else { | 366 | } else { |
367 | println!("else"); | 367 | println!("else"); |
@@ -391,7 +391,7 @@ fn main() { | |||
391 | unwrap_block, | 391 | unwrap_block, |
392 | r#" | 392 | r#" |
393 | fn main() { | 393 | fn main() { |
394 | bar();<|> | 394 | bar();$0 |
395 | if true { | 395 | if true { |
396 | foo(); | 396 | foo(); |
397 | 397 | ||
@@ -411,7 +411,7 @@ fn main() { | |||
411 | unwrap_block, | 411 | unwrap_block, |
412 | r#" | 412 | r#" |
413 | fn main() { | 413 | fn main() { |
414 | for i in 0..5 {<|> | 414 | for i in 0..5 {$0 |
415 | if true { | 415 | if true { |
416 | foo(); | 416 | foo(); |
417 | 417 | ||
@@ -445,7 +445,7 @@ fn main() { | |||
445 | r#" | 445 | r#" |
446 | fn main() { | 446 | fn main() { |
447 | for i in 0..5 { | 447 | for i in 0..5 { |
448 | if true {<|> | 448 | if true {$0 |
449 | foo(); | 449 | foo(); |
450 | 450 | ||
451 | //comment | 451 | //comment |
@@ -475,7 +475,7 @@ fn main() { | |||
475 | unwrap_block, | 475 | unwrap_block, |
476 | r#" | 476 | r#" |
477 | fn main() { | 477 | fn main() { |
478 | loop {<|> | 478 | loop {$0 |
479 | if true { | 479 | if true { |
480 | foo(); | 480 | foo(); |
481 | 481 | ||
@@ -508,7 +508,7 @@ fn main() { | |||
508 | unwrap_block, | 508 | unwrap_block, |
509 | r#" | 509 | r#" |
510 | fn main() { | 510 | fn main() { |
511 | while true {<|> | 511 | while true {$0 |
512 | if true { | 512 | if true { |
513 | foo(); | 513 | foo(); |
514 | 514 | ||
@@ -542,7 +542,7 @@ fn main() { | |||
542 | r#" | 542 | r#" |
543 | fn main() { | 543 | fn main() { |
544 | match rel_path { | 544 | match rel_path { |
545 | Ok(rel_path) => {<|> | 545 | Ok(rel_path) => {$0 |
546 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; | 546 | let rel_path = RelativePathBuf::from_path(rel_path).ok()?; |
547 | Some((*id, rel_path)) | 547 | Some((*id, rel_path)) |
548 | } | 548 | } |
@@ -567,7 +567,7 @@ fn main() { | |||
567 | fn main() { | 567 | fn main() { |
568 | while true { | 568 | while true { |
569 | if true { | 569 | if true { |
570 | foo();<|> | 570 | foo();$0 |
571 | 571 | ||
572 | //comment | 572 | //comment |
573 | bar(); | 573 | bar(); |
diff --git a/crates/assists/src/handlers/wrap_return_type_in_result.rs b/crates/assists/src/handlers/wrap_return_type_in_result.rs index 59e5debb1..fec16fc49 100644 --- a/crates/assists/src/handlers/wrap_return_type_in_result.rs +++ b/crates/assists/src/handlers/wrap_return_type_in_result.rs | |||
@@ -13,7 +13,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists}; | |||
13 | // Wrap the function's return type into Result. | 13 | // Wrap the function's return type into Result. |
14 | // | 14 | // |
15 | // ``` | 15 | // ``` |
16 | // fn foo() -> i32<|> { 42i32 } | 16 | // fn foo() -> i32$0 { 42i32 } |
17 | // ``` | 17 | // ``` |
18 | // -> | 18 | // -> |
19 | // ``` | 19 | // ``` |
@@ -98,7 +98,7 @@ impl TailReturnCollector { | |||
98 | } | 98 | } |
99 | 99 | ||
100 | // Browse tail expressions for each block | 100 | // Browse tail expressions for each block |
101 | if let Some(expr) = block_expr.expr() { | 101 | if let Some(expr) = block_expr.tail_expr() { |
102 | if let Some(last_exprs) = get_tail_expr_from_block(&expr) { | 102 | if let Some(last_exprs) = get_tail_expr_from_block(&expr) { |
103 | for last_expr in last_exprs { | 103 | for last_expr in last_exprs { |
104 | let last_expr = match last_expr { | 104 | let last_expr = match last_expr { |
@@ -170,7 +170,7 @@ impl TailReturnCollector { | |||
170 | } | 170 | } |
171 | 171 | ||
172 | fn collect_tail_exprs(&mut self, block: &BlockExpr) { | 172 | fn collect_tail_exprs(&mut self, block: &BlockExpr) { |
173 | if let Some(expr) = block.expr() { | 173 | if let Some(expr) = block.tail_expr() { |
174 | self.handle_exprs(&expr, true); | 174 | self.handle_exprs(&expr, true); |
175 | self.fetch_tail_exprs(&expr); | 175 | self.fetch_tail_exprs(&expr); |
176 | } | 176 | } |
@@ -206,7 +206,7 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> { | |||
206 | Expr::IfExpr(if_expr) => { | 206 | Expr::IfExpr(if_expr) => { |
207 | let mut nodes = vec![]; | 207 | let mut nodes = vec![]; |
208 | for block in if_expr.blocks() { | 208 | for block in if_expr.blocks() { |
209 | if let Some(block_expr) = block.expr() { | 209 | if let Some(block_expr) = block.tail_expr() { |
210 | if let Some(tail_exprs) = get_tail_expr_from_block(&block_expr) { | 210 | if let Some(tail_exprs) = get_tail_expr_from_block(&block_expr) { |
211 | nodes.extend(tail_exprs); | 211 | nodes.extend(tail_exprs); |
212 | } | 212 | } |
@@ -228,7 +228,7 @@ fn get_tail_expr_from_block(expr: &Expr) -> Option<Vec<NodeType>> { | |||
228 | while_expr.syntax().last_child().map(|lc| vec![NodeType::Node(lc)]) | 228 | while_expr.syntax().last_child().map(|lc| vec![NodeType::Node(lc)]) |
229 | } | 229 | } |
230 | Expr::BlockExpr(block_expr) => { | 230 | Expr::BlockExpr(block_expr) => { |
231 | block_expr.expr().map(|lc| vec![NodeType::Node(lc.syntax().clone())]) | 231 | block_expr.tail_expr().map(|lc| vec![NodeType::Node(lc.syntax().clone())]) |
232 | } | 232 | } |
233 | Expr::MatchExpr(match_expr) => { | 233 | Expr::MatchExpr(match_expr) => { |
234 | let arm_list = match_expr.match_arm_list()?; | 234 | let arm_list = match_expr.match_arm_list()?; |
@@ -282,7 +282,7 @@ mod tests { | |||
282 | check_assist( | 282 | check_assist( |
283 | wrap_return_type_in_result, | 283 | wrap_return_type_in_result, |
284 | r#" | 284 | r#" |
285 | fn foo() -> i3<|>2 { | 285 | fn foo() -> i3$02 { |
286 | let test = "test"; | 286 | let test = "test"; |
287 | return 42i32; | 287 | return 42i32; |
288 | } | 288 | } |
@@ -302,7 +302,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
302 | wrap_return_type_in_result, | 302 | wrap_return_type_in_result, |
303 | r#" | 303 | r#" |
304 | fn foo() { | 304 | fn foo() { |
305 | || -> i32<|> { | 305 | || -> i32$0 { |
306 | let test = "test"; | 306 | let test = "test"; |
307 | return 42i32; | 307 | return 42i32; |
308 | }; | 308 | }; |
@@ -325,7 +325,7 @@ fn foo() { | |||
325 | wrap_return_type_in_result, | 325 | wrap_return_type_in_result, |
326 | r#" | 326 | r#" |
327 | fn foo() -> i32 { | 327 | fn foo() -> i32 { |
328 | let test = "test";<|> | 328 | let test = "test";$0 |
329 | return 42i32; | 329 | return 42i32; |
330 | } | 330 | } |
331 | "#, | 331 | "#, |
@@ -339,7 +339,7 @@ fn foo() -> i32 { | |||
339 | r#" | 339 | r#" |
340 | fn foo() { | 340 | fn foo() { |
341 | || -> i32 { | 341 | || -> i32 { |
342 | let test = "test";<|> | 342 | let test = "test";$0 |
343 | return 42i32; | 343 | return 42i32; |
344 | }; | 344 | }; |
345 | } | 345 | } |
@@ -349,7 +349,7 @@ fn foo() { | |||
349 | 349 | ||
350 | #[test] | 350 | #[test] |
351 | fn wrap_return_type_in_result_closure_non_block() { | 351 | fn wrap_return_type_in_result_closure_non_block() { |
352 | check_assist_not_applicable(wrap_return_type_in_result, r#"fn foo() { || -> i<|>32 3; }"#); | 352 | check_assist_not_applicable(wrap_return_type_in_result, r#"fn foo() { || -> i$032 3; }"#); |
353 | } | 353 | } |
354 | 354 | ||
355 | #[test] | 355 | #[test] |
@@ -357,7 +357,7 @@ fn foo() { | |||
357 | check_assist_not_applicable( | 357 | check_assist_not_applicable( |
358 | wrap_return_type_in_result, | 358 | wrap_return_type_in_result, |
359 | r#" | 359 | r#" |
360 | fn foo() -> std::result::Result<i32<|>, String> { | 360 | fn foo() -> std::result::Result<i32$0, String> { |
361 | let test = "test"; | 361 | let test = "test"; |
362 | return 42i32; | 362 | return 42i32; |
363 | } | 363 | } |
@@ -371,7 +371,7 @@ fn foo() -> std::result::Result<i32<|>, String> { | |||
371 | check_assist_not_applicable( | 371 | check_assist_not_applicable( |
372 | wrap_return_type_in_result, | 372 | wrap_return_type_in_result, |
373 | r#" | 373 | r#" |
374 | fn foo() -> Result<i32<|>, String> { | 374 | fn foo() -> Result<i32$0, String> { |
375 | let test = "test"; | 375 | let test = "test"; |
376 | return 42i32; | 376 | return 42i32; |
377 | } | 377 | } |
@@ -385,7 +385,7 @@ fn foo() -> Result<i32<|>, String> { | |||
385 | wrap_return_type_in_result, | 385 | wrap_return_type_in_result, |
386 | r#" | 386 | r#" |
387 | fn foo() { | 387 | fn foo() { |
388 | || -> Result<i32<|>, String> { | 388 | || -> Result<i32$0, String> { |
389 | let test = "test"; | 389 | let test = "test"; |
390 | return 42i32; | 390 | return 42i32; |
391 | }; | 391 | }; |
@@ -399,7 +399,7 @@ fn foo() { | |||
399 | check_assist( | 399 | check_assist( |
400 | wrap_return_type_in_result, | 400 | wrap_return_type_in_result, |
401 | r#" | 401 | r#" |
402 | fn foo() -> <|>i32 { | 402 | fn foo() -> $0i32 { |
403 | let test = "test"; | 403 | let test = "test"; |
404 | return 42i32; | 404 | return 42i32; |
405 | } | 405 | } |
@@ -418,7 +418,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
418 | check_assist( | 418 | check_assist( |
419 | wrap_return_type_in_result, | 419 | wrap_return_type_in_result, |
420 | r#" | 420 | r#" |
421 | fn foo() -><|> i32 { | 421 | fn foo() ->$0 i32 { |
422 | let test = "test"; | 422 | let test = "test"; |
423 | 42i32 | 423 | 42i32 |
424 | } | 424 | } |
@@ -438,7 +438,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
438 | wrap_return_type_in_result, | 438 | wrap_return_type_in_result, |
439 | r#" | 439 | r#" |
440 | fn foo() { | 440 | fn foo() { |
441 | || -><|> i32 { | 441 | || ->$0 i32 { |
442 | let test = "test"; | 442 | let test = "test"; |
443 | 42i32 | 443 | 42i32 |
444 | }; | 444 | }; |
@@ -459,7 +459,7 @@ fn foo() { | |||
459 | fn wrap_return_type_in_result_simple_with_tail_only() { | 459 | fn wrap_return_type_in_result_simple_with_tail_only() { |
460 | check_assist( | 460 | check_assist( |
461 | wrap_return_type_in_result, | 461 | wrap_return_type_in_result, |
462 | r#"fn foo() -> i32<|> { 42i32 }"#, | 462 | r#"fn foo() -> i32$0 { 42i32 }"#, |
463 | r#"fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }"#, | 463 | r#"fn foo() -> Result<i32, ${0:_}> { Ok(42i32) }"#, |
464 | ); | 464 | ); |
465 | } | 465 | } |
@@ -469,7 +469,7 @@ fn foo() { | |||
469 | check_assist( | 469 | check_assist( |
470 | wrap_return_type_in_result, | 470 | wrap_return_type_in_result, |
471 | r#" | 471 | r#" |
472 | fn foo() -> i32<|> { | 472 | fn foo() -> i32$0 { |
473 | if true { | 473 | if true { |
474 | 42i32 | 474 | 42i32 |
475 | } else { | 475 | } else { |
@@ -495,7 +495,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
495 | wrap_return_type_in_result, | 495 | wrap_return_type_in_result, |
496 | r#" | 496 | r#" |
497 | fn foo() { | 497 | fn foo() { |
498 | || -> i32<|> { | 498 | || -> i32$0 { |
499 | if true { | 499 | if true { |
500 | 42i32 | 500 | 42i32 |
501 | } else { | 501 | } else { |
@@ -523,7 +523,7 @@ fn foo() { | |||
523 | check_assist( | 523 | check_assist( |
524 | wrap_return_type_in_result, | 524 | wrap_return_type_in_result, |
525 | r#" | 525 | r#" |
526 | fn foo() -> i32<|> { | 526 | fn foo() -> i32$0 { |
527 | if true { | 527 | if true { |
528 | if false { | 528 | if false { |
529 | 1 | 529 | 1 |
@@ -556,7 +556,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
556 | check_assist( | 556 | check_assist( |
557 | wrap_return_type_in_result, | 557 | wrap_return_type_in_result, |
558 | r#" | 558 | r#" |
559 | async fn foo() -> i<|>32 { | 559 | async fn foo() -> i$032 { |
560 | if true { | 560 | if true { |
561 | if false { | 561 | if false { |
562 | 1.await | 562 | 1.await |
@@ -588,7 +588,7 @@ async fn foo() -> Result<i32, ${0:_}> { | |||
588 | fn wrap_return_type_in_result_simple_with_array() { | 588 | fn wrap_return_type_in_result_simple_with_array() { |
589 | check_assist( | 589 | check_assist( |
590 | wrap_return_type_in_result, | 590 | wrap_return_type_in_result, |
591 | r#"fn foo() -> [i32;<|> 3] { [1, 2, 3] }"#, | 591 | r#"fn foo() -> [i32;$0 3] { [1, 2, 3] }"#, |
592 | r#"fn foo() -> Result<[i32; 3], ${0:_}> { Ok([1, 2, 3]) }"#, | 592 | r#"fn foo() -> Result<[i32; 3], ${0:_}> { Ok([1, 2, 3]) }"#, |
593 | ); | 593 | ); |
594 | } | 594 | } |
@@ -598,7 +598,7 @@ async fn foo() -> Result<i32, ${0:_}> { | |||
598 | check_assist( | 598 | check_assist( |
599 | wrap_return_type_in_result, | 599 | wrap_return_type_in_result, |
600 | r#" | 600 | r#" |
601 | fn foo() -<|>> i32 { | 601 | fn foo() -$0> i32 { |
602 | if true { | 602 | if true { |
603 | if false { | 603 | if false { |
604 | 1 as i32 | 604 | 1 as i32 |
@@ -631,7 +631,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
631 | check_assist( | 631 | check_assist( |
632 | wrap_return_type_in_result, | 632 | wrap_return_type_in_result, |
633 | r#" | 633 | r#" |
634 | fn foo() -> i32<|> { | 634 | fn foo() -> i32$0 { |
635 | let my_var = 5; | 635 | let my_var = 5; |
636 | match my_var { | 636 | match my_var { |
637 | 5 => 42i32, | 637 | 5 => 42i32, |
@@ -656,7 +656,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
656 | check_assist( | 656 | check_assist( |
657 | wrap_return_type_in_result, | 657 | wrap_return_type_in_result, |
658 | r#" | 658 | r#" |
659 | fn foo() -> i32<|> { | 659 | fn foo() -> i32$0 { |
660 | let my_var = 5; | 660 | let my_var = 5; |
661 | loop { | 661 | loop { |
662 | println!("test"); | 662 | println!("test"); |
@@ -683,7 +683,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
683 | check_assist( | 683 | check_assist( |
684 | wrap_return_type_in_result, | 684 | wrap_return_type_in_result, |
685 | r#" | 685 | r#" |
686 | fn foo() -> i32<|> { | 686 | fn foo() -> i32$0 { |
687 | let my_var = let x = loop { | 687 | let my_var = let x = loop { |
688 | break 1; | 688 | break 1; |
689 | }; | 689 | }; |
@@ -706,7 +706,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
706 | check_assist( | 706 | check_assist( |
707 | wrap_return_type_in_result, | 707 | wrap_return_type_in_result, |
708 | r#" | 708 | r#" |
709 | fn foo() -> i32<|> { | 709 | fn foo() -> i32$0 { |
710 | let my_var = 5; | 710 | let my_var = 5; |
711 | let res = match my_var { | 711 | let res = match my_var { |
712 | 5 => 42i32, | 712 | 5 => 42i32, |
@@ -730,7 +730,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
730 | check_assist( | 730 | check_assist( |
731 | wrap_return_type_in_result, | 731 | wrap_return_type_in_result, |
732 | r#" | 732 | r#" |
733 | fn foo() -> i32<|> { | 733 | fn foo() -> i32$0 { |
734 | let my_var = 5; | 734 | let my_var = 5; |
735 | let res = if my_var == 5 { | 735 | let res = if my_var == 5 { |
736 | 42i32 | 736 | 42i32 |
@@ -759,7 +759,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
759 | check_assist( | 759 | check_assist( |
760 | wrap_return_type_in_result, | 760 | wrap_return_type_in_result, |
761 | r#" | 761 | r#" |
762 | fn foo() -> i32<|> { | 762 | fn foo() -> i32$0 { |
763 | let my_var = 5; | 763 | let my_var = 5; |
764 | match my_var { | 764 | match my_var { |
765 | 5 => { | 765 | 5 => { |
@@ -808,7 +808,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
808 | check_assist( | 808 | check_assist( |
809 | wrap_return_type_in_result, | 809 | wrap_return_type_in_result, |
810 | r#" | 810 | r#" |
811 | fn foo() -> i<|>32 { | 811 | fn foo() -> i$032 { |
812 | let test = "test"; | 812 | let test = "test"; |
813 | if test == "test" { | 813 | if test == "test" { |
814 | return 24i32; | 814 | return 24i32; |
@@ -833,7 +833,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
833 | check_assist( | 833 | check_assist( |
834 | wrap_return_type_in_result, | 834 | wrap_return_type_in_result, |
835 | r#" | 835 | r#" |
836 | fn foo(the_field: u32) -><|> u32 { | 836 | fn foo(the_field: u32) ->$0 u32 { |
837 | let true_closure = || { return true; }; | 837 | let true_closure = || { return true; }; |
838 | if the_field < 5 { | 838 | if the_field < 5 { |
839 | let mut i = 0; | 839 | let mut i = 0; |
@@ -865,7 +865,7 @@ fn foo(the_field: u32) -> Result<u32, ${0:_}> { | |||
865 | check_assist( | 865 | check_assist( |
866 | wrap_return_type_in_result, | 866 | wrap_return_type_in_result, |
867 | r#" | 867 | r#" |
868 | fn foo(the_field: u32) -> u32<|> { | 868 | fn foo(the_field: u32) -> u32$0 { |
869 | let true_closure = || { | 869 | let true_closure = || { |
870 | return true; | 870 | return true; |
871 | }; | 871 | }; |
@@ -912,7 +912,7 @@ fn foo(the_field: u32) -> Result<u32, ${0:_}> { | |||
912 | check_assist( | 912 | check_assist( |
913 | wrap_return_type_in_result, | 913 | wrap_return_type_in_result, |
914 | r#" | 914 | r#" |
915 | fn foo() -> i32<|> { | 915 | fn foo() -> i32$0 { |
916 | let test = "test"; | 916 | let test = "test"; |
917 | if test == "test" { | 917 | if test == "test" { |
918 | return 24i32; | 918 | return 24i32; |
@@ -946,7 +946,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
946 | check_assist( | 946 | check_assist( |
947 | wrap_return_type_in_result, | 947 | wrap_return_type_in_result, |
948 | r#" | 948 | r#" |
949 | fn foo() -> i32<|> { | 949 | fn foo() -> i32$0 { |
950 | let test = "test"; | 950 | let test = "test"; |
951 | if test == "test" { | 951 | if test == "test" { |
952 | return 24i32; | 952 | return 24i32; |
@@ -984,7 +984,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
984 | check_assist( | 984 | check_assist( |
985 | wrap_return_type_in_result, | 985 | wrap_return_type_in_result, |
986 | r#" | 986 | r#" |
987 | fn foo() -> i3<|>2 { | 987 | fn foo() -> i3$02 { |
988 | let test = "test"; | 988 | let test = "test"; |
989 | let other = 5; | 989 | let other = 5; |
990 | if test == "test" { | 990 | if test == "test" { |
@@ -1030,7 +1030,7 @@ fn foo() -> Result<i32, ${0:_}> { | |||
1030 | check_assist( | 1030 | check_assist( |
1031 | wrap_return_type_in_result, | 1031 | wrap_return_type_in_result, |
1032 | r#" | 1032 | r#" |
1033 | fn foo(the_field: u32) -> u32<|> { | 1033 | fn foo(the_field: u32) -> u32$0 { |
1034 | if the_field < 5 { | 1034 | if the_field < 5 { |
1035 | let mut i = 0; | 1035 | let mut i = 0; |
1036 | loop { | 1036 | loop { |
@@ -1070,7 +1070,7 @@ fn foo(the_field: u32) -> Result<u32, ${0:_}> { | |||
1070 | check_assist( | 1070 | check_assist( |
1071 | wrap_return_type_in_result, | 1071 | wrap_return_type_in_result, |
1072 | r#" | 1072 | r#" |
1073 | fn foo(the_field: u32) -> u3<|>2 { | 1073 | fn foo(the_field: u32) -> u3$02 { |
1074 | if the_field < 5 { | 1074 | if the_field < 5 { |
1075 | let mut i = 0; | 1075 | let mut i = 0; |
1076 | match i { | 1076 | match i { |
@@ -1098,7 +1098,7 @@ fn foo(the_field: u32) -> Result<u32, ${0:_}> { | |||
1098 | check_assist( | 1098 | check_assist( |
1099 | wrap_return_type_in_result, | 1099 | wrap_return_type_in_result, |
1100 | r#" | 1100 | r#" |
1101 | fn foo(the_field: u32) -> u32<|> { | 1101 | fn foo(the_field: u32) -> u32$0 { |
1102 | if the_field < 5 { | 1102 | if the_field < 5 { |
1103 | let mut i = 0; | 1103 | let mut i = 0; |
1104 | if i == 5 { | 1104 | if i == 5 { |
@@ -1128,7 +1128,7 @@ fn foo(the_field: u32) -> Result<u32, ${0:_}> { | |||
1128 | check_assist( | 1128 | check_assist( |
1129 | wrap_return_type_in_result, | 1129 | wrap_return_type_in_result, |
1130 | r#" | 1130 | r#" |
1131 | fn foo(the_field: u32) -> <|>u32 { | 1131 | fn foo(the_field: u32) -> $0u32 { |
1132 | if the_field < 5 { | 1132 | if the_field < 5 { |
1133 | let mut i = 0; | 1133 | let mut i = 0; |
1134 | if i == 5 { | 1134 | if i == 5 { |
diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index 212464f85..90009c55a 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs | |||
@@ -24,7 +24,7 @@ use syntax::TextRange; | |||
24 | 24 | ||
25 | pub(crate) use crate::assist_context::{AssistContext, Assists}; | 25 | pub(crate) use crate::assist_context::{AssistContext, Assists}; |
26 | 26 | ||
27 | pub use assist_config::AssistConfig; | 27 | pub use assist_config::{AssistConfig, InsertUseConfig}; |
28 | 28 | ||
29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 29 | #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
30 | pub enum AssistKind { | 30 | pub enum AssistKind { |
@@ -116,8 +116,6 @@ mod handlers { | |||
116 | mod convert_integer_literal; | 116 | mod convert_integer_literal; |
117 | mod early_return; | 117 | mod early_return; |
118 | mod expand_glob_import; | 118 | mod expand_glob_import; |
119 | mod extract_assignment; | ||
120 | mod extract_module_to_file; | ||
121 | mod extract_struct_from_enum_variant; | 119 | mod extract_struct_from_enum_variant; |
122 | mod extract_variable; | 120 | mod extract_variable; |
123 | mod fill_match_arms; | 121 | mod fill_match_arms; |
@@ -125,13 +123,14 @@ mod handlers { | |||
125 | mod flip_binexpr; | 123 | mod flip_binexpr; |
126 | mod flip_comma; | 124 | mod flip_comma; |
127 | mod flip_trait_bound; | 125 | mod flip_trait_bound; |
128 | mod generate_derive; | ||
129 | mod generate_default_from_enum_variant; | 126 | mod generate_default_from_enum_variant; |
127 | mod generate_derive; | ||
130 | mod generate_from_impl_for_enum; | 128 | mod generate_from_impl_for_enum; |
131 | mod generate_function; | 129 | mod generate_function; |
132 | mod generate_impl; | 130 | mod generate_impl; |
133 | mod generate_new; | 131 | mod generate_new; |
134 | mod infer_function_return_type; | 132 | mod infer_function_return_type; |
133 | mod inline_function; | ||
135 | mod inline_local_variable; | 134 | mod inline_local_variable; |
136 | mod introduce_named_lifetime; | 135 | mod introduce_named_lifetime; |
137 | mod invert_if; | 136 | mod invert_if; |
@@ -139,6 +138,8 @@ mod handlers { | |||
139 | mod merge_match_arms; | 138 | mod merge_match_arms; |
140 | mod move_bounds; | 139 | mod move_bounds; |
141 | mod move_guard; | 140 | mod move_guard; |
141 | mod move_module_to_file; | ||
142 | mod pull_assignment_up; | ||
142 | mod qualify_path; | 143 | mod qualify_path; |
143 | mod raw_string; | 144 | mod raw_string; |
144 | mod remove_dbg; | 145 | mod remove_dbg; |
@@ -168,8 +169,7 @@ mod handlers { | |||
168 | convert_integer_literal::convert_integer_literal, | 169 | convert_integer_literal::convert_integer_literal, |
169 | early_return::convert_to_guarded_return, | 170 | early_return::convert_to_guarded_return, |
170 | expand_glob_import::expand_glob_import, | 171 | expand_glob_import::expand_glob_import, |
171 | extract_assignment::extract_assigment, | 172 | move_module_to_file::move_module_to_file, |
172 | extract_module_to_file::extract_module_to_file, | ||
173 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, | 173 | extract_struct_from_enum_variant::extract_struct_from_enum_variant, |
174 | extract_variable::extract_variable, | 174 | extract_variable::extract_variable, |
175 | fill_match_arms::fill_match_arms, | 175 | fill_match_arms::fill_match_arms, |
@@ -177,13 +177,14 @@ mod handlers { | |||
177 | flip_binexpr::flip_binexpr, | 177 | flip_binexpr::flip_binexpr, |
178 | flip_comma::flip_comma, | 178 | flip_comma::flip_comma, |
179 | flip_trait_bound::flip_trait_bound, | 179 | flip_trait_bound::flip_trait_bound, |
180 | generate_derive::generate_derive, | ||
181 | generate_default_from_enum_variant::generate_default_from_enum_variant, | 180 | generate_default_from_enum_variant::generate_default_from_enum_variant, |
181 | generate_derive::generate_derive, | ||
182 | generate_from_impl_for_enum::generate_from_impl_for_enum, | 182 | generate_from_impl_for_enum::generate_from_impl_for_enum, |
183 | generate_function::generate_function, | 183 | generate_function::generate_function, |
184 | generate_impl::generate_impl, | 184 | generate_impl::generate_impl, |
185 | generate_new::generate_new, | 185 | generate_new::generate_new, |
186 | infer_function_return_type::infer_function_return_type, | 186 | infer_function_return_type::infer_function_return_type, |
187 | inline_function::inline_function, | ||
187 | inline_local_variable::inline_local_variable, | 188 | inline_local_variable::inline_local_variable, |
188 | introduce_named_lifetime::introduce_named_lifetime, | 189 | introduce_named_lifetime::introduce_named_lifetime, |
189 | invert_if::invert_if, | 190 | invert_if::invert_if, |
@@ -192,6 +193,7 @@ mod handlers { | |||
192 | move_bounds::move_bounds_to_where_clause, | 193 | move_bounds::move_bounds_to_where_clause, |
193 | move_guard::move_arm_cond_to_match_guard, | 194 | move_guard::move_arm_cond_to_match_guard, |
194 | move_guard::move_guard_to_arm_body, | 195 | move_guard::move_guard_to_arm_body, |
196 | pull_assignment_up::pull_assignment_up, | ||
195 | qualify_path::qualify_path, | 197 | qualify_path::qualify_path, |
196 | raw_string::add_hash, | 198 | raw_string::add_hash, |
197 | raw_string::make_usual_string, | 199 | raw_string::make_usual_string, |
diff --git a/crates/assists/src/tests.rs b/crates/assists/src/tests.rs index 21e448fb8..fef29a0b8 100644 --- a/crates/assists/src/tests.rs +++ b/crates/assists/src/tests.rs | |||
@@ -1,15 +1,29 @@ | |||
1 | mod generated; | 1 | mod generated; |
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}; | 4 | use ide_db::{ |
5 | use ide_db::source_change::FileSystemEdit; | 5 | base_db::{fixture::WithFixture, FileId, FileRange, SourceDatabaseExt}, |
6 | use ide_db::RootDatabase; | 6 | helpers::{insert_use::MergeBehavior, SnippetCap}, |
7 | source_change::FileSystemEdit, | ||
8 | RootDatabase, | ||
9 | }; | ||
7 | use syntax::TextRange; | 10 | use syntax::TextRange; |
8 | use test_utils::{assert_eq_text, extract_offset, extract_range}; | 11 | use test_utils::{assert_eq_text, extract_offset, extract_range}; |
9 | 12 | ||
10 | use crate::{handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists}; | 13 | use crate::{ |
14 | handlers::Handler, Assist, AssistConfig, AssistContext, AssistKind, Assists, InsertUseConfig, | ||
15 | }; | ||
11 | use stdx::{format_to, trim_indent}; | 16 | use stdx::{format_to, trim_indent}; |
12 | 17 | ||
18 | pub(crate) const TEST_CONFIG: AssistConfig = AssistConfig { | ||
19 | snippet_cap: SnippetCap::new(true), | ||
20 | allowed: None, | ||
21 | insert_use: InsertUseConfig { | ||
22 | merge: Some(MergeBehavior::Full), | ||
23 | prefix_kind: hir::PrefixKind::Plain, | ||
24 | }, | ||
25 | }; | ||
26 | |||
13 | pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { | 27 | pub(crate) fn with_single_file(text: &str) -> (RootDatabase, FileId) { |
14 | RootDatabase::with_single_file(text) | 28 | RootDatabase::with_single_file(text) |
15 | } | 29 | } |
@@ -48,14 +62,14 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) { | |||
48 | let before = db.file_text(file_id).to_string(); | 62 | let before = db.file_text(file_id).to_string(); |
49 | let frange = FileRange { file_id, range: selection.into() }; | 63 | let frange = FileRange { file_id, range: selection.into() }; |
50 | 64 | ||
51 | let assist = Assist::get(&db, &AssistConfig::default(), true, frange) | 65 | let assist = Assist::get(&db, &TEST_CONFIG, true, frange) |
52 | .into_iter() | 66 | .into_iter() |
53 | .find(|assist| assist.id.0 == assist_id) | 67 | .find(|assist| assist.id.0 == assist_id) |
54 | .unwrap_or_else(|| { | 68 | .unwrap_or_else(|| { |
55 | panic!( | 69 | panic!( |
56 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", | 70 | "\n\nAssist is not applicable: {}\nAvailable assists: {}", |
57 | assist_id, | 71 | assist_id, |
58 | Assist::get(&db, &AssistConfig::default(), false, frange) | 72 | Assist::get(&db, &TEST_CONFIG, false, frange) |
59 | .into_iter() | 73 | .into_iter() |
60 | .map(|assist| assist.id.0) | 74 | .map(|assist| assist.id.0) |
61 | .collect::<Vec<_>>() | 75 | .collect::<Vec<_>>() |
@@ -89,7 +103,7 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
89 | let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; | 103 | let frange = FileRange { file_id: file_with_caret_id, range: range_or_offset.into() }; |
90 | 104 | ||
91 | let sema = Semantics::new(&db); | 105 | let sema = Semantics::new(&db); |
92 | let config = AssistConfig::default(); | 106 | let config = TEST_CONFIG; |
93 | let ctx = AssistContext::new(sema, &config, frange); | 107 | let ctx = AssistContext::new(sema, &config, frange); |
94 | let mut acc = Assists::new(&ctx, true); | 108 | let mut acc = Assists::new(&ctx, true); |
95 | handler(&mut acc, &ctx); | 109 | handler(&mut acc, &ctx); |
@@ -152,11 +166,11 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult, assist_label: | |||
152 | 166 | ||
153 | #[test] | 167 | #[test] |
154 | fn assist_order_field_struct() { | 168 | fn assist_order_field_struct() { |
155 | let before = "struct Foo { <|>bar: u32 }"; | 169 | let before = "struct Foo { $0bar: u32 }"; |
156 | let (before_cursor_pos, before) = extract_offset(before); | 170 | let (before_cursor_pos, before) = extract_offset(before); |
157 | let (db, file_id) = with_single_file(&before); | 171 | let (db, file_id) = with_single_file(&before); |
158 | let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; | 172 | let frange = FileRange { file_id, range: TextRange::empty(before_cursor_pos) }; |
159 | let assists = Assist::get(&db, &AssistConfig::default(), false, frange); | 173 | let assists = Assist::get(&db, &TEST_CONFIG, false, frange); |
160 | let mut assists = assists.iter(); | 174 | let mut assists = assists.iter(); |
161 | 175 | ||
162 | assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)"); | 176 | assert_eq!(assists.next().expect("expected assist").label, "Change visibility to pub(crate)"); |
@@ -167,7 +181,7 @@ fn assist_order_field_struct() { | |||
167 | fn assist_order_if_expr() { | 181 | fn assist_order_if_expr() { |
168 | let before = " | 182 | let before = " |
169 | pub fn test_some_range(a: int) -> bool { | 183 | pub fn test_some_range(a: int) -> bool { |
170 | if let 2..6 = <|>5<|> { | 184 | if let 2..6 = $05$0 { |
171 | true | 185 | true |
172 | } else { | 186 | } else { |
173 | false | 187 | false |
@@ -176,7 +190,7 @@ fn assist_order_if_expr() { | |||
176 | let (range, before) = extract_range(before); | 190 | let (range, before) = extract_range(before); |
177 | let (db, file_id) = with_single_file(&before); | 191 | let (db, file_id) = with_single_file(&before); |
178 | let frange = FileRange { file_id, range }; | 192 | let frange = FileRange { file_id, range }; |
179 | let assists = Assist::get(&db, &AssistConfig::default(), false, frange); | 193 | let assists = Assist::get(&db, &TEST_CONFIG, false, frange); |
180 | let mut assists = assists.iter(); | 194 | let mut assists = assists.iter(); |
181 | 195 | ||
182 | assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); | 196 | assert_eq!(assists.next().expect("expected assist").label, "Extract into variable"); |
@@ -187,7 +201,7 @@ fn assist_order_if_expr() { | |||
187 | fn assist_filter_works() { | 201 | fn assist_filter_works() { |
188 | let before = " | 202 | let before = " |
189 | pub fn test_some_range(a: int) -> bool { | 203 | pub fn test_some_range(a: int) -> bool { |
190 | if let 2..6 = <|>5<|> { | 204 | if let 2..6 = $05$0 { |
191 | true | 205 | true |
192 | } else { | 206 | } else { |
193 | false | 207 | false |
@@ -198,7 +212,7 @@ fn assist_filter_works() { | |||
198 | let frange = FileRange { file_id, range }; | 212 | let frange = FileRange { file_id, range }; |
199 | 213 | ||
200 | { | 214 | { |
201 | let mut cfg = AssistConfig::default(); | 215 | let mut cfg = TEST_CONFIG; |
202 | cfg.allowed = Some(vec![AssistKind::Refactor]); | 216 | cfg.allowed = Some(vec![AssistKind::Refactor]); |
203 | 217 | ||
204 | let assists = Assist::get(&db, &cfg, false, frange); | 218 | let assists = Assist::get(&db, &cfg, false, frange); |
@@ -209,7 +223,7 @@ fn assist_filter_works() { | |||
209 | } | 223 | } |
210 | 224 | ||
211 | { | 225 | { |
212 | let mut cfg = AssistConfig::default(); | 226 | let mut cfg = TEST_CONFIG; |
213 | cfg.allowed = Some(vec![AssistKind::RefactorExtract]); | 227 | cfg.allowed = Some(vec![AssistKind::RefactorExtract]); |
214 | let assists = Assist::get(&db, &cfg, false, frange); | 228 | let assists = Assist::get(&db, &cfg, false, frange); |
215 | assert_eq!(assists.len(), 1); | 229 | assert_eq!(assists.len(), 1); |
@@ -219,7 +233,7 @@ fn assist_filter_works() { | |||
219 | } | 233 | } |
220 | 234 | ||
221 | { | 235 | { |
222 | let mut cfg = AssistConfig::default(); | 236 | let mut cfg = TEST_CONFIG; |
223 | cfg.allowed = Some(vec![AssistKind::QuickFix]); | 237 | cfg.allowed = Some(vec![AssistKind::QuickFix]); |
224 | let assists = Assist::get(&db, &cfg, false, frange); | 238 | let assists = Assist::get(&db, &cfg, false, frange); |
225 | assert!(assists.is_empty(), "All asserts but quickfixes should be filtered out"); | 239 | assert!(assists.is_empty(), "All asserts but quickfixes should be filtered out"); |
diff --git a/crates/assists/src/tests/generated.rs b/crates/assists/src/tests/generated.rs index b91a816e8..e28837b53 100644 --- a/crates/assists/src/tests/generated.rs +++ b/crates/assists/src/tests/generated.rs | |||
@@ -8,7 +8,7 @@ fn doctest_add_explicit_type() { | |||
8 | "add_explicit_type", | 8 | "add_explicit_type", |
9 | r#####" | 9 | r#####" |
10 | fn main() { | 10 | fn main() { |
11 | let x<|> = 92; | 11 | let x$0 = 92; |
12 | } | 12 | } |
13 | "#####, | 13 | "#####, |
14 | r#####" | 14 | r#####" |
@@ -25,7 +25,7 @@ fn doctest_add_hash() { | |||
25 | "add_hash", | 25 | "add_hash", |
26 | r#####" | 26 | r#####" |
27 | fn main() { | 27 | fn main() { |
28 | r#"Hello,<|> World!"#; | 28 | r#"Hello,$0 World!"#; |
29 | } | 29 | } |
30 | "#####, | 30 | "#####, |
31 | r#####" | 31 | r#####" |
@@ -49,7 +49,7 @@ trait Trait { | |||
49 | 49 | ||
50 | impl Trait for () { | 50 | impl Trait for () { |
51 | type X = (); | 51 | type X = (); |
52 | fn foo(&self) {}<|> | 52 | fn foo(&self) {}$0 |
53 | 53 | ||
54 | } | 54 | } |
55 | "#####, | 55 | "#####, |
@@ -81,7 +81,7 @@ trait Trait<T> { | |||
81 | fn bar(&self) {} | 81 | fn bar(&self) {} |
82 | } | 82 | } |
83 | 83 | ||
84 | impl Trait<u32> for () {<|> | 84 | impl Trait<u32> for () {$0 |
85 | 85 | ||
86 | } | 86 | } |
87 | "#####, | 87 | "#####, |
@@ -110,7 +110,7 @@ fn doctest_add_turbo_fish() { | |||
110 | r#####" | 110 | r#####" |
111 | fn make<T>() -> T { todo!() } | 111 | fn make<T>() -> T { todo!() } |
112 | fn main() { | 112 | fn main() { |
113 | let x = make<|>(); | 113 | let x = make$0(); |
114 | } | 114 | } |
115 | "#####, | 115 | "#####, |
116 | r#####" | 116 | r#####" |
@@ -128,7 +128,7 @@ fn doctest_apply_demorgan() { | |||
128 | "apply_demorgan", | 128 | "apply_demorgan", |
129 | r#####" | 129 | r#####" |
130 | fn main() { | 130 | fn main() { |
131 | if x != 4 ||<|> !y {} | 131 | if x != 4 ||$0 !y {} |
132 | } | 132 | } |
133 | "#####, | 133 | "#####, |
134 | r#####" | 134 | r#####" |
@@ -145,7 +145,7 @@ fn doctest_auto_import() { | |||
145 | "auto_import", | 145 | "auto_import", |
146 | r#####" | 146 | r#####" |
147 | fn main() { | 147 | fn main() { |
148 | let map = HashMap<|>::new(); | 148 | let map = HashMap$0::new(); |
149 | } | 149 | } |
150 | pub mod std { pub mod collections { pub struct HashMap { } } } | 150 | pub mod std { pub mod collections { pub struct HashMap { } } } |
151 | "#####, | 151 | "#####, |
@@ -165,7 +165,7 @@ fn doctest_change_visibility() { | |||
165 | check_doc_test( | 165 | check_doc_test( |
166 | "change_visibility", | 166 | "change_visibility", |
167 | r#####" | 167 | r#####" |
168 | <|>fn frobnicate() {} | 168 | $0fn frobnicate() {} |
169 | "#####, | 169 | "#####, |
170 | r#####" | 170 | r#####" |
171 | pub(crate) fn frobnicate() {} | 171 | pub(crate) fn frobnicate() {} |
@@ -178,7 +178,7 @@ fn doctest_convert_integer_literal() { | |||
178 | check_doc_test( | 178 | check_doc_test( |
179 | "convert_integer_literal", | 179 | "convert_integer_literal", |
180 | r#####" | 180 | r#####" |
181 | const _: i32 = 10<|>; | 181 | const _: i32 = 10$0; |
182 | "#####, | 182 | "#####, |
183 | r#####" | 183 | r#####" |
184 | const _: i32 = 0b1010; | 184 | const _: i32 = 0b1010; |
@@ -192,7 +192,7 @@ fn doctest_convert_to_guarded_return() { | |||
192 | "convert_to_guarded_return", | 192 | "convert_to_guarded_return", |
193 | r#####" | 193 | r#####" |
194 | fn main() { | 194 | fn main() { |
195 | <|>if cond { | 195 | $0if cond { |
196 | foo(); | 196 | foo(); |
197 | bar(); | 197 | bar(); |
198 | } | 198 | } |
@@ -220,7 +220,7 @@ mod foo { | |||
220 | pub struct Baz; | 220 | pub struct Baz; |
221 | } | 221 | } |
222 | 222 | ||
223 | use foo::*<|>; | 223 | use foo::*$0; |
224 | 224 | ||
225 | fn qux(bar: Bar, baz: Baz) {} | 225 | fn qux(bar: Bar, baz: Baz) {} |
226 | "#####, | 226 | "#####, |
@@ -238,55 +238,11 @@ fn qux(bar: Bar, baz: Baz) {} | |||
238 | } | 238 | } |
239 | 239 | ||
240 | #[test] | 240 | #[test] |
241 | fn doctest_extract_assignment() { | ||
242 | check_doc_test( | ||
243 | "extract_assignment", | ||
244 | r#####" | ||
245 | fn main() { | ||
246 | let mut foo = 6; | ||
247 | |||
248 | if true { | ||
249 | <|>foo = 5; | ||
250 | } else { | ||
251 | foo = 4; | ||
252 | } | ||
253 | } | ||
254 | "#####, | ||
255 | r#####" | ||
256 | fn main() { | ||
257 | let mut foo = 6; | ||
258 | |||
259 | foo = if true { | ||
260 | 5 | ||
261 | } else { | ||
262 | 4 | ||
263 | }; | ||
264 | } | ||
265 | "#####, | ||
266 | ) | ||
267 | } | ||
268 | |||
269 | #[test] | ||
270 | fn doctest_extract_module_to_file() { | ||
271 | check_doc_test( | ||
272 | "extract_module_to_file", | ||
273 | r#####" | ||
274 | mod foo {<|> | ||
275 | fn t() {} | ||
276 | } | ||
277 | "#####, | ||
278 | r#####" | ||
279 | mod foo; | ||
280 | "#####, | ||
281 | ) | ||
282 | } | ||
283 | |||
284 | #[test] | ||
285 | fn doctest_extract_struct_from_enum_variant() { | 241 | fn doctest_extract_struct_from_enum_variant() { |
286 | check_doc_test( | 242 | check_doc_test( |
287 | "extract_struct_from_enum_variant", | 243 | "extract_struct_from_enum_variant", |
288 | r#####" | 244 | r#####" |
289 | enum A { <|>One(u32, u32) } | 245 | enum A { $0One(u32, u32) } |
290 | "#####, | 246 | "#####, |
291 | r#####" | 247 | r#####" |
292 | struct One(pub u32, pub u32); | 248 | struct One(pub u32, pub u32); |
@@ -302,7 +258,7 @@ fn doctest_extract_variable() { | |||
302 | "extract_variable", | 258 | "extract_variable", |
303 | r#####" | 259 | r#####" |
304 | fn main() { | 260 | fn main() { |
305 | <|>(1 + 2)<|> * 4; | 261 | $0(1 + 2)$0 * 4; |
306 | } | 262 | } |
307 | "#####, | 263 | "#####, |
308 | r#####" | 264 | r#####" |
@@ -323,7 +279,7 @@ enum Action { Move { distance: u32 }, Stop } | |||
323 | 279 | ||
324 | fn handle(action: Action) { | 280 | fn handle(action: Action) { |
325 | match action { | 281 | match action { |
326 | <|> | 282 | $0 |
327 | } | 283 | } |
328 | } | 284 | } |
329 | "#####, | 285 | "#####, |
@@ -349,7 +305,7 @@ mod m { | |||
349 | fn frobnicate() {} | 305 | fn frobnicate() {} |
350 | } | 306 | } |
351 | fn main() { | 307 | fn main() { |
352 | m::frobnicate<|>() {} | 308 | m::frobnicate$0() {} |
353 | } | 309 | } |
354 | "#####, | 310 | "#####, |
355 | r#####" | 311 | r#####" |
@@ -369,7 +325,7 @@ fn doctest_flip_binexpr() { | |||
369 | "flip_binexpr", | 325 | "flip_binexpr", |
370 | r#####" | 326 | r#####" |
371 | fn main() { | 327 | fn main() { |
372 | let _ = 90 +<|> 2; | 328 | let _ = 90 +$0 2; |
373 | } | 329 | } |
374 | "#####, | 330 | "#####, |
375 | r#####" | 331 | r#####" |
@@ -386,7 +342,7 @@ fn doctest_flip_comma() { | |||
386 | "flip_comma", | 342 | "flip_comma", |
387 | r#####" | 343 | r#####" |
388 | fn main() { | 344 | fn main() { |
389 | ((1, 2),<|> (3, 4)); | 345 | ((1, 2),$0 (3, 4)); |
390 | } | 346 | } |
391 | "#####, | 347 | "#####, |
392 | r#####" | 348 | r#####" |
@@ -402,7 +358,7 @@ fn doctest_flip_trait_bound() { | |||
402 | check_doc_test( | 358 | check_doc_test( |
403 | "flip_trait_bound", | 359 | "flip_trait_bound", |
404 | r#####" | 360 | r#####" |
405 | fn foo<T: Clone +<|> Copy>() { } | 361 | fn foo<T: Clone +$0 Copy>() { } |
406 | "#####, | 362 | "#####, |
407 | r#####" | 363 | r#####" |
408 | fn foo<T: Copy + Clone>() { } | 364 | fn foo<T: Copy + Clone>() { } |
@@ -417,7 +373,7 @@ fn doctest_generate_default_from_enum_variant() { | |||
417 | r#####" | 373 | r#####" |
418 | enum Version { | 374 | enum Version { |
419 | Undefined, | 375 | Undefined, |
420 | Minor<|>, | 376 | Minor$0, |
421 | Major, | 377 | Major, |
422 | } | 378 | } |
423 | "#####, | 379 | "#####, |
@@ -444,7 +400,7 @@ fn doctest_generate_derive() { | |||
444 | r#####" | 400 | r#####" |
445 | struct Point { | 401 | struct Point { |
446 | x: u32, | 402 | x: u32, |
447 | y: u32,<|> | 403 | y: u32,$0 |
448 | } | 404 | } |
449 | "#####, | 405 | "#####, |
450 | r#####" | 406 | r#####" |
@@ -462,7 +418,7 @@ fn doctest_generate_from_impl_for_enum() { | |||
462 | check_doc_test( | 418 | check_doc_test( |
463 | "generate_from_impl_for_enum", | 419 | "generate_from_impl_for_enum", |
464 | r#####" | 420 | r#####" |
465 | enum A { <|>One(u32) } | 421 | enum A { $0One(u32) } |
466 | "#####, | 422 | "#####, |
467 | r#####" | 423 | r#####" |
468 | enum A { One(u32) } | 424 | enum A { One(u32) } |
@@ -484,7 +440,7 @@ fn doctest_generate_function() { | |||
484 | struct Baz; | 440 | struct Baz; |
485 | fn baz() -> Baz { Baz } | 441 | fn baz() -> Baz { Baz } |
486 | fn foo() { | 442 | fn foo() { |
487 | bar<|>("", baz()); | 443 | bar$0("", baz()); |
488 | } | 444 | } |
489 | 445 | ||
490 | "#####, | 446 | "#####, |
@@ -509,7 +465,7 @@ fn doctest_generate_impl() { | |||
509 | "generate_impl", | 465 | "generate_impl", |
510 | r#####" | 466 | r#####" |
511 | struct Ctx<T: Clone> { | 467 | struct Ctx<T: Clone> { |
512 | data: T,<|> | 468 | data: T,$0 |
513 | } | 469 | } |
514 | "#####, | 470 | "#####, |
515 | r#####" | 471 | r#####" |
@@ -530,7 +486,7 @@ fn doctest_generate_new() { | |||
530 | "generate_new", | 486 | "generate_new", |
531 | r#####" | 487 | r#####" |
532 | struct Ctx<T: Clone> { | 488 | struct Ctx<T: Clone> { |
533 | data: T,<|> | 489 | data: T,$0 |
534 | } | 490 | } |
535 | "#####, | 491 | "#####, |
536 | r#####" | 492 | r#####" |
@@ -551,7 +507,7 @@ fn doctest_infer_function_return_type() { | |||
551 | check_doc_test( | 507 | check_doc_test( |
552 | "infer_function_return_type", | 508 | "infer_function_return_type", |
553 | r#####" | 509 | r#####" |
554 | fn foo() { 4<|>2i32 } | 510 | fn foo() { 4$02i32 } |
555 | "#####, | 511 | "#####, |
556 | r#####" | 512 | r#####" |
557 | fn foo() -> i32 { 42i32 } | 513 | fn foo() -> i32 { 42i32 } |
@@ -560,12 +516,35 @@ fn foo() -> i32 { 42i32 } | |||
560 | } | 516 | } |
561 | 517 | ||
562 | #[test] | 518 | #[test] |
519 | fn doctest_inline_function() { | ||
520 | check_doc_test( | ||
521 | "inline_function", | ||
522 | r#####" | ||
523 | fn add(a: u32, b: u32) -> u32 { a + b } | ||
524 | fn main() { | ||
525 | let x = add$0(1, 2); | ||
526 | } | ||
527 | "#####, | ||
528 | r#####" | ||
529 | fn add(a: u32, b: u32) -> u32 { a + b } | ||
530 | fn main() { | ||
531 | let x = { | ||
532 | let a = 1; | ||
533 | let b = 2; | ||
534 | a + b | ||
535 | }; | ||
536 | } | ||
537 | "#####, | ||
538 | ) | ||
539 | } | ||
540 | |||
541 | #[test] | ||
563 | fn doctest_inline_local_variable() { | 542 | fn doctest_inline_local_variable() { |
564 | check_doc_test( | 543 | check_doc_test( |
565 | "inline_local_variable", | 544 | "inline_local_variable", |
566 | r#####" | 545 | r#####" |
567 | fn main() { | 546 | fn main() { |
568 | let x<|> = 1 + 2; | 547 | let x$0 = 1 + 2; |
569 | x * 4; | 548 | x * 4; |
570 | } | 549 | } |
571 | "#####, | 550 | "#####, |
@@ -582,7 +561,7 @@ fn doctest_introduce_named_lifetime() { | |||
582 | check_doc_test( | 561 | check_doc_test( |
583 | "introduce_named_lifetime", | 562 | "introduce_named_lifetime", |
584 | r#####" | 563 | r#####" |
585 | impl Cursor<'_<|>> { | 564 | impl Cursor<'_$0> { |
586 | fn node(self) -> &SyntaxNode { | 565 | fn node(self) -> &SyntaxNode { |
587 | match self { | 566 | match self { |
588 | Cursor::Replace(node) | Cursor::Before(node) => node, | 567 | Cursor::Replace(node) | Cursor::Before(node) => node, |
@@ -608,7 +587,7 @@ fn doctest_invert_if() { | |||
608 | "invert_if", | 587 | "invert_if", |
609 | r#####" | 588 | r#####" |
610 | fn main() { | 589 | fn main() { |
611 | if<|> !y { A } else { B } | 590 | if$0 !y { A } else { B } |
612 | } | 591 | } |
613 | "#####, | 592 | "#####, |
614 | r#####" | 593 | r#####" |
@@ -625,7 +604,7 @@ fn doctest_make_raw_string() { | |||
625 | "make_raw_string", | 604 | "make_raw_string", |
626 | r#####" | 605 | r#####" |
627 | fn main() { | 606 | fn main() { |
628 | "Hello,<|> World!"; | 607 | "Hello,$0 World!"; |
629 | } | 608 | } |
630 | "#####, | 609 | "#####, |
631 | r#####" | 610 | r#####" |
@@ -642,7 +621,7 @@ fn doctest_make_usual_string() { | |||
642 | "make_usual_string", | 621 | "make_usual_string", |
643 | r#####" | 622 | r#####" |
644 | fn main() { | 623 | fn main() { |
645 | r#"Hello,<|> "World!""#; | 624 | r#"Hello,$0 "World!""#; |
646 | } | 625 | } |
647 | "#####, | 626 | "#####, |
648 | r#####" | 627 | r#####" |
@@ -658,7 +637,7 @@ fn doctest_merge_imports() { | |||
658 | check_doc_test( | 637 | check_doc_test( |
659 | "merge_imports", | 638 | "merge_imports", |
660 | r#####" | 639 | r#####" |
661 | use std::<|>fmt::Formatter; | 640 | use std::$0fmt::Formatter; |
662 | use std::io; | 641 | use std::io; |
663 | "#####, | 642 | "#####, |
664 | r#####" | 643 | r#####" |
@@ -676,7 +655,7 @@ enum Action { Move { distance: u32 }, Stop } | |||
676 | 655 | ||
677 | fn handle(action: Action) { | 656 | fn handle(action: Action) { |
678 | match action { | 657 | match action { |
679 | <|>Action::Move(..) => foo(), | 658 | $0Action::Move(..) => foo(), |
680 | Action::Stop => foo(), | 659 | Action::Stop => foo(), |
681 | } | 660 | } |
682 | } | 661 | } |
@@ -702,7 +681,7 @@ enum Action { Move { distance: u32 }, Stop } | |||
702 | 681 | ||
703 | fn handle(action: Action) { | 682 | fn handle(action: Action) { |
704 | match action { | 683 | match action { |
705 | Action::Move { distance } => <|>if distance > 10 { foo() }, | 684 | Action::Move { distance } => $0if distance > 10 { foo() }, |
706 | _ => (), | 685 | _ => (), |
707 | } | 686 | } |
708 | } | 687 | } |
@@ -725,7 +704,7 @@ fn doctest_move_bounds_to_where_clause() { | |||
725 | check_doc_test( | 704 | check_doc_test( |
726 | "move_bounds_to_where_clause", | 705 | "move_bounds_to_where_clause", |
727 | r#####" | 706 | r#####" |
728 | fn apply<T, U, <|>F: FnOnce(T) -> U>(f: F, x: T) -> U { | 707 | fn apply<T, U, $0F: FnOnce(T) -> U>(f: F, x: T) -> U { |
729 | f(x) | 708 | f(x) |
730 | } | 709 | } |
731 | "#####, | 710 | "#####, |
@@ -746,7 +725,7 @@ enum Action { Move { distance: u32 }, Stop } | |||
746 | 725 | ||
747 | fn handle(action: Action) { | 726 | fn handle(action: Action) { |
748 | match action { | 727 | match action { |
749 | Action::Move { distance } <|>if distance > 10 => foo(), | 728 | Action::Move { distance } $0if distance > 10 => foo(), |
750 | _ => (), | 729 | _ => (), |
751 | } | 730 | } |
752 | } | 731 | } |
@@ -767,12 +746,56 @@ fn handle(action: Action) { | |||
767 | } | 746 | } |
768 | 747 | ||
769 | #[test] | 748 | #[test] |
749 | fn doctest_move_module_to_file() { | ||
750 | check_doc_test( | ||
751 | "move_module_to_file", | ||
752 | r#####" | ||
753 | mod $0foo { | ||
754 | fn t() {} | ||
755 | } | ||
756 | "#####, | ||
757 | r#####" | ||
758 | mod foo; | ||
759 | "#####, | ||
760 | ) | ||
761 | } | ||
762 | |||
763 | #[test] | ||
764 | fn doctest_pull_assignment_up() { | ||
765 | check_doc_test( | ||
766 | "pull_assignment_up", | ||
767 | r#####" | ||
768 | fn main() { | ||
769 | let mut foo = 6; | ||
770 | |||
771 | if true { | ||
772 | $0foo = 5; | ||
773 | } else { | ||
774 | foo = 4; | ||
775 | } | ||
776 | } | ||
777 | "#####, | ||
778 | r#####" | ||
779 | fn main() { | ||
780 | let mut foo = 6; | ||
781 | |||
782 | foo = if true { | ||
783 | 5 | ||
784 | } else { | ||
785 | 4 | ||
786 | }; | ||
787 | } | ||
788 | "#####, | ||
789 | ) | ||
790 | } | ||
791 | |||
792 | #[test] | ||
770 | fn doctest_qualify_path() { | 793 | fn doctest_qualify_path() { |
771 | check_doc_test( | 794 | check_doc_test( |
772 | "qualify_path", | 795 | "qualify_path", |
773 | r#####" | 796 | r#####" |
774 | fn main() { | 797 | fn main() { |
775 | let map = HashMap<|>::new(); | 798 | let map = HashMap$0::new(); |
776 | } | 799 | } |
777 | pub mod std { pub mod collections { pub struct HashMap { } } } | 800 | pub mod std { pub mod collections { pub struct HashMap { } } } |
778 | "#####, | 801 | "#####, |
@@ -791,7 +814,7 @@ fn doctest_remove_dbg() { | |||
791 | "remove_dbg", | 814 | "remove_dbg", |
792 | r#####" | 815 | r#####" |
793 | fn main() { | 816 | fn main() { |
794 | <|>dbg!(92); | 817 | $0dbg!(92); |
795 | } | 818 | } |
796 | "#####, | 819 | "#####, |
797 | r#####" | 820 | r#####" |
@@ -808,7 +831,7 @@ fn doctest_remove_hash() { | |||
808 | "remove_hash", | 831 | "remove_hash", |
809 | r#####" | 832 | r#####" |
810 | fn main() { | 833 | fn main() { |
811 | r#"Hello,<|> World!"#; | 834 | r#"Hello,$0 World!"#; |
812 | } | 835 | } |
813 | "#####, | 836 | "#####, |
814 | r#####" | 837 | r#####" |
@@ -825,7 +848,7 @@ fn doctest_remove_mut() { | |||
825 | "remove_mut", | 848 | "remove_mut", |
826 | r#####" | 849 | r#####" |
827 | impl Walrus { | 850 | impl Walrus { |
828 | fn feed(&mut<|> self, amount: u32) {} | 851 | fn feed(&mut$0 self, amount: u32) {} |
829 | } | 852 | } |
830 | "#####, | 853 | "#####, |
831 | r#####" | 854 | r#####" |
@@ -841,7 +864,7 @@ fn doctest_remove_unused_param() { | |||
841 | check_doc_test( | 864 | check_doc_test( |
842 | "remove_unused_param", | 865 | "remove_unused_param", |
843 | r#####" | 866 | r#####" |
844 | fn frobnicate(x: i32<|>) {} | 867 | fn frobnicate(x: i32$0) {} |
845 | 868 | ||
846 | fn main() { | 869 | fn main() { |
847 | frobnicate(92); | 870 | frobnicate(92); |
@@ -863,7 +886,7 @@ fn doctest_reorder_fields() { | |||
863 | "reorder_fields", | 886 | "reorder_fields", |
864 | r#####" | 887 | r#####" |
865 | struct Foo {foo: i32, bar: i32}; | 888 | struct Foo {foo: i32, bar: i32}; |
866 | const test: Foo = <|>Foo {bar: 0, foo: 1} | 889 | const test: Foo = $0Foo {bar: 0, foo: 1} |
867 | "#####, | 890 | "#####, |
868 | r#####" | 891 | r#####" |
869 | struct Foo {foo: i32, bar: i32}; | 892 | struct Foo {foo: i32, bar: i32}; |
@@ -878,7 +901,7 @@ fn doctest_replace_derive_with_manual_impl() { | |||
878 | "replace_derive_with_manual_impl", | 901 | "replace_derive_with_manual_impl", |
879 | r#####" | 902 | r#####" |
880 | trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } | 903 | trait Debug { fn fmt(&self, f: &mut Formatter) -> Result<()>; } |
881 | #[derive(Deb<|>ug, Display)] | 904 | #[derive(Deb$0ug, Display)] |
882 | struct S; | 905 | struct S; |
883 | "#####, | 906 | "#####, |
884 | r#####" | 907 | r#####" |
@@ -903,7 +926,7 @@ fn doctest_replace_if_let_with_match() { | |||
903 | enum Action { Move { distance: u32 }, Stop } | 926 | enum Action { Move { distance: u32 }, Stop } |
904 | 927 | ||
905 | fn handle(action: Action) { | 928 | fn handle(action: Action) { |
906 | <|>if let Action::Move { distance } = action { | 929 | $0if let Action::Move { distance } = action { |
907 | foo(distance) | 930 | foo(distance) |
908 | } else { | 931 | } else { |
909 | bar() | 932 | bar() |
@@ -928,7 +951,7 @@ fn doctest_replace_impl_trait_with_generic() { | |||
928 | check_doc_test( | 951 | check_doc_test( |
929 | "replace_impl_trait_with_generic", | 952 | "replace_impl_trait_with_generic", |
930 | r#####" | 953 | r#####" |
931 | fn foo(bar: <|>impl Bar) {} | 954 | fn foo(bar: $0impl Bar) {} |
932 | "#####, | 955 | "#####, |
933 | r#####" | 956 | r#####" |
934 | fn foo<B: Bar>(bar: B) {} | 957 | fn foo<B: Bar>(bar: B) {} |
@@ -944,7 +967,7 @@ fn doctest_replace_let_with_if_let() { | |||
944 | enum Option<T> { Some(T), None } | 967 | enum Option<T> { Some(T), None } |
945 | 968 | ||
946 | fn main(action: Action) { | 969 | fn main(action: Action) { |
947 | <|>let x = compute(); | 970 | $0let x = compute(); |
948 | } | 971 | } |
949 | 972 | ||
950 | fn compute() -> Option<i32> { None } | 973 | fn compute() -> Option<i32> { None } |
@@ -970,7 +993,7 @@ fn doctest_replace_match_with_if_let() { | |||
970 | enum Action { Move { distance: u32 }, Stop } | 993 | enum Action { Move { distance: u32 }, Stop } |
971 | 994 | ||
972 | fn handle(action: Action) { | 995 | fn handle(action: Action) { |
973 | <|>match action { | 996 | $0match action { |
974 | Action::Move { distance } => foo(distance), | 997 | Action::Move { distance } => foo(distance), |
975 | _ => bar(), | 998 | _ => bar(), |
976 | } | 999 | } |
@@ -995,7 +1018,7 @@ fn doctest_replace_qualified_name_with_use() { | |||
995 | check_doc_test( | 1018 | check_doc_test( |
996 | "replace_qualified_name_with_use", | 1019 | "replace_qualified_name_with_use", |
997 | r#####" | 1020 | r#####" |
998 | fn process(map: std::collections::<|>HashMap<String, String>) {} | 1021 | fn process(map: std::collections::$0HashMap<String, String>) {} |
999 | "#####, | 1022 | "#####, |
1000 | r#####" | 1023 | r#####" |
1001 | use std::collections::HashMap; | 1024 | use std::collections::HashMap; |
@@ -1011,7 +1034,7 @@ fn doctest_replace_string_with_char() { | |||
1011 | "replace_string_with_char", | 1034 | "replace_string_with_char", |
1012 | r#####" | 1035 | r#####" |
1013 | fn main() { | 1036 | fn main() { |
1014 | find("{<|>"); | 1037 | find("{$0"); |
1015 | } | 1038 | } |
1016 | "#####, | 1039 | "#####, |
1017 | r#####" | 1040 | r#####" |
@@ -1030,7 +1053,7 @@ fn doctest_replace_unwrap_with_match() { | |||
1030 | enum Result<T, E> { Ok(T), Err(E) } | 1053 | enum Result<T, E> { Ok(T), Err(E) } |
1031 | fn main() { | 1054 | fn main() { |
1032 | let x: Result<i32, i32> = Result::Ok(92); | 1055 | let x: Result<i32, i32> = Result::Ok(92); |
1033 | let y = x.<|>unwrap(); | 1056 | let y = x.$0unwrap(); |
1034 | } | 1057 | } |
1035 | "#####, | 1058 | "#####, |
1036 | r#####" | 1059 | r#####" |
@@ -1051,7 +1074,7 @@ fn doctest_split_import() { | |||
1051 | check_doc_test( | 1074 | check_doc_test( |
1052 | "split_import", | 1075 | "split_import", |
1053 | r#####" | 1076 | r#####" |
1054 | use std::<|>collections::HashMap; | 1077 | use std::$0collections::HashMap; |
1055 | "#####, | 1078 | "#####, |
1056 | r#####" | 1079 | r#####" |
1057 | use std::{collections::HashMap}; | 1080 | use std::{collections::HashMap}; |
@@ -1064,7 +1087,7 @@ fn doctest_toggle_ignore() { | |||
1064 | check_doc_test( | 1087 | check_doc_test( |
1065 | "toggle_ignore", | 1088 | "toggle_ignore", |
1066 | r#####" | 1089 | r#####" |
1067 | <|>#[test] | 1090 | $0#[test] |
1068 | fn arithmetics { | 1091 | fn arithmetics { |
1069 | assert_eq!(2 + 2, 5); | 1092 | assert_eq!(2 + 2, 5); |
1070 | } | 1093 | } |
@@ -1085,7 +1108,7 @@ fn doctest_unwrap_block() { | |||
1085 | "unwrap_block", | 1108 | "unwrap_block", |
1086 | r#####" | 1109 | r#####" |
1087 | fn foo() { | 1110 | fn foo() { |
1088 | if true {<|> | 1111 | if true {$0 |
1089 | println!("foo"); | 1112 | println!("foo"); |
1090 | } | 1113 | } |
1091 | } | 1114 | } |
@@ -1103,7 +1126,7 @@ fn doctest_wrap_return_type_in_result() { | |||
1103 | check_doc_test( | 1126 | check_doc_test( |
1104 | "wrap_return_type_in_result", | 1127 | "wrap_return_type_in_result", |
1105 | r#####" | 1128 | r#####" |
1106 | fn foo() -> i32<|> { 42i32 } | 1129 | fn foo() -> i32$0 { 42i32 } |
1107 | "#####, | 1130 | "#####, |
1108 | r#####" | 1131 | r#####" |
1109 | fn foo() -> Result<i32, ${0:_}> { Ok(42i32) } | 1132 | fn foo() -> Result<i32, ${0:_}> { Ok(42i32) } |
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs index b05596446..9ea96eb73 100644 --- a/crates/assists/src/utils.rs +++ b/crates/assists/src/utils.rs | |||
@@ -4,7 +4,7 @@ pub(crate) mod import_assets; | |||
4 | use std::ops; | 4 | use std::ops; |
5 | 5 | ||
6 | use hir::HasSource; | 6 | use hir::HasSource; |
7 | use ide_db::RootDatabase; | 7 | use ide_db::{helpers::SnippetCap, RootDatabase}; |
8 | use itertools::Itertools; | 8 | use itertools::Itertools; |
9 | use syntax::{ | 9 | use syntax::{ |
10 | ast::edit::AstNodeEdit, | 10 | ast::edit::AstNodeEdit, |
@@ -16,10 +16,7 @@ use syntax::{ | |||
16 | SyntaxNode, TextSize, T, | 16 | SyntaxNode, TextSize, T, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | use crate::{ | 19 | use crate::ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}; |
20 | assist_config::SnippetCap, | ||
21 | ast_transform::{self, AstTransform, QualifyPaths, SubstituteTypeParams}, | ||
22 | }; | ||
23 | 20 | ||
24 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { | 21 | pub(crate) fn unwrap_trivial_block(block: ast::BlockExpr) -> ast::Expr { |
25 | extract_trivial_expression(&block) | 22 | extract_trivial_expression(&block) |
@@ -37,7 +34,7 @@ pub fn extract_trivial_expression(block: &ast::BlockExpr) -> Option<ast::Expr> { | |||
37 | non_trivial_children.next().is_some() | 34 | non_trivial_children.next().is_some() |
38 | }; | 35 | }; |
39 | 36 | ||
40 | if let Some(expr) = block.expr() { | 37 | if let Some(expr) = block.tail_expr() { |
41 | if has_anything_else(expr.syntax()) { | 38 | if has_anything_else(expr.syntax()) { |
42 | return None; | 39 | return None; |
43 | } | 40 | } |
diff --git a/crates/base_db/src/fixture.rs b/crates/base_db/src/fixture.rs index 66e6443cb..98acd61b1 100644 --- a/crates/base_db/src/fixture.rs +++ b/crates/base_db/src/fixture.rs | |||
@@ -61,7 +61,9 @@ use std::{str::FromStr, sync::Arc}; | |||
61 | 61 | ||
62 | use cfg::CfgOptions; | 62 | use cfg::CfgOptions; |
63 | use rustc_hash::FxHashMap; | 63 | use rustc_hash::FxHashMap; |
64 | use test_utils::{extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER}; | 64 | use test_utils::{ |
65 | extract_range_or_offset, Fixture, RangeOrOffset, CURSOR_MARKER, ESCAPED_CURSOR_MARKER, | ||
66 | }; | ||
65 | use vfs::{file_set::FileSet, VfsPath}; | 67 | use vfs::{file_set::FileSet, VfsPath}; |
66 | 68 | ||
67 | use crate::{ | 69 | use crate::{ |
@@ -142,10 +144,14 @@ impl ChangeFixture { | |||
142 | 144 | ||
143 | for entry in fixture { | 145 | for entry in fixture { |
144 | let text = if entry.text.contains(CURSOR_MARKER) { | 146 | let text = if entry.text.contains(CURSOR_MARKER) { |
145 | let (range_or_offset, text) = extract_range_or_offset(&entry.text); | 147 | if entry.text.contains(ESCAPED_CURSOR_MARKER) { |
146 | assert!(file_position.is_none()); | 148 | entry.text.replace(ESCAPED_CURSOR_MARKER, CURSOR_MARKER) |
147 | file_position = Some((file_id, range_or_offset)); | 149 | } else { |
148 | text.to_string() | 150 | let (range_or_offset, text) = extract_range_or_offset(&entry.text); |
151 | assert!(file_position.is_none()); | ||
152 | file_position = Some((file_id, range_or_offset)); | ||
153 | text.to_string() | ||
154 | } | ||
149 | } else { | 155 | } else { |
150 | entry.text.clone() | 156 | entry.text.clone() |
151 | }; | 157 | }; |
diff --git a/crates/cfg/Cargo.toml b/crates/cfg/Cargo.toml index c68e391c1..73247d130 100644 --- a/crates/cfg/Cargo.toml +++ b/crates/cfg/Cargo.toml | |||
@@ -17,4 +17,4 @@ tt = { path = "../tt", version = "0.0.0" } | |||
17 | [dev-dependencies] | 17 | [dev-dependencies] |
18 | mbe = { path = "../mbe" } | 18 | mbe = { path = "../mbe" } |
19 | syntax = { path = "../syntax" } | 19 | syntax = { path = "../syntax" } |
20 | expect-test = "1.0" | 20 | expect-test = "1.1" |
diff --git a/crates/completion/Cargo.toml b/crates/completion/Cargo.toml index 78e93e78e..99a1bdd54 100644 --- a/crates/completion/Cargo.toml +++ b/crates/completion/Cargo.toml | |||
@@ -28,4 +28,4 @@ test_utils = { path = "../test_utils", version = "0.0.0" } | |||
28 | hir = { path = "../hir", version = "0.0.0" } | 28 | hir = { path = "../hir", version = "0.0.0" } |
29 | 29 | ||
30 | [dev-dependencies] | 30 | [dev-dependencies] |
31 | expect-test = "1.0" | 31 | expect-test = "1.1" |
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index 8695eed39..3a29b5203 100644 --- a/crates/completion/src/completions/attribute.rs +++ b/crates/completion/src/completions/attribute.rs | |||
@@ -21,20 +21,15 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
21 | 21 | ||
22 | let attribute = ctx.attribute_under_caret.as_ref()?; | 22 | let attribute = ctx.attribute_under_caret.as_ref()?; |
23 | match (attribute.path(), attribute.token_tree()) { | 23 | match (attribute.path(), attribute.token_tree()) { |
24 | (Some(path), Some(token_tree)) if path.to_string() == "derive" => { | 24 | (Some(path), Some(token_tree)) => match path.to_string().as_str() { |
25 | complete_derive(acc, ctx, token_tree) | 25 | "derive" => complete_derive(acc, ctx, token_tree), |
26 | } | 26 | "feature" => complete_lint(acc, ctx, token_tree, FEATURES), |
27 | (Some(path), Some(token_tree)) if path.to_string() == "feature" => { | 27 | "allow" | "warn" | "deny" | "forbid" => { |
28 | complete_lint(acc, ctx, token_tree, FEATURES); | 28 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); |
29 | } | 29 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
30 | (Some(path), Some(token_tree)) | 30 | } |
31 | if ["allow", "warn", "deny", "forbid"] | 31 | _ => {} |
32 | .iter() | 32 | }, |
33 | .any(|lint_level| lint_level == &path.to_string()) => | ||
34 | { | ||
35 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); | ||
36 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | ||
37 | } | ||
38 | (_, Some(_token_tree)) => {} | 33 | (_, Some(_token_tree)) => {} |
39 | _ => complete_attribute_start(acc, ctx, attribute), | 34 | _ => complete_attribute_start(acc, ctx, attribute), |
40 | } | 35 | } |
@@ -54,11 +49,8 @@ fn complete_attribute_start(acc: &mut Completions, ctx: &CompletionContext, attr | |||
54 | item = item.lookup_by(lookup); | 49 | item = item.lookup_by(lookup); |
55 | } | 50 | } |
56 | 51 | ||
57 | match (attr_completion.snippet, ctx.config.snippet_cap) { | 52 | if let Some((snippet, cap)) = attr_completion.snippet.zip(ctx.config.snippet_cap) { |
58 | (Some(snippet), Some(cap)) => { | 53 | item = item.insert_snippet(cap, snippet); |
59 | item = item.insert_snippet(cap, snippet); | ||
60 | } | ||
61 | _ => {} | ||
62 | } | 54 | } |
63 | 55 | ||
64 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner { | 56 | if attribute.kind() == ast::AttrKind::Inner || !attr_completion.prefer_inner { |
@@ -98,7 +90,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
98 | attr(r#"crate_name = """#, Some("crate_name"), Some(r#"crate_name = "${0:crate_name}""#)) | 90 | attr(r#"crate_name = """#, Some("crate_name"), Some(r#"crate_name = "${0:crate_name}""#)) |
99 | .prefer_inner(), | 91 | .prefer_inner(), |
100 | attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), | 92 | attr("deny(…)", Some("deny"), Some("deny(${0:lint})")), |
101 | attr(r#"deprecated = "…""#, Some("deprecated"), Some(r#"deprecated = "${0:reason}""#)), | 93 | attr(r#"deprecated"#, Some("deprecated"), Some(r#"deprecated"#)), |
102 | attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), | 94 | attr("derive(…)", Some("derive"), Some(r#"derive(${0:Debug})"#)), |
103 | attr( | 95 | attr( |
104 | r#"export_name = "…""#, | 96 | r#"export_name = "…""#, |
@@ -121,7 +113,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
121 | ), | 113 | ), |
122 | attr("macro_export", None, None), | 114 | attr("macro_export", None, None), |
123 | attr("macro_use", None, None), | 115 | attr("macro_use", None, None), |
124 | attr(r#"must_use = "…""#, Some("must_use"), Some(r#"must_use = "${0:reason}""#)), | 116 | attr(r#"must_use"#, Some("must_use"), Some(r#"must_use"#)), |
125 | attr("no_link", None, None).prefer_inner(), | 117 | attr("no_link", None, None).prefer_inner(), |
126 | attr("no_implicit_prelude", None, None).prefer_inner(), | 118 | attr("no_implicit_prelude", None, None).prefer_inner(), |
127 | attr("no_main", None, None).prefer_inner(), | 119 | attr("no_main", None, None).prefer_inner(), |
@@ -136,11 +128,7 @@ const ATTRIBUTES: &[AttrCompletion] = &[ | |||
136 | attr("recursion_limit = …", Some("recursion_limit"), Some("recursion_limit = ${0:128}")) | 128 | attr("recursion_limit = …", Some("recursion_limit"), Some("recursion_limit = ${0:128}")) |
137 | .prefer_inner(), | 129 | .prefer_inner(), |
138 | attr("repr(…)", Some("repr"), Some("repr(${0:C})")), | 130 | attr("repr(…)", Some("repr"), Some("repr(${0:C})")), |
139 | attr( | 131 | attr("should_panic", Some("should_panic"), Some(r#"should_panic"#)), |
140 | "should_panic(…)", | ||
141 | Some("should_panic"), | ||
142 | Some(r#"should_panic(expected = "${0:reason}")"#), | ||
143 | ), | ||
144 | attr( | 132 | attr( |
145 | r#"target_feature = "…""#, | 133 | r#"target_feature = "…""#, |
146 | Some("target_feature"), | 134 | Some("target_feature"), |
@@ -417,7 +405,7 @@ mod tests { | |||
417 | fn empty_derive_completion() { | 405 | fn empty_derive_completion() { |
418 | check( | 406 | check( |
419 | r#" | 407 | r#" |
420 | #[derive(<|>)] | 408 | #[derive($0)] |
421 | struct Test {} | 409 | struct Test {} |
422 | "#, | 410 | "#, |
423 | expect![[r#" | 411 | expect![[r#" |
@@ -438,7 +426,7 @@ struct Test {} | |||
438 | fn no_completion_for_incorrect_derive() { | 426 | fn no_completion_for_incorrect_derive() { |
439 | check( | 427 | check( |
440 | r#" | 428 | r#" |
441 | #[derive{<|>)] | 429 | #[derive{$0)] |
442 | struct Test {} | 430 | struct Test {} |
443 | "#, | 431 | "#, |
444 | expect![[r#""#]], | 432 | expect![[r#""#]], |
@@ -449,7 +437,7 @@ struct Test {} | |||
449 | fn derive_with_input_completion() { | 437 | fn derive_with_input_completion() { |
450 | check( | 438 | check( |
451 | r#" | 439 | r#" |
452 | #[derive(serde::Serialize, PartialEq, <|>)] | 440 | #[derive(serde::Serialize, PartialEq, $0)] |
453 | struct Test {} | 441 | struct Test {} |
454 | "#, | 442 | "#, |
455 | expect![[r#" | 443 | expect![[r#" |
@@ -468,7 +456,7 @@ struct Test {} | |||
468 | #[test] | 456 | #[test] |
469 | fn test_attribute_completion() { | 457 | fn test_attribute_completion() { |
470 | check( | 458 | check( |
471 | r#"#[<|>]"#, | 459 | r#"#[$0]"#, |
472 | expect![[r#" | 460 | expect![[r#" |
473 | at allow(…) | 461 | at allow(…) |
474 | at automatically_derived | 462 | at automatically_derived |
@@ -476,7 +464,7 @@ struct Test {} | |||
476 | at cfg(…) | 464 | at cfg(…) |
477 | at cold | 465 | at cold |
478 | at deny(…) | 466 | at deny(…) |
479 | at deprecated = "…" | 467 | at deprecated |
480 | at derive(…) | 468 | at derive(…) |
481 | at export_name = "…" | 469 | at export_name = "…" |
482 | at doc = "…" | 470 | at doc = "…" |
@@ -488,7 +476,7 @@ struct Test {} | |||
488 | at link_section = "…" | 476 | at link_section = "…" |
489 | at macro_export | 477 | at macro_export |
490 | at macro_use | 478 | at macro_use |
491 | at must_use = "…" | 479 | at must_use |
492 | at no_mangle | 480 | at no_mangle |
493 | at non_exhaustive | 481 | at non_exhaustive |
494 | at path = "…" | 482 | at path = "…" |
@@ -496,7 +484,7 @@ struct Test {} | |||
496 | at proc_macro_attribute | 484 | at proc_macro_attribute |
497 | at proc_macro_derive(…) | 485 | at proc_macro_derive(…) |
498 | at repr(…) | 486 | at repr(…) |
499 | at should_panic(…) | 487 | at should_panic |
500 | at target_feature = "…" | 488 | at target_feature = "…" |
501 | at test | 489 | at test |
502 | at track_caller | 490 | at track_caller |
@@ -508,13 +496,13 @@ struct Test {} | |||
508 | 496 | ||
509 | #[test] | 497 | #[test] |
510 | fn test_attribute_completion_inside_nested_attr() { | 498 | fn test_attribute_completion_inside_nested_attr() { |
511 | check(r#"#[cfg(<|>)]"#, expect![[]]) | 499 | check(r#"#[cfg($0)]"#, expect![[]]) |
512 | } | 500 | } |
513 | 501 | ||
514 | #[test] | 502 | #[test] |
515 | fn test_inner_attribute_completion() { | 503 | fn test_inner_attribute_completion() { |
516 | check( | 504 | check( |
517 | r"#![<|>]", | 505 | r"#![$0]", |
518 | expect![[r#" | 506 | expect![[r#" |
519 | at allow(…) | 507 | at allow(…) |
520 | at automatically_derived | 508 | at automatically_derived |
@@ -523,7 +511,7 @@ struct Test {} | |||
523 | at cold | 511 | at cold |
524 | at crate_name = "" | 512 | at crate_name = "" |
525 | at deny(…) | 513 | at deny(…) |
526 | at deprecated = "…" | 514 | at deprecated |
527 | at derive(…) | 515 | at derive(…) |
528 | at export_name = "…" | 516 | at export_name = "…" |
529 | at doc = "…" | 517 | at doc = "…" |
@@ -537,7 +525,7 @@ struct Test {} | |||
537 | at link_section = "…" | 525 | at link_section = "…" |
538 | at macro_export | 526 | at macro_export |
539 | at macro_use | 527 | at macro_use |
540 | at must_use = "…" | 528 | at must_use |
541 | at no_link | 529 | at no_link |
542 | at no_implicit_prelude | 530 | at no_implicit_prelude |
543 | at no_main | 531 | at no_main |
@@ -551,7 +539,7 @@ struct Test {} | |||
551 | at proc_macro_derive(…) | 539 | at proc_macro_derive(…) |
552 | at recursion_limit = … | 540 | at recursion_limit = … |
553 | at repr(…) | 541 | at repr(…) |
554 | at should_panic(…) | 542 | at should_panic |
555 | at target_feature = "…" | 543 | at target_feature = "…" |
556 | at test | 544 | at test |
557 | at track_caller | 545 | at track_caller |
diff --git a/crates/completion/src/completions/dot.rs b/crates/completion/src/completions/dot.rs index 551ef1771..2e25c8ba2 100644 --- a/crates/completion/src/completions/dot.rs +++ b/crates/completion/src/completions/dot.rs | |||
@@ -79,7 +79,7 @@ struct S { foo: u32 } | |||
79 | impl S { | 79 | impl S { |
80 | fn bar(&self) {} | 80 | fn bar(&self) {} |
81 | } | 81 | } |
82 | fn foo(s: S) { s.<|> } | 82 | fn foo(s: S) { s.$0 } |
83 | "#, | 83 | "#, |
84 | expect![[r#" | 84 | expect![[r#" |
85 | fd foo u32 | 85 | fd foo u32 |
@@ -94,7 +94,7 @@ fn foo(s: S) { s.<|> } | |||
94 | r#" | 94 | r#" |
95 | struct S { the_field: (u32,) } | 95 | struct S { the_field: (u32,) } |
96 | impl S { | 96 | impl S { |
97 | fn foo(self) { self.<|> } | 97 | fn foo(self) { self.$0 } |
98 | } | 98 | } |
99 | "#, | 99 | "#, |
100 | expect![[r#" | 100 | expect![[r#" |
@@ -110,7 +110,7 @@ impl S { | |||
110 | r#" | 110 | r#" |
111 | struct A { the_field: (u32, i32) } | 111 | struct A { the_field: (u32, i32) } |
112 | impl A { | 112 | impl A { |
113 | fn foo(&self) { self.<|> } | 113 | fn foo(&self) { self.$0 } |
114 | } | 114 | } |
115 | "#, | 115 | "#, |
116 | expect![[r#" | 116 | expect![[r#" |
@@ -126,7 +126,7 @@ impl A { | |||
126 | check( | 126 | check( |
127 | r#" | 127 | r#" |
128 | struct A { the_field: u32 } | 128 | struct A { the_field: u32 } |
129 | fn foo(a: A) { a.<|>() } | 129 | fn foo(a: A) { a.$0() } |
130 | "#, | 130 | "#, |
131 | expect![[""]], | 131 | expect![[""]], |
132 | ); | 132 | ); |
@@ -144,7 +144,7 @@ mod inner { | |||
144 | pub(crate) super_field: u32, | 144 | pub(crate) super_field: u32, |
145 | } | 145 | } |
146 | } | 146 | } |
147 | fn foo(a: inner::A) { a.<|> } | 147 | fn foo(a: inner::A) { a.$0 } |
148 | "#, | 148 | "#, |
149 | expect![[r#" | 149 | expect![[r#" |
150 | fd pub_field u32 | 150 | fd pub_field u32 |
@@ -162,7 +162,7 @@ mod m { | |||
162 | pub(crate) fn the_method(&self) {} | 162 | pub(crate) fn the_method(&self) {} |
163 | } | 163 | } |
164 | } | 164 | } |
165 | fn foo(a: A) { a.<|> } | 165 | fn foo(a: A) { a.$0 } |
166 | "#, | 166 | "#, |
167 | expect![[r#" | 167 | expect![[r#" |
168 | me the_method() pub(crate) fn the_method(&self) | 168 | me the_method() pub(crate) fn the_method(&self) |
@@ -175,7 +175,7 @@ fn foo(a: A) { a.<|> } | |||
175 | check( | 175 | check( |
176 | r#" | 176 | r#" |
177 | union U { field: u8, other: u16 } | 177 | union U { field: u8, other: u16 } |
178 | fn foo(u: U) { u.<|> } | 178 | fn foo(u: U) { u.$0 } |
179 | "#, | 179 | "#, |
180 | expect![[r#" | 180 | expect![[r#" |
181 | fd field u8 | 181 | fd field u8 |
@@ -195,7 +195,7 @@ impl A<u32> { | |||
195 | impl A<i32> { | 195 | impl A<i32> { |
196 | fn the_other_method(&self) {} | 196 | fn the_other_method(&self) {} |
197 | } | 197 | } |
198 | fn foo(a: A<u32>) { a.<|> } | 198 | fn foo(a: A<u32>) { a.$0 } |
199 | "#, | 199 | "#, |
200 | expect![[r#" | 200 | expect![[r#" |
201 | me the_method() fn the_method(&self) | 201 | me the_method() fn the_method(&self) |
@@ -210,7 +210,7 @@ fn foo(a: A<u32>) { a.<|> } | |||
210 | struct A {} | 210 | struct A {} |
211 | trait Trait { fn the_method(&self); } | 211 | trait Trait { fn the_method(&self); } |
212 | impl Trait for A {} | 212 | impl Trait for A {} |
213 | fn foo(a: A) { a.<|> } | 213 | fn foo(a: A) { a.$0 } |
214 | "#, | 214 | "#, |
215 | expect![[r#" | 215 | expect![[r#" |
216 | me the_method() fn the_method(&self) | 216 | me the_method() fn the_method(&self) |
@@ -225,7 +225,7 @@ fn foo(a: A) { a.<|> } | |||
225 | struct A {} | 225 | struct A {} |
226 | trait Trait { fn the_method(&self); } | 226 | trait Trait { fn the_method(&self); } |
227 | impl<T> Trait for T {} | 227 | impl<T> Trait for T {} |
228 | fn foo(a: &A) { a.<|> } | 228 | fn foo(a: &A) { a.$0 } |
229 | ", | 229 | ", |
230 | expect![[r#" | 230 | expect![[r#" |
231 | me the_method() fn the_method(&self) | 231 | me the_method() fn the_method(&self) |
@@ -243,7 +243,7 @@ mod m { | |||
243 | } | 243 | } |
244 | use m::Trait; | 244 | use m::Trait; |
245 | impl Trait for A {} | 245 | impl Trait for A {} |
246 | fn foo(a: A) { a.<|> } | 246 | fn foo(a: A) { a.$0 } |
247 | ", | 247 | ", |
248 | expect![[r#" | 248 | expect![[r#" |
249 | me the_method() fn the_method(&self) | 249 | me the_method() fn the_method(&self) |
@@ -260,7 +260,7 @@ impl A { | |||
260 | fn the_method() {} | 260 | fn the_method() {} |
261 | } | 261 | } |
262 | fn foo(a: A) { | 262 | fn foo(a: A) { |
263 | a.<|> | 263 | a.$0 |
264 | } | 264 | } |
265 | "#, | 265 | "#, |
266 | expect![[""]], | 266 | expect![[""]], |
@@ -273,7 +273,7 @@ fn foo(a: A) { | |||
273 | r#" | 273 | r#" |
274 | fn foo() { | 274 | fn foo() { |
275 | let b = (0, 3.14); | 275 | let b = (0, 3.14); |
276 | b.<|> | 276 | b.$0 |
277 | } | 277 | } |
278 | "#, | 278 | "#, |
279 | expect![[r#" | 279 | expect![[r#" |
@@ -295,7 +295,7 @@ struct T(S); | |||
295 | impl T { | 295 | impl T { |
296 | fn foo(&self) { | 296 | fn foo(&self) { |
297 | // FIXME: This doesn't work without the trailing `a` as `0.` is a float | 297 | // FIXME: This doesn't work without the trailing `a` as `0.` is a float |
298 | self.0.a<|> | 298 | self.0.a$0 |
299 | } | 299 | } |
300 | } | 300 | } |
301 | "#, | 301 | "#, |
@@ -311,7 +311,7 @@ impl T { | |||
311 | r#" | 311 | r#" |
312 | struct A { the_field: u32 } | 312 | struct A { the_field: u32 } |
313 | const X: u32 = { | 313 | const X: u32 = { |
314 | A { the_field: 92 }.<|> | 314 | A { the_field: 92 }.$0 |
315 | }; | 315 | }; |
316 | "#, | 316 | "#, |
317 | expect![[r#" | 317 | expect![[r#" |
@@ -327,7 +327,7 @@ const X: u32 = { | |||
327 | macro_rules! m { ($e:expr) => { $e } } | 327 | macro_rules! m { ($e:expr) => { $e } } |
328 | struct A { the_field: u32 } | 328 | struct A { the_field: u32 } |
329 | fn foo(a: A) { | 329 | fn foo(a: A) { |
330 | m!(a.x<|>) | 330 | m!(a.x$0) |
331 | } | 331 | } |
332 | "#, | 332 | "#, |
333 | expect![[r#" | 333 | expect![[r#" |
@@ -344,7 +344,7 @@ fn foo(a: A) { | |||
344 | macro_rules! m { ($e:expr) => { $e } } | 344 | macro_rules! m { ($e:expr) => { $e } } |
345 | struct A { the_field: u32 } | 345 | struct A { the_field: u32 } |
346 | fn foo(a: A) { | 346 | fn foo(a: A) { |
347 | m!(a.<|>) | 347 | m!(a.$0) |
348 | } | 348 | } |
349 | "#, | 349 | "#, |
350 | expect![[r#" | 350 | expect![[r#" |
@@ -360,7 +360,7 @@ fn foo(a: A) { | |||
360 | macro_rules! m { ($e:expr) => { $e } } | 360 | macro_rules! m { ($e:expr) => { $e } } |
361 | struct A { the_field: u32 } | 361 | struct A { the_field: u32 } |
362 | fn foo(a: A) { | 362 | fn foo(a: A) { |
363 | m!(m!(m!(a.x<|>))) | 363 | m!(m!(m!(a.x$0))) |
364 | } | 364 | } |
365 | "#, | 365 | "#, |
366 | expect![[r#" | 366 | expect![[r#" |
@@ -386,7 +386,7 @@ macro_rules! dbg { | |||
386 | } | 386 | } |
387 | struct A { the_field: u32 } | 387 | struct A { the_field: u32 } |
388 | fn foo(a: A) { | 388 | fn foo(a: A) { |
389 | dbg!(a.<|>) | 389 | dbg!(a.$0) |
390 | } | 390 | } |
391 | "#, | 391 | "#, |
392 | expect![[r#" | 392 | expect![[r#" |
@@ -405,7 +405,7 @@ impl<T> HashSet<T> { | |||
405 | } | 405 | } |
406 | fn foo() { | 406 | fn foo() { |
407 | let s: HashSet<_>; | 407 | let s: HashSet<_>; |
408 | s.<|> | 408 | s.$0 |
409 | } | 409 | } |
410 | "#, | 410 | "#, |
411 | expect![[r#" | 411 | expect![[r#" |
@@ -421,7 +421,7 @@ fn foo() { | |||
421 | struct S; | 421 | struct S; |
422 | impl S { fn foo(&self) {} } | 422 | impl S { fn foo(&self) {} } |
423 | macro_rules! make_s { () => { S }; } | 423 | macro_rules! make_s { () => { S }; } |
424 | fn main() { make_s!().f<|>; } | 424 | fn main() { make_s!().f$0; } |
425 | "#, | 425 | "#, |
426 | expect![[r#" | 426 | expect![[r#" |
427 | me foo() fn foo(&self) | 427 | me foo() fn foo(&self) |
diff --git a/crates/completion/src/completions/fn_param.rs b/crates/completion/src/completions/fn_param.rs index e777a53c1..5505c3559 100644 --- a/crates/completion/src/completions/fn_param.rs +++ b/crates/completion/src/completions/fn_param.rs | |||
@@ -81,7 +81,7 @@ mod tests { | |||
81 | r#" | 81 | r#" |
82 | fn foo(file_id: FileId) {} | 82 | fn foo(file_id: FileId) {} |
83 | fn bar(file_id: FileId) {} | 83 | fn bar(file_id: FileId) {} |
84 | fn baz(file<|>) {} | 84 | fn baz(file$0) {} |
85 | "#, | 85 | "#, |
86 | expect![[r#" | 86 | expect![[r#" |
87 | bn file_id: FileId | 87 | bn file_id: FileId |
@@ -94,7 +94,7 @@ fn baz(file<|>) {} | |||
94 | check( | 94 | check( |
95 | r#" | 95 | r#" |
96 | fn foo(file_id: FileId) {} | 96 | fn foo(file_id: FileId) {} |
97 | fn baz(file<|>, x: i32) {} | 97 | fn baz(file$0, x: i32) {} |
98 | "#, | 98 | "#, |
99 | expect![[r#" | 99 | expect![[r#" |
100 | bn file_id: FileId | 100 | bn file_id: FileId |
@@ -110,7 +110,7 @@ pub(crate) trait SourceRoot { | |||
110 | pub fn contains(&self, file_id: FileId) -> bool; | 110 | pub fn contains(&self, file_id: FileId) -> bool; |
111 | pub fn module_map(&self) -> &ModuleMap; | 111 | pub fn module_map(&self) -> &ModuleMap; |
112 | pub fn lines(&self, file_id: FileId) -> &LineIndex; | 112 | pub fn lines(&self, file_id: FileId) -> &LineIndex; |
113 | pub fn syntax(&self, file<|>) | 113 | pub fn syntax(&self, file$0) |
114 | } | 114 | } |
115 | "#, | 115 | "#, |
116 | expect![[r#" | 116 | expect![[r#" |
@@ -124,7 +124,7 @@ pub(crate) trait SourceRoot { | |||
124 | check( | 124 | check( |
125 | r#" | 125 | r#" |
126 | fn outer(text: String) { | 126 | fn outer(text: String) { |
127 | fn inner(<|>) | 127 | fn inner($0) |
128 | } | 128 | } |
129 | "#, | 129 | "#, |
130 | expect![[r#" | 130 | expect![[r#" |
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs index 1859dec70..425a688ff 100644 --- a/crates/completion/src/completions/keyword.rs +++ b/crates/completion/src/completions/keyword.rs | |||
@@ -193,7 +193,7 @@ mod tests { | |||
193 | #[test] | 193 | #[test] |
194 | fn test_keywords_in_use_stmt() { | 194 | fn test_keywords_in_use_stmt() { |
195 | check( | 195 | check( |
196 | r"use <|>", | 196 | r"use $0", |
197 | expect![[r#" | 197 | expect![[r#" |
198 | kw crate:: | 198 | kw crate:: |
199 | kw self | 199 | kw self |
@@ -202,7 +202,7 @@ mod tests { | |||
202 | ); | 202 | ); |
203 | 203 | ||
204 | check( | 204 | check( |
205 | r"use a::<|>", | 205 | r"use a::$0", |
206 | expect![[r#" | 206 | expect![[r#" |
207 | kw self | 207 | kw self |
208 | kw super:: | 208 | kw super:: |
@@ -210,7 +210,7 @@ mod tests { | |||
210 | ); | 210 | ); |
211 | 211 | ||
212 | check( | 212 | check( |
213 | r"use a::{b, <|>}", | 213 | r"use a::{b, $0}", |
214 | expect![[r#" | 214 | expect![[r#" |
215 | kw self | 215 | kw self |
216 | kw super:: | 216 | kw super:: |
@@ -221,7 +221,7 @@ mod tests { | |||
221 | #[test] | 221 | #[test] |
222 | fn test_keywords_at_source_file_level() { | 222 | fn test_keywords_at_source_file_level() { |
223 | check( | 223 | check( |
224 | r"m<|>", | 224 | r"m$0", |
225 | expect![[r#" | 225 | expect![[r#" |
226 | kw fn | 226 | kw fn |
227 | kw use | 227 | kw use |
@@ -245,7 +245,7 @@ mod tests { | |||
245 | #[test] | 245 | #[test] |
246 | fn test_keywords_in_function() { | 246 | fn test_keywords_in_function() { |
247 | check( | 247 | check( |
248 | r"fn quux() { <|> }", | 248 | r"fn quux() { $0 }", |
249 | expect![[r#" | 249 | expect![[r#" |
250 | kw fn | 250 | kw fn |
251 | kw use | 251 | kw use |
@@ -271,7 +271,7 @@ mod tests { | |||
271 | #[test] | 271 | #[test] |
272 | fn test_keywords_inside_block() { | 272 | fn test_keywords_inside_block() { |
273 | check( | 273 | check( |
274 | r"fn quux() { if true { <|> } }", | 274 | r"fn quux() { if true { $0 } }", |
275 | expect![[r#" | 275 | expect![[r#" |
276 | kw fn | 276 | kw fn |
277 | kw use | 277 | kw use |
@@ -297,7 +297,7 @@ mod tests { | |||
297 | #[test] | 297 | #[test] |
298 | fn test_keywords_after_if() { | 298 | fn test_keywords_after_if() { |
299 | check( | 299 | check( |
300 | r#"fn quux() { if true { () } <|> }"#, | 300 | r#"fn quux() { if true { () } $0 }"#, |
301 | expect![[r#" | 301 | expect![[r#" |
302 | kw fn | 302 | kw fn |
303 | kw use | 303 | kw use |
@@ -322,7 +322,7 @@ mod tests { | |||
322 | ); | 322 | ); |
323 | check_edit( | 323 | check_edit( |
324 | "else", | 324 | "else", |
325 | r#"fn quux() { if true { () } <|> }"#, | 325 | r#"fn quux() { if true { () } $0 }"#, |
326 | r#"fn quux() { if true { () } else {$0} }"#, | 326 | r#"fn quux() { if true { () } else {$0} }"#, |
327 | ); | 327 | ); |
328 | } | 328 | } |
@@ -332,7 +332,7 @@ mod tests { | |||
332 | check( | 332 | check( |
333 | r#" | 333 | r#" |
334 | fn quux() -> i32 { | 334 | fn quux() -> i32 { |
335 | match () { () => <|> } | 335 | match () { () => $0 } |
336 | } | 336 | } |
337 | "#, | 337 | "#, |
338 | expect![[r#" | 338 | expect![[r#" |
@@ -350,7 +350,7 @@ fn quux() -> i32 { | |||
350 | #[test] | 350 | #[test] |
351 | fn test_keywords_in_trait_def() { | 351 | fn test_keywords_in_trait_def() { |
352 | check( | 352 | check( |
353 | r"trait My { <|> }", | 353 | r"trait My { $0 }", |
354 | expect![[r#" | 354 | expect![[r#" |
355 | kw fn | 355 | kw fn |
356 | kw const | 356 | kw const |
@@ -363,7 +363,7 @@ fn quux() -> i32 { | |||
363 | #[test] | 363 | #[test] |
364 | fn test_keywords_in_impl_def() { | 364 | fn test_keywords_in_impl_def() { |
365 | check( | 365 | check( |
366 | r"impl My { <|> }", | 366 | r"impl My { $0 }", |
367 | expect![[r#" | 367 | expect![[r#" |
368 | kw fn | 368 | kw fn |
369 | kw const | 369 | kw const |
@@ -378,7 +378,7 @@ fn quux() -> i32 { | |||
378 | #[test] | 378 | #[test] |
379 | fn test_keywords_in_loop() { | 379 | fn test_keywords_in_loop() { |
380 | check( | 380 | check( |
381 | r"fn my() { loop { <|> } }", | 381 | r"fn my() { loop { $0 } }", |
382 | expect![[r#" | 382 | expect![[r#" |
383 | kw fn | 383 | kw fn |
384 | kw use | 384 | kw use |
@@ -406,7 +406,7 @@ fn quux() -> i32 { | |||
406 | #[test] | 406 | #[test] |
407 | fn test_keywords_after_unsafe_in_item_list() { | 407 | fn test_keywords_after_unsafe_in_item_list() { |
408 | check( | 408 | check( |
409 | r"unsafe <|>", | 409 | r"unsafe $0", |
410 | expect![[r#" | 410 | expect![[r#" |
411 | kw fn | 411 | kw fn |
412 | kw trait | 412 | kw trait |
@@ -418,7 +418,7 @@ fn quux() -> i32 { | |||
418 | #[test] | 418 | #[test] |
419 | fn test_keywords_after_unsafe_in_block_expr() { | 419 | fn test_keywords_after_unsafe_in_block_expr() { |
420 | check( | 420 | check( |
421 | r"fn my_fn() { unsafe <|> }", | 421 | r"fn my_fn() { unsafe $0 }", |
422 | expect![[r#" | 422 | expect![[r#" |
423 | kw fn | 423 | kw fn |
424 | kw trait | 424 | kw trait |
@@ -430,19 +430,19 @@ fn quux() -> i32 { | |||
430 | #[test] | 430 | #[test] |
431 | fn test_mut_in_ref_and_in_fn_parameters_list() { | 431 | fn test_mut_in_ref_and_in_fn_parameters_list() { |
432 | check( | 432 | check( |
433 | r"fn my_fn(&<|>) {}", | 433 | r"fn my_fn(&$0) {}", |
434 | expect![[r#" | 434 | expect![[r#" |
435 | kw mut | 435 | kw mut |
436 | "#]], | 436 | "#]], |
437 | ); | 437 | ); |
438 | check( | 438 | check( |
439 | r"fn my_fn(<|>) {}", | 439 | r"fn my_fn($0) {}", |
440 | expect![[r#" | 440 | expect![[r#" |
441 | kw mut | 441 | kw mut |
442 | "#]], | 442 | "#]], |
443 | ); | 443 | ); |
444 | check( | 444 | check( |
445 | r"fn my_fn() { let &<|> }", | 445 | r"fn my_fn() { let &$0 }", |
446 | expect![[r#" | 446 | expect![[r#" |
447 | kw mut | 447 | kw mut |
448 | "#]], | 448 | "#]], |
@@ -452,13 +452,13 @@ fn quux() -> i32 { | |||
452 | #[test] | 452 | #[test] |
453 | fn test_where_keyword() { | 453 | fn test_where_keyword() { |
454 | check( | 454 | check( |
455 | r"trait A <|>", | 455 | r"trait A $0", |
456 | expect![[r#" | 456 | expect![[r#" |
457 | kw where | 457 | kw where |
458 | "#]], | 458 | "#]], |
459 | ); | 459 | ); |
460 | check( | 460 | check( |
461 | r"impl A <|>", | 461 | r"impl A $0", |
462 | expect![[r#" | 462 | expect![[r#" |
463 | kw where | 463 | kw where |
464 | "#]], | 464 | "#]], |
@@ -471,7 +471,7 @@ fn quux() -> i32 { | |||
471 | check( | 471 | check( |
472 | r#" | 472 | r#" |
473 | fn test() { | 473 | fn test() { |
474 | let x = 2; // A comment<|> | 474 | let x = 2; // A comment$0 |
475 | } | 475 | } |
476 | "#, | 476 | "#, |
477 | expect![[""]], | 477 | expect![[""]], |
@@ -479,7 +479,7 @@ fn test() { | |||
479 | check( | 479 | check( |
480 | r#" | 480 | r#" |
481 | /* | 481 | /* |
482 | Some multi-line comment<|> | 482 | Some multi-line comment$0 |
483 | */ | 483 | */ |
484 | "#, | 484 | "#, |
485 | expect![[""]], | 485 | expect![[""]], |
@@ -487,7 +487,7 @@ Some multi-line comment<|> | |||
487 | check( | 487 | check( |
488 | r#" | 488 | r#" |
489 | /// Some doc comment | 489 | /// Some doc comment |
490 | /// let test<|> = 1 | 490 | /// let test$0 = 1 |
491 | "#, | 491 | "#, |
492 | expect![[""]], | 492 | expect![[""]], |
493 | ); | 493 | ); |
@@ -501,7 +501,7 @@ Some multi-line comment<|> | |||
501 | use std::future::*; | 501 | use std::future::*; |
502 | struct A {} | 502 | struct A {} |
503 | impl Future for A {} | 503 | impl Future for A {} |
504 | fn foo(a: A) { a.<|> } | 504 | fn foo(a: A) { a.$0 } |
505 | 505 | ||
506 | //- /std/lib.rs crate:std | 506 | //- /std/lib.rs crate:std |
507 | pub mod future { | 507 | pub mod future { |
@@ -520,7 +520,7 @@ pub mod future { | |||
520 | use std::future::*; | 520 | use std::future::*; |
521 | fn foo() { | 521 | fn foo() { |
522 | let a = async {}; | 522 | let a = async {}; |
523 | a.<|> | 523 | a.$0 |
524 | } | 524 | } |
525 | 525 | ||
526 | //- /std/lib.rs crate:std | 526 | //- /std/lib.rs crate:std |
@@ -540,7 +540,7 @@ pub mod future { | |||
540 | #[test] | 540 | #[test] |
541 | fn after_let() { | 541 | fn after_let() { |
542 | check( | 542 | check( |
543 | r#"fn main() { let _ = <|> }"#, | 543 | r#"fn main() { let _ = $0 }"#, |
544 | expect![[r#" | 544 | expect![[r#" |
545 | kw match | 545 | kw match |
546 | kw while | 546 | kw while |
@@ -557,7 +557,7 @@ pub mod future { | |||
557 | check( | 557 | check( |
558 | r#" | 558 | r#" |
559 | struct Foo { | 559 | struct Foo { |
560 | <|> | 560 | $0 |
561 | pub f: i32, | 561 | pub f: i32, |
562 | } | 562 | } |
563 | "#, | 563 | "#, |
@@ -578,7 +578,7 @@ struct Foo { | |||
578 | } | 578 | } |
579 | fn foo() { | 579 | fn foo() { |
580 | Foo { | 580 | Foo { |
581 | <|> | 581 | $0 |
582 | } | 582 | } |
583 | } | 583 | } |
584 | "#, | 584 | "#, |
@@ -595,7 +595,7 @@ struct Foo { | |||
595 | } | 595 | } |
596 | fn foo() { | 596 | fn foo() { |
597 | Foo { | 597 | Foo { |
598 | f: <|> | 598 | f: $0 |
599 | } | 599 | } |
600 | } | 600 | } |
601 | "#, | 601 | "#, |
diff --git a/crates/completion/src/completions/macro_in_item_position.rs b/crates/completion/src/completions/macro_in_item_position.rs index 82884a181..2be299ac2 100644 --- a/crates/completion/src/completions/macro_in_item_position.rs +++ b/crates/completion/src/completions/macro_in_item_position.rs | |||
@@ -31,7 +31,7 @@ mod tests { | |||
31 | macro_rules! foo { () => {} } | 31 | macro_rules! foo { () => {} } |
32 | fn foo() {} | 32 | fn foo() {} |
33 | 33 | ||
34 | <|> | 34 | $0 |
35 | "#, | 35 | "#, |
36 | expect![[r#" | 36 | expect![[r#" |
37 | ma foo!(…) macro_rules! foo | 37 | ma foo!(…) macro_rules! foo |
diff --git a/crates/completion/src/completions/mod_.rs b/crates/completion/src/completions/mod_.rs index f77864b77..00e951ca9 100644 --- a/crates/completion/src/completions/mod_.rs +++ b/crates/completion/src/completions/mod_.rs | |||
@@ -1,5 +1,7 @@ | |||
1 | //! Completes mod declarations. | 1 | //! Completes mod declarations. |
2 | 2 | ||
3 | use std::iter; | ||
4 | |||
3 | use hir::{Module, ModuleSource}; | 5 | use hir::{Module, ModuleSource}; |
4 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; | 6 | use ide_db::base_db::{SourceDatabaseExt, VfsPath}; |
5 | use ide_db::RootDatabase; | 7 | use ide_db::RootDatabase; |
@@ -9,12 +11,11 @@ use crate::{CompletionItem, CompletionItemKind}; | |||
9 | 11 | ||
10 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; | 12 | use crate::{context::CompletionContext, item::CompletionKind, Completions}; |
11 | 13 | ||
12 | /// Complete mod declaration, i.e. `mod <|> ;` | 14 | /// Complete mod declaration, i.e. `mod $0 ;` |
13 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 15 | pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { |
14 | let mod_under_caret = match &ctx.mod_declaration_under_caret { | 16 | let mod_under_caret = match &ctx.mod_declaration_under_caret { |
15 | Some(mod_under_caret) if mod_under_caret.item_list().is_some() => return None, | 17 | Some(mod_under_caret) if mod_under_caret.item_list().is_none() => mod_under_caret, |
16 | Some(mod_under_caret) => mod_under_caret, | 18 | _ => return None, |
17 | None => return None, | ||
18 | }; | 19 | }; |
19 | 20 | ||
20 | let _p = profile::span("completion::complete_mod"); | 21 | let _p = profile::span("completion::complete_mod"); |
@@ -49,9 +50,13 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
49 | .filter_map(|submodule_file| { | 50 | .filter_map(|submodule_file| { |
50 | let submodule_path = source_root.path_for_file(&submodule_file)?; | 51 | let submodule_path = source_root.path_for_file(&submodule_file)?; |
51 | let directory_with_submodule = submodule_path.parent()?; | 52 | let directory_with_submodule = submodule_path.parent()?; |
52 | match submodule_path.name_and_extension()? { | 53 | let (name, ext) = submodule_path.name_and_extension()?; |
53 | ("lib", Some("rs")) | ("main", Some("rs")) => None, | 54 | if ext != Some("rs") { |
54 | ("mod", Some("rs")) => { | 55 | return None; |
56 | } | ||
57 | match name { | ||
58 | "lib" | "main" => None, | ||
59 | "mod" => { | ||
55 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { | 60 | if directory_with_submodule.parent()? == directory_to_look_for_submodules { |
56 | match directory_with_submodule.name_and_extension()? { | 61 | match directory_with_submodule.name_and_extension()? { |
57 | (directory_name, None) => Some(directory_name.to_owned()), | 62 | (directory_name, None) => Some(directory_name.to_owned()), |
@@ -61,9 +66,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
61 | None | 66 | None |
62 | } | 67 | } |
63 | } | 68 | } |
64 | (file_name, Some("rs")) | 69 | file_name if directory_with_submodule == directory_to_look_for_submodules => { |
65 | if directory_with_submodule == directory_to_look_for_submodules => | ||
66 | { | ||
67 | Some(file_name.to_owned()) | 70 | Some(file_name.to_owned()) |
68 | } | 71 | } |
69 | _ => None, | 72 | _ => None, |
@@ -73,7 +76,7 @@ pub(crate) fn complete_mod(acc: &mut Completions, ctx: &CompletionContext) -> Op | |||
73 | .for_each(|submodule_name| { | 76 | .for_each(|submodule_name| { |
74 | let mut label = submodule_name; | 77 | let mut label = submodule_name; |
75 | if mod_under_caret.semicolon_token().is_none() { | 78 | if mod_under_caret.semicolon_token().is_none() { |
76 | label.push(';') | 79 | label.push(';'); |
77 | } | 80 | } |
78 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) | 81 | CompletionItem::new(CompletionKind::Magic, ctx.source_range(), &label) |
79 | .kind(CompletionItemKind::Module) | 82 | .kind(CompletionItemKind::Module) |
@@ -89,11 +92,13 @@ fn directory_to_look_for_submodules( | |||
89 | module_file_path: &VfsPath, | 92 | module_file_path: &VfsPath, |
90 | ) -> Option<VfsPath> { | 93 | ) -> Option<VfsPath> { |
91 | let directory_with_module_path = module_file_path.parent()?; | 94 | let directory_with_module_path = module_file_path.parent()?; |
92 | let base_directory = match module_file_path.name_and_extension()? { | 95 | let (name, ext) = module_file_path.name_and_extension()?; |
93 | ("mod", Some("rs")) | ("lib", Some("rs")) | ("main", Some("rs")) => { | 96 | if ext != Some("rs") { |
94 | Some(directory_with_module_path) | 97 | return None; |
95 | } | 98 | } |
96 | (regular_rust_file_name, Some("rs")) => { | 99 | let base_directory = match name { |
100 | "mod" | "lib" | "main" => Some(directory_with_module_path), | ||
101 | regular_rust_file_name => { | ||
97 | if matches!( | 102 | if matches!( |
98 | ( | 103 | ( |
99 | directory_with_module_path | 104 | directory_with_module_path |
@@ -110,37 +115,25 @@ fn directory_to_look_for_submodules( | |||
110 | directory_with_module_path.join(regular_rust_file_name) | 115 | directory_with_module_path.join(regular_rust_file_name) |
111 | } | 116 | } |
112 | } | 117 | } |
113 | _ => None, | ||
114 | }?; | 118 | }?; |
115 | 119 | ||
116 | let mut resulting_path = base_directory; | 120 | module_chain_to_containing_module_file(module, db) |
117 | for module in module_chain_to_containing_module_file(module, db) { | 121 | .into_iter() |
118 | if let Some(name) = module.name(db) { | 122 | .filter_map(|module| module.name(db)) |
119 | resulting_path = resulting_path.join(&name.to_string())?; | 123 | .try_fold(base_directory, |path, name| path.join(&name.to_string())) |
120 | } | ||
121 | } | ||
122 | |||
123 | Some(resulting_path) | ||
124 | } | 124 | } |
125 | 125 | ||
126 | fn module_chain_to_containing_module_file( | 126 | fn module_chain_to_containing_module_file( |
127 | current_module: Module, | 127 | current_module: Module, |
128 | db: &RootDatabase, | 128 | db: &RootDatabase, |
129 | ) -> Vec<Module> { | 129 | ) -> Vec<Module> { |
130 | let mut path = Vec::new(); | 130 | let mut path = |
131 | 131 | iter::successors(Some(current_module), |current_module| current_module.parent(db)) | |
132 | let mut current_module = Some(current_module); | 132 | .take_while(|current_module| { |
133 | while let Some(ModuleSource::Module(_)) = | 133 | matches!(current_module.definition_source(db).value, ModuleSource::Module(_)) |
134 | current_module.map(|module| module.definition_source(db).value) | 134 | }) |
135 | { | 135 | .collect::<Vec<_>>(); |
136 | if let Some(module) = current_module { | 136 | path.reverse(); |
137 | path.insert(0, module); | ||
138 | current_module = module.parent(db); | ||
139 | } else { | ||
140 | current_module = None; | ||
141 | } | ||
142 | } | ||
143 | |||
144 | path | 137 | path |
145 | } | 138 | } |
146 | 139 | ||
@@ -159,7 +152,7 @@ mod tests { | |||
159 | check( | 152 | check( |
160 | r#" | 153 | r#" |
161 | //- /lib.rs | 154 | //- /lib.rs |
162 | mod <|> | 155 | mod $0 |
163 | //- /foo.rs | 156 | //- /foo.rs |
164 | fn foo() {} | 157 | fn foo() {} |
165 | //- /foo/ignored_foo.rs | 158 | //- /foo/ignored_foo.rs |
@@ -181,7 +174,7 @@ mod tests { | |||
181 | check( | 174 | check( |
182 | r#" | 175 | r#" |
183 | //- /lib.rs | 176 | //- /lib.rs |
184 | mod <|> { | 177 | mod $0 { |
185 | 178 | ||
186 | } | 179 | } |
187 | //- /foo.rs | 180 | //- /foo.rs |
@@ -196,7 +189,7 @@ mod tests { | |||
196 | check( | 189 | check( |
197 | r#" | 190 | r#" |
198 | //- /main.rs | 191 | //- /main.rs |
199 | mod <|> | 192 | mod $0 |
200 | //- /foo.rs | 193 | //- /foo.rs |
201 | fn foo() {} | 194 | fn foo() {} |
202 | //- /foo/ignored_foo.rs | 195 | //- /foo/ignored_foo.rs |
@@ -219,7 +212,7 @@ mod tests { | |||
219 | r#" | 212 | r#" |
220 | //- /main.rs | 213 | //- /main.rs |
221 | mod tests { | 214 | mod tests { |
222 | mod <|>; | 215 | mod $0; |
223 | } | 216 | } |
224 | //- /tests/foo.rs | 217 | //- /tests/foo.rs |
225 | fn foo() {} | 218 | fn foo() {} |
@@ -237,7 +230,7 @@ mod tests { | |||
237 | //- /lib.rs | 230 | //- /lib.rs |
238 | mod foo; | 231 | mod foo; |
239 | //- /foo.rs | 232 | //- /foo.rs |
240 | mod <|>; | 233 | mod $0; |
241 | //- /foo/bar.rs | 234 | //- /foo/bar.rs |
242 | fn bar() {} | 235 | fn bar() {} |
243 | //- /foo/bar/ignored_bar.rs | 236 | //- /foo/bar/ignored_bar.rs |
@@ -262,7 +255,7 @@ mod tests { | |||
262 | mod foo; | 255 | mod foo; |
263 | //- /foo.rs | 256 | //- /foo.rs |
264 | mod bar { | 257 | mod bar { |
265 | mod <|> | 258 | mod $0 |
266 | } | 259 | } |
267 | //- /foo/bar/baz.rs | 260 | //- /foo/bar/baz.rs |
268 | fn baz() {} | 261 | fn baz() {} |
@@ -288,7 +281,7 @@ mod tests { | |||
288 | // //- /src/bin.rs | 281 | // //- /src/bin.rs |
289 | // fn main() {} | 282 | // fn main() {} |
290 | // //- /src/bin/foo.rs | 283 | // //- /src/bin/foo.rs |
291 | // mod <|> | 284 | // mod $0 |
292 | // //- /src/bin/bar.rs | 285 | // //- /src/bin/bar.rs |
293 | // fn bar() {} | 286 | // fn bar() {} |
294 | // //- /src/bin/bar/bar_ignored.rs | 287 | // //- /src/bin/bar/bar_ignored.rs |
@@ -307,7 +300,7 @@ mod tests { | |||
307 | //- /src/bin.rs crate:main | 300 | //- /src/bin.rs crate:main |
308 | fn main() {} | 301 | fn main() {} |
309 | //- /src/bin/foo.rs | 302 | //- /src/bin/foo.rs |
310 | mod <|> | 303 | mod $0 |
311 | //- /src/bin/bar.rs | 304 | //- /src/bin/bar.rs |
312 | mod foo; | 305 | mod foo; |
313 | fn bar() {} | 306 | fn bar() {} |
diff --git a/crates/completion/src/completions/pattern.rs b/crates/completion/src/completions/pattern.rs index eee31098d..595160ff5 100644 --- a/crates/completion/src/completions/pattern.rs +++ b/crates/completion/src/completions/pattern.rs | |||
@@ -71,7 +71,7 @@ static FOO: E = E::X; | |||
71 | struct Bar { f: u32 } | 71 | struct Bar { f: u32 } |
72 | 72 | ||
73 | fn foo() { | 73 | fn foo() { |
74 | match E::X { <|> } | 74 | match E::X { $0 } |
75 | } | 75 | } |
76 | "#, | 76 | "#, |
77 | expect![[r#" | 77 | expect![[r#" |
@@ -92,7 +92,7 @@ macro_rules! m { ($e:expr) => { $e } } | |||
92 | enum E { X } | 92 | enum E { X } |
93 | 93 | ||
94 | fn foo() { | 94 | fn foo() { |
95 | m!(match E::X { <|> }) | 95 | m!(match E::X { $0 }) |
96 | } | 96 | } |
97 | "#, | 97 | "#, |
98 | expect![[r#" | 98 | expect![[r#" |
@@ -115,7 +115,7 @@ static FOO: E = E::X; | |||
115 | struct Bar { f: u32 } | 115 | struct Bar { f: u32 } |
116 | 116 | ||
117 | fn foo() { | 117 | fn foo() { |
118 | let <|> | 118 | let $0 |
119 | } | 119 | } |
120 | "#, | 120 | "#, |
121 | expect![[r#" | 121 | expect![[r#" |
@@ -133,7 +133,7 @@ enum E { X } | |||
133 | static FOO: E = E::X; | 133 | static FOO: E = E::X; |
134 | struct Bar { f: u32 } | 134 | struct Bar { f: u32 } |
135 | 135 | ||
136 | fn foo(<|>) { | 136 | fn foo($0) { |
137 | } | 137 | } |
138 | "#, | 138 | "#, |
139 | expect![[r#" | 139 | expect![[r#" |
@@ -149,7 +149,7 @@ fn foo(<|>) { | |||
149 | struct Bar { f: u32 } | 149 | struct Bar { f: u32 } |
150 | 150 | ||
151 | fn foo() { | 151 | fn foo() { |
152 | let <|> | 152 | let $0 |
153 | } | 153 | } |
154 | "#, | 154 | "#, |
155 | expect![[r#" | 155 | expect![[r#" |
@@ -165,7 +165,7 @@ fn foo() { | |||
165 | struct Foo { bar: String, baz: String } | 165 | struct Foo { bar: String, baz: String } |
166 | struct Bar(String, String); | 166 | struct Bar(String, String); |
167 | struct Baz; | 167 | struct Baz; |
168 | fn outer(<|>) {} | 168 | fn outer($0) {} |
169 | "#, | 169 | "#, |
170 | expect![[r#" | 170 | expect![[r#" |
171 | bn Foo Foo { bar$1, baz$2 }: Foo$0 | 171 | bn Foo Foo { bar$1, baz$2 }: Foo$0 |
@@ -182,7 +182,7 @@ struct Foo { bar: String, baz: String } | |||
182 | struct Bar(String, String); | 182 | struct Bar(String, String); |
183 | struct Baz; | 183 | struct Baz; |
184 | fn outer() { | 184 | fn outer() { |
185 | let <|> | 185 | let $0 |
186 | } | 186 | } |
187 | "#, | 187 | "#, |
188 | expect![[r#" | 188 | expect![[r#" |
@@ -201,7 +201,7 @@ struct Bar(String, String); | |||
201 | struct Baz; | 201 | struct Baz; |
202 | fn outer() { | 202 | fn outer() { |
203 | match () { | 203 | match () { |
204 | <|> | 204 | $0 |
205 | } | 205 | } |
206 | } | 206 | } |
207 | "#, | 207 | "#, |
@@ -225,7 +225,7 @@ use foo::*; | |||
225 | 225 | ||
226 | fn outer() { | 226 | fn outer() { |
227 | match () { | 227 | match () { |
228 | <|> | 228 | $0 |
229 | } | 229 | } |
230 | } | 230 | } |
231 | "#, | 231 | "#, |
@@ -244,7 +244,7 @@ fn outer() { | |||
244 | struct Foo(i32); | 244 | struct Foo(i32); |
245 | fn main() { | 245 | fn main() { |
246 | match Foo(92) { | 246 | match Foo(92) { |
247 | <|>(92) => (), | 247 | $0(92) => (), |
248 | } | 248 | } |
249 | } | 249 | } |
250 | "#, | 250 | "#, |
diff --git a/crates/completion/src/completions/postfix.rs b/crates/completion/src/completions/postfix.rs index 3883d6d21..87f0c0b2a 100644 --- a/crates/completion/src/completions/postfix.rs +++ b/crates/completion/src/completions/postfix.rs | |||
@@ -1,8 +1,8 @@ | |||
1 | //! Postfix completions, like `Ok(10).ifl<|>` => `if let Ok() = Ok(10) { <|> }`. | 1 | //! Postfix completions, like `Ok(10).ifl$0` => `if let Ok() = Ok(10) { $0 }`. |
2 | 2 | ||
3 | mod format_like; | 3 | mod format_like; |
4 | 4 | ||
5 | use ide_db::ty_filter::TryEnum; | 5 | use ide_db::{helpers::SnippetCap, ty_filter::TryEnum}; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | ast::{self, AstNode, AstToken}, | 7 | ast::{self, AstNode, AstToken}, |
8 | SyntaxKind::{BLOCK_EXPR, EXPR_STMT}, | 8 | SyntaxKind::{BLOCK_EXPR, EXPR_STMT}, |
@@ -10,9 +10,8 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | use text_edit::TextEdit; | 11 | use text_edit::TextEdit; |
12 | 12 | ||
13 | use self::format_like::add_format_like_completions; | ||
14 | use crate::{ | 13 | use crate::{ |
15 | config::SnippetCap, | 14 | completions::postfix::format_like::add_format_like_completions, |
16 | context::CompletionContext, | 15 | context::CompletionContext, |
17 | item::{Builder, CompletionKind}, | 16 | item::{Builder, CompletionKind}, |
18 | CompletionItem, CompletionItemKind, Completions, | 17 | CompletionItem, CompletionItemKind, Completions, |
@@ -311,7 +310,7 @@ mod tests { | |||
311 | r#" | 310 | r#" |
312 | fn main() { | 311 | fn main() { |
313 | let bar = true; | 312 | let bar = true; |
314 | bar.<|> | 313 | bar.$0 |
315 | } | 314 | } |
316 | "#, | 315 | "#, |
317 | expect![[r#" | 316 | expect![[r#" |
@@ -343,7 +342,7 @@ fn foo(elt: bool) -> bool { | |||
343 | 342 | ||
344 | fn main() { | 343 | fn main() { |
345 | let bar = true; | 344 | let bar = true; |
346 | foo(bar.<|>) | 345 | foo(bar.$0) |
347 | } | 346 | } |
348 | "#, | 347 | "#, |
349 | expect![[r#" | 348 | expect![[r#" |
@@ -369,7 +368,7 @@ fn main() { | |||
369 | r#" | 368 | r#" |
370 | fn main() { | 369 | fn main() { |
371 | let bar: u8 = 12; | 370 | let bar: u8 = 12; |
372 | bar.<|> | 371 | bar.$0 |
373 | } | 372 | } |
374 | "#, | 373 | "#, |
375 | expect![[r#" | 374 | expect![[r#" |
@@ -393,7 +392,7 @@ fn main() { | |||
393 | check( | 392 | check( |
394 | r#" | 393 | r#" |
395 | fn main() { | 394 | fn main() { |
396 | baz.l<|> | 395 | baz.l$0 |
397 | res | 396 | res |
398 | } | 397 | } |
399 | "#, | 398 | "#, |
@@ -425,7 +424,7 @@ enum Option<T> { Some(T), None } | |||
425 | 424 | ||
426 | fn main() { | 425 | fn main() { |
427 | let bar = Option::Some(true); | 426 | let bar = Option::Some(true); |
428 | bar.<|> | 427 | bar.$0 |
429 | } | 428 | } |
430 | "#, | 429 | "#, |
431 | r#" | 430 | r#" |
@@ -450,7 +449,7 @@ enum Result<T, E> { Ok(T), Err(E) } | |||
450 | 449 | ||
451 | fn main() { | 450 | fn main() { |
452 | let bar = Result::Ok(true); | 451 | let bar = Result::Ok(true); |
453 | bar.<|> | 452 | bar.$0 |
454 | } | 453 | } |
455 | "#, | 454 | "#, |
456 | r#" | 455 | r#" |
@@ -469,7 +468,7 @@ fn main() { | |||
469 | 468 | ||
470 | #[test] | 469 | #[test] |
471 | fn postfix_completion_works_for_ambiguous_float_literal() { | 470 | fn postfix_completion_works_for_ambiguous_float_literal() { |
472 | check_edit("refm", r#"fn main() { 42.<|> }"#, r#"fn main() { &mut 42 }"#) | 471 | check_edit("refm", r#"fn main() { 42.$0 }"#, r#"fn main() { &mut 42 }"#) |
473 | } | 472 | } |
474 | 473 | ||
475 | #[test] | 474 | #[test] |
@@ -480,7 +479,7 @@ fn main() { | |||
480 | macro_rules! m { ($e:expr) => { $e } } | 479 | macro_rules! m { ($e:expr) => { $e } } |
481 | fn main() { | 480 | fn main() { |
482 | let bar: u8 = 12; | 481 | let bar: u8 = 12; |
483 | m!(bar.d<|>) | 482 | m!(bar.d$0) |
484 | } | 483 | } |
485 | "#, | 484 | "#, |
486 | r#" | 485 | r#" |
@@ -495,55 +494,47 @@ fn main() { | |||
495 | 494 | ||
496 | #[test] | 495 | #[test] |
497 | fn postfix_completion_for_references() { | 496 | fn postfix_completion_for_references() { |
498 | check_edit("dbg", r#"fn main() { &&42.<|> }"#, r#"fn main() { dbg!(&&42) }"#); | 497 | check_edit("dbg", r#"fn main() { &&42.$0 }"#, r#"fn main() { dbg!(&&42) }"#); |
499 | check_edit("refm", r#"fn main() { &&42.<|> }"#, r#"fn main() { &&&mut 42 }"#); | 498 | check_edit("refm", r#"fn main() { &&42.$0 }"#, r#"fn main() { &&&mut 42 }"#); |
500 | } | 499 | } |
501 | 500 | ||
502 | #[test] | 501 | #[test] |
503 | fn postfix_completion_for_format_like_strings() { | 502 | fn postfix_completion_for_format_like_strings() { |
504 | check_edit( | 503 | check_edit( |
505 | "format", | 504 | "format", |
506 | r#"fn main() { "{some_var:?}".<|> }"#, | 505 | r#"fn main() { "{some_var:?}".$0 }"#, |
507 | r#"fn main() { format!("{:?}", some_var) }"#, | 506 | r#"fn main() { format!("{:?}", some_var) }"#, |
508 | ); | 507 | ); |
509 | check_edit( | 508 | check_edit( |
510 | "panic", | 509 | "panic", |
511 | r#"fn main() { "Panic with {a}".<|> }"#, | 510 | r#"fn main() { "Panic with {a}".$0 }"#, |
512 | r#"fn main() { panic!("Panic with {}", a) }"#, | 511 | r#"fn main() { panic!("Panic with {}", a) }"#, |
513 | ); | 512 | ); |
514 | check_edit( | 513 | check_edit( |
515 | "println", | 514 | "println", |
516 | r#"fn main() { "{ 2+2 } { SomeStruct { val: 1, other: 32 } :?}".<|> }"#, | 515 | r#"fn main() { "{ 2+2 } { SomeStruct { val: 1, other: 32 } :?}".$0 }"#, |
517 | r#"fn main() { println!("{} {:?}", 2+2, SomeStruct { val: 1, other: 32 }) }"#, | 516 | r#"fn main() { println!("{} {:?}", 2+2, SomeStruct { val: 1, other: 32 }) }"#, |
518 | ); | 517 | ); |
519 | check_edit( | 518 | check_edit( |
520 | "loge", | 519 | "loge", |
521 | r#"fn main() { "{2+2}".<|> }"#, | 520 | r#"fn main() { "{2+2}".$0 }"#, |
522 | r#"fn main() { log::error!("{}", 2+2) }"#, | 521 | r#"fn main() { log::error!("{}", 2+2) }"#, |
523 | ); | 522 | ); |
524 | check_edit( | 523 | check_edit( |
525 | "logt", | 524 | "logt", |
526 | r#"fn main() { "{2+2}".<|> }"#, | 525 | r#"fn main() { "{2+2}".$0 }"#, |
527 | r#"fn main() { log::trace!("{}", 2+2) }"#, | 526 | r#"fn main() { log::trace!("{}", 2+2) }"#, |
528 | ); | 527 | ); |
529 | check_edit( | 528 | check_edit( |
530 | "logd", | 529 | "logd", |
531 | r#"fn main() { "{2+2}".<|> }"#, | 530 | r#"fn main() { "{2+2}".$0 }"#, |
532 | r#"fn main() { log::debug!("{}", 2+2) }"#, | 531 | r#"fn main() { log::debug!("{}", 2+2) }"#, |
533 | ); | 532 | ); |
534 | check_edit( | 533 | check_edit("logi", r#"fn main() { "{2+2}".$0 }"#, r#"fn main() { log::info!("{}", 2+2) }"#); |
535 | "logi", | 534 | check_edit("logw", r#"fn main() { "{2+2}".$0 }"#, r#"fn main() { log::warn!("{}", 2+2) }"#); |
536 | r#"fn main() { "{2+2}".<|> }"#, | ||
537 | r#"fn main() { log::info!("{}", 2+2) }"#, | ||
538 | ); | ||
539 | check_edit( | ||
540 | "logw", | ||
541 | r#"fn main() { "{2+2}".<|> }"#, | ||
542 | r#"fn main() { log::warn!("{}", 2+2) }"#, | ||
543 | ); | ||
544 | check_edit( | 535 | check_edit( |
545 | "loge", | 536 | "loge", |
546 | r#"fn main() { "{2+2}".<|> }"#, | 537 | r#"fn main() { "{2+2}".$0 }"#, |
547 | r#"fn main() { log::error!("{}", 2+2) }"#, | 538 | r#"fn main() { log::error!("{}", 2+2) }"#, |
548 | ); | 539 | ); |
549 | } | 540 | } |
diff --git a/crates/completion/src/completions/postfix/format_like.rs b/crates/completion/src/completions/postfix/format_like.rs index def4b13fb..3afc63021 100644 --- a/crates/completion/src/completions/postfix/format_like.rs +++ b/crates/completion/src/completions/postfix/format_like.rs | |||
@@ -14,12 +14,11 @@ | |||
14 | // + `logw` -> `log::warn!(...)` | 14 | // + `logw` -> `log::warn!(...)` |
15 | // + `loge` -> `log::error!(...)` | 15 | // + `loge` -> `log::error!(...)` |
16 | 16 | ||
17 | use crate::{ | 17 | use ide_db::helpers::SnippetCap; |
18 | completions::postfix::postfix_snippet, config::SnippetCap, context::CompletionContext, | ||
19 | Completions, | ||
20 | }; | ||
21 | use syntax::ast::{self, AstToken}; | 18 | use syntax::ast::{self, AstToken}; |
22 | 19 | ||
20 | use crate::{completions::postfix::postfix_snippet, context::CompletionContext, Completions}; | ||
21 | |||
23 | /// Mapping ("postfix completion item" => "macro to use") | 22 | /// Mapping ("postfix completion item" => "macro to use") |
24 | static KINDS: &[(&str, &str)] = &[ | 23 | static KINDS: &[(&str, &str)] = &[ |
25 | ("format", "format!"), | 24 | ("format", "format!"), |
diff --git a/crates/completion/src/completions/qualified_path.rs b/crates/completion/src/completions/qualified_path.rs index 882c4dcbc..fa9e6e810 100644 --- a/crates/completion/src/completions/qualified_path.rs +++ b/crates/completion/src/completions/qualified_path.rs | |||
@@ -1,4 +1,4 @@ | |||
1 | //! Completion of paths, i.e. `some::prefix::<|>`. | 1 | //! Completion of paths, i.e. `some::prefix::$0`. |
2 | 2 | ||
3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; | 3 | use hir::{Adt, HasVisibility, PathResolution, ScopeDef}; |
4 | use rustc_hash::FxHashSet; | 4 | use rustc_hash::FxHashSet; |
@@ -38,7 +38,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon | |||
38 | if let ScopeDef::Unknown = def { | 38 | if let ScopeDef::Unknown = def { |
39 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { | 39 | if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { |
40 | if name_ref.syntax().text() == name.to_string().as_str() { | 40 | if name_ref.syntax().text() == name.to_string().as_str() { |
41 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 41 | // for `use self::foo$0`, don't suggest `foo` as a completion |
42 | mark::hit!(dont_complete_current_use); | 42 | mark::hit!(dont_complete_current_use); |
43 | continue; | 43 | continue; |
44 | } | 44 | } |
@@ -173,7 +173,7 @@ mod tests { | |||
173 | #[test] | 173 | #[test] |
174 | fn dont_complete_current_use() { | 174 | fn dont_complete_current_use() { |
175 | mark::check!(dont_complete_current_use); | 175 | mark::check!(dont_complete_current_use); |
176 | check(r#"use self::foo<|>;"#, expect![[""]]); | 176 | check(r#"use self::foo$0;"#, expect![[""]]); |
177 | } | 177 | } |
178 | 178 | ||
179 | #[test] | 179 | #[test] |
@@ -181,7 +181,7 @@ mod tests { | |||
181 | check( | 181 | check( |
182 | r#" | 182 | r#" |
183 | mod foo { pub struct S; } | 183 | mod foo { pub struct S; } |
184 | use self::{foo::*, bar<|>}; | 184 | use self::{foo::*, bar$0}; |
185 | "#, | 185 | "#, |
186 | expect![[r#" | 186 | expect![[r#" |
187 | st S | 187 | st S |
@@ -192,18 +192,18 @@ use self::{foo::*, bar<|>}; | |||
192 | 192 | ||
193 | #[test] | 193 | #[test] |
194 | fn dont_complete_primitive_in_use() { | 194 | fn dont_complete_primitive_in_use() { |
195 | check_builtin(r#"use self::<|>;"#, expect![[""]]); | 195 | check_builtin(r#"use self::$0;"#, expect![[""]]); |
196 | } | 196 | } |
197 | 197 | ||
198 | #[test] | 198 | #[test] |
199 | fn dont_complete_primitive_in_module_scope() { | 199 | fn dont_complete_primitive_in_module_scope() { |
200 | check_builtin(r#"fn foo() { self::<|> }"#, expect![[""]]); | 200 | check_builtin(r#"fn foo() { self::$0 }"#, expect![[""]]); |
201 | } | 201 | } |
202 | 202 | ||
203 | #[test] | 203 | #[test] |
204 | fn completes_primitives() { | 204 | fn completes_primitives() { |
205 | check_builtin( | 205 | check_builtin( |
206 | r#"fn main() { let _: <|> = 92; }"#, | 206 | r#"fn main() { let _: $0 = 92; }"#, |
207 | expect![[r#" | 207 | expect![[r#" |
208 | bt u32 | 208 | bt u32 |
209 | bt bool | 209 | bt bool |
@@ -230,7 +230,7 @@ use self::{foo::*, bar<|>}; | |||
230 | fn completes_mod_with_same_name_as_function() { | 230 | fn completes_mod_with_same_name_as_function() { |
231 | check( | 231 | check( |
232 | r#" | 232 | r#" |
233 | use self::my::<|>; | 233 | use self::my::$0; |
234 | 234 | ||
235 | mod my { pub struct Bar; } | 235 | mod my { pub struct Bar; } |
236 | fn my() {} | 236 | fn my() {} |
@@ -245,7 +245,7 @@ fn my() {} | |||
245 | fn filters_visibility() { | 245 | fn filters_visibility() { |
246 | check( | 246 | check( |
247 | r#" | 247 | r#" |
248 | use self::my::<|>; | 248 | use self::my::$0; |
249 | 249 | ||
250 | mod my { | 250 | mod my { |
251 | struct Bar; | 251 | struct Bar; |
@@ -264,7 +264,7 @@ mod my { | |||
264 | fn completes_use_item_starting_with_self() { | 264 | fn completes_use_item_starting_with_self() { |
265 | check( | 265 | check( |
266 | r#" | 266 | r#" |
267 | use self::m::<|>; | 267 | use self::m::$0; |
268 | 268 | ||
269 | mod m { pub struct Bar; } | 269 | mod m { pub struct Bar; } |
270 | "#, | 270 | "#, |
@@ -282,7 +282,7 @@ mod m { pub struct Bar; } | |||
282 | mod foo; | 282 | mod foo; |
283 | struct Spam; | 283 | struct Spam; |
284 | //- /foo.rs | 284 | //- /foo.rs |
285 | use crate::Sp<|> | 285 | use crate::Sp$0 |
286 | "#, | 286 | "#, |
287 | expect![[r#" | 287 | expect![[r#" |
288 | md foo | 288 | md foo |
@@ -299,7 +299,7 @@ use crate::Sp<|> | |||
299 | mod foo; | 299 | mod foo; |
300 | struct Spam; | 300 | struct Spam; |
301 | //- /foo.rs | 301 | //- /foo.rs |
302 | use crate::{Sp<|>}; | 302 | use crate::{Sp$0}; |
303 | "#, | 303 | "#, |
304 | expect![[r#" | 304 | expect![[r#" |
305 | md foo | 305 | md foo |
@@ -320,7 +320,7 @@ pub mod bar { | |||
320 | } | 320 | } |
321 | } | 321 | } |
322 | //- /foo.rs | 322 | //- /foo.rs |
323 | use crate::{bar::{baz::Sp<|>}}; | 323 | use crate::{bar::{baz::Sp$0}}; |
324 | "#, | 324 | "#, |
325 | expect![[r#" | 325 | expect![[r#" |
326 | st Spam | 326 | st Spam |
@@ -333,7 +333,7 @@ use crate::{bar::{baz::Sp<|>}}; | |||
333 | check( | 333 | check( |
334 | r#" | 334 | r#" |
335 | enum E { Foo, Bar(i32) } | 335 | enum E { Foo, Bar(i32) } |
336 | fn foo() { let _ = E::<|> } | 336 | fn foo() { let _ = E::$0 } |
337 | "#, | 337 | "#, |
338 | expect![[r#" | 338 | expect![[r#" |
339 | ev Foo () | 339 | ev Foo () |
@@ -356,7 +356,7 @@ impl S { | |||
356 | type T = i32; | 356 | type T = i32; |
357 | } | 357 | } |
358 | 358 | ||
359 | fn foo() { let _ = S::<|> } | 359 | fn foo() { let _ = S::$0 } |
360 | "#, | 360 | "#, |
361 | expect![[r#" | 361 | expect![[r#" |
362 | fn a() fn a() | 362 | fn a() fn a() |
@@ -384,7 +384,7 @@ mod m { | |||
384 | } | 384 | } |
385 | } | 385 | } |
386 | 386 | ||
387 | fn foo() { let _ = S::<|> } | 387 | fn foo() { let _ = S::$0 } |
388 | "#, | 388 | "#, |
389 | expect![[r#" | 389 | expect![[r#" |
390 | fn public_method() pub(crate) fn public_method() | 390 | fn public_method() pub(crate) fn public_method() |
@@ -401,7 +401,7 @@ fn foo() { let _ = S::<|> } | |||
401 | enum E {}; | 401 | enum E {}; |
402 | impl E { fn m() { } } | 402 | impl E { fn m() { } } |
403 | 403 | ||
404 | fn foo() { let _ = E::<|> } | 404 | fn foo() { let _ = E::$0 } |
405 | "#, | 405 | "#, |
406 | expect![[r#" | 406 | expect![[r#" |
407 | fn m() fn m() | 407 | fn m() fn m() |
@@ -416,7 +416,7 @@ fn foo() { let _ = E::<|> } | |||
416 | union U {}; | 416 | union U {}; |
417 | impl U { fn m() { } } | 417 | impl U { fn m() { } } |
418 | 418 | ||
419 | fn foo() { let _ = U::<|> } | 419 | fn foo() { let _ = U::$0 } |
420 | "#, | 420 | "#, |
421 | expect![[r#" | 421 | expect![[r#" |
422 | fn m() fn m() | 422 | fn m() fn m() |
@@ -429,7 +429,7 @@ fn foo() { let _ = U::<|> } | |||
429 | check( | 429 | check( |
430 | r#" | 430 | r#" |
431 | //- /main.rs crate:main deps:foo | 431 | //- /main.rs crate:main deps:foo |
432 | use foo::<|>; | 432 | use foo::$0; |
433 | 433 | ||
434 | //- /foo/lib.rs crate:foo | 434 | //- /foo/lib.rs crate:foo |
435 | pub mod bar { pub struct S; } | 435 | pub mod bar { pub struct S; } |
@@ -446,7 +446,7 @@ pub mod bar { pub struct S; } | |||
446 | r#" | 446 | r#" |
447 | trait Trait { fn m(); } | 447 | trait Trait { fn m(); } |
448 | 448 | ||
449 | fn foo() { let _ = Trait::<|> } | 449 | fn foo() { let _ = Trait::$0 } |
450 | "#, | 450 | "#, |
451 | expect![[r#" | 451 | expect![[r#" |
452 | fn m() fn m() | 452 | fn m() fn m() |
@@ -463,7 +463,7 @@ trait Trait { fn m(); } | |||
463 | struct S; | 463 | struct S; |
464 | impl Trait for S {} | 464 | impl Trait for S {} |
465 | 465 | ||
466 | fn foo() { let _ = S::<|> } | 466 | fn foo() { let _ = S::$0 } |
467 | "#, | 467 | "#, |
468 | expect![[r#" | 468 | expect![[r#" |
469 | fn m() fn m() | 469 | fn m() fn m() |
@@ -480,7 +480,7 @@ trait Trait { fn m(); } | |||
480 | struct S; | 480 | struct S; |
481 | impl Trait for S {} | 481 | impl Trait for S {} |
482 | 482 | ||
483 | fn foo() { let _ = <S as Trait>::<|> } | 483 | fn foo() { let _ = <S as Trait>::$0 } |
484 | "#, | 484 | "#, |
485 | expect![[r#" | 485 | expect![[r#" |
486 | fn m() fn m() | 486 | fn m() fn m() |
@@ -506,7 +506,7 @@ trait Sub: Super { | |||
506 | fn submethod(&self) {} | 506 | fn submethod(&self) {} |
507 | } | 507 | } |
508 | 508 | ||
509 | fn foo<T: Sub>() { T::<|> } | 509 | fn foo<T: Sub>() { T::$0 } |
510 | "#, | 510 | "#, |
511 | expect![[r#" | 511 | expect![[r#" |
512 | ta SubTy type SubTy; | 512 | ta SubTy type SubTy; |
@@ -544,7 +544,7 @@ impl<T> Super for Wrap<T> {} | |||
544 | impl<T> Sub for Wrap<T> { | 544 | impl<T> Sub for Wrap<T> { |
545 | fn subfunc() { | 545 | fn subfunc() { |
546 | // Should be able to assume `Self: Sub + Super` | 546 | // Should be able to assume `Self: Sub + Super` |
547 | Self::<|> | 547 | Self::$0 |
548 | } | 548 | } |
549 | } | 549 | } |
550 | "#, | 550 | "#, |
@@ -570,7 +570,7 @@ impl S { fn foo() {} } | |||
570 | type T = S; | 570 | type T = S; |
571 | impl T { fn bar() {} } | 571 | impl T { fn bar() {} } |
572 | 572 | ||
573 | fn main() { T::<|>; } | 573 | fn main() { T::$0; } |
574 | "#, | 574 | "#, |
575 | expect![[r#" | 575 | expect![[r#" |
576 | fn foo() fn foo() | 576 | fn foo() fn foo() |
@@ -586,7 +586,7 @@ fn main() { T::<|>; } | |||
586 | #[macro_export] | 586 | #[macro_export] |
587 | macro_rules! foo { () => {} } | 587 | macro_rules! foo { () => {} } |
588 | 588 | ||
589 | fn main() { let _ = crate::<|> } | 589 | fn main() { let _ = crate::$0 } |
590 | "#, | 590 | "#, |
591 | expect![[r##" | 591 | expect![[r##" |
592 | fn main() fn main() | 592 | fn main() fn main() |
@@ -604,7 +604,7 @@ mod a { | |||
604 | const A: usize = 0; | 604 | const A: usize = 0; |
605 | mod b { | 605 | mod b { |
606 | const B: usize = 0; | 606 | const B: usize = 0; |
607 | mod c { use super::super::<|> } | 607 | mod c { use super::super::$0 } |
608 | } | 608 | } |
609 | } | 609 | } |
610 | "#, | 610 | "#, |
@@ -619,7 +619,7 @@ mod a { | |||
619 | fn completes_reexported_items_under_correct_name() { | 619 | fn completes_reexported_items_under_correct_name() { |
620 | check( | 620 | check( |
621 | r#" | 621 | r#" |
622 | fn foo() { self::m::<|> } | 622 | fn foo() { self::m::$0 } |
623 | 623 | ||
624 | mod m { | 624 | mod m { |
625 | pub use super::p::wrong_fn as right_fn; | 625 | pub use super::p::wrong_fn as right_fn; |
@@ -642,7 +642,7 @@ mod p { | |||
642 | check_edit( | 642 | check_edit( |
643 | "RightType", | 643 | "RightType", |
644 | r#" | 644 | r#" |
645 | fn foo() { self::m::<|> } | 645 | fn foo() { self::m::$0 } |
646 | 646 | ||
647 | mod m { | 647 | mod m { |
648 | pub use super::p::wrong_fn as right_fn; | 648 | pub use super::p::wrong_fn as right_fn; |
@@ -677,7 +677,7 @@ mod p { | |||
677 | check( | 677 | check( |
678 | r#" | 678 | r#" |
679 | macro_rules! m { ($e:expr) => { $e } } | 679 | macro_rules! m { ($e:expr) => { $e } } |
680 | fn main() { m!(self::f<|>); } | 680 | fn main() { m!(self::f$0); } |
681 | fn foo() {} | 681 | fn foo() {} |
682 | "#, | 682 | "#, |
683 | expect![[r#" | 683 | expect![[r#" |
@@ -691,7 +691,7 @@ fn foo() {} | |||
691 | fn function_mod_share_name() { | 691 | fn function_mod_share_name() { |
692 | check( | 692 | check( |
693 | r#" | 693 | r#" |
694 | fn foo() { self::m::<|> } | 694 | fn foo() { self::m::$0 } |
695 | 695 | ||
696 | mod m { | 696 | mod m { |
697 | pub mod z {} | 697 | pub mod z {} |
@@ -716,7 +716,7 @@ impl<K, V> HashMap<K, V, RandomState> { | |||
716 | pub fn new() -> HashMap<K, V, RandomState> { } | 716 | pub fn new() -> HashMap<K, V, RandomState> { } |
717 | } | 717 | } |
718 | fn foo() { | 718 | fn foo() { |
719 | HashMap::<|> | 719 | HashMap::$0 |
720 | } | 720 | } |
721 | "#, | 721 | "#, |
722 | expect![[r#" | 722 | expect![[r#" |
@@ -730,7 +730,7 @@ fn foo() { | |||
730 | check( | 730 | check( |
731 | r#" | 731 | r#" |
732 | mod foo { pub struct Foo; } | 732 | mod foo { pub struct Foo; } |
733 | #[foo::<|>] | 733 | #[foo::$0] |
734 | fn f() {} | 734 | fn f() {} |
735 | "#, | 735 | "#, |
736 | expect![[""]], | 736 | expect![[""]], |
@@ -749,7 +749,7 @@ fn foo( | |||
749 | } | 749 | } |
750 | 750 | ||
751 | fn main() { | 751 | fn main() { |
752 | fo<|> | 752 | fo$0 |
753 | } | 753 | } |
754 | "#, | 754 | "#, |
755 | expect![[r#" | 755 | expect![[r#" |
@@ -770,7 +770,7 @@ enum Foo { | |||
770 | 770 | ||
771 | impl Foo { | 771 | impl Foo { |
772 | fn foo(self) { | 772 | fn foo(self) { |
773 | Self::<|> | 773 | Self::$0 |
774 | } | 774 | } |
775 | } | 775 | } |
776 | "#, | 776 | "#, |
diff --git a/crates/completion/src/completions/record.rs b/crates/completion/src/completions/record.rs index e58b9a274..bb6354ded 100644 --- a/crates/completion/src/completions/record.rs +++ b/crates/completion/src/completions/record.rs | |||
@@ -99,7 +99,7 @@ impl core::default::Default for S { | |||
99 | fn process(f: S) { | 99 | fn process(f: S) { |
100 | let other = S { | 100 | let other = S { |
101 | foo: 5, | 101 | foo: 5, |
102 | .<|> | 102 | .$0 |
103 | }; | 103 | }; |
104 | } | 104 | } |
105 | "#; | 105 | "#; |
@@ -139,7 +139,7 @@ impl core::default::Default for S { | |||
139 | fn process(f: S) { | 139 | fn process(f: S) { |
140 | let other = S { | 140 | let other = S { |
141 | foo: 5, | 141 | foo: 5, |
142 | .<|> | 142 | .$0 |
143 | }; | 143 | }; |
144 | } | 144 | } |
145 | "#, | 145 | "#, |
@@ -173,7 +173,7 @@ struct S { foo: u32, bar: usize } | |||
173 | fn process(f: S) { | 173 | fn process(f: S) { |
174 | let other = S { | 174 | let other = S { |
175 | foo: 5, | 175 | foo: 5, |
176 | .<|> | 176 | .$0 |
177 | }; | 177 | }; |
178 | } | 178 | } |
179 | "#; | 179 | "#; |
@@ -201,7 +201,7 @@ struct S { foo: u32 } | |||
201 | 201 | ||
202 | fn process(f: S) { | 202 | fn process(f: S) { |
203 | match f { | 203 | match f { |
204 | S { f<|>: 92 } => (), | 204 | S { f$0: 92 } => (), |
205 | } | 205 | } |
206 | } | 206 | } |
207 | "#, | 207 | "#, |
@@ -219,7 +219,7 @@ enum E { S { foo: u32, bar: () } } | |||
219 | 219 | ||
220 | fn process(e: E) { | 220 | fn process(e: E) { |
221 | match e { | 221 | match e { |
222 | E::S { <|> } => (), | 222 | E::S { $0 } => (), |
223 | } | 223 | } |
224 | } | 224 | } |
225 | "#, | 225 | "#, |
@@ -239,7 +239,7 @@ struct S { foo: u32 } | |||
239 | 239 | ||
240 | fn process(f: S) { | 240 | fn process(f: S) { |
241 | m!(match f { | 241 | m!(match f { |
242 | S { f<|>: 92 } => (), | 242 | S { f$0: 92 } => (), |
243 | }) | 243 | }) |
244 | } | 244 | } |
245 | ", | 245 | ", |
@@ -263,7 +263,7 @@ fn main() { | |||
263 | foo1: 1, foo2: 2, | 263 | foo1: 1, foo2: 2, |
264 | bar: 3, baz: 4, | 264 | bar: 3, baz: 4, |
265 | }; | 265 | }; |
266 | if let S { foo1, foo2: a, <|> } = s {} | 266 | if let S { foo1, foo2: a, $0 } = s {} |
267 | } | 267 | } |
268 | "#, | 268 | "#, |
269 | expect![[r#" | 269 | expect![[r#" |
@@ -279,7 +279,7 @@ fn main() { | |||
279 | r#" | 279 | r#" |
280 | struct A { the_field: u32 } | 280 | struct A { the_field: u32 } |
281 | fn foo() { | 281 | fn foo() { |
282 | A { the<|> } | 282 | A { the$0 } |
283 | } | 283 | } |
284 | "#, | 284 | "#, |
285 | expect![[r#" | 285 | expect![[r#" |
@@ -294,7 +294,7 @@ fn foo() { | |||
294 | r#" | 294 | r#" |
295 | enum E { A { a: u32 } } | 295 | enum E { A { a: u32 } } |
296 | fn foo() { | 296 | fn foo() { |
297 | let _ = E::A { <|> } | 297 | let _ = E::A { $0 } |
298 | } | 298 | } |
299 | "#, | 299 | "#, |
300 | expect![[r#" | 300 | expect![[r#" |
@@ -311,7 +311,7 @@ struct A { a: u32 } | |||
311 | struct B { b: u32 } | 311 | struct B { b: u32 } |
312 | 312 | ||
313 | fn foo() { | 313 | fn foo() { |
314 | let _: A = B { <|> } | 314 | let _: A = B { $0 } |
315 | } | 315 | } |
316 | "#, | 316 | "#, |
317 | expect![[r#" | 317 | expect![[r#" |
@@ -327,7 +327,7 @@ fn foo() { | |||
327 | struct A<T> { a: T } | 327 | struct A<T> { a: T } |
328 | 328 | ||
329 | fn foo() { | 329 | fn foo() { |
330 | let _: A<u32> = A { <|> } | 330 | let _: A<u32> = A { $0 } |
331 | } | 331 | } |
332 | "#, | 332 | "#, |
333 | expect![[r#" | 333 | expect![[r#" |
@@ -343,7 +343,7 @@ fn foo() { | |||
343 | macro_rules! m { ($e:expr) => { $e } } | 343 | macro_rules! m { ($e:expr) => { $e } } |
344 | struct A { the_field: u32 } | 344 | struct A { the_field: u32 } |
345 | fn foo() { | 345 | fn foo() { |
346 | m!(A { the<|> }) | 346 | m!(A { the$0 }) |
347 | } | 347 | } |
348 | "#, | 348 | "#, |
349 | expect![[r#" | 349 | expect![[r#" |
@@ -363,7 +363,7 @@ struct S { | |||
363 | 363 | ||
364 | fn main() { | 364 | fn main() { |
365 | let foo1 = 1; | 365 | let foo1 = 1; |
366 | let s = S { foo1, foo2: 5, <|> } | 366 | let s = S { foo1, foo2: 5, $0 } |
367 | } | 367 | } |
368 | "#, | 368 | "#, |
369 | expect![[r#" | 369 | expect![[r#" |
@@ -381,7 +381,7 @@ struct S { foo1: u32, foo2: u32 } | |||
381 | 381 | ||
382 | fn main() { | 382 | fn main() { |
383 | let foo1 = 1; | 383 | let foo1 = 1; |
384 | let s = S { foo1, <|> .. loop {} } | 384 | let s = S { foo1, $0 .. loop {} } |
385 | } | 385 | } |
386 | "#, | 386 | "#, |
387 | expect![[r#" | 387 | expect![[r#" |
diff --git a/crates/completion/src/completions/snippet.rs b/crates/completion/src/completions/snippet.rs index 842590130..df17a15c5 100644 --- a/crates/completion/src/completions/snippet.rs +++ b/crates/completion/src/completions/snippet.rs | |||
@@ -1,8 +1,10 @@ | |||
1 | //! This file provides snippet completions, like `pd` => `eprintln!(...)`. | 1 | //! This file provides snippet completions, like `pd` => `eprintln!(...)`. |
2 | 2 | ||
3 | use ide_db::helpers::SnippetCap; | ||
4 | |||
3 | use crate::{ | 5 | use crate::{ |
4 | config::SnippetCap, item::Builder, CompletionContext, CompletionItem, CompletionItemKind, | 6 | item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, |
5 | CompletionKind, Completions, | 7 | Completions, |
6 | }; | 8 | }; |
7 | 9 | ||
8 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { | 10 | fn snippet(ctx: &CompletionContext, cap: SnippetCap, label: &str, snippet: &str) -> Builder { |
@@ -81,7 +83,7 @@ mod tests { | |||
81 | #[test] | 83 | #[test] |
82 | fn completes_snippets_in_expressions() { | 84 | fn completes_snippets_in_expressions() { |
83 | check( | 85 | check( |
84 | r#"fn foo(x: i32) { <|> }"#, | 86 | r#"fn foo(x: i32) { $0 }"#, |
85 | expect![[r#" | 87 | expect![[r#" |
86 | sn pd | 88 | sn pd |
87 | sn ppd | 89 | sn ppd |
@@ -91,8 +93,8 @@ mod tests { | |||
91 | 93 | ||
92 | #[test] | 94 | #[test] |
93 | fn should_not_complete_snippets_in_path() { | 95 | fn should_not_complete_snippets_in_path() { |
94 | check(r#"fn foo(x: i32) { ::foo<|> }"#, expect![[""]]); | 96 | check(r#"fn foo(x: i32) { ::foo$0 }"#, expect![[""]]); |
95 | check(r#"fn foo(x: i32) { ::<|> }"#, expect![[""]]); | 97 | check(r#"fn foo(x: i32) { ::$0 }"#, expect![[""]]); |
96 | } | 98 | } |
97 | 99 | ||
98 | #[test] | 100 | #[test] |
@@ -101,7 +103,7 @@ mod tests { | |||
101 | r#" | 103 | r#" |
102 | #[cfg(test)] | 104 | #[cfg(test)] |
103 | mod tests { | 105 | mod tests { |
104 | <|> | 106 | $0 |
105 | } | 107 | } |
106 | "#, | 108 | "#, |
107 | expect![[r#" | 109 | expect![[r#" |
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs index 54bb897e9..aa9c845da 100644 --- a/crates/completion/src/completions/trait_impl.rs +++ b/crates/completion/src/completions/trait_impl.rs | |||
@@ -15,7 +15,7 @@ | |||
15 | //! } | 15 | //! } |
16 | //! | 16 | //! |
17 | //! impl SomeTrait for () { | 17 | //! impl SomeTrait for () { |
18 | //! fn f<|> | 18 | //! fn f$0 |
19 | //! } | 19 | //! } |
20 | //! ``` | 20 | //! ``` |
21 | //! | 21 | //! |
@@ -27,7 +27,7 @@ | |||
27 | //! # } | 27 | //! # } |
28 | //! | 28 | //! |
29 | //! impl SomeTrait for () { | 29 | //! impl SomeTrait for () { |
30 | //! fn foo() {}<|> | 30 | //! fn foo() {}$0 |
31 | //! } | 31 | //! } |
32 | //! ``` | 32 | //! ``` |
33 | 33 | ||
@@ -82,7 +82,7 @@ pub(crate) fn complete_trait_impl(acc: &mut Completions, ctx: &CompletionContext | |||
82 | 82 | ||
83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { | 83 | fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, SyntaxNode, Impl)> { |
84 | let mut token = ctx.token.clone(); | 84 | let mut token = ctx.token.clone(); |
85 | // For keywork without name like `impl .. { fn <|> }`, the current position is inside | 85 | // For keywork without name like `impl .. { fn $0 }`, the current position is inside |
86 | // the whitespace token, which is outside `FN` syntax node. | 86 | // the whitespace token, which is outside `FN` syntax node. |
87 | // We need to follow the previous token in this case. | 87 | // We need to follow the previous token in this case. |
88 | if token.kind() == SyntaxKind::WHITESPACE { | 88 | if token.kind() == SyntaxKind::WHITESPACE { |
@@ -90,20 +90,20 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
90 | } | 90 | } |
91 | 91 | ||
92 | let impl_item_offset = match token.kind() { | 92 | let impl_item_offset = match token.kind() { |
93 | // `impl .. { const <|> }` | 93 | // `impl .. { const $0 }` |
94 | // ERROR 0 | 94 | // ERROR 0 |
95 | // CONST_KW <- * | 95 | // CONST_KW <- * |
96 | SyntaxKind::CONST_KW => 0, | 96 | SyntaxKind::CONST_KW => 0, |
97 | // `impl .. { fn/type <|> }` | 97 | // `impl .. { fn/type $0 }` |
98 | // FN/TYPE_ALIAS 0 | 98 | // FN/TYPE_ALIAS 0 |
99 | // FN_KW <- * | 99 | // FN_KW <- * |
100 | SyntaxKind::FN_KW | SyntaxKind::TYPE_KW => 0, | 100 | SyntaxKind::FN_KW | SyntaxKind::TYPE_KW => 0, |
101 | // `impl .. { fn/type/const foo<|> }` | 101 | // `impl .. { fn/type/const foo$0 }` |
102 | // FN/TYPE_ALIAS/CONST 1 | 102 | // FN/TYPE_ALIAS/CONST 1 |
103 | // NAME 0 | 103 | // NAME 0 |
104 | // IDENT <- * | 104 | // IDENT <- * |
105 | SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1, | 105 | SyntaxKind::IDENT if token.parent().kind() == SyntaxKind::NAME => 1, |
106 | // `impl .. { foo<|> }` | 106 | // `impl .. { foo$0 }` |
107 | // MACRO_CALL 3 | 107 | // MACRO_CALL 3 |
108 | // PATH 2 | 108 | // PATH 2 |
109 | // PATH_SEGMENT 1 | 109 | // PATH_SEGMENT 1 |
@@ -120,7 +120,7 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
120 | // <item> | 120 | // <item> |
121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; | 121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; |
122 | let kind = match impl_item.kind() { | 122 | let kind = match impl_item.kind() { |
123 | // `impl ... { const <|> fn/type/const }` | 123 | // `impl ... { const $0 fn/type/const }` |
124 | _ if token.kind() == SyntaxKind::CONST_KW => ImplCompletionKind::Const, | 124 | _ if token.kind() == SyntaxKind::CONST_KW => ImplCompletionKind::Const, |
125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, | 125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, |
126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, | 126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, |
@@ -267,7 +267,7 @@ trait Test { | |||
267 | struct T; | 267 | struct T; |
268 | 268 | ||
269 | impl Test for T { | 269 | impl Test for T { |
270 | t<|> | 270 | t$0 |
271 | } | 271 | } |
272 | "#, | 272 | "#, |
273 | expect![[" | 273 | expect![[" |
@@ -287,7 +287,7 @@ struct T; | |||
287 | 287 | ||
288 | impl Test for T { | 288 | impl Test for T { |
289 | fn test() { | 289 | fn test() { |
290 | t<|> | 290 | t$0 |
291 | } | 291 | } |
292 | } | 292 | } |
293 | ", | 293 | ", |
@@ -301,7 +301,7 @@ struct T; | |||
301 | 301 | ||
302 | impl Test for T { | 302 | impl Test for T { |
303 | fn test() { | 303 | fn test() { |
304 | fn t<|> | 304 | fn t$0 |
305 | } | 305 | } |
306 | } | 306 | } |
307 | ", | 307 | ", |
@@ -315,7 +315,7 @@ struct T; | |||
315 | 315 | ||
316 | impl Test for T { | 316 | impl Test for T { |
317 | fn test() { | 317 | fn test() { |
318 | fn <|> | 318 | fn $0 |
319 | } | 319 | } |
320 | } | 320 | } |
321 | ", | 321 | ", |
@@ -330,7 +330,7 @@ struct T; | |||
330 | 330 | ||
331 | impl Test for T { | 331 | impl Test for T { |
332 | fn test() { | 332 | fn test() { |
333 | foo.<|> | 333 | foo.$0 |
334 | } | 334 | } |
335 | } | 335 | } |
336 | ", | 336 | ", |
@@ -343,7 +343,7 @@ trait Test { fn test(_: i32); fn test2(); } | |||
343 | struct T; | 343 | struct T; |
344 | 344 | ||
345 | impl Test for T { | 345 | impl Test for T { |
346 | fn test(t<|>) | 346 | fn test(t$0) |
347 | } | 347 | } |
348 | ", | 348 | ", |
349 | expect![[""]], | 349 | expect![[""]], |
@@ -355,7 +355,7 @@ trait Test { fn test(_: fn()); fn test2(); } | |||
355 | struct T; | 355 | struct T; |
356 | 356 | ||
357 | impl Test for T { | 357 | impl Test for T { |
358 | fn test(f: fn <|>) | 358 | fn test(f: fn $0) |
359 | } | 359 | } |
360 | ", | 360 | ", |
361 | expect![[""]], | 361 | expect![[""]], |
@@ -370,7 +370,7 @@ trait Test { const TEST: fn(); const TEST2: u32; type Test; fn test(); } | |||
370 | struct T; | 370 | struct T; |
371 | 371 | ||
372 | impl Test for T { | 372 | impl Test for T { |
373 | const TEST: fn <|> | 373 | const TEST: fn $0 |
374 | } | 374 | } |
375 | ", | 375 | ", |
376 | expect![[""]], | 376 | expect![[""]], |
@@ -382,7 +382,7 @@ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); } | |||
382 | struct T; | 382 | struct T; |
383 | 383 | ||
384 | impl Test for T { | 384 | impl Test for T { |
385 | const TEST: T<|> | 385 | const TEST: T$0 |
386 | } | 386 | } |
387 | ", | 387 | ", |
388 | expect![[""]], | 388 | expect![[""]], |
@@ -394,7 +394,7 @@ trait Test { const TEST: u32; const TEST2: u32; type Test; fn test(); } | |||
394 | struct T; | 394 | struct T; |
395 | 395 | ||
396 | impl Test for T { | 396 | impl Test for T { |
397 | const TEST: u32 = f<|> | 397 | const TEST: u32 = f$0 |
398 | } | 398 | } |
399 | ", | 399 | ", |
400 | expect![[""]], | 400 | expect![[""]], |
@@ -407,7 +407,7 @@ struct T; | |||
407 | 407 | ||
408 | impl Test for T { | 408 | impl Test for T { |
409 | const TEST: u32 = { | 409 | const TEST: u32 = { |
410 | t<|> | 410 | t$0 |
411 | }; | 411 | }; |
412 | } | 412 | } |
413 | ", | 413 | ", |
@@ -421,7 +421,7 @@ struct T; | |||
421 | 421 | ||
422 | impl Test for T { | 422 | impl Test for T { |
423 | const TEST: u32 = { | 423 | const TEST: u32 = { |
424 | fn <|> | 424 | fn $0 |
425 | }; | 425 | }; |
426 | } | 426 | } |
427 | ", | 427 | ", |
@@ -435,7 +435,7 @@ struct T; | |||
435 | 435 | ||
436 | impl Test for T { | 436 | impl Test for T { |
437 | const TEST: u32 = { | 437 | const TEST: u32 = { |
438 | fn t<|> | 438 | fn t$0 |
439 | }; | 439 | }; |
440 | } | 440 | } |
441 | ", | 441 | ", |
@@ -451,7 +451,7 @@ trait Test { type Test; type Test2; fn test(); } | |||
451 | struct T; | 451 | struct T; |
452 | 452 | ||
453 | impl Test for T { | 453 | impl Test for T { |
454 | type Test = T<|>; | 454 | type Test = T$0; |
455 | } | 455 | } |
456 | ", | 456 | ", |
457 | expect![[""]], | 457 | expect![[""]], |
@@ -463,7 +463,7 @@ trait Test { type Test; type Test2; fn test(); } | |||
463 | struct T; | 463 | struct T; |
464 | 464 | ||
465 | impl Test for T { | 465 | impl Test for T { |
466 | type Test = fn <|>; | 466 | type Test = fn $0; |
467 | } | 467 | } |
468 | ", | 468 | ", |
469 | expect![[""]], | 469 | expect![[""]], |
@@ -481,7 +481,7 @@ trait Test { | |||
481 | struct T; | 481 | struct T; |
482 | 482 | ||
483 | impl Test for T { | 483 | impl Test for T { |
484 | t<|> | 484 | t$0 |
485 | } | 485 | } |
486 | "#, | 486 | "#, |
487 | r#" | 487 | r#" |
@@ -510,7 +510,7 @@ trait Test { | |||
510 | struct T; | 510 | struct T; |
511 | 511 | ||
512 | impl Test for T { | 512 | impl Test for T { |
513 | fn t<|> | 513 | fn t$0 |
514 | } | 514 | } |
515 | "#, | 515 | "#, |
516 | r#" | 516 | r#" |
@@ -540,7 +540,7 @@ struct T; | |||
540 | 540 | ||
541 | impl Test for T { | 541 | impl Test for T { |
542 | fn foo() {} | 542 | fn foo() {} |
543 | fn f<|> | 543 | fn f$0 |
544 | } | 544 | } |
545 | "#, | 545 | "#, |
546 | expect![[r#" | 546 | expect![[r#" |
@@ -560,7 +560,7 @@ trait Test { | |||
560 | struct T; | 560 | struct T; |
561 | 561 | ||
562 | impl Test for T { | 562 | impl Test for T { |
563 | fn f<|> | 563 | fn f$0 |
564 | } | 564 | } |
565 | "#, | 565 | "#, |
566 | r#" | 566 | r#" |
@@ -585,7 +585,7 @@ trait Test { | |||
585 | struct T; | 585 | struct T; |
586 | 586 | ||
587 | impl Test for T { | 587 | impl Test for T { |
588 | fn f<|> | 588 | fn f$0 |
589 | } | 589 | } |
590 | "#, | 590 | "#, |
591 | r#" | 591 | r#" |
@@ -614,7 +614,7 @@ trait Test { | |||
614 | } | 614 | } |
615 | 615 | ||
616 | impl Test for () { | 616 | impl Test for () { |
617 | type S<|> | 617 | type S$0 |
618 | } | 618 | } |
619 | "#, | 619 | "#, |
620 | " | 620 | " |
@@ -639,7 +639,7 @@ trait Test { | |||
639 | } | 639 | } |
640 | 640 | ||
641 | impl Test for () { | 641 | impl Test for () { |
642 | const S<|> | 642 | const S$0 |
643 | } | 643 | } |
644 | "#, | 644 | "#, |
645 | " | 645 | " |
@@ -661,7 +661,7 @@ trait Test { | |||
661 | } | 661 | } |
662 | 662 | ||
663 | impl Test for () { | 663 | impl Test for () { |
664 | const S<|> | 664 | const S$0 |
665 | } | 665 | } |
666 | "#, | 666 | "#, |
667 | " | 667 | " |
@@ -724,7 +724,7 @@ impl Test for T {{ | |||
724 | // Enumerate some possible next siblings. | 724 | // Enumerate some possible next siblings. |
725 | for next_sibling in &[ | 725 | for next_sibling in &[ |
726 | "", | 726 | "", |
727 | "fn other_fn() {}", // `const <|> fn` -> `const fn` | 727 | "fn other_fn() {}", // `const $0 fn` -> `const fn` |
728 | "type OtherType = i32;", | 728 | "type OtherType = i32;", |
729 | "const OTHER_CONST: i32 = 0;", | 729 | "const OTHER_CONST: i32 = 0;", |
730 | "async fn other_fn() {}", | 730 | "async fn other_fn() {}", |
@@ -733,9 +733,9 @@ impl Test for T {{ | |||
733 | "default type OtherType = i32;", | 733 | "default type OtherType = i32;", |
734 | "default const OTHER_CONST: i32 = 0;", | 734 | "default const OTHER_CONST: i32 = 0;", |
735 | ] { | 735 | ] { |
736 | test("bar", "fn <|>", "fn bar() {\n $0\n}", next_sibling); | 736 | test("bar", "fn $0", "fn bar() {\n $0\n}", next_sibling); |
737 | test("Foo", "type <|>", "type Foo = ", next_sibling); | 737 | test("Foo", "type $0", "type Foo = ", next_sibling); |
738 | test("CONST", "const <|>", "const CONST: u16 = ", next_sibling); | 738 | test("CONST", "const $0", "const CONST: u16 = ", next_sibling); |
739 | } | 739 | } |
740 | } | 740 | } |
741 | } | 741 | } |
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs index 81a6d00e2..12cdb869d 100644 --- a/crates/completion/src/completions/unqualified_path.rs +++ b/crates/completion/src/completions/unqualified_path.rs | |||
@@ -46,7 +46,7 @@ pub(crate) fn complete_unqualified_path(acc: &mut Completions, ctx: &CompletionC | |||
46 | acc.add_resolution(ctx, name.to_string(), &res) | 46 | acc.add_resolution(ctx, name.to_string(), &res) |
47 | }); | 47 | }); |
48 | 48 | ||
49 | if ctx.config.enable_autoimport_completions && ctx.config.resolve_additional_edits_lazily() { | 49 | if ctx.config.enable_autoimport_completions { |
50 | fuzzy_completion(acc, ctx); | 50 | fuzzy_completion(acc, ctx); |
51 | } | 51 | } |
52 | } | 52 | } |
@@ -85,7 +85,7 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T | |||
85 | // | 85 | // |
86 | // ``` | 86 | // ``` |
87 | // fn main() { | 87 | // fn main() { |
88 | // pda<|> | 88 | // pda$0 |
89 | // } | 89 | // } |
90 | // # pub mod std { pub mod marker { pub struct PhantomData { } } } | 90 | // # pub mod std { pub mod marker { pub struct PhantomData { } } } |
91 | // ``` | 91 | // ``` |
@@ -124,8 +124,8 @@ fn complete_enum_variants(acc: &mut Completions, ctx: &CompletionContext, ty: &T | |||
124 | // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding | 124 | // Note that having this flag set to `true` does not guarantee that the feature is enabled: your client needs to have the corredponding |
125 | // capability enabled. | 125 | // capability enabled. |
126 | fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { | 126 | fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> { |
127 | let _p = profile::span("fuzzy_completion"); | ||
128 | let potential_import_name = ctx.token.to_string(); | 127 | let potential_import_name = ctx.token.to_string(); |
128 | let _p = profile::span("fuzzy_completion").detail(|| potential_import_name.clone()); | ||
129 | 129 | ||
130 | if potential_import_name.len() < 2 { | 130 | if potential_import_name.len() < 2 { |
131 | return None; | 131 | return None; |
@@ -142,6 +142,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<() | |||
142 | Some(40), | 142 | Some(40), |
143 | potential_import_name, | 143 | potential_import_name, |
144 | true, | 144 | true, |
145 | true, | ||
145 | ) | 146 | ) |
146 | .filter_map(|import_candidate| { | 147 | .filter_map(|import_candidate| { |
147 | Some(match import_candidate { | 148 | Some(match import_candidate { |
@@ -191,12 +192,14 @@ mod tests { | |||
191 | use test_utils::mark; | 192 | use test_utils::mark; |
192 | 193 | ||
193 | use crate::{ | 194 | use crate::{ |
194 | test_utils::{check_edit, check_edit_with_config, completion_list_with_config}, | 195 | test_utils::{ |
196 | check_edit, check_edit_with_config, completion_list_with_config, TEST_CONFIG, | ||
197 | }, | ||
195 | CompletionConfig, CompletionKind, | 198 | CompletionConfig, CompletionKind, |
196 | }; | 199 | }; |
197 | 200 | ||
198 | fn check(ra_fixture: &str, expect: Expect) { | 201 | fn check(ra_fixture: &str, expect: Expect) { |
199 | check_with_config(CompletionConfig::default(), ra_fixture, expect); | 202 | check_with_config(TEST_CONFIG, ra_fixture, expect); |
200 | } | 203 | } |
201 | 204 | ||
202 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { | 205 | fn check_with_config(config: CompletionConfig, ra_fixture: &str, expect: Expect) { |
@@ -204,20 +207,12 @@ mod tests { | |||
204 | expect.assert_eq(&actual) | 207 | expect.assert_eq(&actual) |
205 | } | 208 | } |
206 | 209 | ||
207 | fn fuzzy_completion_config() -> CompletionConfig { | ||
208 | let mut completion_config = CompletionConfig::default(); | ||
209 | completion_config | ||
210 | .active_resolve_capabilities | ||
211 | .insert(crate::CompletionResolveCapability::AdditionalTextEdits); | ||
212 | completion_config | ||
213 | } | ||
214 | |||
215 | #[test] | 210 | #[test] |
216 | fn self_fulfilling_completion() { | 211 | fn self_fulfilling_completion() { |
217 | mark::check!(self_fulfilling_completion); | 212 | mark::check!(self_fulfilling_completion); |
218 | check( | 213 | check( |
219 | r#" | 214 | r#" |
220 | use foo<|> | 215 | use foo$0 |
221 | use std::collections; | 216 | use std::collections; |
222 | "#, | 217 | "#, |
223 | expect![[r#" | 218 | expect![[r#" |
@@ -234,7 +229,7 @@ enum Enum { A, B } | |||
234 | fn quux(x: Option<Enum>) { | 229 | fn quux(x: Option<Enum>) { |
235 | match x { | 230 | match x { |
236 | None => (), | 231 | None => (), |
237 | Some(en<|> @ Enum::A) => (), | 232 | Some(en$0 @ Enum::A) => (), |
238 | } | 233 | } |
239 | } | 234 | } |
240 | "#, | 235 | "#, |
@@ -250,7 +245,7 @@ enum Enum { A, B } | |||
250 | fn quux(x: Option<Enum>) { | 245 | fn quux(x: Option<Enum>) { |
251 | match x { | 246 | match x { |
252 | None => (), | 247 | None => (), |
253 | Some(ref en<|>) => (), | 248 | Some(ref en$0) => (), |
254 | } | 249 | } |
255 | } | 250 | } |
256 | "#, | 251 | "#, |
@@ -266,7 +261,7 @@ enum Enum { A, B } | |||
266 | fn quux(x: Option<Enum>) { | 261 | fn quux(x: Option<Enum>) { |
267 | match x { | 262 | match x { |
268 | None => (), | 263 | None => (), |
269 | Some(En<|>) => (), | 264 | Some(En$0) => (), |
270 | } | 265 | } |
271 | } | 266 | } |
272 | "#, | 267 | "#, |
@@ -282,7 +277,7 @@ fn quux(x: Option<Enum>) { | |||
282 | r#" | 277 | r#" |
283 | fn quux(x: i32) { | 278 | fn quux(x: i32) { |
284 | let y = 92; | 279 | let y = 92; |
285 | 1 + <|>; | 280 | 1 + $0; |
286 | let z = (); | 281 | let z = (); |
287 | } | 282 | } |
288 | "#, | 283 | "#, |
@@ -304,7 +299,7 @@ fn quux() { | |||
304 | }; | 299 | }; |
305 | if let Some(a) = bar() { | 300 | if let Some(a) = bar() { |
306 | let b = 62; | 301 | let b = 62; |
307 | 1 + <|> | 302 | 1 + $0 |
308 | } | 303 | } |
309 | } | 304 | } |
310 | "#, | 305 | "#, |
@@ -321,7 +316,7 @@ fn quux() { | |||
321 | check( | 316 | check( |
322 | r#" | 317 | r#" |
323 | fn quux() { | 318 | fn quux() { |
324 | for x in &[1, 2, 3] { <|> } | 319 | for x in &[1, 2, 3] { $0 } |
325 | } | 320 | } |
326 | "#, | 321 | "#, |
327 | expect![[r#" | 322 | expect![[r#" |
@@ -339,7 +334,7 @@ fn quux() { | |||
339 | r#" | 334 | r#" |
340 | fn main() { | 335 | fn main() { |
341 | let wherewolf = 92; | 336 | let wherewolf = 92; |
342 | drop(where<|>) | 337 | drop(where$0) |
343 | } | 338 | } |
344 | "#, | 339 | "#, |
345 | r#" | 340 | r#" |
@@ -354,7 +349,7 @@ fn main() { | |||
354 | #[test] | 349 | #[test] |
355 | fn completes_generic_params() { | 350 | fn completes_generic_params() { |
356 | check( | 351 | check( |
357 | r#"fn quux<T>() { <|> }"#, | 352 | r#"fn quux<T>() { $0 }"#, |
358 | expect![[r#" | 353 | expect![[r#" |
359 | tp T | 354 | tp T |
360 | fn quux() fn quux<T>() | 355 | fn quux() fn quux<T>() |
@@ -365,7 +360,7 @@ fn main() { | |||
365 | #[test] | 360 | #[test] |
366 | fn completes_generic_params_in_struct() { | 361 | fn completes_generic_params_in_struct() { |
367 | check( | 362 | check( |
368 | r#"struct S<T> { x: <|>}"#, | 363 | r#"struct S<T> { x: $0}"#, |
369 | expect![[r#" | 364 | expect![[r#" |
370 | tp Self | 365 | tp Self |
371 | tp T | 366 | tp T |
@@ -377,7 +372,7 @@ fn main() { | |||
377 | #[test] | 372 | #[test] |
378 | fn completes_self_in_enum() { | 373 | fn completes_self_in_enum() { |
379 | check( | 374 | check( |
380 | r#"enum X { Y(<|>) }"#, | 375 | r#"enum X { Y($0) }"#, |
381 | expect![[r#" | 376 | expect![[r#" |
382 | tp Self | 377 | tp Self |
383 | en X | 378 | en X |
@@ -391,7 +386,7 @@ fn main() { | |||
391 | r#" | 386 | r#" |
392 | struct S; | 387 | struct S; |
393 | enum E {} | 388 | enum E {} |
394 | fn quux() { <|> } | 389 | fn quux() { $0 } |
395 | "#, | 390 | "#, |
396 | expect![[r#" | 391 | expect![[r#" |
397 | st S | 392 | st S |
@@ -408,7 +403,7 @@ fn quux() { <|> } | |||
408 | "_alpha", | 403 | "_alpha", |
409 | r#" | 404 | r#" |
410 | fn main() { | 405 | fn main() { |
411 | _<|> | 406 | _$0 |
412 | } | 407 | } |
413 | fn _alpha() {} | 408 | fn _alpha() {} |
414 | "#, | 409 | "#, |
@@ -426,7 +421,7 @@ fn _alpha() {} | |||
426 | check( | 421 | check( |
427 | r#" | 422 | r#" |
428 | //- /lib.rs crate:main deps:other_crate | 423 | //- /lib.rs crate:main deps:other_crate |
429 | use <|>; | 424 | use $0; |
430 | 425 | ||
431 | //- /other_crate/lib.rs crate:other_crate | 426 | //- /other_crate/lib.rs crate:other_crate |
432 | // nothing here | 427 | // nothing here |
@@ -444,7 +439,7 @@ use <|>; | |||
444 | struct Foo; | 439 | struct Foo; |
445 | mod m { | 440 | mod m { |
446 | struct Bar; | 441 | struct Bar; |
447 | fn quux() { <|> } | 442 | fn quux() { $0 } |
448 | } | 443 | } |
449 | "#, | 444 | "#, |
450 | expect![[r#" | 445 | expect![[r#" |
@@ -459,7 +454,7 @@ mod m { | |||
459 | check( | 454 | check( |
460 | r#" | 455 | r#" |
461 | struct Foo; | 456 | struct Foo; |
462 | fn x() -> <|> | 457 | fn x() -> $0 |
463 | "#, | 458 | "#, |
464 | expect![[r#" | 459 | expect![[r#" |
465 | st Foo | 460 | st Foo |
@@ -476,7 +471,7 @@ fn foo() { | |||
476 | let bar = 92; | 471 | let bar = 92; |
477 | { | 472 | { |
478 | let bar = 62; | 473 | let bar = 62; |
479 | drop(<|>) | 474 | drop($0) |
480 | } | 475 | } |
481 | } | 476 | } |
482 | "#, | 477 | "#, |
@@ -492,7 +487,7 @@ fn foo() { | |||
492 | #[test] | 487 | #[test] |
493 | fn completes_self_in_methods() { | 488 | fn completes_self_in_methods() { |
494 | check( | 489 | check( |
495 | r#"impl S { fn foo(&self) { <|> } }"#, | 490 | r#"impl S { fn foo(&self) { $0 } }"#, |
496 | expect![[r#" | 491 | expect![[r#" |
497 | bn self &{unknown} | 492 | bn self &{unknown} |
498 | tp Self | 493 | tp Self |
@@ -505,7 +500,7 @@ fn foo() { | |||
505 | check( | 500 | check( |
506 | r#" | 501 | r#" |
507 | //- /main.rs crate:main deps:std | 502 | //- /main.rs crate:main deps:std |
508 | fn foo() { let x: <|> } | 503 | fn foo() { let x: $0 } |
509 | 504 | ||
510 | //- /std/lib.rs crate:std | 505 | //- /std/lib.rs crate:std |
511 | #[prelude_import] | 506 | #[prelude_import] |
@@ -526,7 +521,7 @@ mod prelude { struct Option; } | |||
526 | check( | 521 | check( |
527 | r#" | 522 | r#" |
528 | //- /main.rs crate:main deps:core,std | 523 | //- /main.rs crate:main deps:core,std |
529 | fn foo() { let x: <|> } | 524 | fn foo() { let x: $0 } |
530 | 525 | ||
531 | //- /core/lib.rs crate:core | 526 | //- /core/lib.rs crate:core |
532 | #[prelude_import] | 527 | #[prelude_import] |
@@ -567,7 +562,7 @@ mod m2 { | |||
567 | macro_rules! baz { () => {} } | 562 | macro_rules! baz { () => {} } |
568 | } | 563 | } |
569 | 564 | ||
570 | fn main() { let v = <|> } | 565 | fn main() { let v = $0 } |
571 | "#, | 566 | "#, |
572 | expect![[r##" | 567 | expect![[r##" |
573 | md m1 | 568 | md m1 |
@@ -586,7 +581,7 @@ fn main() { let v = <|> } | |||
586 | check( | 581 | check( |
587 | r#" | 582 | r#" |
588 | macro_rules! foo { () => {} } | 583 | macro_rules! foo { () => {} } |
589 | fn foo() { <|> } | 584 | fn foo() { $0 } |
590 | "#, | 585 | "#, |
591 | expect![[r#" | 586 | expect![[r#" |
592 | fn foo() fn foo() | 587 | fn foo() fn foo() |
@@ -600,7 +595,7 @@ fn foo() { <|> } | |||
600 | check( | 595 | check( |
601 | r#" | 596 | r#" |
602 | macro_rules! foo { () => {} } | 597 | macro_rules! foo { () => {} } |
603 | fn main() { let x: <|> } | 598 | fn main() { let x: $0 } |
604 | "#, | 599 | "#, |
605 | expect![[r#" | 600 | expect![[r#" |
606 | fn main() fn main() | 601 | fn main() fn main() |
@@ -614,7 +609,7 @@ fn main() { let x: <|> } | |||
614 | check( | 609 | check( |
615 | r#" | 610 | r#" |
616 | macro_rules! foo { () => {} } | 611 | macro_rules! foo { () => {} } |
617 | fn main() { <|> } | 612 | fn main() { $0 } |
618 | "#, | 613 | "#, |
619 | expect![[r#" | 614 | expect![[r#" |
620 | fn main() fn main() | 615 | fn main() fn main() |
@@ -628,7 +623,7 @@ fn main() { <|> } | |||
628 | check( | 623 | check( |
629 | r#" | 624 | r#" |
630 | fn main() { | 625 | fn main() { |
631 | return f<|>; | 626 | return f$0; |
632 | fn frobnicate() {} | 627 | fn frobnicate() {} |
633 | } | 628 | } |
634 | "#, | 629 | "#, |
@@ -646,7 +641,7 @@ fn main() { | |||
646 | macro_rules! m { ($e:expr) => { $e } } | 641 | macro_rules! m { ($e:expr) => { $e } } |
647 | fn quux(x: i32) { | 642 | fn quux(x: i32) { |
648 | let y = 92; | 643 | let y = 92; |
649 | m!(<|>); | 644 | m!($0); |
650 | } | 645 | } |
651 | "#, | 646 | "#, |
652 | expect![[r#" | 647 | expect![[r#" |
@@ -665,7 +660,7 @@ fn quux(x: i32) { | |||
665 | macro_rules! m { ($e:expr) => { $e } } | 660 | macro_rules! m { ($e:expr) => { $e } } |
666 | fn quux(x: i32) { | 661 | fn quux(x: i32) { |
667 | let y = 92; | 662 | let y = 92; |
668 | m!(x<|>); | 663 | m!(x$0); |
669 | } | 664 | } |
670 | ", | 665 | ", |
671 | expect![[r#" | 666 | expect![[r#" |
@@ -684,7 +679,7 @@ fn quux(x: i32) { | |||
684 | macro_rules! m { ($e:expr) => { $e } } | 679 | macro_rules! m { ($e:expr) => { $e } } |
685 | fn quux(x: i32) { | 680 | fn quux(x: i32) { |
686 | let y = 92; | 681 | let y = 92; |
687 | m!(x<|> | 682 | m!(x$0 |
688 | } | 683 | } |
689 | "#, | 684 | "#, |
690 | expect![[r#" | 685 | expect![[r#" |
@@ -702,7 +697,7 @@ fn quux(x: i32) { | |||
702 | r#" | 697 | r#" |
703 | use spam::Quux; | 698 | use spam::Quux; |
704 | 699 | ||
705 | fn main() { <|> } | 700 | fn main() { $0 } |
706 | "#, | 701 | "#, |
707 | expect![[r#" | 702 | expect![[r#" |
708 | fn main() fn main() | 703 | fn main() fn main() |
@@ -719,7 +714,7 @@ enum Foo { Bar, Baz, Quux } | |||
719 | 714 | ||
720 | fn main() { | 715 | fn main() { |
721 | let foo = Foo::Quux; | 716 | let foo = Foo::Quux; |
722 | match foo { Qu<|> } | 717 | match foo { Qu$0 } |
723 | } | 718 | } |
724 | "#, | 719 | "#, |
725 | expect![[r#" | 720 | expect![[r#" |
@@ -739,7 +734,7 @@ enum Foo { Bar, Baz, Quux } | |||
739 | 734 | ||
740 | fn main() { | 735 | fn main() { |
741 | let foo = Foo::Quux; | 736 | let foo = Foo::Quux; |
742 | match &foo { Qu<|> } | 737 | match &foo { Qu$0 } |
743 | } | 738 | } |
744 | "#, | 739 | "#, |
745 | expect![[r#" | 740 | expect![[r#" |
@@ -759,7 +754,7 @@ enum Foo { Bar, Baz, Quux } | |||
759 | 754 | ||
760 | fn main() { | 755 | fn main() { |
761 | let foo = Foo::Quux; | 756 | let foo = Foo::Quux; |
762 | if let Qu<|> = foo { } | 757 | if let Qu$0 = foo { } |
763 | } | 758 | } |
764 | "#, | 759 | "#, |
765 | expect![[r#" | 760 | expect![[r#" |
@@ -776,7 +771,7 @@ fn main() { | |||
776 | check( | 771 | check( |
777 | r#" | 772 | r#" |
778 | enum Foo { Bar, Baz, Quux } | 773 | enum Foo { Bar, Baz, Quux } |
779 | fn main() { let foo: Foo = Q<|> } | 774 | fn main() { let foo: Foo = Q$0 } |
780 | "#, | 775 | "#, |
781 | expect![[r#" | 776 | expect![[r#" |
782 | ev Foo::Bar () | 777 | ev Foo::Bar () |
@@ -793,7 +788,7 @@ fn main() { let foo: Foo = Q<|> } | |||
793 | check( | 788 | check( |
794 | r#" | 789 | r#" |
795 | mod m { pub enum E { V } } | 790 | mod m { pub enum E { V } } |
796 | fn f() -> m::E { V<|> } | 791 | fn f() -> m::E { V$0 } |
797 | "#, | 792 | "#, |
798 | expect![[r#" | 793 | expect![[r#" |
799 | ev m::E::V () | 794 | ev m::E::V () |
@@ -808,7 +803,7 @@ fn f() -> m::E { V<|> } | |||
808 | check( | 803 | check( |
809 | r#" | 804 | r#" |
810 | struct Foo; | 805 | struct Foo; |
811 | #[<|>] | 806 | #[$0] |
812 | fn f() {} | 807 | fn f() {} |
813 | "#, | 808 | "#, |
814 | expect![[""]], | 809 | expect![[""]], |
@@ -822,7 +817,7 @@ fn f() {} | |||
822 | trait MyTrait {} | 817 | trait MyTrait {} |
823 | struct MyStruct {} | 818 | struct MyStruct {} |
824 | 819 | ||
825 | impl My<|> | 820 | impl My$0 |
826 | "#, | 821 | "#, |
827 | expect![[r#" | 822 | expect![[r#" |
828 | tp Self | 823 | tp Self |
@@ -835,7 +830,7 @@ impl My<|> | |||
835 | #[test] | 830 | #[test] |
836 | fn function_fuzzy_completion() { | 831 | fn function_fuzzy_completion() { |
837 | check_edit_with_config( | 832 | check_edit_with_config( |
838 | fuzzy_completion_config(), | 833 | TEST_CONFIG, |
839 | "stdin", | 834 | "stdin", |
840 | r#" | 835 | r#" |
841 | //- /lib.rs crate:dep | 836 | //- /lib.rs crate:dep |
@@ -845,7 +840,7 @@ pub mod io { | |||
845 | 840 | ||
846 | //- /main.rs crate:main deps:dep | 841 | //- /main.rs crate:main deps:dep |
847 | fn main() { | 842 | fn main() { |
848 | stdi<|> | 843 | stdi$0 |
849 | } | 844 | } |
850 | "#, | 845 | "#, |
851 | r#" | 846 | r#" |
@@ -861,7 +856,7 @@ fn main() { | |||
861 | #[test] | 856 | #[test] |
862 | fn macro_fuzzy_completion() { | 857 | fn macro_fuzzy_completion() { |
863 | check_edit_with_config( | 858 | check_edit_with_config( |
864 | fuzzy_completion_config(), | 859 | TEST_CONFIG, |
865 | "macro_with_curlies!", | 860 | "macro_with_curlies!", |
866 | r#" | 861 | r#" |
867 | //- /lib.rs crate:dep | 862 | //- /lib.rs crate:dep |
@@ -873,7 +868,7 @@ macro_rules! macro_with_curlies { | |||
873 | 868 | ||
874 | //- /main.rs crate:main deps:dep | 869 | //- /main.rs crate:main deps:dep |
875 | fn main() { | 870 | fn main() { |
876 | curli<|> | 871 | curli$0 |
877 | } | 872 | } |
878 | "#, | 873 | "#, |
879 | r#" | 874 | r#" |
@@ -889,7 +884,7 @@ fn main() { | |||
889 | #[test] | 884 | #[test] |
890 | fn struct_fuzzy_completion() { | 885 | fn struct_fuzzy_completion() { |
891 | check_edit_with_config( | 886 | check_edit_with_config( |
892 | fuzzy_completion_config(), | 887 | TEST_CONFIG, |
893 | "ThirdStruct", | 888 | "ThirdStruct", |
894 | r#" | 889 | r#" |
895 | //- /lib.rs crate:dep | 890 | //- /lib.rs crate:dep |
@@ -903,7 +898,7 @@ pub mod some_module { | |||
903 | use dep::{FirstStruct, some_module::SecondStruct}; | 898 | use dep::{FirstStruct, some_module::SecondStruct}; |
904 | 899 | ||
905 | fn main() { | 900 | fn main() { |
906 | this<|> | 901 | this$0 |
907 | } | 902 | } |
908 | "#, | 903 | "#, |
909 | r#" | 904 | r#" |
@@ -920,7 +915,7 @@ fn main() { | |||
920 | fn fuzzy_completions_come_in_specific_order() { | 915 | fn fuzzy_completions_come_in_specific_order() { |
921 | mark::check!(certain_fuzzy_order_test); | 916 | mark::check!(certain_fuzzy_order_test); |
922 | check_with_config( | 917 | check_with_config( |
923 | fuzzy_completion_config(), | 918 | TEST_CONFIG, |
924 | r#" | 919 | r#" |
925 | //- /lib.rs crate:dep | 920 | //- /lib.rs crate:dep |
926 | pub struct FirstStruct; | 921 | pub struct FirstStruct; |
@@ -941,7 +936,7 @@ pub mod some_module { | |||
941 | use dep::{FirstStruct, some_module::SecondStruct}; | 936 | use dep::{FirstStruct, some_module::SecondStruct}; |
942 | 937 | ||
943 | fn main() { | 938 | fn main() { |
944 | hir<|> | 939 | hir$0 |
945 | } | 940 | } |
946 | "#, | 941 | "#, |
947 | expect![[r#" | 942 | expect![[r#" |
diff --git a/crates/completion/src/config.rs b/crates/completion/src/config.rs index 30577dc11..b4439b7d1 100644 --- a/crates/completion/src/config.rs +++ b/crates/completion/src/config.rs | |||
@@ -4,8 +4,7 @@ | |||
4 | //! module, and we use to statically check that we only produce snippet | 4 | //! module, and we use to statically check that we only produce snippet |
5 | //! completions if we are allowed to. | 5 | //! completions if we are allowed to. |
6 | 6 | ||
7 | use ide_db::helpers::insert_use::MergeBehavior; | 7 | use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; |
8 | use rustc_hash::FxHashSet; | ||
9 | 8 | ||
10 | #[derive(Clone, Debug, PartialEq, Eq)] | 9 | #[derive(Clone, Debug, PartialEq, Eq)] |
11 | pub struct CompletionConfig { | 10 | pub struct CompletionConfig { |
@@ -15,49 +14,4 @@ pub struct CompletionConfig { | |||
15 | pub add_call_argument_snippets: bool, | 14 | pub add_call_argument_snippets: bool, |
16 | pub snippet_cap: Option<SnippetCap>, | 15 | pub snippet_cap: Option<SnippetCap>, |
17 | pub merge: Option<MergeBehavior>, | 16 | pub merge: Option<MergeBehavior>, |
18 | /// A set of capabilities, enabled on the client and supported on the server. | ||
19 | pub active_resolve_capabilities: FxHashSet<CompletionResolveCapability>, | ||
20 | } | ||
21 | |||
22 | /// A resolve capability, supported on the server. | ||
23 | /// If the client registers any completion resolve capabilities, | ||
24 | /// the server is able to render completion items' corresponding fields later, | ||
25 | /// not during an initial completion item request. | ||
26 | /// See https://github.com/rust-analyzer/rust-analyzer/issues/6366 for more details. | ||
27 | #[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)] | ||
28 | pub enum CompletionResolveCapability { | ||
29 | Documentation, | ||
30 | Detail, | ||
31 | AdditionalTextEdits, | ||
32 | } | ||
33 | |||
34 | impl CompletionConfig { | ||
35 | pub fn allow_snippets(&mut self, yes: bool) { | ||
36 | self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None } | ||
37 | } | ||
38 | |||
39 | /// Whether the completions' additional edits are calculated when sending an initional completions list | ||
40 | /// or later, in a separate resolve request. | ||
41 | pub fn resolve_additional_edits_lazily(&self) -> bool { | ||
42 | self.active_resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits) | ||
43 | } | ||
44 | } | ||
45 | |||
46 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
47 | pub struct SnippetCap { | ||
48 | _private: (), | ||
49 | } | ||
50 | |||
51 | impl Default for CompletionConfig { | ||
52 | fn default() -> Self { | ||
53 | CompletionConfig { | ||
54 | enable_postfix_completions: true, | ||
55 | enable_autoimport_completions: true, | ||
56 | add_call_parenthesis: true, | ||
57 | add_call_argument_snippets: true, | ||
58 | snippet_cap: Some(SnippetCap { _private: () }), | ||
59 | merge: Some(MergeBehavior::Full), | ||
60 | active_resolve_capabilities: FxHashSet::default(), | ||
61 | } | ||
62 | } | ||
63 | } | 17 | } |
diff --git a/crates/completion/src/context.rs b/crates/completion/src/context.rs index 41de324d8..ebf28e887 100644 --- a/crates/completion/src/context.rs +++ b/crates/completion/src/context.rs | |||
@@ -63,7 +63,7 @@ pub(crate) struct CompletionContext<'a> { | |||
63 | pub(super) is_expr: bool, | 63 | pub(super) is_expr: bool, |
64 | /// Something is typed at the "top" level, in module or impl/trait. | 64 | /// Something is typed at the "top" level, in module or impl/trait. |
65 | pub(super) is_new_item: bool, | 65 | pub(super) is_new_item: bool, |
66 | /// The receiver if this is a field or method access, i.e. writing something.<|> | 66 | /// The receiver if this is a field or method access, i.e. writing something.$0 |
67 | pub(super) dot_receiver: Option<ast::Expr>, | 67 | pub(super) dot_receiver: Option<ast::Expr>, |
68 | pub(super) dot_receiver_is_ambiguous_float_literal: bool, | 68 | pub(super) dot_receiver_is_ambiguous_float_literal: bool, |
69 | /// If this is a call (method or function) in particular, i.e. the () are already there. | 69 | /// If this is a call (method or function) in particular, i.e. the () are already there. |
@@ -228,9 +228,9 @@ impl<'a> CompletionContext<'a> { | |||
228 | 228 | ||
229 | /// Checks whether completions in that particular case don't make much sense. | 229 | /// Checks whether completions in that particular case don't make much sense. |
230 | /// Examples: | 230 | /// Examples: |
231 | /// - `fn <|>` -- we expect function name, it's unlikely that "hint" will be helpful. | 231 | /// - `fn $0` -- we expect function name, it's unlikely that "hint" will be helpful. |
232 | /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. | 232 | /// Exception for this case is `impl Trait for Foo`, where we would like to hint trait method names. |
233 | /// - `for _ i<|>` -- obviously, it'll be "in" keyword. | 233 | /// - `for _ i$0` -- obviously, it'll be "in" keyword. |
234 | pub(crate) fn no_completion_required(&self) -> bool { | 234 | pub(crate) fn no_completion_required(&self) -> bool { |
235 | (self.fn_is_prev && !self.inside_impl_trait_block) || self.for_is_prev2 | 235 | (self.fn_is_prev && !self.inside_impl_trait_block) || self.for_is_prev2 |
236 | } | 236 | } |
@@ -279,7 +279,7 @@ impl<'a> CompletionContext<'a> { | |||
279 | offset: TextSize, | 279 | offset: TextSize, |
280 | ) { | 280 | ) { |
281 | // FIXME: this is wrong in at least two cases: | 281 | // FIXME: this is wrong in at least two cases: |
282 | // * when there's no token `foo(<|>)` | 282 | // * when there's no token `foo($0)` |
283 | // * when there is a token, but it happens to have type of it's own | 283 | // * when there is a token, but it happens to have type of it's own |
284 | self.expected_type = self | 284 | self.expected_type = self |
285 | .token | 285 | .token |
@@ -458,7 +458,7 @@ impl<'a> CompletionContext<'a> { | |||
458 | } | 458 | } |
459 | if let Some(block) = ast::BlockExpr::cast(node) { | 459 | if let Some(block) = ast::BlockExpr::cast(node) { |
460 | return Some( | 460 | return Some( |
461 | block.expr().map(|e| e.syntax().text_range()) | 461 | block.tail_expr().map(|e| e.syntax().text_range()) |
462 | == Some(name_ref.syntax().text_range()), | 462 | == Some(name_ref.syntax().text_range()), |
463 | ); | 463 | ); |
464 | } | 464 | } |
diff --git a/crates/completion/src/item.rs b/crates/completion/src/item.rs index 65f8353e7..35af354b0 100644 --- a/crates/completion/src/item.rs +++ b/crates/completion/src/item.rs | |||
@@ -5,13 +5,11 @@ use std::fmt; | |||
5 | use hir::{Documentation, ModPath, Mutability}; | 5 | use hir::{Documentation, ModPath, Mutability}; |
6 | use ide_db::helpers::{ | 6 | use ide_db::helpers::{ |
7 | insert_use::{self, ImportScope, MergeBehavior}, | 7 | insert_use::{self, ImportScope, MergeBehavior}, |
8 | mod_path_to_ast, | 8 | mod_path_to_ast, SnippetCap, |
9 | }; | 9 | }; |
10 | use syntax::{algo, TextRange}; | 10 | use syntax::{algo, TextRange}; |
11 | use text_edit::TextEdit; | 11 | use text_edit::TextEdit; |
12 | 12 | ||
13 | use crate::config::SnippetCap; | ||
14 | |||
15 | /// `CompletionItem` describes a single completion variant in the editor pop-up. | 13 | /// `CompletionItem` describes a single completion variant in the editor pop-up. |
16 | /// It is basically a POD with various properties. To construct a | 14 | /// It is basically a POD with various properties. To construct a |
17 | /// `CompletionItem`, use `new` method and the `Builder` struct. | 15 | /// `CompletionItem`, use `new` method and the `Builder` struct. |
@@ -45,7 +43,7 @@ pub struct CompletionItem { | |||
45 | /// Lookup is used to check if completion item indeed can complete current | 43 | /// Lookup is used to check if completion item indeed can complete current |
46 | /// ident. | 44 | /// ident. |
47 | /// | 45 | /// |
48 | /// That is, in `foo.bar<|>` lookup of `abracadabra` will be accepted (it | 46 | /// That is, in `foo.bar$0` lookup of `abracadabra` will be accepted (it |
49 | /// contains `bar` sub sequence), and `quux` will rejected. | 47 | /// contains `bar` sub sequence), and `quux` will rejected. |
50 | lookup: Option<String>, | 48 | lookup: Option<String>, |
51 | 49 | ||
diff --git a/crates/completion/src/lib.rs b/crates/completion/src/lib.rs index c57d05bbe..6cba88a6b 100644 --- a/crates/completion/src/lib.rs +++ b/crates/completion/src/lib.rs | |||
@@ -20,7 +20,7 @@ use text_edit::TextEdit; | |||
20 | use crate::{completions::Completions, context::CompletionContext, item::CompletionKind}; | 20 | use crate::{completions::Completions, context::CompletionContext, item::CompletionKind}; |
21 | 21 | ||
22 | pub use crate::{ | 22 | pub use crate::{ |
23 | config::{CompletionConfig, CompletionResolveCapability}, | 23 | config::CompletionConfig, |
24 | item::{CompletionItem, CompletionItemKind, CompletionScore, ImportEdit, InsertTextFormat}, | 24 | item::{CompletionItem, CompletionItemKind, CompletionScore, ImportEdit, InsertTextFormat}, |
25 | }; | 25 | }; |
26 | 26 | ||
@@ -47,8 +47,8 @@ pub use crate::{ | |||
47 | // - `expr.while` -> `while expr {}` or `while let ... {}` for `Option` or `Result` | 47 | // - `expr.while` -> `while expr {}` or `while let ... {}` for `Option` or `Result` |
48 | // - `expr.ref` -> `&expr` | 48 | // - `expr.ref` -> `&expr` |
49 | // - `expr.refm` -> `&mut expr` | 49 | // - `expr.refm` -> `&mut expr` |
50 | // - `expr.let` -> `let <|> = expr;` | 50 | // - `expr.let` -> `let $0 = expr;` |
51 | // - `expr.letm` -> `let mut <|> = expr;` | 51 | // - `expr.letm` -> `let mut $0 = expr;` |
52 | // - `expr.not` -> `!expr` | 52 | // - `expr.not` -> `!expr` |
53 | // - `expr.dbg` -> `dbg!(expr)` | 53 | // - `expr.dbg` -> `dbg!(expr)` |
54 | // - `expr.dbgr` -> `dbg!(&expr)` | 54 | // - `expr.dbgr` -> `dbg!(&expr)` |
@@ -92,7 +92,7 @@ pub use crate::{ | |||
92 | /// ```no_run | 92 | /// ```no_run |
93 | /// fn f() { | 93 | /// fn f() { |
94 | /// let foo = 92; | 94 | /// let foo = 92; |
95 | /// let _ = bar<|> | 95 | /// let _ = bar$0 |
96 | /// } | 96 | /// } |
97 | /// ``` | 97 | /// ``` |
98 | /// | 98 | /// |
@@ -158,8 +158,7 @@ pub fn resolve_completion_edits( | |||
158 | 158 | ||
159 | #[cfg(test)] | 159 | #[cfg(test)] |
160 | mod tests { | 160 | mod tests { |
161 | use crate::config::CompletionConfig; | 161 | use crate::test_utils::{self, TEST_CONFIG}; |
162 | use crate::test_utils; | ||
163 | 162 | ||
164 | struct DetailAndDocumentation<'a> { | 163 | struct DetailAndDocumentation<'a> { |
165 | detail: &'a str, | 164 | detail: &'a str, |
@@ -168,7 +167,7 @@ mod tests { | |||
168 | 167 | ||
169 | fn check_detail_and_documentation(ra_fixture: &str, expected: DetailAndDocumentation) { | 168 | fn check_detail_and_documentation(ra_fixture: &str, expected: DetailAndDocumentation) { |
170 | let (db, position) = test_utils::position(ra_fixture); | 169 | let (db, position) = test_utils::position(ra_fixture); |
171 | let config = CompletionConfig::default(); | 170 | let config = TEST_CONFIG; |
172 | let completions: Vec<_> = crate::completions(&db, &config, position).unwrap().into(); | 171 | let completions: Vec<_> = crate::completions(&db, &config, position).unwrap().into(); |
173 | for item in completions { | 172 | for item in completions { |
174 | if item.detail() == Some(expected.detail) { | 173 | if item.detail() == Some(expected.detail) { |
@@ -183,7 +182,7 @@ mod tests { | |||
183 | 182 | ||
184 | fn check_no_completion(ra_fixture: &str) { | 183 | fn check_no_completion(ra_fixture: &str) { |
185 | let (db, position) = test_utils::position(ra_fixture); | 184 | let (db, position) = test_utils::position(ra_fixture); |
186 | let config = CompletionConfig::default(); | 185 | let config = TEST_CONFIG; |
187 | 186 | ||
188 | let completions: Option<Vec<String>> = crate::completions(&db, &config, position) | 187 | let completions: Option<Vec<String>> = crate::completions(&db, &config, position) |
189 | .and_then(|completions| { | 188 | .and_then(|completions| { |
@@ -221,7 +220,7 @@ mod tests { | |||
221 | 220 | ||
222 | fn foo() { | 221 | fn foo() { |
223 | let bar = Bar; | 222 | let bar = Bar; |
224 | bar.fo<|>; | 223 | bar.fo$0; |
225 | } | 224 | } |
226 | "#, | 225 | "#, |
227 | DetailAndDocumentation { detail: "fn foo(&self)", documentation: "Do the foo" }, | 226 | DetailAndDocumentation { detail: "fn foo(&self)", documentation: "Do the foo" }, |
@@ -247,7 +246,7 @@ mod tests { | |||
247 | 246 | ||
248 | fn foo() { | 247 | fn foo() { |
249 | let bar = Bar; | 248 | let bar = Bar; |
250 | bar.fo<|>; | 249 | bar.fo$0; |
251 | } | 250 | } |
252 | "#, | 251 | "#, |
253 | DetailAndDocumentation { detail: "fn foo(&self)", documentation: " Do the foo" }, | 252 | DetailAndDocumentation { detail: "fn foo(&self)", documentation: " Do the foo" }, |
@@ -260,7 +259,7 @@ mod tests { | |||
260 | check_no_completion( | 259 | check_no_completion( |
261 | r#" | 260 | r#" |
262 | fn foo() { | 261 | fn foo() { |
263 | for i i<|> | 262 | for i i$0 |
264 | } | 263 | } |
265 | "#, | 264 | "#, |
266 | ); | 265 | ); |
@@ -271,7 +270,7 @@ mod tests { | |||
271 | fn foo() -> &'static str { "foo" } | 270 | fn foo() -> &'static str { "foo" } |
272 | 271 | ||
273 | fn bar() { | 272 | fn bar() { |
274 | for c in fo<|> | 273 | for c in fo$0 |
275 | } | 274 | } |
276 | "#, | 275 | "#, |
277 | DetailAndDocumentation { | 276 | DetailAndDocumentation { |
diff --git a/crates/completion/src/patterns.rs b/crates/completion/src/patterns.rs index b0f35f9bf..f148b9402 100644 --- a/crates/completion/src/patterns.rs +++ b/crates/completion/src/patterns.rs | |||
@@ -20,7 +20,7 @@ pub(crate) fn has_trait_parent(element: SyntaxElement) -> bool { | |||
20 | } | 20 | } |
21 | #[test] | 21 | #[test] |
22 | fn test_has_trait_parent() { | 22 | fn test_has_trait_parent() { |
23 | check_pattern_is_applicable(r"trait A { f<|> }", has_trait_parent); | 23 | check_pattern_is_applicable(r"trait A { f$0 }", has_trait_parent); |
24 | } | 24 | } |
25 | 25 | ||
26 | pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { | 26 | pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { |
@@ -32,7 +32,7 @@ pub(crate) fn has_impl_parent(element: SyntaxElement) -> bool { | |||
32 | } | 32 | } |
33 | #[test] | 33 | #[test] |
34 | fn test_has_impl_parent() { | 34 | fn test_has_impl_parent() { |
35 | check_pattern_is_applicable(r"impl A { f<|> }", has_impl_parent); | 35 | check_pattern_is_applicable(r"impl A { f$0 }", has_impl_parent); |
36 | } | 36 | } |
37 | 37 | ||
38 | pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { | 38 | pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { |
@@ -47,10 +47,10 @@ pub(crate) fn inside_impl_trait_block(element: SyntaxElement) -> bool { | |||
47 | } | 47 | } |
48 | #[test] | 48 | #[test] |
49 | fn test_inside_impl_trait_block() { | 49 | fn test_inside_impl_trait_block() { |
50 | check_pattern_is_applicable(r"impl Foo for Bar { f<|> }", inside_impl_trait_block); | 50 | check_pattern_is_applicable(r"impl Foo for Bar { f$0 }", inside_impl_trait_block); |
51 | check_pattern_is_applicable(r"impl Foo for Bar { fn f<|> }", inside_impl_trait_block); | 51 | check_pattern_is_applicable(r"impl Foo for Bar { fn f$0 }", inside_impl_trait_block); |
52 | check_pattern_is_not_applicable(r"impl A { f<|> }", inside_impl_trait_block); | 52 | check_pattern_is_not_applicable(r"impl A { f$0 }", inside_impl_trait_block); |
53 | check_pattern_is_not_applicable(r"impl A { fn f<|> }", inside_impl_trait_block); | 53 | check_pattern_is_not_applicable(r"impl A { fn f$0 }", inside_impl_trait_block); |
54 | } | 54 | } |
55 | 55 | ||
56 | pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { | 56 | pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { |
@@ -58,8 +58,8 @@ pub(crate) fn has_field_list_parent(element: SyntaxElement) -> bool { | |||
58 | } | 58 | } |
59 | #[test] | 59 | #[test] |
60 | fn test_has_field_list_parent() { | 60 | fn test_has_field_list_parent() { |
61 | check_pattern_is_applicable(r"struct Foo { f<|> }", has_field_list_parent); | 61 | check_pattern_is_applicable(r"struct Foo { f$0 }", has_field_list_parent); |
62 | check_pattern_is_applicable(r"struct Foo { f<|> pub f: i32}", has_field_list_parent); | 62 | check_pattern_is_applicable(r"struct Foo { f$0 pub f: i32}", has_field_list_parent); |
63 | } | 63 | } |
64 | 64 | ||
65 | pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { | 65 | pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { |
@@ -67,7 +67,7 @@ pub(crate) fn has_block_expr_parent(element: SyntaxElement) -> bool { | |||
67 | } | 67 | } |
68 | #[test] | 68 | #[test] |
69 | fn test_has_block_expr_parent() { | 69 | fn test_has_block_expr_parent() { |
70 | check_pattern_is_applicable(r"fn my_fn() { let a = 2; f<|> }", has_block_expr_parent); | 70 | check_pattern_is_applicable(r"fn my_fn() { let a = 2; f$0 }", has_block_expr_parent); |
71 | } | 71 | } |
72 | 72 | ||
73 | pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { | 73 | pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { |
@@ -75,8 +75,8 @@ pub(crate) fn has_bind_pat_parent(element: SyntaxElement) -> bool { | |||
75 | } | 75 | } |
76 | #[test] | 76 | #[test] |
77 | fn test_has_bind_pat_parent() { | 77 | fn test_has_bind_pat_parent() { |
78 | check_pattern_is_applicable(r"fn my_fn(m<|>) {}", has_bind_pat_parent); | 78 | check_pattern_is_applicable(r"fn my_fn(m$0) {}", has_bind_pat_parent); |
79 | check_pattern_is_applicable(r"fn my_fn() { let m<|> }", has_bind_pat_parent); | 79 | check_pattern_is_applicable(r"fn my_fn() { let m$0 }", has_bind_pat_parent); |
80 | } | 80 | } |
81 | 81 | ||
82 | pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { | 82 | pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { |
@@ -86,8 +86,8 @@ pub(crate) fn has_ref_parent(element: SyntaxElement) -> bool { | |||
86 | } | 86 | } |
87 | #[test] | 87 | #[test] |
88 | fn test_has_ref_parent() { | 88 | fn test_has_ref_parent() { |
89 | check_pattern_is_applicable(r"fn my_fn(&m<|>) {}", has_ref_parent); | 89 | check_pattern_is_applicable(r"fn my_fn(&m$0) {}", has_ref_parent); |
90 | check_pattern_is_applicable(r"fn my() { let &m<|> }", has_ref_parent); | 90 | check_pattern_is_applicable(r"fn my() { let &m$0 }", has_ref_parent); |
91 | } | 91 | } |
92 | 92 | ||
93 | pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool { | 93 | pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> bool { |
@@ -99,8 +99,8 @@ pub(crate) fn has_item_list_or_source_file_parent(element: SyntaxElement) -> boo | |||
99 | } | 99 | } |
100 | #[test] | 100 | #[test] |
101 | fn test_has_item_list_or_source_file_parent() { | 101 | fn test_has_item_list_or_source_file_parent() { |
102 | check_pattern_is_applicable(r"i<|>", has_item_list_or_source_file_parent); | 102 | check_pattern_is_applicable(r"i$0", has_item_list_or_source_file_parent); |
103 | check_pattern_is_applicable(r"mod foo { f<|> }", has_item_list_or_source_file_parent); | 103 | check_pattern_is_applicable(r"mod foo { f$0 }", has_item_list_or_source_file_parent); |
104 | } | 104 | } |
105 | 105 | ||
106 | pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { | 106 | pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { |
@@ -112,7 +112,7 @@ pub(crate) fn is_match_arm(element: SyntaxElement) -> bool { | |||
112 | } | 112 | } |
113 | #[test] | 113 | #[test] |
114 | fn test_is_match_arm() { | 114 | fn test_is_match_arm() { |
115 | check_pattern_is_applicable(r"fn my_fn() { match () { () => m<|> } }", is_match_arm); | 115 | check_pattern_is_applicable(r"fn my_fn() { match () { () => m$0 } }", is_match_arm); |
116 | } | 116 | } |
117 | 117 | ||
118 | pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { | 118 | pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { |
@@ -124,7 +124,7 @@ pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { | |||
124 | } | 124 | } |
125 | #[test] | 125 | #[test] |
126 | fn test_unsafe_is_prev() { | 126 | fn test_unsafe_is_prev() { |
127 | check_pattern_is_applicable(r"unsafe i<|>", unsafe_is_prev); | 127 | check_pattern_is_applicable(r"unsafe i$0", unsafe_is_prev); |
128 | } | 128 | } |
129 | 129 | ||
130 | pub(crate) fn if_is_prev(element: SyntaxElement) -> bool { | 130 | pub(crate) fn if_is_prev(element: SyntaxElement) -> bool { |
@@ -144,11 +144,11 @@ pub(crate) fn fn_is_prev(element: SyntaxElement) -> bool { | |||
144 | } | 144 | } |
145 | #[test] | 145 | #[test] |
146 | fn test_fn_is_prev() { | 146 | fn test_fn_is_prev() { |
147 | check_pattern_is_applicable(r"fn l<|>", fn_is_prev); | 147 | check_pattern_is_applicable(r"fn l$0", fn_is_prev); |
148 | } | 148 | } |
149 | 149 | ||
150 | /// Check if the token previous to the previous one is `for`. | 150 | /// Check if the token previous to the previous one is `for`. |
151 | /// For example, `for _ i<|>` => true. | 151 | /// For example, `for _ i$0` => true. |
152 | pub(crate) fn for_is_prev2(element: SyntaxElement) -> bool { | 152 | pub(crate) fn for_is_prev2(element: SyntaxElement) -> bool { |
153 | element | 153 | element |
154 | .into_token() | 154 | .into_token() |
@@ -159,12 +159,12 @@ pub(crate) fn for_is_prev2(element: SyntaxElement) -> bool { | |||
159 | } | 159 | } |
160 | #[test] | 160 | #[test] |
161 | fn test_for_is_prev2() { | 161 | fn test_for_is_prev2() { |
162 | check_pattern_is_applicable(r"for i i<|>", for_is_prev2); | 162 | check_pattern_is_applicable(r"for i i$0", for_is_prev2); |
163 | } | 163 | } |
164 | 164 | ||
165 | #[test] | 165 | #[test] |
166 | fn test_if_is_prev() { | 166 | fn test_if_is_prev() { |
167 | check_pattern_is_applicable(r"if l<|>", if_is_prev); | 167 | check_pattern_is_applicable(r"if l$0", if_is_prev); |
168 | } | 168 | } |
169 | 169 | ||
170 | pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { | 170 | pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { |
@@ -172,7 +172,7 @@ pub(crate) fn has_trait_as_prev_sibling(element: SyntaxElement) -> bool { | |||
172 | } | 172 | } |
173 | #[test] | 173 | #[test] |
174 | fn test_has_trait_as_prev_sibling() { | 174 | fn test_has_trait_as_prev_sibling() { |
175 | check_pattern_is_applicable(r"trait A w<|> {}", has_trait_as_prev_sibling); | 175 | check_pattern_is_applicable(r"trait A w$0 {}", has_trait_as_prev_sibling); |
176 | } | 176 | } |
177 | 177 | ||
178 | pub(crate) fn has_impl_as_prev_sibling(element: SyntaxElement) -> bool { | 178 | pub(crate) fn has_impl_as_prev_sibling(element: SyntaxElement) -> bool { |
@@ -180,7 +180,7 @@ pub(crate) fn has_impl_as_prev_sibling(element: SyntaxElement) -> bool { | |||
180 | } | 180 | } |
181 | #[test] | 181 | #[test] |
182 | fn test_has_impl_as_prev_sibling() { | 182 | fn test_has_impl_as_prev_sibling() { |
183 | check_pattern_is_applicable(r"impl A w<|> {}", has_impl_as_prev_sibling); | 183 | check_pattern_is_applicable(r"impl A w$0 {}", has_impl_as_prev_sibling); |
184 | } | 184 | } |
185 | 185 | ||
186 | pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { | 186 | pub(crate) fn is_in_loop_body(element: SyntaxElement) -> bool { |
diff --git a/crates/completion/src/render.rs b/crates/completion/src/render.rs index ac0b2a513..e93c59f71 100644 --- a/crates/completion/src/render.rs +++ b/crates/completion/src/render.rs | |||
@@ -11,13 +11,13 @@ pub(crate) mod type_alias; | |||
11 | mod builder_ext; | 11 | mod builder_ext; |
12 | 12 | ||
13 | use hir::{Documentation, HasAttrs, HirDisplay, Mutability, ScopeDef, Type}; | 13 | use hir::{Documentation, HasAttrs, HirDisplay, Mutability, ScopeDef, Type}; |
14 | use ide_db::RootDatabase; | 14 | use ide_db::{helpers::SnippetCap, RootDatabase}; |
15 | use syntax::TextRange; | 15 | use syntax::TextRange; |
16 | use test_utils::mark; | 16 | use test_utils::mark; |
17 | 17 | ||
18 | use crate::{ | 18 | use crate::{ |
19 | config::SnippetCap, item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, | 19 | item::ImportEdit, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, |
20 | CompletionKind, CompletionScore, | 20 | CompletionScore, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}; | 23 | use crate::render::{enum_variant::render_variant, function::render_fn, macro_::render_macro}; |
@@ -320,8 +320,8 @@ mod tests { | |||
320 | use test_utils::mark; | 320 | use test_utils::mark; |
321 | 321 | ||
322 | use crate::{ | 322 | use crate::{ |
323 | test_utils::{check_edit, do_completion, get_all_items}, | 323 | test_utils::{check_edit, do_completion, get_all_items, TEST_CONFIG}, |
324 | CompletionConfig, CompletionKind, CompletionScore, | 324 | CompletionKind, CompletionScore, |
325 | }; | 325 | }; |
326 | 326 | ||
327 | fn check(ra_fixture: &str, expect: Expect) { | 327 | fn check(ra_fixture: &str, expect: Expect) { |
@@ -338,7 +338,7 @@ mod tests { | |||
338 | } | 338 | } |
339 | } | 339 | } |
340 | 340 | ||
341 | let mut completions = get_all_items(CompletionConfig::default(), ra_fixture); | 341 | let mut completions = get_all_items(TEST_CONFIG, ra_fixture); |
342 | completions.sort_by_key(|it| (Reverse(it.score()), it.label().to_string())); | 342 | completions.sort_by_key(|it| (Reverse(it.score()), it.label().to_string())); |
343 | let actual = completions | 343 | let actual = completions |
344 | .into_iter() | 344 | .into_iter() |
@@ -358,7 +358,7 @@ mod tests { | |||
358 | r#" | 358 | r#" |
359 | enum Foo { Foo { x: i32, y: i32 } } | 359 | enum Foo { Foo { x: i32, y: i32 } } |
360 | 360 | ||
361 | fn main() { Foo::Fo<|> } | 361 | fn main() { Foo::Fo$0 } |
362 | "#, | 362 | "#, |
363 | expect![[r#" | 363 | expect![[r#" |
364 | [ | 364 | [ |
@@ -381,7 +381,7 @@ fn main() { Foo::Fo<|> } | |||
381 | r#" | 381 | r#" |
382 | enum Foo { Foo (i32, i32) } | 382 | enum Foo { Foo (i32, i32) } |
383 | 383 | ||
384 | fn main() { Foo::Fo<|> } | 384 | fn main() { Foo::Fo$0 } |
385 | "#, | 385 | "#, |
386 | expect![[r#" | 386 | expect![[r#" |
387 | [ | 387 | [ |
@@ -406,7 +406,7 @@ fn main() { Foo::Fo<|> } | |||
406 | r#" | 406 | r#" |
407 | enum Foo { Foo } | 407 | enum Foo { Foo } |
408 | 408 | ||
409 | fn main() { Foo::Fo<|> } | 409 | fn main() { Foo::Fo$0 } |
410 | "#, | 410 | "#, |
411 | expect![[r#" | 411 | expect![[r#" |
412 | [ | 412 | [ |
@@ -430,7 +430,7 @@ fn main() { Foo::Fo<|> } | |||
430 | mod m { | 430 | mod m { |
431 | pub enum Spam { Foo, Bar(i32) } | 431 | pub enum Spam { Foo, Bar(i32) } |
432 | } | 432 | } |
433 | fn main() { let _: m::Spam = S<|> } | 433 | fn main() { let _: m::Spam = S$0 } |
434 | "#, | 434 | "#, |
435 | expect![[r#" | 435 | expect![[r#" |
436 | [ | 436 | [ |
@@ -483,7 +483,7 @@ fn something_deprecated() {} | |||
483 | #[deprecated(since = "1.0.0")] | 483 | #[deprecated(since = "1.0.0")] |
484 | fn something_else_deprecated() {} | 484 | fn something_else_deprecated() {} |
485 | 485 | ||
486 | fn main() { som<|> } | 486 | fn main() { som$0 } |
487 | "#, | 487 | "#, |
488 | expect![[r#" | 488 | expect![[r#" |
489 | [ | 489 | [ |
@@ -523,7 +523,7 @@ fn main() { som<|> } | |||
523 | check( | 523 | check( |
524 | r#" | 524 | r#" |
525 | struct A { #[deprecated] the_field: u32 } | 525 | struct A { #[deprecated] the_field: u32 } |
526 | fn foo() { A { the<|> } } | 526 | fn foo() { A { the$0 } } |
527 | "#, | 527 | "#, |
528 | expect![[r#" | 528 | expect![[r#" |
529 | [ | 529 | [ |
@@ -551,7 +551,7 @@ struct S { | |||
551 | } | 551 | } |
552 | impl S { | 552 | impl S { |
553 | /// Method docs | 553 | /// Method docs |
554 | fn bar(self) { self.<|> } | 554 | fn bar(self) { self.$0 } |
555 | }"#, | 555 | }"#, |
556 | expect![[r#" | 556 | expect![[r#" |
557 | [ | 557 | [ |
@@ -584,7 +584,7 @@ impl S { | |||
584 | 584 | ||
585 | check( | 585 | check( |
586 | r#" | 586 | r#" |
587 | use self::my<|>; | 587 | use self::my$0; |
588 | 588 | ||
589 | /// mod docs | 589 | /// mod docs |
590 | mod my { } | 590 | mod my { } |
@@ -643,7 +643,7 @@ impl S { | |||
643 | #[inline] | 643 | #[inline] |
644 | fn the_method(&self) { } | 644 | fn the_method(&self) { } |
645 | } | 645 | } |
646 | fn foo(s: S) { s.<|> } | 646 | fn foo(s: S) { s.$0 } |
647 | "#, | 647 | "#, |
648 | expect![[r#" | 648 | expect![[r#" |
649 | [ | 649 | [ |
@@ -671,7 +671,7 @@ fn foo(foo: u8, bar: u8) {} | |||
671 | struct ManualVtable { f: fn(u8, u8) } | 671 | struct ManualVtable { f: fn(u8, u8) } |
672 | 672 | ||
673 | fn main() -> ManualVtable { | 673 | fn main() -> ManualVtable { |
674 | ManualVtable { f: f<|> } | 674 | ManualVtable { f: f$0 } |
675 | } | 675 | } |
676 | "#, | 676 | "#, |
677 | r#" | 677 | r#" |
@@ -692,7 +692,7 @@ fn main() -> ManualVtable { | |||
692 | "foo", | 692 | "foo", |
693 | r#" | 693 | r#" |
694 | mod m { pub fn foo() {} } | 694 | mod m { pub fn foo() {} } |
695 | use crate::m::f<|>; | 695 | use crate::m::f$0; |
696 | "#, | 696 | "#, |
697 | r#" | 697 | r#" |
698 | mod m { pub fn foo() {} } | 698 | mod m { pub fn foo() {} } |
@@ -707,7 +707,7 @@ use crate::m::foo; | |||
707 | "foo", | 707 | "foo", |
708 | r#" | 708 | r#" |
709 | fn foo(x: i32) {} | 709 | fn foo(x: i32) {} |
710 | fn main() { f<|>(); } | 710 | fn main() { f$0(); } |
711 | "#, | 711 | "#, |
712 | r#" | 712 | r#" |
713 | fn foo(x: i32) {} | 713 | fn foo(x: i32) {} |
@@ -719,7 +719,7 @@ fn main() { foo(); } | |||
719 | r#" | 719 | r#" |
720 | struct Foo; | 720 | struct Foo; |
721 | impl Foo { fn foo(&self){} } | 721 | impl Foo { fn foo(&self){} } |
722 | fn f(foo: &Foo) { foo.f<|>(); } | 722 | fn f(foo: &Foo) { foo.f$0(); } |
723 | "#, | 723 | "#, |
724 | r#" | 724 | r#" |
725 | struct Foo; | 725 | struct Foo; |
@@ -736,7 +736,7 @@ fn f(foo: &Foo) { foo.foo(); } | |||
736 | "Vec", | 736 | "Vec", |
737 | r#" | 737 | r#" |
738 | struct Vec<T> {} | 738 | struct Vec<T> {} |
739 | fn foo(xs: Ve<|>) | 739 | fn foo(xs: Ve$0) |
740 | "#, | 740 | "#, |
741 | r#" | 741 | r#" |
742 | struct Vec<T> {} | 742 | struct Vec<T> {} |
@@ -747,7 +747,7 @@ fn foo(xs: Vec<$0>) | |||
747 | "Vec", | 747 | "Vec", |
748 | r#" | 748 | r#" |
749 | type Vec<T> = (T,); | 749 | type Vec<T> = (T,); |
750 | fn foo(xs: Ve<|>) | 750 | fn foo(xs: Ve$0) |
751 | "#, | 751 | "#, |
752 | r#" | 752 | r#" |
753 | type Vec<T> = (T,); | 753 | type Vec<T> = (T,); |
@@ -758,7 +758,7 @@ fn foo(xs: Vec<$0>) | |||
758 | "Vec", | 758 | "Vec", |
759 | r#" | 759 | r#" |
760 | struct Vec<T = i128> {} | 760 | struct Vec<T = i128> {} |
761 | fn foo(xs: Ve<|>) | 761 | fn foo(xs: Ve$0) |
762 | "#, | 762 | "#, |
763 | r#" | 763 | r#" |
764 | struct Vec<T = i128> {} | 764 | struct Vec<T = i128> {} |
@@ -769,7 +769,7 @@ fn foo(xs: Vec) | |||
769 | "Vec", | 769 | "Vec", |
770 | r#" | 770 | r#" |
771 | struct Vec<T> {} | 771 | struct Vec<T> {} |
772 | fn foo(xs: Ve<|><i128>) | 772 | fn foo(xs: Ve$0<i128>) |
773 | "#, | 773 | "#, |
774 | r#" | 774 | r#" |
775 | struct Vec<T> {} | 775 | struct Vec<T> {} |
@@ -785,7 +785,7 @@ fn foo(xs: Vec<i128>) | |||
785 | r#" | 785 | r#" |
786 | struct S { foo: i64, bar: u32, baz: u32 } | 786 | struct S { foo: i64, bar: u32, baz: u32 } |
787 | fn test(bar: u32) { } | 787 | fn test(bar: u32) { } |
788 | fn foo(s: S) { test(s.<|>) } | 788 | fn foo(s: S) { test(s.$0) } |
789 | "#, | 789 | "#, |
790 | expect![[r#" | 790 | expect![[r#" |
791 | fd bar [type+name] | 791 | fd bar [type+name] |
@@ -802,7 +802,7 @@ fn foo(s: S) { test(s.<|>) } | |||
802 | r#" | 802 | r#" |
803 | struct A { foo: i64, bar: u32, baz: u32 } | 803 | struct A { foo: i64, bar: u32, baz: u32 } |
804 | struct B { x: (), y: f32, bar: u32 } | 804 | struct B { x: (), y: f32, bar: u32 } |
805 | fn foo(a: A) { B { bar: a.<|> }; } | 805 | fn foo(a: A) { B { bar: a.$0 }; } |
806 | "#, | 806 | "#, |
807 | expect![[r#" | 807 | expect![[r#" |
808 | fd bar [type+name] | 808 | fd bar [type+name] |
@@ -819,7 +819,7 @@ fn foo(a: A) { B { bar: a.<|> }; } | |||
819 | struct A { foo: i64, bar: u32, baz: u32 } | 819 | struct A { foo: i64, bar: u32, baz: u32 } |
820 | struct B { x: (), y: f32, bar: u32 } | 820 | struct B { x: (), y: f32, bar: u32 } |
821 | fn f(foo: i64) { } | 821 | fn f(foo: i64) { } |
822 | fn foo(a: A) { B { bar: f(a.<|>) }; } | 822 | fn foo(a: A) { B { bar: f(a.$0) }; } |
823 | "#, | 823 | "#, |
824 | expect![[r#" | 824 | expect![[r#" |
825 | fd foo [type+name] | 825 | fd foo [type+name] |
@@ -832,7 +832,7 @@ fn foo(a: A) { B { bar: f(a.<|>) }; } | |||
832 | struct A { foo: i64, bar: u32, baz: u32 } | 832 | struct A { foo: i64, bar: u32, baz: u32 } |
833 | struct B { x: (), y: f32, bar: u32 } | 833 | struct B { x: (), y: f32, bar: u32 } |
834 | fn f(foo: i64) { } | 834 | fn f(foo: i64) { } |
835 | fn foo(a: A) { f(B { bar: a.<|> }); } | 835 | fn foo(a: A) { f(B { bar: a.$0 }); } |
836 | "#, | 836 | "#, |
837 | expect![[r#" | 837 | expect![[r#" |
838 | fd bar [type+name] | 838 | fd bar [type+name] |
@@ -847,7 +847,7 @@ fn foo(a: A) { f(B { bar: a.<|> }); } | |||
847 | check_scores( | 847 | check_scores( |
848 | r#" | 848 | r#" |
849 | struct WorldSnapshot { _f: () }; | 849 | struct WorldSnapshot { _f: () }; |
850 | fn go(world: &WorldSnapshot) { go(w<|>) } | 850 | fn go(world: &WorldSnapshot) { go(w$0) } |
851 | "#, | 851 | "#, |
852 | expect![[r#" | 852 | expect![[r#" |
853 | bn world [type+name] | 853 | bn world [type+name] |
@@ -862,7 +862,7 @@ fn go(world: &WorldSnapshot) { go(w<|>) } | |||
862 | check_scores( | 862 | check_scores( |
863 | r#" | 863 | r#" |
864 | struct Foo; | 864 | struct Foo; |
865 | fn f(foo: &Foo) { f(foo, w<|>) } | 865 | fn f(foo: &Foo) { f(foo, w$0) } |
866 | "#, | 866 | "#, |
867 | expect![[r#" | 867 | expect![[r#" |
868 | st Foo [] | 868 | st Foo [] |
diff --git a/crates/completion/src/render/enum_variant.rs b/crates/completion/src/render/enum_variant.rs index 732e139ec..89fb49773 100644 --- a/crates/completion/src/render/enum_variant.rs +++ b/crates/completion/src/render/enum_variant.rs | |||
@@ -115,7 +115,7 @@ mod tests { | |||
115 | enum Option<T> { Some(T), None } | 115 | enum Option<T> { Some(T), None } |
116 | use Option::*; | 116 | use Option::*; |
117 | fn main() -> Option<i32> { | 117 | fn main() -> Option<i32> { |
118 | Som<|> | 118 | Som$0 |
119 | } | 119 | } |
120 | "#, | 120 | "#, |
121 | r#" | 121 | r#" |
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs index 081be14f4..f5b0ce3e3 100644 --- a/crates/completion/src/render/function.rs +++ b/crates/completion/src/render/function.rs | |||
@@ -113,7 +113,7 @@ mod tests { | |||
113 | use test_utils::mark; | 113 | use test_utils::mark; |
114 | 114 | ||
115 | use crate::{ | 115 | use crate::{ |
116 | test_utils::{check_edit, check_edit_with_config}, | 116 | test_utils::{check_edit, check_edit_with_config, TEST_CONFIG}, |
117 | CompletionConfig, | 117 | CompletionConfig, |
118 | }; | 118 | }; |
119 | 119 | ||
@@ -124,7 +124,7 @@ mod tests { | |||
124 | "no_args", | 124 | "no_args", |
125 | r#" | 125 | r#" |
126 | fn no_args() {} | 126 | fn no_args() {} |
127 | fn main() { no_<|> } | 127 | fn main() { no_$0 } |
128 | "#, | 128 | "#, |
129 | r#" | 129 | r#" |
130 | fn no_args() {} | 130 | fn no_args() {} |
@@ -136,7 +136,7 @@ fn main() { no_args()$0 } | |||
136 | "with_args", | 136 | "with_args", |
137 | r#" | 137 | r#" |
138 | fn with_args(x: i32, y: String) {} | 138 | fn with_args(x: i32, y: String) {} |
139 | fn main() { with_<|> } | 139 | fn main() { with_$0 } |
140 | "#, | 140 | "#, |
141 | r#" | 141 | r#" |
142 | fn with_args(x: i32, y: String) {} | 142 | fn with_args(x: i32, y: String) {} |
@@ -151,7 +151,7 @@ struct S; | |||
151 | impl S { | 151 | impl S { |
152 | fn foo(&self) {} | 152 | fn foo(&self) {} |
153 | } | 153 | } |
154 | fn bar(s: &S) { s.f<|> } | 154 | fn bar(s: &S) { s.f$0 } |
155 | "#, | 155 | "#, |
156 | r#" | 156 | r#" |
157 | struct S; | 157 | struct S; |
@@ -170,7 +170,7 @@ impl S { | |||
170 | fn foo(&self, x: i32) {} | 170 | fn foo(&self, x: i32) {} |
171 | } | 171 | } |
172 | fn bar(s: &S) { | 172 | fn bar(s: &S) { |
173 | s.f<|> | 173 | s.f$0 |
174 | } | 174 | } |
175 | "#, | 175 | "#, |
176 | r#" | 176 | r#" |
@@ -195,7 +195,7 @@ struct S; | |||
195 | impl S { | 195 | impl S { |
196 | fn foo(&self) {} | 196 | fn foo(&self) {} |
197 | } | 197 | } |
198 | fn main() { S::f<|> } | 198 | fn main() { S::f$0 } |
199 | "#, | 199 | "#, |
200 | r#" | 200 | r#" |
201 | struct S; | 201 | struct S; |
@@ -211,11 +211,11 @@ fn main() { S::foo(${1:&self})$0 } | |||
211 | fn suppress_arg_snippets() { | 211 | fn suppress_arg_snippets() { |
212 | mark::check!(suppress_arg_snippets); | 212 | mark::check!(suppress_arg_snippets); |
213 | check_edit_with_config( | 213 | check_edit_with_config( |
214 | CompletionConfig { add_call_argument_snippets: false, ..CompletionConfig::default() }, | 214 | CompletionConfig { add_call_argument_snippets: false, ..TEST_CONFIG }, |
215 | "with_args", | 215 | "with_args", |
216 | r#" | 216 | r#" |
217 | fn with_args(x: i32, y: String) {} | 217 | fn with_args(x: i32, y: String) {} |
218 | fn main() { with_<|> } | 218 | fn main() { with_$0 } |
219 | "#, | 219 | "#, |
220 | r#" | 220 | r#" |
221 | fn with_args(x: i32, y: String) {} | 221 | fn with_args(x: i32, y: String) {} |
@@ -230,7 +230,7 @@ fn main() { with_args($0) } | |||
230 | "foo", | 230 | "foo", |
231 | r#" | 231 | r#" |
232 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} | 232 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} |
233 | fn main() { f<|> } | 233 | fn main() { f$0 } |
234 | "#, | 234 | "#, |
235 | r#" | 235 | r#" |
236 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} | 236 | fn foo(_foo: i32, ___bar: bool, ho_ge_: String) {} |
@@ -248,7 +248,7 @@ struct Foo {} | |||
248 | fn ref_arg(x: &Foo) {} | 248 | fn ref_arg(x: &Foo) {} |
249 | fn main() { | 249 | fn main() { |
250 | let x = Foo {}; | 250 | let x = Foo {}; |
251 | ref_ar<|> | 251 | ref_ar$0 |
252 | } | 252 | } |
253 | "#, | 253 | "#, |
254 | r#" | 254 | r#" |
@@ -271,7 +271,7 @@ struct Foo {} | |||
271 | fn ref_arg(x: &mut Foo) {} | 271 | fn ref_arg(x: &mut Foo) {} |
272 | fn main() { | 272 | fn main() { |
273 | let x = Foo {}; | 273 | let x = Foo {}; |
274 | ref_ar<|> | 274 | ref_ar$0 |
275 | } | 275 | } |
276 | "#, | 276 | "#, |
277 | r#" | 277 | r#" |
@@ -299,7 +299,7 @@ impl Bar { | |||
299 | fn main() { | 299 | fn main() { |
300 | let x = Foo {}; | 300 | let x = Foo {}; |
301 | let y = Bar {}; | 301 | let y = Bar {}; |
302 | y.<|> | 302 | y.$0 |
303 | } | 303 | } |
304 | "#, | 304 | "#, |
305 | r#" | 305 | r#" |
@@ -326,7 +326,7 @@ fn main() { | |||
326 | fn take_mutably(mut x: &i32) {} | 326 | fn take_mutably(mut x: &i32) {} |
327 | 327 | ||
328 | fn main() { | 328 | fn main() { |
329 | take_m<|> | 329 | take_m$0 |
330 | } | 330 | } |
331 | "#, | 331 | "#, |
332 | r#" | 332 | r#" |
diff --git a/crates/completion/src/render/macro_.rs b/crates/completion/src/render/macro_.rs index 6f4f9945c..f893e420a 100644 --- a/crates/completion/src/render/macro_.rs +++ b/crates/completion/src/render/macro_.rs | |||
@@ -135,7 +135,7 @@ mod tests { | |||
135 | "frobnicate!", | 135 | "frobnicate!", |
136 | r#" | 136 | r#" |
137 | //- /main.rs crate:main deps:foo | 137 | //- /main.rs crate:main deps:foo |
138 | use foo::<|>; | 138 | use foo::$0; |
139 | //- /foo/lib.rs crate:foo | 139 | //- /foo/lib.rs crate:foo |
140 | #[macro_export] | 140 | #[macro_export] |
141 | macro_rules! frobnicate { () => () } | 141 | macro_rules! frobnicate { () => () } |
@@ -149,7 +149,7 @@ use foo::frobnicate; | |||
149 | "frobnicate!", | 149 | "frobnicate!", |
150 | r#" | 150 | r#" |
151 | macro_rules! frobnicate { () => () } | 151 | macro_rules! frobnicate { () => () } |
152 | fn main() { frob<|>!(); } | 152 | fn main() { frob$0!(); } |
153 | "#, | 153 | "#, |
154 | r#" | 154 | r#" |
155 | macro_rules! frobnicate { () => () } | 155 | macro_rules! frobnicate { () => () } |
@@ -173,7 +173,7 @@ fn main() { frobnicate!(); } | |||
173 | /// ``` | 173 | /// ``` |
174 | macro_rules! vec { () => {} } | 174 | macro_rules! vec { () => {} } |
175 | 175 | ||
176 | fn fn main() { v<|> } | 176 | fn fn main() { v$0 } |
177 | "#, | 177 | "#, |
178 | r#" | 178 | r#" |
179 | /// Creates a [`Vec`] containing the arguments. | 179 | /// Creates a [`Vec`] containing the arguments. |
@@ -198,7 +198,7 @@ fn fn main() { vec![$0] } | |||
198 | /// Don't call `fooo!()` `fooo!()`, or `_foo![]` `_foo![]`, | 198 | /// Don't call `fooo!()` `fooo!()`, or `_foo![]` `_foo![]`, |
199 | /// call as `let _=foo! { hello world };` | 199 | /// call as `let _=foo! { hello world };` |
200 | macro_rules! foo { () => {} } | 200 | macro_rules! foo { () => {} } |
201 | fn main() { <|> } | 201 | fn main() { $0 } |
202 | "#, | 202 | "#, |
203 | r#" | 203 | r#" |
204 | /// Foo | 204 | /// Foo |
diff --git a/crates/completion/src/render/pattern.rs b/crates/completion/src/render/pattern.rs index a3b6a3cac..61d8a17e5 100644 --- a/crates/completion/src/render/pattern.rs +++ b/crates/completion/src/render/pattern.rs | |||
@@ -1,12 +1,10 @@ | |||
1 | //! Renderer for patterns. | 1 | //! Renderer for patterns. |
2 | 2 | ||
3 | use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; | 3 | use hir::{db::HirDatabase, HasAttrs, HasVisibility, Name, StructKind}; |
4 | use ide_db::helpers::SnippetCap; | ||
4 | use itertools::Itertools; | 5 | use itertools::Itertools; |
5 | 6 | ||
6 | use crate::{ | 7 | use crate::{item::CompletionKind, render::RenderContext, CompletionItem, CompletionItemKind}; |
7 | config::SnippetCap, item::CompletionKind, render::RenderContext, CompletionItem, | ||
8 | CompletionItemKind, | ||
9 | }; | ||
10 | 8 | ||
11 | fn visible_fields( | 9 | fn visible_fields( |
12 | ctx: &RenderContext<'_>, | 10 | ctx: &RenderContext<'_>, |
diff --git a/crates/completion/src/test_utils.rs b/crates/completion/src/test_utils.rs index eb0c16f52..3f4b9d4ac 100644 --- a/crates/completion/src/test_utils.rs +++ b/crates/completion/src/test_utils.rs | |||
@@ -1,8 +1,11 @@ | |||
1 | //! Runs completion for testing purposes. | 1 | //! Runs completion for testing purposes. |
2 | 2 | ||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::base_db::{fixture::ChangeFixture, FileLoader, FilePosition}; | 4 | use ide_db::{ |
5 | use ide_db::RootDatabase; | 5 | base_db::{fixture::ChangeFixture, FileLoader, FilePosition}, |
6 | helpers::{insert_use::MergeBehavior, SnippetCap}, | ||
7 | RootDatabase, | ||
8 | }; | ||
6 | use itertools::Itertools; | 9 | use itertools::Itertools; |
7 | use stdx::{format_to, trim_indent}; | 10 | use stdx::{format_to, trim_indent}; |
8 | use syntax::{AstNode, NodeOrToken, SyntaxElement}; | 11 | use syntax::{AstNode, NodeOrToken, SyntaxElement}; |
@@ -10,12 +13,21 @@ use test_utils::{assert_eq_text, RangeOrOffset}; | |||
10 | 13 | ||
11 | use crate::{item::CompletionKind, CompletionConfig, CompletionItem}; | 14 | use crate::{item::CompletionKind, CompletionConfig, CompletionItem}; |
12 | 15 | ||
13 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | 16 | pub(crate) const TEST_CONFIG: CompletionConfig = CompletionConfig { |
17 | enable_postfix_completions: true, | ||
18 | enable_autoimport_completions: true, | ||
19 | add_call_parenthesis: true, | ||
20 | add_call_argument_snippets: true, | ||
21 | snippet_cap: SnippetCap::new(true), | ||
22 | merge: Some(MergeBehavior::Full), | ||
23 | }; | ||
24 | |||
25 | /// Creates analysis from a multi-file fixture, returns positions marked with $0. | ||
14 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | 26 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { |
15 | let change_fixture = ChangeFixture::parse(ra_fixture); | 27 | let change_fixture = ChangeFixture::parse(ra_fixture); |
16 | let mut database = RootDatabase::default(); | 28 | let mut database = RootDatabase::default(); |
17 | database.apply_change(change_fixture.change); | 29 | database.apply_change(change_fixture.change); |
18 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 30 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
19 | let offset = match range_or_offset { | 31 | let offset = match range_or_offset { |
20 | RangeOrOffset::Range(_) => panic!(), | 32 | RangeOrOffset::Range(_) => panic!(), |
21 | RangeOrOffset::Offset(it) => it, | 33 | RangeOrOffset::Offset(it) => it, |
@@ -24,7 +36,7 @@ pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | |||
24 | } | 36 | } |
25 | 37 | ||
26 | pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> { | 38 | pub(crate) fn do_completion(code: &str, kind: CompletionKind) -> Vec<CompletionItem> { |
27 | do_completion_with_config(CompletionConfig::default(), code, kind) | 39 | do_completion_with_config(TEST_CONFIG, code, kind) |
28 | } | 40 | } |
29 | 41 | ||
30 | pub(crate) fn do_completion_with_config( | 42 | pub(crate) fn do_completion_with_config( |
@@ -39,7 +51,7 @@ pub(crate) fn do_completion_with_config( | |||
39 | } | 51 | } |
40 | 52 | ||
41 | pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String { | 53 | pub(crate) fn completion_list(code: &str, kind: CompletionKind) -> String { |
42 | completion_list_with_config(CompletionConfig::default(), code, kind) | 54 | completion_list_with_config(TEST_CONFIG, code, kind) |
43 | } | 55 | } |
44 | 56 | ||
45 | pub(crate) fn completion_list_with_config( | 57 | pub(crate) fn completion_list_with_config( |
@@ -76,7 +88,7 @@ fn monospace_width(s: &str) -> usize { | |||
76 | } | 88 | } |
77 | 89 | ||
78 | pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) { | 90 | pub(crate) fn check_edit(what: &str, ra_fixture_before: &str, ra_fixture_after: &str) { |
79 | check_edit_with_config(CompletionConfig::default(), what, ra_fixture_before, ra_fixture_after) | 91 | check_edit_with_config(TEST_CONFIG, what, ra_fixture_before, ra_fixture_after) |
80 | } | 92 | } |
81 | 93 | ||
82 | pub(crate) fn check_edit_with_config( | 94 | pub(crate) fn check_edit_with_config( |
diff --git a/crates/flycheck/Cargo.toml b/crates/flycheck/Cargo.toml index 3d9436d69..1bad64a1b 100644 --- a/crates/flycheck/Cargo.toml +++ b/crates/flycheck/Cargo.toml | |||
@@ -17,3 +17,4 @@ serde_json = "1.0.48" | |||
17 | jod-thread = "0.1.1" | 17 | jod-thread = "0.1.1" |
18 | 18 | ||
19 | toolchain = { path = "../toolchain", version = "0.0.0" } | 19 | toolchain = { path = "../toolchain", version = "0.0.0" } |
20 | stdx = { path = "../stdx", version = "0.0.0" } | ||
diff --git a/crates/flycheck/src/lib.rs b/crates/flycheck/src/lib.rs index d982c5f29..4388e8c67 100644 --- a/crates/flycheck/src/lib.rs +++ b/crates/flycheck/src/lib.rs | |||
@@ -5,13 +5,13 @@ | |||
5 | use std::{ | 5 | use std::{ |
6 | fmt, | 6 | fmt, |
7 | io::{self, BufReader}, | 7 | io::{self, BufReader}, |
8 | ops, | ||
9 | path::PathBuf, | 8 | path::PathBuf, |
10 | process::{self, Command, Stdio}, | 9 | process::{self, Command, Stdio}, |
11 | time::Duration, | 10 | time::Duration, |
12 | }; | 11 | }; |
13 | 12 | ||
14 | use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; | 13 | use crossbeam_channel::{never, select, unbounded, Receiver, Sender}; |
14 | use stdx::JodChild; | ||
15 | 15 | ||
16 | pub use cargo_metadata::diagnostic::{ | 16 | pub use cargo_metadata::diagnostic::{ |
17 | Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan, | 17 | Applicability, Diagnostic, DiagnosticCode, DiagnosticLevel, DiagnosticSpan, |
@@ -323,24 +323,3 @@ impl CargoActor { | |||
323 | Ok(read_at_least_one_message) | 323 | Ok(read_at_least_one_message) |
324 | } | 324 | } |
325 | } | 325 | } |
326 | |||
327 | struct JodChild(process::Child); | ||
328 | |||
329 | impl ops::Deref for JodChild { | ||
330 | type Target = process::Child; | ||
331 | fn deref(&self) -> &process::Child { | ||
332 | &self.0 | ||
333 | } | ||
334 | } | ||
335 | |||
336 | impl ops::DerefMut for JodChild { | ||
337 | fn deref_mut(&mut self) -> &mut process::Child { | ||
338 | &mut self.0 | ||
339 | } | ||
340 | } | ||
341 | |||
342 | impl Drop for JodChild { | ||
343 | fn drop(&mut self) { | ||
344 | let _ = self.0.kill(); | ||
345 | } | ||
346 | } | ||
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index 62eccf475..cc1938333 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -5,9 +5,7 @@ use arrayvec::ArrayVec; | |||
5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; | 5 | use base_db::{CrateDisplayName, CrateId, Edition, FileId}; |
6 | use either::Either; | 6 | use either::Either; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | adt::ReprKind, | 8 | adt::{ReprKind, StructKind, VariantData}, |
9 | adt::StructKind, | ||
10 | adt::VariantData, | ||
11 | builtin_type::BuiltinType, | 9 | builtin_type::BuiltinType, |
12 | expr::{BindingAnnotation, LabelId, Pat, PatId}, | 10 | expr::{BindingAnnotation, LabelId, Pat, PatId}, |
13 | import_map, | 11 | import_map, |
@@ -31,7 +29,7 @@ use hir_expand::{ | |||
31 | }; | 29 | }; |
32 | use hir_ty::{ | 30 | use hir_ty::{ |
33 | autoderef, | 31 | autoderef, |
34 | display::{HirDisplayError, HirFormatter}, | 32 | display::{write_bounds_like_dyn_trait, HirDisplayError, HirFormatter}, |
35 | method_resolution, | 33 | method_resolution, |
36 | traits::{FnTrait, Solution, SolutionVariables}, | 34 | traits::{FnTrait, Solution, SolutionVariables}, |
37 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, | 35 | ApplicationTy, BoundVar, CallableDefId, Canonical, DebruijnIndex, FnSig, GenericPredicate, |
@@ -745,6 +743,18 @@ impl Function { | |||
745 | db.function_data(self.id).name.clone() | 743 | db.function_data(self.id).name.clone() |
746 | } | 744 | } |
747 | 745 | ||
746 | /// Get this function's return type | ||
747 | pub fn ret_type(self, db: &dyn HirDatabase) -> Type { | ||
748 | let resolver = self.id.resolver(db.upcast()); | ||
749 | let ret_type = &db.function_data(self.id).ret_type; | ||
750 | let ctx = hir_ty::TyLoweringContext::new(db, &resolver); | ||
751 | let environment = TraitEnvironment::lower(db, &resolver); | ||
752 | Type { | ||
753 | krate: self.id.lookup(db.upcast()).container.module(db.upcast()).krate, | ||
754 | ty: InEnvironment { value: Ty::from_hir_ext(&ctx, ret_type).0, environment }, | ||
755 | } | ||
756 | } | ||
757 | |||
748 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { | 758 | pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> { |
749 | if !db.function_data(self.id).has_self_param { | 759 | if !db.function_data(self.id).has_self_param { |
750 | return None; | 760 | return None; |
@@ -1278,6 +1288,18 @@ impl TypeParam { | |||
1278 | } | 1288 | } |
1279 | } | 1289 | } |
1280 | 1290 | ||
1291 | pub fn trait_bounds(self, db: &dyn HirDatabase) -> Vec<Trait> { | ||
1292 | db.generic_predicates_for_param(self.id) | ||
1293 | .into_iter() | ||
1294 | .filter_map(|pred| match &pred.value { | ||
1295 | hir_ty::GenericPredicate::Implemented(trait_ref) => { | ||
1296 | Some(Trait::from(trait_ref.trait_)) | ||
1297 | } | ||
1298 | _ => None, | ||
1299 | }) | ||
1300 | .collect() | ||
1301 | } | ||
1302 | |||
1281 | pub fn default(self, db: &dyn HirDatabase) -> Option<Type> { | 1303 | pub fn default(self, db: &dyn HirDatabase) -> Option<Type> { |
1282 | let params = db.generic_defaults(self.id.parent); | 1304 | let params = db.generic_defaults(self.id.parent); |
1283 | let local_idx = hir_ty::param_idx(db, self.id)?; | 1305 | let local_idx = hir_ty::param_idx(db, self.id)?; |
@@ -1293,6 +1315,20 @@ impl TypeParam { | |||
1293 | } | 1315 | } |
1294 | } | 1316 | } |
1295 | 1317 | ||
1318 | impl HirDisplay for TypeParam { | ||
1319 | fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> { | ||
1320 | write!(f, "{}", self.name(f.db))?; | ||
1321 | let bounds = f.db.generic_predicates_for_param(self.id); | ||
1322 | let substs = Substs::type_params(f.db, self.id.parent); | ||
1323 | let predicates = bounds.iter().cloned().map(|b| b.subst(&substs)).collect::<Vec<_>>(); | ||
1324 | if !(predicates.is_empty() || f.omit_verbose_types()) { | ||
1325 | write!(f, ": ")?; | ||
1326 | write_bounds_like_dyn_trait(&predicates, f)?; | ||
1327 | } | ||
1328 | Ok(()) | ||
1329 | } | ||
1330 | } | ||
1331 | |||
1296 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1332 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1297 | pub struct LifetimeParam { | 1333 | pub struct LifetimeParam { |
1298 | pub(crate) id: LifetimeParamId, | 1334 | pub(crate) id: LifetimeParamId, |
@@ -1331,6 +1367,12 @@ impl ConstParam { | |||
1331 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { | 1367 | pub fn parent(self, _db: &dyn HirDatabase) -> GenericDef { |
1332 | self.id.parent.into() | 1368 | self.id.parent.into() |
1333 | } | 1369 | } |
1370 | |||
1371 | pub fn ty(self, db: &dyn HirDatabase) -> Type { | ||
1372 | let def = self.id.parent; | ||
1373 | let krate = def.module(db.upcast()).krate; | ||
1374 | Type::new(db, krate, def, db.const_param_ty(self.id)) | ||
1375 | } | ||
1334 | } | 1376 | } |
1335 | 1377 | ||
1336 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 1378 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -1600,9 +1642,10 @@ impl Type { | |||
1600 | } | 1642 | } |
1601 | 1643 | ||
1602 | pub fn is_fn(&self) -> bool { | 1644 | pub fn is_fn(&self) -> bool { |
1603 | matches!(&self.ty.value, | 1645 | matches!( |
1604 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) | | 1646 | &self.ty.value, |
1605 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | 1647 | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnDef(..), .. }) |
1648 | | Ty::Apply(ApplicationTy { ctor: TypeCtor::FnPtr { .. }, .. }) | ||
1606 | ) | 1649 | ) |
1607 | } | 1650 | } |
1608 | 1651 | ||
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs index b1c924167..447faa04f 100644 --- a/crates/hir/src/diagnostics.rs +++ b/crates/hir/src/diagnostics.rs | |||
@@ -4,6 +4,6 @@ pub use hir_expand::diagnostics::{ | |||
4 | Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, | 4 | Diagnostic, DiagnosticCode, DiagnosticSink, DiagnosticSinkBuilder, |
5 | }; | 5 | }; |
6 | pub use hir_ty::diagnostics::{ | 6 | pub use hir_ty::diagnostics::{ |
7 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, | 7 | IncorrectCase, MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, |
8 | NoSuchField, RemoveThisSemicolon, | 8 | NoSuchField, RemoveThisSemicolon, |
9 | }; | 9 | }; |
diff --git a/crates/hir_def/Cargo.toml b/crates/hir_def/Cargo.toml index e8b581e2f..7ef966cd2 100644 --- a/crates/hir_def/Cargo.toml +++ b/crates/hir_def/Cargo.toml | |||
@@ -33,4 +33,4 @@ cfg = { path = "../cfg", version = "0.0.0" } | |||
33 | tt = { path = "../tt", version = "0.0.0" } | 33 | tt = { path = "../tt", version = "0.0.0" } |
34 | 34 | ||
35 | [dev-dependencies] | 35 | [dev-dependencies] |
36 | expect-test = "1.0" | 36 | expect-test = "1.1" |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 6b79e7bad..9e6426b31 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use arena::map::ArenaMap; | ||
5 | use base_db::CrateId; | 6 | use base_db::CrateId; |
6 | use cfg::{CfgExpr, CfgOptions}; | 7 | use cfg::{CfgExpr, CfgOptions}; |
7 | use either::Either; | 8 | use either::Either; |
@@ -21,7 +22,8 @@ use crate::{ | |||
21 | nameres::ModuleSource, | 22 | nameres::ModuleSource, |
22 | path::{ModPath, PathKind}, | 23 | path::{ModPath, PathKind}, |
23 | src::HasChildSource, | 24 | src::HasChildSource, |
24 | AdtId, AttrDefId, GenericParamId, Lookup, | 25 | AdtId, AttrDefId, EnumId, GenericParamId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, |
26 | VariantId, | ||
25 | }; | 27 | }; |
26 | 28 | ||
27 | /// Holds documentation | 29 | /// Holds documentation |
@@ -210,16 +212,10 @@ impl Attrs { | |||
210 | } | 212 | } |
211 | } | 213 | } |
212 | AttrDefId::FieldId(it) => { | 214 | AttrDefId::FieldId(it) => { |
213 | let src = it.parent.child_source(db); | 215 | return db.fields_attrs(it.parent)[it.local_id].clone(); |
214 | match &src.value[it.local_id] { | ||
215 | Either::Left(_tuple) => RawAttrs::default(), | ||
216 | Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)), | ||
217 | } | ||
218 | } | 216 | } |
219 | AttrDefId::EnumVariantId(var_id) => { | 217 | AttrDefId::EnumVariantId(it) => { |
220 | let src = var_id.parent.child_source(db); | 218 | return db.variants_attrs(it.parent)[it.local_id].clone(); |
221 | let src = src.as_ref().map(|it| &it[var_id.local_id]); | ||
222 | RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) | ||
223 | } | 219 | } |
224 | AttrDefId::AdtId(it) => match it { | 220 | AttrDefId::AdtId(it) => match it { |
225 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 221 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
@@ -259,6 +255,46 @@ impl Attrs { | |||
259 | raw_attrs.filter(db, def.krate(db)) | 255 | raw_attrs.filter(db, def.krate(db)) |
260 | } | 256 | } |
261 | 257 | ||
258 | pub(crate) fn variants_attrs_query( | ||
259 | db: &dyn DefDatabase, | ||
260 | e: EnumId, | ||
261 | ) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>> { | ||
262 | let krate = e.lookup(db).container.module(db).krate; | ||
263 | let src = e.child_source(db); | ||
264 | let mut res = ArenaMap::default(); | ||
265 | |||
266 | for (id, var) in src.value.iter() { | ||
267 | let attrs = RawAttrs::from_attrs_owner(db, src.with_value(var as &dyn AttrsOwner)) | ||
268 | .filter(db, krate); | ||
269 | |||
270 | res.insert(id, attrs) | ||
271 | } | ||
272 | |||
273 | Arc::new(res) | ||
274 | } | ||
275 | |||
276 | pub(crate) fn fields_attrs_query( | ||
277 | db: &dyn DefDatabase, | ||
278 | v: VariantId, | ||
279 | ) -> Arc<ArenaMap<LocalFieldId, Attrs>> { | ||
280 | let krate = v.module(db).krate; | ||
281 | let src = v.child_source(db); | ||
282 | let mut res = ArenaMap::default(); | ||
283 | |||
284 | for (id, fld) in src.value.iter() { | ||
285 | let attrs = match fld { | ||
286 | Either::Left(_tuple) => Attrs::default(), | ||
287 | Either::Right(record) => { | ||
288 | RawAttrs::from_attrs_owner(db, src.with_value(record)).filter(db, krate) | ||
289 | } | ||
290 | }; | ||
291 | |||
292 | res.insert(id, attrs); | ||
293 | } | ||
294 | |||
295 | Arc::new(res) | ||
296 | } | ||
297 | |||
262 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { | 298 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { |
263 | AttrQuery { attrs: self, key } | 299 | AttrQuery { attrs: self, key } |
264 | } | 300 | } |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 17c72779b..6be1eaade 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -695,7 +695,7 @@ impl ExprCollector<'_> { | |||
695 | self.collect_stmts_items(block.statements()); | 695 | self.collect_stmts_items(block.statements()); |
696 | let statements = | 696 | let statements = |
697 | block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); | 697 | block.statements().filter_map(|s| self.collect_stmt(s)).flatten().collect(); |
698 | let tail = block.expr().map(|e| self.collect_expr(e)); | 698 | let tail = block.tail_expr().map(|e| self.collect_expr(e)); |
699 | self.alloc_expr(Expr::Block { statements, tail, label: None }, syntax_node_ptr) | 699 | self.alloc_expr(Expr::Block { statements, tail, label: None }, syntax_node_ptr) |
700 | } | 700 | } |
701 | 701 | ||
diff --git a/crates/hir_def/src/body/scope.rs b/crates/hir_def/src/body/scope.rs index 9142bc05b..065785da7 100644 --- a/crates/hir_def/src/body/scope.rs +++ b/crates/hir_def/src/body/scope.rs | |||
@@ -194,7 +194,7 @@ mod tests { | |||
194 | let mut buf = String::new(); | 194 | let mut buf = String::new(); |
195 | let off: usize = offset.into(); | 195 | let off: usize = offset.into(); |
196 | buf.push_str(&code[..off]); | 196 | buf.push_str(&code[..off]); |
197 | buf.push_str("<|>marker"); | 197 | buf.push_str("$0marker"); |
198 | buf.push_str(&code[off..]); | 198 | buf.push_str(&code[off..]); |
199 | buf | 199 | buf |
200 | }; | 200 | }; |
@@ -231,7 +231,7 @@ mod tests { | |||
231 | r" | 231 | r" |
232 | fn quux(foo: i32) { | 232 | fn quux(foo: i32) { |
233 | let f = |bar, baz: i32| { | 233 | let f = |bar, baz: i32| { |
234 | <|> | 234 | $0 |
235 | }; | 235 | }; |
236 | }", | 236 | }", |
237 | &["bar", "baz", "foo"], | 237 | &["bar", "baz", "foo"], |
@@ -243,7 +243,7 @@ mod tests { | |||
243 | do_check( | 243 | do_check( |
244 | r" | 244 | r" |
245 | fn quux() { | 245 | fn quux() { |
246 | f(|x| <|> ); | 246 | f(|x| $0 ); |
247 | }", | 247 | }", |
248 | &["x"], | 248 | &["x"], |
249 | ); | 249 | ); |
@@ -254,7 +254,7 @@ mod tests { | |||
254 | do_check( | 254 | do_check( |
255 | r" | 255 | r" |
256 | fn quux() { | 256 | fn quux() { |
257 | z.f(|x| <|> ); | 257 | z.f(|x| $0 ); |
258 | }", | 258 | }", |
259 | &["x"], | 259 | &["x"], |
260 | ); | 260 | ); |
@@ -267,7 +267,7 @@ mod tests { | |||
267 | fn quux() { | 267 | fn quux() { |
268 | loop { | 268 | loop { |
269 | let x = (); | 269 | let x = (); |
270 | <|> | 270 | $0 |
271 | }; | 271 | }; |
272 | }", | 272 | }", |
273 | &["x"], | 273 | &["x"], |
@@ -281,7 +281,7 @@ mod tests { | |||
281 | fn quux() { | 281 | fn quux() { |
282 | match () { | 282 | match () { |
283 | Some(x) => { | 283 | Some(x) => { |
284 | <|> | 284 | $0 |
285 | } | 285 | } |
286 | }; | 286 | }; |
287 | }", | 287 | }", |
@@ -294,7 +294,7 @@ mod tests { | |||
294 | do_check( | 294 | do_check( |
295 | r" | 295 | r" |
296 | fn foo(x: String) { | 296 | fn foo(x: String) { |
297 | let x : &str = &x<|>; | 297 | let x : &str = &x$0; |
298 | }", | 298 | }", |
299 | &["x"], | 299 | &["x"], |
300 | ); | 300 | ); |
@@ -307,7 +307,7 @@ mod tests { | |||
307 | fn foo() { | 307 | fn foo() { |
308 | match Some(()) { | 308 | match Some(()) { |
309 | opt @ Some(unit) => { | 309 | opt @ Some(unit) => { |
310 | <|> | 310 | $0 |
311 | } | 311 | } |
312 | _ => {} | 312 | _ => {} |
313 | } | 313 | } |
@@ -330,7 +330,7 @@ fn foo() { | |||
330 | 330 | ||
331 | fn foo() { | 331 | fn foo() { |
332 | mac!(); | 332 | mac!(); |
333 | <|> | 333 | $0 |
334 | } | 334 | } |
335 | ", | 335 | ", |
336 | &[], | 336 | &[], |
@@ -343,7 +343,7 @@ fn foo() { | |||
343 | r" | 343 | r" |
344 | fn foo() { | 344 | fn foo() { |
345 | trait {} | 345 | trait {} |
346 | <|> | 346 | $0 |
347 | } | 347 | } |
348 | ", | 348 | ", |
349 | &[], | 349 | &[], |
@@ -391,7 +391,7 @@ fn foo(x: i32, y: u32) { | |||
391 | let z = x * 2; | 391 | let z = x * 2; |
392 | } | 392 | } |
393 | { | 393 | { |
394 | let t = x<|> * 3; | 394 | let t = x$0 * 3; |
395 | } | 395 | } |
396 | } | 396 | } |
397 | "#, | 397 | "#, |
@@ -404,7 +404,7 @@ fn foo(x: i32, y: u32) { | |||
404 | do_check_local_name( | 404 | do_check_local_name( |
405 | r#" | 405 | r#" |
406 | fn foo(x: String) { | 406 | fn foo(x: String) { |
407 | let x : &str = &x<|>; | 407 | let x : &str = &x$0; |
408 | } | 408 | } |
409 | "#, | 409 | "#, |
410 | 7, | 410 | 7, |
@@ -417,7 +417,7 @@ fn foo(x: String) { | |||
417 | r" | 417 | r" |
418 | fn foo(x: String) { | 418 | fn foo(x: String) { |
419 | let x : &str = &x; | 419 | let x : &str = &x; |
420 | x<|> | 420 | x$0 |
421 | } | 421 | } |
422 | ", | 422 | ", |
423 | 28, | 423 | 28, |
@@ -430,7 +430,7 @@ fn foo(x: String) { | |||
430 | r" | 430 | r" |
431 | fn foo() { | 431 | fn foo() { |
432 | if let Some(&from) = bar() { | 432 | if let Some(&from) = bar() { |
433 | from<|>; | 433 | from$0; |
434 | } | 434 | } |
435 | } | 435 | } |
436 | ", | 436 | ", |
@@ -446,7 +446,7 @@ fn foo() { | |||
446 | fn test() { | 446 | fn test() { |
447 | let foo: Option<f32> = None; | 447 | let foo: Option<f32> = None; |
448 | while let Option::Some(spam) = foo { | 448 | while let Option::Some(spam) = foo { |
449 | spam<|> | 449 | spam$0 |
450 | } | 450 | } |
451 | } | 451 | } |
452 | "#, | 452 | "#, |
diff --git a/crates/hir_def/src/db.rs b/crates/hir_def/src/db.rs index d1a459066..d3bf5b34c 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -1,6 +1,7 @@ | |||
1 | //! Defines database & queries for name resolution. | 1 | //! Defines database & queries for name resolution. |
2 | use std::sync::Arc; | 2 | use std::sync::Arc; |
3 | 3 | ||
4 | use arena::map::ArenaMap; | ||
4 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; | 5 | use base_db::{salsa, CrateId, SourceDatabase, Upcast}; |
5 | use hir_expand::{db::AstDatabase, HirFileId}; | 6 | use hir_expand::{db::AstDatabase, HirFileId}; |
6 | use syntax::SmolStr; | 7 | use syntax::SmolStr; |
@@ -16,8 +17,8 @@ use crate::{ | |||
16 | lang_item::{LangItemTarget, LangItems}, | 17 | lang_item::{LangItemTarget, LangItems}, |
17 | nameres::CrateDefMap, | 18 | nameres::CrateDefMap, |
18 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, | 19 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, |
19 | GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, | 20 | GenericDefId, ImplId, ImplLoc, LocalEnumVariantId, LocalFieldId, StaticId, StaticLoc, StructId, |
20 | TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, | 21 | StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, VariantId, |
21 | }; | 22 | }; |
22 | 23 | ||
23 | #[salsa::query_group(InternDatabaseStorage)] | 24 | #[salsa::query_group(InternDatabaseStorage)] |
@@ -92,6 +93,12 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
92 | #[salsa::invoke(GenericParams::generic_params_query)] | 93 | #[salsa::invoke(GenericParams::generic_params_query)] |
93 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; | 94 | fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>; |
94 | 95 | ||
96 | #[salsa::invoke(Attrs::variants_attrs_query)] | ||
97 | fn variants_attrs(&self, def: EnumId) -> Arc<ArenaMap<LocalEnumVariantId, Attrs>>; | ||
98 | |||
99 | #[salsa::invoke(Attrs::fields_attrs_query)] | ||
100 | fn fields_attrs(&self, def: VariantId) -> Arc<ArenaMap<LocalFieldId, Attrs>>; | ||
101 | |||
95 | #[salsa::invoke(Attrs::attrs_query)] | 102 | #[salsa::invoke(Attrs::attrs_query)] |
96 | fn attrs(&self, def: AttrDefId) -> Attrs; | 103 | fn attrs(&self, def: AttrDefId) -> Attrs; |
97 | 104 | ||
diff --git a/crates/hir_def/src/diagnostics.rs b/crates/hir_def/src/diagnostics.rs index c71266dc0..ab3f059ce 100644 --- a/crates/hir_def/src/diagnostics.rs +++ b/crates/hir_def/src/diagnostics.rs | |||
@@ -133,6 +133,10 @@ impl Diagnostic for InactiveCode { | |||
133 | // This diagnostic is shown when a procedural macro can not be found. This usually means that | 133 | // This diagnostic is shown when a procedural macro can not be found. This usually means that |
134 | // procedural macro support is simply disabled (and hence is only a weak hint instead of an error), | 134 | // procedural macro support is simply disabled (and hence is only a weak hint instead of an error), |
135 | // but can also indicate project setup problems. | 135 | // but can also indicate project setup problems. |
136 | // | ||
137 | // If you are seeing a lot of "proc macro not expanded" warnings, you can add this option to the | ||
138 | // `rust-analyzer.diagnostics.disabled` list to prevent them from showing. Alternatively you can | ||
139 | // enable support for procedural macros (see `rust-analyzer.procMacro.enable`). | ||
136 | #[derive(Debug, Clone, Eq, PartialEq)] | 140 | #[derive(Debug, Clone, Eq, PartialEq)] |
137 | pub struct UnresolvedProcMacro { | 141 | pub struct UnresolvedProcMacro { |
138 | pub file: HirFileId, | 142 | pub file: HirFileId, |
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs index 02613c4c4..4a212d291 100644 --- a/crates/hir_def/src/find_path.rs +++ b/crates/hir_def/src/find_path.rs | |||
@@ -410,7 +410,7 @@ mod tests { | |||
410 | let code = r#" | 410 | let code = r#" |
411 | //- /main.rs | 411 | //- /main.rs |
412 | struct S; | 412 | struct S; |
413 | <|> | 413 | $0 |
414 | "#; | 414 | "#; |
415 | check_found_path(code, "S", "S", "crate::S", "self::S"); | 415 | check_found_path(code, "S", "S", "crate::S", "self::S"); |
416 | } | 416 | } |
@@ -420,7 +420,7 @@ mod tests { | |||
420 | let code = r#" | 420 | let code = r#" |
421 | //- /main.rs | 421 | //- /main.rs |
422 | enum E { A } | 422 | enum E { A } |
423 | <|> | 423 | $0 |
424 | "#; | 424 | "#; |
425 | check_found_path(code, "E::A", "E::A", "E::A", "E::A"); | 425 | check_found_path(code, "E::A", "E::A", "E::A", "E::A"); |
426 | } | 426 | } |
@@ -432,7 +432,7 @@ mod tests { | |||
432 | mod foo { | 432 | mod foo { |
433 | pub struct S; | 433 | pub struct S; |
434 | } | 434 | } |
435 | <|> | 435 | $0 |
436 | "#; | 436 | "#; |
437 | check_found_path(code, "foo::S", "foo::S", "crate::foo::S", "self::foo::S"); | 437 | check_found_path(code, "foo::S", "foo::S", "crate::foo::S", "self::foo::S"); |
438 | } | 438 | } |
@@ -446,7 +446,7 @@ mod tests { | |||
446 | mod bar; | 446 | mod bar; |
447 | struct S; | 447 | struct S; |
448 | //- /foo/bar.rs | 448 | //- /foo/bar.rs |
449 | <|> | 449 | $0 |
450 | "#; | 450 | "#; |
451 | check_found_path(code, "super::S", "super::S", "crate::foo::S", "super::S"); | 451 | check_found_path(code, "super::S", "super::S", "crate::foo::S", "super::S"); |
452 | } | 452 | } |
@@ -457,7 +457,7 @@ mod tests { | |||
457 | //- /main.rs | 457 | //- /main.rs |
458 | mod foo; | 458 | mod foo; |
459 | //- /foo.rs | 459 | //- /foo.rs |
460 | <|> | 460 | $0 |
461 | "#; | 461 | "#; |
462 | check_found_path(code, "self", "self", "crate::foo", "self"); | 462 | check_found_path(code, "self", "self", "crate::foo", "self"); |
463 | } | 463 | } |
@@ -468,7 +468,7 @@ mod tests { | |||
468 | //- /main.rs | 468 | //- /main.rs |
469 | mod foo; | 469 | mod foo; |
470 | //- /foo.rs | 470 | //- /foo.rs |
471 | <|> | 471 | $0 |
472 | "#; | 472 | "#; |
473 | check_found_path(code, "crate", "crate", "crate", "crate"); | 473 | check_found_path(code, "crate", "crate", "crate", "crate"); |
474 | } | 474 | } |
@@ -480,7 +480,7 @@ mod tests { | |||
480 | mod foo; | 480 | mod foo; |
481 | struct S; | 481 | struct S; |
482 | //- /foo.rs | 482 | //- /foo.rs |
483 | <|> | 483 | $0 |
484 | "#; | 484 | "#; |
485 | check_found_path(code, "crate::S", "crate::S", "crate::S", "crate::S"); | 485 | check_found_path(code, "crate::S", "crate::S", "crate::S", "crate::S"); |
486 | } | 486 | } |
@@ -489,7 +489,7 @@ mod tests { | |||
489 | fn different_crate() { | 489 | fn different_crate() { |
490 | let code = r#" | 490 | let code = r#" |
491 | //- /main.rs crate:main deps:std | 491 | //- /main.rs crate:main deps:std |
492 | <|> | 492 | $0 |
493 | //- /std.rs crate:std | 493 | //- /std.rs crate:std |
494 | pub struct S; | 494 | pub struct S; |
495 | "#; | 495 | "#; |
@@ -501,7 +501,7 @@ mod tests { | |||
501 | let code = r#" | 501 | let code = r#" |
502 | //- /main.rs crate:main deps:std | 502 | //- /main.rs crate:main deps:std |
503 | extern crate std as std_renamed; | 503 | extern crate std as std_renamed; |
504 | <|> | 504 | $0 |
505 | //- /std.rs crate:std | 505 | //- /std.rs crate:std |
506 | pub struct S; | 506 | pub struct S; |
507 | "#; | 507 | "#; |
@@ -523,7 +523,7 @@ mod tests { | |||
523 | //- /main.rs crate:main deps:syntax | 523 | //- /main.rs crate:main deps:syntax |
524 | 524 | ||
525 | use syntax::ast; | 525 | use syntax::ast; |
526 | <|> | 526 | $0 |
527 | 527 | ||
528 | //- /lib.rs crate:syntax | 528 | //- /lib.rs crate:syntax |
529 | pub mod ast { | 529 | pub mod ast { |
@@ -543,7 +543,7 @@ mod tests { | |||
543 | let code = r#" | 543 | let code = r#" |
544 | //- /main.rs crate:main deps:syntax | 544 | //- /main.rs crate:main deps:syntax |
545 | 545 | ||
546 | <|> | 546 | $0 |
547 | 547 | ||
548 | //- /lib.rs crate:syntax | 548 | //- /lib.rs crate:syntax |
549 | pub mod ast { | 549 | pub mod ast { |
@@ -569,7 +569,7 @@ mod tests { | |||
569 | mod foo { pub(super) struct S; } | 569 | mod foo { pub(super) struct S; } |
570 | pub(crate) use foo::*; | 570 | pub(crate) use foo::*; |
571 | } | 571 | } |
572 | <|> | 572 | $0 |
573 | "#; | 573 | "#; |
574 | check_found_path(code, "bar::S", "bar::S", "crate::bar::S", "self::bar::S"); | 574 | check_found_path(code, "bar::S", "bar::S", "crate::bar::S", "self::bar::S"); |
575 | } | 575 | } |
@@ -582,7 +582,7 @@ mod tests { | |||
582 | mod foo { pub(super) struct S; } | 582 | mod foo { pub(super) struct S; } |
583 | pub(crate) use foo::S as U; | 583 | pub(crate) use foo::S as U; |
584 | } | 584 | } |
585 | <|> | 585 | $0 |
586 | "#; | 586 | "#; |
587 | check_found_path(code, "bar::U", "bar::U", "crate::bar::U", "self::bar::U"); | 587 | check_found_path(code, "bar::U", "bar::U", "crate::bar::U", "self::bar::U"); |
588 | } | 588 | } |
@@ -591,7 +591,7 @@ mod tests { | |||
591 | fn different_crate_reexport() { | 591 | fn different_crate_reexport() { |
592 | let code = r#" | 592 | let code = r#" |
593 | //- /main.rs crate:main deps:std | 593 | //- /main.rs crate:main deps:std |
594 | <|> | 594 | $0 |
595 | //- /std.rs crate:std deps:core | 595 | //- /std.rs crate:std deps:core |
596 | pub use core::S; | 596 | pub use core::S; |
597 | //- /core.rs crate:core | 597 | //- /core.rs crate:core |
@@ -604,7 +604,7 @@ mod tests { | |||
604 | fn prelude() { | 604 | fn prelude() { |
605 | let code = r#" | 605 | let code = r#" |
606 | //- /main.rs crate:main deps:std | 606 | //- /main.rs crate:main deps:std |
607 | <|> | 607 | $0 |
608 | //- /std.rs crate:std | 608 | //- /std.rs crate:std |
609 | pub mod prelude { pub struct S; } | 609 | pub mod prelude { pub struct S; } |
610 | #[prelude_import] | 610 | #[prelude_import] |
@@ -617,7 +617,7 @@ mod tests { | |||
617 | fn enum_variant_from_prelude() { | 617 | fn enum_variant_from_prelude() { |
618 | let code = r#" | 618 | let code = r#" |
619 | //- /main.rs crate:main deps:std | 619 | //- /main.rs crate:main deps:std |
620 | <|> | 620 | $0 |
621 | //- /std.rs crate:std | 621 | //- /std.rs crate:std |
622 | pub mod prelude { | 622 | pub mod prelude { |
623 | pub enum Option<T> { Some(T), None } | 623 | pub enum Option<T> { Some(T), None } |
@@ -637,7 +637,7 @@ mod tests { | |||
637 | pub mod foo; | 637 | pub mod foo; |
638 | pub mod baz; | 638 | pub mod baz; |
639 | struct S; | 639 | struct S; |
640 | <|> | 640 | $0 |
641 | //- /foo.rs | 641 | //- /foo.rs |
642 | pub mod bar { pub struct S; } | 642 | pub mod bar { pub struct S; } |
643 | //- /baz.rs | 643 | //- /baz.rs |
@@ -654,7 +654,7 @@ mod tests { | |||
654 | pub mod bar { pub struct S; } | 654 | pub mod bar { pub struct S; } |
655 | use bar::S; | 655 | use bar::S; |
656 | //- /foo.rs | 656 | //- /foo.rs |
657 | <|> | 657 | $0 |
658 | "#; | 658 | "#; |
659 | // crate::S would be shorter, but using private imports seems wrong | 659 | // crate::S would be shorter, but using private imports seems wrong |
660 | check_found_path(code, "crate::bar::S", "crate::bar::S", "crate::bar::S", "crate::bar::S"); | 660 | check_found_path(code, "crate::bar::S", "crate::bar::S", "crate::bar::S", "crate::bar::S"); |
@@ -668,7 +668,7 @@ mod tests { | |||
668 | pub mod bar; | 668 | pub mod bar; |
669 | pub mod baz; | 669 | pub mod baz; |
670 | //- /bar.rs | 670 | //- /bar.rs |
671 | <|> | 671 | $0 |
672 | //- /foo.rs | 672 | //- /foo.rs |
673 | pub use super::baz; | 673 | pub use super::baz; |
674 | pub struct S; | 674 | pub struct S; |
@@ -683,7 +683,7 @@ mod tests { | |||
683 | mark::check!(prefer_std_paths); | 683 | mark::check!(prefer_std_paths); |
684 | let code = r#" | 684 | let code = r#" |
685 | //- /main.rs crate:main deps:alloc,std | 685 | //- /main.rs crate:main deps:alloc,std |
686 | <|> | 686 | $0 |
687 | 687 | ||
688 | //- /std.rs crate:std deps:alloc | 688 | //- /std.rs crate:std deps:alloc |
689 | pub mod sync { | 689 | pub mod sync { |
@@ -711,7 +711,7 @@ mod tests { | |||
711 | //- /main.rs crate:main deps:core,std | 711 | //- /main.rs crate:main deps:core,std |
712 | #![no_std] | 712 | #![no_std] |
713 | 713 | ||
714 | <|> | 714 | $0 |
715 | 715 | ||
716 | //- /std.rs crate:std deps:core | 716 | //- /std.rs crate:std deps:core |
717 | 717 | ||
@@ -740,7 +740,7 @@ mod tests { | |||
740 | //- /main.rs crate:main deps:alloc,std | 740 | //- /main.rs crate:main deps:alloc,std |
741 | #![no_std] | 741 | #![no_std] |
742 | 742 | ||
743 | <|> | 743 | $0 |
744 | 744 | ||
745 | //- /std.rs crate:std deps:alloc | 745 | //- /std.rs crate:std deps:alloc |
746 | 746 | ||
@@ -767,7 +767,7 @@ mod tests { | |||
767 | fn prefer_shorter_paths_if_not_alloc() { | 767 | fn prefer_shorter_paths_if_not_alloc() { |
768 | let code = r#" | 768 | let code = r#" |
769 | //- /main.rs crate:main deps:megaalloc,std | 769 | //- /main.rs crate:main deps:megaalloc,std |
770 | <|> | 770 | $0 |
771 | 771 | ||
772 | //- /std.rs crate:std deps:megaalloc | 772 | //- /std.rs crate:std deps:megaalloc |
773 | pub mod sync { | 773 | pub mod sync { |
@@ -790,7 +790,7 @@ mod tests { | |||
790 | fn builtins_are_in_scope() { | 790 | fn builtins_are_in_scope() { |
791 | let code = r#" | 791 | let code = r#" |
792 | //- /main.rs | 792 | //- /main.rs |
793 | <|> | 793 | $0 |
794 | 794 | ||
795 | pub mod primitive { | 795 | pub mod primitive { |
796 | pub use u8; | 796 | pub use u8; |
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs index 30b22f51d..e5368b293 100644 --- a/crates/hir_def/src/import_map.rs +++ b/crates/hir_def/src/import_map.rs | |||
@@ -7,9 +7,8 @@ use fst::{self, Streamer}; | |||
7 | use hir_expand::name::Name; | 7 | use hir_expand::name::Name; |
8 | use indexmap::{map::Entry, IndexMap}; | 8 | use indexmap::{map::Entry, IndexMap}; |
9 | use itertools::Itertools; | 9 | use itertools::Itertools; |
10 | use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; | 10 | use rustc_hash::{FxHashSet, FxHasher}; |
11 | use smallvec::SmallVec; | 11 | use test_utils::mark; |
12 | use syntax::SmolStr; | ||
13 | 12 | ||
14 | use crate::{ | 13 | use crate::{ |
15 | db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId, | 14 | db::DefDatabase, item_scope::ItemInNs, visibility::Visibility, AssocItemId, ModuleDefId, |
@@ -25,6 +24,8 @@ pub struct ImportInfo { | |||
25 | pub path: ImportPath, | 24 | pub path: ImportPath, |
26 | /// The module containing this item. | 25 | /// The module containing this item. |
27 | pub container: ModuleId, | 26 | pub container: ModuleId, |
27 | /// Whether the import is a trait associated item or not. | ||
28 | pub is_trait_assoc_item: bool, | ||
28 | } | 29 | } |
29 | 30 | ||
30 | #[derive(Debug, Clone, Eq, PartialEq)] | 31 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -64,10 +65,6 @@ pub struct ImportMap { | |||
64 | /// the index of the first one. | 65 | /// the index of the first one. |
65 | importables: Vec<ItemInNs>, | 66 | importables: Vec<ItemInNs>, |
66 | fst: fst::Map<Vec<u8>>, | 67 | fst: fst::Map<Vec<u8>>, |
67 | |||
68 | /// Maps names of associated items to the item's ID. Only includes items whose defining trait is | ||
69 | /// exported. | ||
70 | assoc_map: FxHashMap<SmolStr, SmallVec<[AssocItemId; 1]>>, | ||
71 | } | 68 | } |
72 | 69 | ||
73 | impl ImportMap { | 70 | impl ImportMap { |
@@ -108,14 +105,27 @@ impl ImportMap { | |||
108 | 105 | ||
109 | for item in per_ns.iter_items() { | 106 | for item in per_ns.iter_items() { |
110 | let path = mk_path(); | 107 | let path = mk_path(); |
108 | let path_len = path.len(); | ||
109 | let import_info = | ||
110 | ImportInfo { path, container: module, is_trait_assoc_item: false }; | ||
111 | |||
112 | if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() { | ||
113 | import_map.collect_trait_assoc_items( | ||
114 | db, | ||
115 | tr, | ||
116 | matches!(item, ItemInNs::Types(_)), | ||
117 | &import_info, | ||
118 | ); | ||
119 | } | ||
120 | |||
111 | match import_map.map.entry(item) { | 121 | match import_map.map.entry(item) { |
112 | Entry::Vacant(entry) => { | 122 | Entry::Vacant(entry) => { |
113 | entry.insert(ImportInfo { path, container: module }); | 123 | entry.insert(import_info); |
114 | } | 124 | } |
115 | Entry::Occupied(mut entry) => { | 125 | Entry::Occupied(mut entry) => { |
116 | // If the new path is shorter, prefer that one. | 126 | // If the new path is shorter, prefer that one. |
117 | if path.len() < entry.get().path.len() { | 127 | if path_len < entry.get().path.len() { |
118 | *entry.get_mut() = ImportInfo { path, container: module }; | 128 | *entry.get_mut() = import_info; |
119 | } else { | 129 | } else { |
120 | continue; | 130 | continue; |
121 | } | 131 | } |
@@ -128,11 +138,6 @@ impl ImportMap { | |||
128 | if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() { | 138 | if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() { |
129 | worklist.push((mod_id, mk_path())); | 139 | worklist.push((mod_id, mk_path())); |
130 | } | 140 | } |
131 | |||
132 | // If we've added a path to a trait, add the trait's methods to the method map. | ||
133 | if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() { | ||
134 | import_map.collect_trait_methods(db, tr); | ||
135 | } | ||
136 | } | 141 | } |
137 | } | 142 | } |
138 | } | 143 | } |
@@ -153,12 +158,10 @@ impl ImportMap { | |||
153 | } | 158 | } |
154 | } | 159 | } |
155 | 160 | ||
156 | let start = last_batch_start; | 161 | let key = fst_path(&importables[last_batch_start].1.path); |
157 | last_batch_start = idx + 1; | 162 | builder.insert(key, last_batch_start as u64).unwrap(); |
158 | |||
159 | let key = fst_path(&importables[start].1.path); | ||
160 | 163 | ||
161 | builder.insert(key, start as u64).unwrap(); | 164 | last_batch_start = idx + 1; |
162 | } | 165 | } |
163 | 166 | ||
164 | import_map.fst = fst::Map::new(builder.into_inner().unwrap()).unwrap(); | 167 | import_map.fst = fst::Map::new(builder.into_inner().unwrap()).unwrap(); |
@@ -176,10 +179,34 @@ impl ImportMap { | |||
176 | self.map.get(&item) | 179 | self.map.get(&item) |
177 | } | 180 | } |
178 | 181 | ||
179 | fn collect_trait_methods(&mut self, db: &dyn DefDatabase, tr: TraitId) { | 182 | fn collect_trait_assoc_items( |
180 | let data = db.trait_data(tr); | 183 | &mut self, |
181 | for (name, item) in data.items.iter() { | 184 | db: &dyn DefDatabase, |
182 | self.assoc_map.entry(name.to_string().into()).or_default().push(*item); | 185 | tr: TraitId, |
186 | is_type_in_ns: bool, | ||
187 | original_import_info: &ImportInfo, | ||
188 | ) { | ||
189 | for (assoc_item_name, item) in &db.trait_data(tr).items { | ||
190 | let module_def_id = match item { | ||
191 | AssocItemId::FunctionId(f) => ModuleDefId::from(*f), | ||
192 | AssocItemId::ConstId(c) => ModuleDefId::from(*c), | ||
193 | // cannot use associated type aliases directly: need a `<Struct as Trait>::TypeAlias` | ||
194 | // qualifier, ergo no need to store it for imports in import_map | ||
195 | AssocItemId::TypeAliasId(_) => { | ||
196 | mark::hit!(type_aliases_ignored); | ||
197 | continue; | ||
198 | } | ||
199 | }; | ||
200 | let assoc_item = if is_type_in_ns { | ||
201 | ItemInNs::Types(module_def_id) | ||
202 | } else { | ||
203 | ItemInNs::Values(module_def_id) | ||
204 | }; | ||
205 | |||
206 | let mut assoc_item_info = original_import_info.clone(); | ||
207 | assoc_item_info.path.segments.push(assoc_item_name.to_owned()); | ||
208 | assoc_item_info.is_trait_assoc_item = true; | ||
209 | self.map.insert(assoc_item, assoc_item_info); | ||
183 | } | 210 | } |
184 | } | 211 | } |
185 | } | 212 | } |
@@ -302,38 +329,38 @@ impl Query { | |||
302 | self.exclude_import_kinds.insert(import_kind); | 329 | self.exclude_import_kinds.insert(import_kind); |
303 | self | 330 | self |
304 | } | 331 | } |
305 | } | ||
306 | 332 | ||
307 | fn contains_query(query: &Query, input_path: &ImportPath, enforce_lowercase: bool) -> bool { | 333 | fn import_matches(&self, import: &ImportInfo, enforce_lowercase: bool) -> bool { |
308 | let mut input = if query.name_only { | 334 | let mut input = if import.is_trait_assoc_item || self.name_only { |
309 | input_path.segments.last().unwrap().to_string() | 335 | import.path.segments.last().unwrap().to_string() |
310 | } else { | 336 | } else { |
311 | input_path.to_string() | 337 | import.path.to_string() |
312 | }; | 338 | }; |
313 | if enforce_lowercase || !query.case_sensitive { | 339 | if enforce_lowercase || !self.case_sensitive { |
314 | input.make_ascii_lowercase(); | 340 | input.make_ascii_lowercase(); |
315 | } | 341 | } |
316 | 342 | ||
317 | let query_string = | 343 | let query_string = |
318 | if !enforce_lowercase && query.case_sensitive { &query.query } else { &query.lowercased }; | 344 | if !enforce_lowercase && self.case_sensitive { &self.query } else { &self.lowercased }; |
319 | 345 | ||
320 | match query.search_mode { | 346 | match self.search_mode { |
321 | SearchMode::Equals => &input == query_string, | 347 | SearchMode::Equals => &input == query_string, |
322 | SearchMode::Contains => input.contains(query_string), | 348 | SearchMode::Contains => input.contains(query_string), |
323 | SearchMode::Fuzzy => { | 349 | SearchMode::Fuzzy => { |
324 | let mut unchecked_query_chars = query_string.chars(); | 350 | let mut unchecked_query_chars = query_string.chars(); |
325 | let mut mismatching_query_char = unchecked_query_chars.next(); | 351 | let mut mismatching_query_char = unchecked_query_chars.next(); |
326 | 352 | ||
327 | for input_char in input.chars() { | 353 | for input_char in input.chars() { |
328 | match mismatching_query_char { | 354 | match mismatching_query_char { |
329 | None => return true, | 355 | None => return true, |
330 | Some(matching_query_char) if matching_query_char == input_char => { | 356 | Some(matching_query_char) if matching_query_char == input_char => { |
331 | mismatching_query_char = unchecked_query_chars.next(); | 357 | mismatching_query_char = unchecked_query_chars.next(); |
358 | } | ||
359 | _ => (), | ||
332 | } | 360 | } |
333 | _ => (), | ||
334 | } | 361 | } |
362 | mismatching_query_char.is_none() | ||
335 | } | 363 | } |
336 | mismatching_query_char.is_none() | ||
337 | } | 364 | } |
338 | } | 365 | } |
339 | } | 366 | } |
@@ -366,13 +393,13 @@ pub fn search_dependencies<'a>( | |||
366 | let import_map = &import_maps[indexed_value.index]; | 393 | let import_map = &import_maps[indexed_value.index]; |
367 | let importables = &import_map.importables[indexed_value.value as usize..]; | 394 | let importables = &import_map.importables[indexed_value.value as usize..]; |
368 | 395 | ||
369 | // Path shared by the importable items in this group. | 396 | let common_importable_data = &import_map.map[&importables[0]]; |
370 | let common_importables_path = &import_map.map[&importables[0]].path; | 397 | if !query.import_matches(common_importable_data, true) { |
371 | if !contains_query(&query, common_importables_path, true) { | ||
372 | continue; | 398 | continue; |
373 | } | 399 | } |
374 | 400 | ||
375 | let common_importables_path_fst = fst_path(common_importables_path); | 401 | // Path shared by the importable items in this group. |
402 | let common_importables_path_fst = fst_path(&common_importable_data.path); | ||
376 | // Add the items from this `ModPath` group. Those are all subsequent items in | 403 | // Add the items from this `ModPath` group. Those are all subsequent items in |
377 | // `importables` whose paths match `path`. | 404 | // `importables` whose paths match `path`. |
378 | let iter = importables | 405 | let iter = importables |
@@ -387,7 +414,7 @@ pub fn search_dependencies<'a>( | |||
387 | }) | 414 | }) |
388 | .filter(|item| { | 415 | .filter(|item| { |
389 | !query.case_sensitive // we've already checked the common importables path case-insensitively | 416 | !query.case_sensitive // we've already checked the common importables path case-insensitively |
390 | || contains_query(&query, &import_map.map[item].path, false) | 417 | || query.import_matches(&import_map.map[item], false) |
391 | }); | 418 | }); |
392 | res.extend(iter); | 419 | res.extend(iter); |
393 | 420 | ||
@@ -398,19 +425,6 @@ pub fn search_dependencies<'a>( | |||
398 | } | 425 | } |
399 | } | 426 | } |
400 | 427 | ||
401 | // Add all exported associated items whose names match the query (exactly). | ||
402 | for map in &import_maps { | ||
403 | if let Some(v) = map.assoc_map.get(&*query.query) { | ||
404 | res.extend(v.iter().map(|&assoc| { | ||
405 | ItemInNs::Types(match assoc { | ||
406 | AssocItemId::FunctionId(it) => it.into(), | ||
407 | AssocItemId::ConstId(it) => it.into(), | ||
408 | AssocItemId::TypeAliasId(it) => it.into(), | ||
409 | }) | ||
410 | })); | ||
411 | } | ||
412 | } | ||
413 | |||
414 | res | 428 | res |
415 | } | 429 | } |
416 | 430 | ||
@@ -432,9 +446,9 @@ fn item_import_kind(item: ItemInNs) -> Option<ImportKind> { | |||
432 | mod tests { | 446 | mod tests { |
433 | use base_db::{fixture::WithFixture, SourceDatabase, Upcast}; | 447 | use base_db::{fixture::WithFixture, SourceDatabase, Upcast}; |
434 | use expect_test::{expect, Expect}; | 448 | use expect_test::{expect, Expect}; |
435 | use stdx::format_to; | 449 | use test_utils::mark; |
436 | 450 | ||
437 | use crate::{data::FunctionData, test_db::TestDB, AssocContainerId, Lookup}; | 451 | use crate::{test_db::TestDB, AssocContainerId, Lookup}; |
438 | 452 | ||
439 | use super::*; | 453 | use super::*; |
440 | 454 | ||
@@ -451,46 +465,66 @@ mod tests { | |||
451 | 465 | ||
452 | let actual = search_dependencies(db.upcast(), krate, query) | 466 | let actual = search_dependencies(db.upcast(), krate, query) |
453 | .into_iter() | 467 | .into_iter() |
454 | .filter_map(|item| { | 468 | .filter_map(|dependency| { |
455 | let mark = match item { | 469 | let dependency_krate = dependency.krate(db.upcast())?; |
456 | ItemInNs::Types(ModuleDefId::FunctionId(_)) | 470 | let dependency_imports = db.import_map(dependency_krate); |
457 | | ItemInNs::Values(ModuleDefId::FunctionId(_)) => "f", | 471 | |
458 | ItemInNs::Types(_) => "t", | 472 | let (path, mark) = match assoc_item_path(&db, &dependency_imports, dependency) { |
459 | ItemInNs::Values(_) => "v", | 473 | Some(assoc_item_path) => (assoc_item_path, "a"), |
460 | ItemInNs::Macros(_) => "m", | 474 | None => ( |
475 | dependency_imports.path_of(dependency)?.to_string(), | ||
476 | match dependency { | ||
477 | ItemInNs::Types(ModuleDefId::FunctionId(_)) | ||
478 | | ItemInNs::Values(ModuleDefId::FunctionId(_)) => "f", | ||
479 | ItemInNs::Types(_) => "t", | ||
480 | ItemInNs::Values(_) => "v", | ||
481 | ItemInNs::Macros(_) => "m", | ||
482 | }, | ||
483 | ), | ||
461 | }; | 484 | }; |
462 | item.krate(db.upcast()).map(|krate| { | 485 | |
463 | let map = db.import_map(krate); | 486 | Some(format!( |
464 | 487 | "{}::{} ({})\n", | |
465 | let path = match assoc_to_trait(&db, item) { | 488 | crate_graph[dependency_krate].display_name.as_ref()?, |
466 | Some(trait_) => { | 489 | path, |
467 | let mut full_path = map.path_of(trait_).unwrap().to_string(); | 490 | mark |
468 | if let ItemInNs::Types(ModuleDefId::FunctionId(function_id)) | 491 | )) |
469 | | ItemInNs::Values(ModuleDefId::FunctionId(function_id)) = item | ||
470 | { | ||
471 | format_to!( | ||
472 | full_path, | ||
473 | "::{}", | ||
474 | FunctionData::fn_data_query(&db, function_id).name, | ||
475 | ); | ||
476 | } | ||
477 | full_path | ||
478 | } | ||
479 | None => map.path_of(item).unwrap().to_string(), | ||
480 | }; | ||
481 | |||
482 | format!( | ||
483 | "{}::{} ({})\n", | ||
484 | crate_graph[krate].display_name.as_ref().unwrap(), | ||
485 | path, | ||
486 | mark | ||
487 | ) | ||
488 | }) | ||
489 | }) | 492 | }) |
490 | .collect::<String>(); | 493 | .collect::<String>(); |
491 | expect.assert_eq(&actual) | 494 | expect.assert_eq(&actual) |
492 | } | 495 | } |
493 | 496 | ||
497 | fn assoc_item_path( | ||
498 | db: &dyn DefDatabase, | ||
499 | dependency_imports: &ImportMap, | ||
500 | dependency: ItemInNs, | ||
501 | ) -> Option<String> { | ||
502 | let dependency_assoc_item_id = match dependency { | ||
503 | ItemInNs::Types(ModuleDefId::FunctionId(id)) | ||
504 | | ItemInNs::Values(ModuleDefId::FunctionId(id)) => AssocItemId::from(id), | ||
505 | ItemInNs::Types(ModuleDefId::ConstId(id)) | ||
506 | | ItemInNs::Values(ModuleDefId::ConstId(id)) => AssocItemId::from(id), | ||
507 | ItemInNs::Types(ModuleDefId::TypeAliasId(id)) | ||
508 | | ItemInNs::Values(ModuleDefId::TypeAliasId(id)) => AssocItemId::from(id), | ||
509 | _ => return None, | ||
510 | }; | ||
511 | |||
512 | let trait_ = assoc_to_trait(db, dependency)?; | ||
513 | if let ModuleDefId::TraitId(tr) = trait_.as_module_def_id()? { | ||
514 | let trait_data = db.trait_data(tr); | ||
515 | let assoc_item_name = | ||
516 | trait_data.items.iter().find_map(|(assoc_item_name, assoc_item_id)| { | ||
517 | if &dependency_assoc_item_id == assoc_item_id { | ||
518 | Some(assoc_item_name) | ||
519 | } else { | ||
520 | None | ||
521 | } | ||
522 | })?; | ||
523 | return Some(format!("{}::{}", dependency_imports.path_of(trait_)?, assoc_item_name)); | ||
524 | } | ||
525 | None | ||
526 | } | ||
527 | |||
494 | fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> Option<ItemInNs> { | 528 | fn assoc_to_trait(db: &dyn DefDatabase, item: ItemInNs) -> Option<ItemInNs> { |
495 | let assoc: AssocItemId = match item { | 529 | let assoc: AssocItemId = match item { |
496 | ItemInNs::Types(it) | ItemInNs::Values(it) => match it { | 530 | ItemInNs::Types(it) | ItemInNs::Values(it) => match it { |
@@ -749,6 +783,37 @@ mod tests { | |||
749 | } | 783 | } |
750 | 784 | ||
751 | #[test] | 785 | #[test] |
786 | fn fuzzy_import_trait_and_assoc_items() { | ||
787 | mark::check!(type_aliases_ignored); | ||
788 | let ra_fixture = r#" | ||
789 | //- /main.rs crate:main deps:dep | ||
790 | //- /dep.rs crate:dep | ||
791 | pub mod fmt { | ||
792 | pub trait Display { | ||
793 | type FmtTypeAlias; | ||
794 | const FMT_CONST: bool; | ||
795 | |||
796 | fn format_function(); | ||
797 | fn format_method(&self); | ||
798 | } | ||
799 | } | ||
800 | "#; | ||
801 | |||
802 | check_search( | ||
803 | ra_fixture, | ||
804 | "main", | ||
805 | Query::new("fmt".to_string()).search_mode(SearchMode::Fuzzy), | ||
806 | expect![[r#" | ||
807 | dep::fmt (t) | ||
808 | dep::fmt::Display (t) | ||
809 | dep::fmt::Display::FMT_CONST (a) | ||
810 | dep::fmt::Display::format_function (a) | ||
811 | dep::fmt::Display::format_method (a) | ||
812 | "#]], | ||
813 | ); | ||
814 | } | ||
815 | |||
816 | #[test] | ||
752 | fn search_mode() { | 817 | fn search_mode() { |
753 | let ra_fixture = r#" | 818 | let ra_fixture = r#" |
754 | //- /main.rs crate:main deps:dep | 819 | //- /main.rs crate:main deps:dep |
@@ -784,8 +849,8 @@ mod tests { | |||
784 | dep::Fmt (v) | 849 | dep::Fmt (v) |
785 | dep::Fmt (m) | 850 | dep::Fmt (m) |
786 | dep::fmt::Display (t) | 851 | dep::fmt::Display (t) |
852 | dep::fmt::Display::fmt (a) | ||
787 | dep::format (f) | 853 | dep::format (f) |
788 | dep::fmt::Display::fmt (f) | ||
789 | "#]], | 854 | "#]], |
790 | ); | 855 | ); |
791 | 856 | ||
@@ -798,7 +863,7 @@ mod tests { | |||
798 | dep::Fmt (t) | 863 | dep::Fmt (t) |
799 | dep::Fmt (v) | 864 | dep::Fmt (v) |
800 | dep::Fmt (m) | 865 | dep::Fmt (m) |
801 | dep::fmt::Display::fmt (f) | 866 | dep::fmt::Display::fmt (a) |
802 | "#]], | 867 | "#]], |
803 | ); | 868 | ); |
804 | 869 | ||
@@ -812,7 +877,7 @@ mod tests { | |||
812 | dep::Fmt (v) | 877 | dep::Fmt (v) |
813 | dep::Fmt (m) | 878 | dep::Fmt (m) |
814 | dep::fmt::Display (t) | 879 | dep::fmt::Display (t) |
815 | dep::fmt::Display::fmt (f) | 880 | dep::fmt::Display::fmt (a) |
816 | "#]], | 881 | "#]], |
817 | ); | 882 | ); |
818 | } | 883 | } |
@@ -853,7 +918,7 @@ mod tests { | |||
853 | dep::Fmt (v) | 918 | dep::Fmt (v) |
854 | dep::Fmt (m) | 919 | dep::Fmt (m) |
855 | dep::fmt::Display (t) | 920 | dep::fmt::Display (t) |
856 | dep::fmt::Display::fmt (f) | 921 | dep::fmt::Display::fmt (a) |
857 | "#]], | 922 | "#]], |
858 | ); | 923 | ); |
859 | 924 | ||
@@ -866,7 +931,7 @@ mod tests { | |||
866 | dep::Fmt (t) | 931 | dep::Fmt (t) |
867 | dep::Fmt (v) | 932 | dep::Fmt (v) |
868 | dep::Fmt (m) | 933 | dep::Fmt (m) |
869 | dep::fmt::Display::fmt (f) | 934 | dep::fmt::Display::fmt (a) |
870 | "#]], | 935 | "#]], |
871 | ); | 936 | ); |
872 | } | 937 | } |
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index 62ab3b2bd..2750e1c91 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs | |||
@@ -10,10 +10,9 @@ use once_cell::sync::Lazy; | |||
10 | use rustc_hash::{FxHashMap, FxHashSet}; | 10 | use rustc_hash::{FxHashMap, FxHashSet}; |
11 | use test_utils::mark; | 11 | use test_utils::mark; |
12 | 12 | ||
13 | use crate::ModuleId; | ||
14 | use crate::{ | 13 | use crate::{ |
15 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, | 14 | db::DefDatabase, per_ns::PerNs, visibility::Visibility, AdtId, BuiltinType, HasModule, ImplId, |
16 | LocalModuleId, Lookup, MacroDefId, ModuleDefId, TraitId, | 15 | LocalModuleId, Lookup, MacroDefId, ModuleDefId, ModuleId, TraitId, |
17 | }; | 16 | }; |
18 | 17 | ||
19 | #[derive(Copy, Clone)] | 18 | #[derive(Copy, Clone)] |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index a636ec77d..77017e4ea 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -13,7 +13,7 @@ use hir_expand::{ | |||
13 | builtin_macro::find_builtin_macro, | 13 | builtin_macro::find_builtin_macro, |
14 | name::{AsName, Name}, | 14 | name::{AsName, Name}, |
15 | proc_macro::ProcMacroExpander, | 15 | proc_macro::ProcMacroExpander, |
16 | HirFileId, MacroCallId, MacroDefId, MacroDefKind, | 16 | HirFileId, MacroCallId, MacroCallKind, MacroDefId, MacroDefKind, |
17 | }; | 17 | }; |
18 | use hir_expand::{InFile, MacroCallLoc}; | 18 | use hir_expand::{InFile, MacroCallLoc}; |
19 | use rustc_hash::{FxHashMap, FxHashSet}; | 19 | use rustc_hash::{FxHashMap, FxHashSet}; |
@@ -860,6 +860,37 @@ impl DefCollector<'_> { | |||
860 | } | 860 | } |
861 | 861 | ||
862 | fn finish(mut self) -> CrateDefMap { | 862 | fn finish(mut self) -> CrateDefMap { |
863 | // Emit diagnostics for all remaining unexpanded macros. | ||
864 | |||
865 | for directive in &self.unexpanded_macros { | ||
866 | let mut error = None; | ||
867 | directive.ast_id.as_call_id_with_errors( | ||
868 | self.db, | ||
869 | self.def_map.krate, | ||
870 | |path| { | ||
871 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | ||
872 | self.db, | ||
873 | ResolveMode::Other, | ||
874 | directive.module_id, | ||
875 | &path, | ||
876 | BuiltinShadowMode::Module, | ||
877 | ); | ||
878 | resolved_res.resolved_def.take_macros() | ||
879 | }, | ||
880 | &mut |e| { | ||
881 | error.get_or_insert(e); | ||
882 | }, | ||
883 | ); | ||
884 | |||
885 | if let Some(err) = error { | ||
886 | self.def_map.diagnostics.push(DefDiagnostic::macro_error( | ||
887 | directive.module_id, | ||
888 | MacroCallKind::FnLike(directive.ast_id.ast_id), | ||
889 | err.to_string(), | ||
890 | )); | ||
891 | } | ||
892 | } | ||
893 | |||
863 | // Emit diagnostics for all remaining unresolved imports. | 894 | // Emit diagnostics for all remaining unresolved imports. |
864 | 895 | ||
865 | // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't | 896 | // We'd like to avoid emitting a diagnostics avalanche when some `extern crate` doesn't |
diff --git a/crates/hir_def/src/nameres/tests/incremental.rs b/crates/hir_def/src/nameres/tests/incremental.rs index 8981fa7c9..509e1bbbc 100644 --- a/crates/hir_def/src/nameres/tests/incremental.rs +++ b/crates/hir_def/src/nameres/tests/incremental.rs | |||
@@ -28,7 +28,7 @@ fn typing_inside_a_function_should_not_invalidate_def_map() { | |||
28 | check_def_map_is_not_recomputed( | 28 | check_def_map_is_not_recomputed( |
29 | r" | 29 | r" |
30 | //- /lib.rs | 30 | //- /lib.rs |
31 | mod foo;<|> | 31 | mod foo;$0 |
32 | 32 | ||
33 | use crate::foo::bar::Baz; | 33 | use crate::foo::bar::Baz; |
34 | 34 | ||
@@ -81,7 +81,7 @@ fn typing_inside_a_macro_should_not_invalidate_def_map() { | |||
81 | pub mod bar; | 81 | pub mod bar; |
82 | 82 | ||
83 | //- /foo/bar.rs | 83 | //- /foo/bar.rs |
84 | <|> | 84 | $0 |
85 | m!(X); | 85 | m!(X); |
86 | ", | 86 | ", |
87 | ); | 87 | ); |
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs index e2bf85bbc..3dd7c3cbb 100644 --- a/crates/hir_def/src/path.rs +++ b/crates/hir_def/src/path.rs | |||
@@ -305,6 +305,7 @@ pub use hir_expand::name as __name; | |||
305 | macro_rules! __known_path { | 305 | macro_rules! __known_path { |
306 | (core::iter::IntoIterator) => {}; | 306 | (core::iter::IntoIterator) => {}; |
307 | (core::result::Result) => {}; | 307 | (core::result::Result) => {}; |
308 | (core::option::Option) => {}; | ||
308 | (core::ops::Range) => {}; | 309 | (core::ops::Range) => {}; |
309 | (core::ops::RangeFrom) => {}; | 310 | (core::ops::RangeFrom) => {}; |
310 | (core::ops::RangeFull) => {}; | 311 | (core::ops::RangeFull) => {}; |
diff --git a/crates/hir_expand/src/builtin_derive.rs b/crates/hir_expand/src/builtin_derive.rs index ad378762a..eb257579f 100644 --- a/crates/hir_expand/src/builtin_derive.rs +++ b/crates/hir_expand/src/builtin_derive.rs | |||
@@ -277,7 +277,7 @@ mod tests { | |||
277 | let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap(); | 277 | let expander = BuiltinDeriveExpander::find_by_name(&name).unwrap(); |
278 | let fixture = format!( | 278 | let fixture = format!( |
279 | r#"//- /main.rs crate:main deps:core | 279 | r#"//- /main.rs crate:main deps:core |
280 | <|> | 280 | $0 |
281 | {} | 281 | {} |
282 | //- /lib.rs crate:core | 282 | //- /lib.rs crate:core |
283 | // empty | 283 | // empty |
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 2f44876a8..95d853b6d 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -164,6 +164,7 @@ pub mod known { | |||
164 | future, | 164 | future, |
165 | result, | 165 | result, |
166 | boxed, | 166 | boxed, |
167 | option, | ||
167 | // Components of known path (type name) | 168 | // Components of known path (type name) |
168 | Iterator, | 169 | Iterator, |
169 | IntoIterator, | 170 | IntoIterator, |
@@ -172,6 +173,7 @@ pub mod known { | |||
172 | Ok, | 173 | Ok, |
173 | Future, | 174 | Future, |
174 | Result, | 175 | Result, |
176 | Option, | ||
175 | Output, | 177 | Output, |
176 | Target, | 178 | Target, |
177 | Box, | 179 | Box, |
diff --git a/crates/hir_expand/src/proc_macro.rs b/crates/hir_expand/src/proc_macro.rs index 7c77f6ce0..1923daca5 100644 --- a/crates/hir_expand/src/proc_macro.rs +++ b/crates/hir_expand/src/proc_macro.rs | |||
@@ -58,7 +58,7 @@ impl ProcMacroExpander { | |||
58 | } | 58 | } |
59 | 59 | ||
60 | fn eat_punct(cursor: &mut Cursor, c: char) -> bool { | 60 | fn eat_punct(cursor: &mut Cursor, c: char) -> bool { |
61 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = cursor.token_tree() { | 61 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(punct), _)) = cursor.token_tree() { |
62 | if punct.char == c { | 62 | if punct.char == c { |
63 | *cursor = cursor.bump(); | 63 | *cursor = cursor.bump(); |
64 | return true; | 64 | return true; |
@@ -68,7 +68,7 @@ fn eat_punct(cursor: &mut Cursor, c: char) -> bool { | |||
68 | } | 68 | } |
69 | 69 | ||
70 | fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { | 70 | fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { |
71 | if let Some(tt::TokenTree::Subtree(subtree)) = cursor.token_tree() { | 71 | if let Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) = cursor.token_tree() { |
72 | if Some(kind) == subtree.delimiter_kind() { | 72 | if Some(kind) == subtree.delimiter_kind() { |
73 | *cursor = cursor.bump_subtree(); | 73 | *cursor = cursor.bump_subtree(); |
74 | return true; | 74 | return true; |
@@ -78,7 +78,7 @@ fn eat_subtree(cursor: &mut Cursor, kind: tt::DelimiterKind) -> bool { | |||
78 | } | 78 | } |
79 | 79 | ||
80 | fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { | 80 | fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { |
81 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) = cursor.token_tree() { | 81 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Ident(ident), _)) = cursor.token_tree() { |
82 | if t == ident.text.as_str() { | 82 | if t == ident.text.as_str() { |
83 | *cursor = cursor.bump(); | 83 | *cursor = cursor.bump(); |
84 | return true; | 84 | return true; |
@@ -88,7 +88,7 @@ fn eat_ident(cursor: &mut Cursor, t: &str) -> bool { | |||
88 | } | 88 | } |
89 | 89 | ||
90 | fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { | 90 | fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { |
91 | let buffer = TokenBuffer::new(&tt.token_trees); | 91 | let buffer = TokenBuffer::from_tokens(&tt.token_trees); |
92 | let mut p = buffer.begin(); | 92 | let mut p = buffer.begin(); |
93 | let mut result = tt::Subtree::default(); | 93 | let mut result = tt::Subtree::default(); |
94 | 94 | ||
@@ -106,7 +106,7 @@ fn remove_derive_attrs(tt: &tt::Subtree) -> Option<tt::Subtree> { | |||
106 | } | 106 | } |
107 | } | 107 | } |
108 | 108 | ||
109 | result.token_trees.push(curr.token_tree()?.clone()); | 109 | result.token_trees.push(curr.token_tree()?.cloned()); |
110 | p = curr.bump(); | 110 | p = curr.bump(); |
111 | } | 111 | } |
112 | 112 | ||
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml index 2dfccd191..b0a453961 100644 --- a/crates/hir_ty/Cargo.toml +++ b/crates/hir_ty/Cargo.toml | |||
@@ -17,9 +17,9 @@ ena = "0.14.0" | |||
17 | log = "0.4.8" | 17 | log = "0.4.8" |
18 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
19 | scoped-tls = "1" | 19 | scoped-tls = "1" |
20 | chalk-solve = { version = "0.45", default-features = false } | 20 | chalk-solve = { version = "0.47", default-features = false } |
21 | chalk-ir = "0.45" | 21 | chalk-ir = "0.47" |
22 | chalk-recursive = "0.45" | 22 | chalk-recursive = "0.47" |
23 | 23 | ||
24 | stdx = { path = "../stdx", version = "0.0.0" } | 24 | stdx = { path = "../stdx", version = "0.0.0" } |
25 | hir_def = { path = "../hir_def", version = "0.0.0" } | 25 | hir_def = { path = "../hir_def", version = "0.0.0" } |
@@ -31,7 +31,7 @@ syntax = { path = "../syntax", version = "0.0.0" } | |||
31 | test_utils = { path = "../test_utils", version = "0.0.0" } | 31 | test_utils = { path = "../test_utils", version = "0.0.0" } |
32 | 32 | ||
33 | [dev-dependencies] | 33 | [dev-dependencies] |
34 | expect-test = "1.0" | 34 | expect-test = "1.1" |
35 | tracing = "0.1" | 35 | tracing = "0.1" |
36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } | 36 | tracing-subscriber = { version = "0.2", default-features = false, features = ["env-filter", "registry"] } |
37 | tracing-tree = { version = "0.1.4" } | 37 | tracing-tree = { version = "0.1.4" } |
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs index 14e18f5a1..c67a289f2 100644 --- a/crates/hir_ty/src/diagnostics.rs +++ b/crates/hir_ty/src/diagnostics.rs | |||
@@ -186,9 +186,10 @@ impl Diagnostic for MissingMatchArms { | |||
186 | } | 186 | } |
187 | } | 187 | } |
188 | 188 | ||
189 | // Diagnostic: missing-ok-in-tail-expr | 189 | // Diagnostic: missing-ok-or-some-in-tail-expr |
190 | // | 190 | // |
191 | // This diagnostic is triggered if block that should return `Result` returns a value not wrapped in `Ok`. | 191 | // This diagnostic is triggered if a block that should return `Result` returns a value not wrapped in `Ok`, |
192 | // or if a block that should return `Option` returns a value not wrapped in `Some`. | ||
192 | // | 193 | // |
193 | // Example: | 194 | // Example: |
194 | // | 195 | // |
@@ -198,17 +199,19 @@ impl Diagnostic for MissingMatchArms { | |||
198 | // } | 199 | // } |
199 | // ``` | 200 | // ``` |
200 | #[derive(Debug)] | 201 | #[derive(Debug)] |
201 | pub struct MissingOkInTailExpr { | 202 | pub struct MissingOkOrSomeInTailExpr { |
202 | pub file: HirFileId, | 203 | pub file: HirFileId, |
203 | pub expr: AstPtr<ast::Expr>, | 204 | pub expr: AstPtr<ast::Expr>, |
205 | // `Some` or `Ok` depending on whether the return type is Result or Option | ||
206 | pub required: String, | ||
204 | } | 207 | } |
205 | 208 | ||
206 | impl Diagnostic for MissingOkInTailExpr { | 209 | impl Diagnostic for MissingOkOrSomeInTailExpr { |
207 | fn code(&self) -> DiagnosticCode { | 210 | fn code(&self) -> DiagnosticCode { |
208 | DiagnosticCode("missing-ok-in-tail-expr") | 211 | DiagnosticCode("missing-ok-or-some-in-tail-expr") |
209 | } | 212 | } |
210 | fn message(&self) -> String { | 213 | fn message(&self) -> String { |
211 | "wrap return expression in Ok".to_string() | 214 | format!("wrap return expression in {}", self.required) |
212 | } | 215 | } |
213 | fn display_source(&self) -> InFile<SyntaxNodePtr> { | 216 | fn display_source(&self) -> InFile<SyntaxNodePtr> { |
214 | InFile { file_id: self.file, value: self.expr.clone().into() } | 217 | InFile { file_id: self.file, value: self.expr.clone().into() } |
diff --git a/crates/hir_ty/src/diagnostics/expr.rs b/crates/hir_ty/src/diagnostics/expr.rs index b4e453411..a1c484fdf 100644 --- a/crates/hir_ty/src/diagnostics/expr.rs +++ b/crates/hir_ty/src/diagnostics/expr.rs | |||
@@ -11,8 +11,8 @@ use crate::{ | |||
11 | db::HirDatabase, | 11 | db::HirDatabase, |
12 | diagnostics::{ | 12 | diagnostics::{ |
13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, | 13 | match_check::{is_useful, MatchCheckCtx, Matrix, PatStack, Usefulness}, |
14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkInTailExpr, MissingPatFields, | 14 | MismatchedArgCount, MissingFields, MissingMatchArms, MissingOkOrSomeInTailExpr, |
15 | RemoveThisSemicolon, | 15 | MissingPatFields, RemoveThisSemicolon, |
16 | }, | 16 | }, |
17 | utils::variant_data, | 17 | utils::variant_data, |
18 | ApplicationTy, InferenceResult, Ty, TypeCtor, | 18 | ApplicationTy, InferenceResult, Ty, TypeCtor, |
@@ -306,27 +306,40 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
306 | }; | 306 | }; |
307 | 307 | ||
308 | let core_result_path = path![core::result::Result]; | 308 | let core_result_path = path![core::result::Result]; |
309 | let core_option_path = path![core::option::Option]; | ||
309 | 310 | ||
310 | let resolver = self.owner.resolver(db.upcast()); | 311 | let resolver = self.owner.resolver(db.upcast()); |
311 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { | 312 | let core_result_enum = match resolver.resolve_known_enum(db.upcast(), &core_result_path) { |
312 | Some(it) => it, | 313 | Some(it) => it, |
313 | _ => return, | 314 | _ => return, |
314 | }; | 315 | }; |
316 | let core_option_enum = match resolver.resolve_known_enum(db.upcast(), &core_option_path) { | ||
317 | Some(it) => it, | ||
318 | _ => return, | ||
319 | }; | ||
315 | 320 | ||
316 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); | 321 | let core_result_ctor = TypeCtor::Adt(AdtId::EnumId(core_result_enum)); |
317 | let params = match &mismatch.expected { | 322 | let core_option_ctor = TypeCtor::Adt(AdtId::EnumId(core_option_enum)); |
323 | |||
324 | let (params, required) = match &mismatch.expected { | ||
318 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { | 325 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_result_ctor => { |
319 | parameters | 326 | (parameters, "Ok".to_string()) |
327 | } | ||
328 | Ty::Apply(ApplicationTy { ctor, parameters }) if ctor == &core_option_ctor => { | ||
329 | (parameters, "Some".to_string()) | ||
320 | } | 330 | } |
321 | _ => return, | 331 | _ => return, |
322 | }; | 332 | }; |
323 | 333 | ||
324 | if params.len() == 2 && params[0] == mismatch.actual { | 334 | if params.len() > 0 && params[0] == mismatch.actual { |
325 | let (_, source_map) = db.body_with_source_map(self.owner.into()); | 335 | let (_, source_map) = db.body_with_source_map(self.owner.into()); |
326 | 336 | ||
327 | if let Ok(source_ptr) = source_map.expr_syntax(id) { | 337 | if let Ok(source_ptr) = source_map.expr_syntax(id) { |
328 | self.sink | 338 | self.sink.push(MissingOkOrSomeInTailExpr { |
329 | .push(MissingOkInTailExpr { file: source_ptr.file_id, expr: source_ptr.value }); | 339 | file: source_ptr.file_id, |
340 | expr: source_ptr.value, | ||
341 | required, | ||
342 | }); | ||
330 | } | 343 | } |
331 | } | 344 | } |
332 | } | 345 | } |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index 0e827a29e..e9e949c47 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -168,7 +168,7 @@ pub enum DisplayTarget { | |||
168 | 168 | ||
169 | impl DisplayTarget { | 169 | impl DisplayTarget { |
170 | fn is_source_code(&self) -> bool { | 170 | fn is_source_code(&self) -> bool { |
171 | matches!(self, Self::SourceCode {..}) | 171 | matches!(self, Self::SourceCode { .. }) |
172 | } | 172 | } |
173 | fn is_test(&self) -> bool { | 173 | fn is_test(&self) -> bool { |
174 | matches!(self, Self::Test) | 174 | matches!(self, Self::Test) |
@@ -595,7 +595,7 @@ impl HirDisplay for FnSig { | |||
595 | } | 595 | } |
596 | } | 596 | } |
597 | 597 | ||
598 | fn write_bounds_like_dyn_trait( | 598 | pub fn write_bounds_like_dyn_trait( |
599 | predicates: &[GenericPredicate], | 599 | predicates: &[GenericPredicate], |
600 | f: &mut HirFormatter, | 600 | f: &mut HirFormatter, |
601 | ) -> Result<(), HirDisplayError> { | 601 | ) -> Result<(), HirDisplayError> { |
diff --git a/crates/hir_ty/src/tests.rs b/crates/hir_ty/src/tests.rs index 0a400cb70..3b1675f0b 100644 --- a/crates/hir_ty/src/tests.rs +++ b/crates/hir_ty/src/tests.rs | |||
@@ -314,7 +314,7 @@ fn typing_whitespace_inside_a_function_should_not_invalidate_types() { | |||
314 | " | 314 | " |
315 | //- /lib.rs | 315 | //- /lib.rs |
316 | fn foo() -> i32 { | 316 | fn foo() -> i32 { |
317 | <|>1 + 1 | 317 | $01 + 1 |
318 | } | 318 | } |
319 | ", | 319 | ", |
320 | ); | 320 | ); |
diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index f1544dbe0..bb28cca4d 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml | |||
@@ -36,4 +36,4 @@ completion = { path = "../completion", version = "0.0.0" } | |||
36 | hir = { path = "../hir", version = "0.0.0" } | 36 | hir = { path = "../hir", version = "0.0.0" } |
37 | 37 | ||
38 | [dev-dependencies] | 38 | [dev-dependencies] |
39 | expect-test = "1.0" | 39 | expect-test = "1.1" |
diff --git a/crates/ide/src/call_hierarchy.rs b/crates/ide/src/call_hierarchy.rs index 3c2d39f5d..4d8983cb2 100644 --- a/crates/ide/src/call_hierarchy.rs +++ b/crates/ide/src/call_hierarchy.rs | |||
@@ -178,7 +178,7 @@ mod tests { | |||
178 | //- /lib.rs | 178 | //- /lib.rs |
179 | fn callee() {} | 179 | fn callee() {} |
180 | fn caller() { | 180 | fn caller() { |
181 | call<|>ee(); | 181 | call$0ee(); |
182 | } | 182 | } |
183 | "#, | 183 | "#, |
184 | "callee Function FileId(0) 0..14 3..9", | 184 | "callee Function FileId(0) 0..14 3..9", |
@@ -192,7 +192,7 @@ fn caller() { | |||
192 | check_hierarchy( | 192 | check_hierarchy( |
193 | r#" | 193 | r#" |
194 | //- /lib.rs | 194 | //- /lib.rs |
195 | fn call<|>ee() {} | 195 | fn call$0ee() {} |
196 | fn caller() { | 196 | fn caller() { |
197 | callee(); | 197 | callee(); |
198 | } | 198 | } |
@@ -210,7 +210,7 @@ fn caller() { | |||
210 | //- /lib.rs | 210 | //- /lib.rs |
211 | fn callee() {} | 211 | fn callee() {} |
212 | fn caller() { | 212 | fn caller() { |
213 | call<|>ee(); | 213 | call$0ee(); |
214 | callee(); | 214 | callee(); |
215 | } | 215 | } |
216 | "#, | 216 | "#, |
@@ -227,7 +227,7 @@ fn caller() { | |||
227 | //- /lib.rs | 227 | //- /lib.rs |
228 | fn callee() {} | 228 | fn callee() {} |
229 | fn caller1() { | 229 | fn caller1() { |
230 | call<|>ee(); | 230 | call$0ee(); |
231 | } | 231 | } |
232 | 232 | ||
233 | fn caller2() { | 233 | fn caller2() { |
@@ -250,7 +250,7 @@ fn caller2() { | |||
250 | //- /lib.rs cfg:test | 250 | //- /lib.rs cfg:test |
251 | fn callee() {} | 251 | fn callee() {} |
252 | fn caller1() { | 252 | fn caller1() { |
253 | call<|>ee(); | 253 | call$0ee(); |
254 | } | 254 | } |
255 | 255 | ||
256 | #[cfg(test)] | 256 | #[cfg(test)] |
@@ -281,7 +281,7 @@ mod foo; | |||
281 | use foo::callee; | 281 | use foo::callee; |
282 | 282 | ||
283 | fn caller() { | 283 | fn caller() { |
284 | call<|>ee(); | 284 | call$0ee(); |
285 | } | 285 | } |
286 | 286 | ||
287 | //- /foo/mod.rs | 287 | //- /foo/mod.rs |
@@ -299,7 +299,7 @@ pub fn callee() {} | |||
299 | r#" | 299 | r#" |
300 | //- /lib.rs | 300 | //- /lib.rs |
301 | fn callee() {} | 301 | fn callee() {} |
302 | fn call<|>er() { | 302 | fn call$0er() { |
303 | callee(); | 303 | callee(); |
304 | callee(); | 304 | callee(); |
305 | } | 305 | } |
@@ -318,7 +318,7 @@ fn call<|>er() { | |||
318 | mod foo; | 318 | mod foo; |
319 | use foo::callee; | 319 | use foo::callee; |
320 | 320 | ||
321 | fn call<|>er() { | 321 | fn call$0er() { |
322 | callee(); | 322 | callee(); |
323 | } | 323 | } |
324 | 324 | ||
@@ -337,7 +337,7 @@ pub fn callee() {} | |||
337 | r#" | 337 | r#" |
338 | //- /lib.rs | 338 | //- /lib.rs |
339 | fn caller1() { | 339 | fn caller1() { |
340 | call<|>er2(); | 340 | call$0er2(); |
341 | } | 341 | } |
342 | 342 | ||
343 | fn caller2() { | 343 | fn caller2() { |
@@ -365,7 +365,7 @@ fn a() { | |||
365 | fn b() {} | 365 | fn b() {} |
366 | 366 | ||
367 | fn main() { | 367 | fn main() { |
368 | a<|>() | 368 | a$0() |
369 | } | 369 | } |
370 | "#, | 370 | "#, |
371 | "a Function FileId(0) 0..18 3..4", | 371 | "a Function FileId(0) 0..18 3..4", |
@@ -376,7 +376,7 @@ fn main() { | |||
376 | check_hierarchy( | 376 | check_hierarchy( |
377 | r#" | 377 | r#" |
378 | fn a() { | 378 | fn a() { |
379 | b<|>() | 379 | b$0() |
380 | } | 380 | } |
381 | 381 | ||
382 | fn b() {} | 382 | fn b() {} |
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index 79d126ff2..055c0a79c 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -125,7 +125,7 @@ pub(crate) fn diagnostics( | |||
125 | .on::<hir::diagnostics::MissingFields, _>(|d| { | 125 | .on::<hir::diagnostics::MissingFields, _>(|d| { |
126 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); | 126 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); |
127 | }) | 127 | }) |
128 | .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { | 128 | .on::<hir::diagnostics::MissingOkOrSomeInTailExpr, _>(|d| { |
129 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); | 129 | res.borrow_mut().push(diagnostic_with_fix(d, &sema)); |
130 | }) | 130 | }) |
131 | .on::<hir::diagnostics::NoSuchField, _>(|d| { | 131 | .on::<hir::diagnostics::NoSuchField, _>(|d| { |
@@ -305,6 +305,40 @@ mod tests { | |||
305 | } | 305 | } |
306 | 306 | ||
307 | #[test] | 307 | #[test] |
308 | fn test_wrap_return_type_option() { | ||
309 | check_fix( | ||
310 | r#" | ||
311 | //- /main.rs crate:main deps:core | ||
312 | use core::option::Option::{self, Some, None}; | ||
313 | |||
314 | fn div(x: i32, y: i32) -> Option<i32> { | ||
315 | if y == 0 { | ||
316 | return None; | ||
317 | } | ||
318 | x / y$0 | ||
319 | } | ||
320 | //- /core/lib.rs crate:core | ||
321 | pub mod result { | ||
322 | pub enum Result<T, E> { Ok(T), Err(E) } | ||
323 | } | ||
324 | pub mod option { | ||
325 | pub enum Option<T> { Some(T), None } | ||
326 | } | ||
327 | "#, | ||
328 | r#" | ||
329 | use core::option::Option::{self, Some, None}; | ||
330 | |||
331 | fn div(x: i32, y: i32) -> Option<i32> { | ||
332 | if y == 0 { | ||
333 | return None; | ||
334 | } | ||
335 | Some(x / y) | ||
336 | } | ||
337 | "#, | ||
338 | ); | ||
339 | } | ||
340 | |||
341 | #[test] | ||
308 | fn test_wrap_return_type() { | 342 | fn test_wrap_return_type() { |
309 | check_fix( | 343 | check_fix( |
310 | r#" | 344 | r#" |
@@ -315,12 +349,15 @@ fn div(x: i32, y: i32) -> Result<i32, ()> { | |||
315 | if y == 0 { | 349 | if y == 0 { |
316 | return Err(()); | 350 | return Err(()); |
317 | } | 351 | } |
318 | x / y<|> | 352 | x / y$0 |
319 | } | 353 | } |
320 | //- /core/lib.rs crate:core | 354 | //- /core/lib.rs crate:core |
321 | pub mod result { | 355 | pub mod result { |
322 | pub enum Result<T, E> { Ok(T), Err(E) } | 356 | pub enum Result<T, E> { Ok(T), Err(E) } |
323 | } | 357 | } |
358 | pub mod option { | ||
359 | pub enum Option<T> { Some(T), None } | ||
360 | } | ||
324 | "#, | 361 | "#, |
325 | r#" | 362 | r#" |
326 | use core::result::Result::{self, Ok, Err}; | 363 | use core::result::Result::{self, Ok, Err}; |
@@ -346,12 +383,15 @@ fn div<T>(x: T) -> Result<T, i32> { | |||
346 | if x == 0 { | 383 | if x == 0 { |
347 | return Err(7); | 384 | return Err(7); |
348 | } | 385 | } |
349 | <|>x | 386 | $0x |
350 | } | 387 | } |
351 | //- /core/lib.rs crate:core | 388 | //- /core/lib.rs crate:core |
352 | pub mod result { | 389 | pub mod result { |
353 | pub enum Result<T, E> { Ok(T), Err(E) } | 390 | pub enum Result<T, E> { Ok(T), Err(E) } |
354 | } | 391 | } |
392 | pub mod option { | ||
393 | pub enum Option<T> { Some(T), None } | ||
394 | } | ||
355 | "#, | 395 | "#, |
356 | r#" | 396 | r#" |
357 | use core::result::Result::{self, Ok, Err}; | 397 | use core::result::Result::{self, Ok, Err}; |
@@ -379,12 +419,15 @@ fn div(x: i32, y: i32) -> MyResult<i32> { | |||
379 | if y == 0 { | 419 | if y == 0 { |
380 | return Err(()); | 420 | return Err(()); |
381 | } | 421 | } |
382 | x <|>/ y | 422 | x $0/ y |
383 | } | 423 | } |
384 | //- /core/lib.rs crate:core | 424 | //- /core/lib.rs crate:core |
385 | pub mod result { | 425 | pub mod result { |
386 | pub enum Result<T, E> { Ok(T), Err(E) } | 426 | pub enum Result<T, E> { Ok(T), Err(E) } |
387 | } | 427 | } |
428 | pub mod option { | ||
429 | pub enum Option<T> { Some(T), None } | ||
430 | } | ||
388 | "#, | 431 | "#, |
389 | r#" | 432 | r#" |
390 | use core::result::Result::{self, Ok, Err}; | 433 | use core::result::Result::{self, Ok, Err}; |
@@ -414,12 +457,15 @@ fn foo() -> Result<(), i32> { 0 } | |||
414 | pub mod result { | 457 | pub mod result { |
415 | pub enum Result<T, E> { Ok(T), Err(E) } | 458 | pub enum Result<T, E> { Ok(T), Err(E) } |
416 | } | 459 | } |
460 | pub mod option { | ||
461 | pub enum Option<T> { Some(T), None } | ||
462 | } | ||
417 | "#, | 463 | "#, |
418 | ); | 464 | ); |
419 | } | 465 | } |
420 | 466 | ||
421 | #[test] | 467 | #[test] |
422 | fn test_wrap_return_type_not_applicable_when_return_type_is_not_result() { | 468 | fn test_wrap_return_type_not_applicable_when_return_type_is_not_result_or_option() { |
423 | check_no_diagnostics( | 469 | check_no_diagnostics( |
424 | r#" | 470 | r#" |
425 | //- /main.rs crate:main deps:core | 471 | //- /main.rs crate:main deps:core |
@@ -433,6 +479,9 @@ fn foo() -> SomeOtherEnum { 0 } | |||
433 | pub mod result { | 479 | pub mod result { |
434 | pub enum Result<T, E> { Ok(T), Err(E) } | 480 | pub enum Result<T, E> { Ok(T), Err(E) } |
435 | } | 481 | } |
482 | pub mod option { | ||
483 | pub enum Option<T> { Some(T), None } | ||
484 | } | ||
436 | "#, | 485 | "#, |
437 | ); | 486 | ); |
438 | } | 487 | } |
@@ -444,7 +493,7 @@ pub mod result { | |||
444 | struct TestStruct { one: i32, two: i64 } | 493 | struct TestStruct { one: i32, two: i64 } |
445 | 494 | ||
446 | fn test_fn() { | 495 | fn test_fn() { |
447 | let s = TestStruct {<|>}; | 496 | let s = TestStruct {$0}; |
448 | } | 497 | } |
449 | "#, | 498 | "#, |
450 | r#" | 499 | r#" |
@@ -464,7 +513,7 @@ fn test_fn() { | |||
464 | struct TestStruct { one: i32 } | 513 | struct TestStruct { one: i32 } |
465 | 514 | ||
466 | impl TestStruct { | 515 | impl TestStruct { |
467 | fn test_fn() { let s = Self {<|>}; } | 516 | fn test_fn() { let s = Self {$0}; } |
468 | } | 517 | } |
469 | "#, | 518 | "#, |
470 | r#" | 519 | r#" |
@@ -487,7 +536,7 @@ enum Expr { | |||
487 | 536 | ||
488 | impl Expr { | 537 | impl Expr { |
489 | fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { | 538 | fn new_bin(lhs: Box<Expr>, rhs: Box<Expr>) -> Expr { |
490 | Expr::Bin {<|> } | 539 | Expr::Bin {$0 } |
491 | } | 540 | } |
492 | } | 541 | } |
493 | "#, | 542 | "#, |
@@ -512,7 +561,7 @@ impl Expr { | |||
512 | struct TestStruct { one: i32, two: i64 } | 561 | struct TestStruct { one: i32, two: i64 } |
513 | 562 | ||
514 | fn test_fn() { | 563 | fn test_fn() { |
515 | let s = TestStruct{ two: 2<|> }; | 564 | let s = TestStruct{ two: 2$0 }; |
516 | } | 565 | } |
517 | "#, | 566 | "#, |
518 | r" | 567 | r" |
@@ -608,7 +657,7 @@ fn here() {} | |||
608 | macro_rules! id { ($($tt:tt)*) => { $($tt)*}; } | 657 | macro_rules! id { ($($tt:tt)*) => { $($tt)*}; } |
609 | 658 | ||
610 | fn main() { | 659 | fn main() { |
611 | let _x = id![Foo { a: <|>42 }]; | 660 | let _x = id![Foo { a: $042 }]; |
612 | } | 661 | } |
613 | 662 | ||
614 | pub struct Foo { pub a: i32, pub b: i32 } | 663 | pub struct Foo { pub a: i32, pub b: i32 } |
@@ -663,7 +712,7 @@ mod a { | |||
663 | check_fix( | 712 | check_fix( |
664 | r" | 713 | r" |
665 | mod b {} | 714 | mod b {} |
666 | use {<|>b}; | 715 | use {$0b}; |
667 | ", | 716 | ", |
668 | r" | 717 | r" |
669 | mod b {} | 718 | mod b {} |
@@ -673,7 +722,7 @@ mod a { | |||
673 | check_fix( | 722 | check_fix( |
674 | r" | 723 | r" |
675 | mod b {} | 724 | mod b {} |
676 | use {b<|>}; | 725 | use {b$0}; |
677 | ", | 726 | ", |
678 | r" | 727 | r" |
679 | mod b {} | 728 | mod b {} |
@@ -683,7 +732,7 @@ mod a { | |||
683 | check_fix( | 732 | check_fix( |
684 | r" | 733 | r" |
685 | mod a { mod c {} } | 734 | mod a { mod c {} } |
686 | use a::{c<|>}; | 735 | use a::{c$0}; |
687 | ", | 736 | ", |
688 | r" | 737 | r" |
689 | mod a { mod c {} } | 738 | mod a { mod c {} } |
@@ -693,7 +742,7 @@ mod a { | |||
693 | check_fix( | 742 | check_fix( |
694 | r" | 743 | r" |
695 | mod a {} | 744 | mod a {} |
696 | use a::{self<|>}; | 745 | use a::{self$0}; |
697 | ", | 746 | ", |
698 | r" | 747 | r" |
699 | mod a {} | 748 | mod a {} |
@@ -703,7 +752,7 @@ mod a { | |||
703 | check_fix( | 752 | check_fix( |
704 | r" | 753 | r" |
705 | mod a { mod c {} mod d { mod e {} } } | 754 | mod a { mod c {} mod d { mod e {} } } |
706 | use a::{c, d::{e<|>}}; | 755 | use a::{c, d::{e$0}}; |
707 | ", | 756 | ", |
708 | r" | 757 | r" |
709 | mod a { mod c {} mod d { mod e {} } } | 758 | mod a { mod c {} mod d { mod e {} } } |
@@ -717,7 +766,7 @@ mod a { | |||
717 | check_fix( | 766 | check_fix( |
718 | r" | 767 | r" |
719 | fn main() { | 768 | fn main() { |
720 | Foo { bar: 3, baz<|>: false}; | 769 | Foo { bar: 3, baz$0: false}; |
721 | } | 770 | } |
722 | struct Foo { | 771 | struct Foo { |
723 | bar: i32 | 772 | bar: i32 |
@@ -743,7 +792,7 @@ struct Foo { | |||
743 | mod foo; | 792 | mod foo; |
744 | 793 | ||
745 | fn main() { | 794 | fn main() { |
746 | foo::Foo { bar: 3, <|>baz: false}; | 795 | foo::Foo { bar: 3, $0baz: false}; |
747 | } | 796 | } |
748 | //- /foo.rs | 797 | //- /foo.rs |
749 | struct Foo { | 798 | struct Foo { |
@@ -777,7 +826,7 @@ struct Foo { | |||
777 | fn test_rename_incorrect_case() { | 826 | fn test_rename_incorrect_case() { |
778 | check_fix( | 827 | check_fix( |
779 | r#" | 828 | r#" |
780 | pub struct test_struct<|> { one: i32 } | 829 | pub struct test_struct$0 { one: i32 } |
781 | 830 | ||
782 | pub fn some_fn(val: test_struct) -> test_struct { | 831 | pub fn some_fn(val: test_struct) -> test_struct { |
783 | test_struct { one: val.one + 1 } | 832 | test_struct { one: val.one + 1 } |
@@ -794,7 +843,7 @@ pub fn some_fn(val: TestStruct) -> TestStruct { | |||
794 | 843 | ||
795 | check_fix( | 844 | check_fix( |
796 | r#" | 845 | r#" |
797 | pub fn some_fn(NonSnakeCase<|>: u8) -> u8 { | 846 | pub fn some_fn(NonSnakeCase$0: u8) -> u8 { |
798 | NonSnakeCase | 847 | NonSnakeCase |
799 | } | 848 | } |
800 | "#, | 849 | "#, |
@@ -807,7 +856,7 @@ pub fn some_fn(non_snake_case: u8) -> u8 { | |||
807 | 856 | ||
808 | check_fix( | 857 | check_fix( |
809 | r#" | 858 | r#" |
810 | pub fn SomeFn<|>(val: u8) -> u8 { | 859 | pub fn SomeFn$0(val: u8) -> u8 { |
811 | if val != 0 { SomeFn(val - 1) } else { val } | 860 | if val != 0 { SomeFn(val - 1) } else { val } |
812 | } | 861 | } |
813 | "#, | 862 | "#, |
@@ -821,7 +870,7 @@ pub fn some_fn(val: u8) -> u8 { | |||
821 | check_fix( | 870 | check_fix( |
822 | r#" | 871 | r#" |
823 | fn some_fn() { | 872 | fn some_fn() { |
824 | let whatAWeird_Formatting<|> = 10; | 873 | let whatAWeird_Formatting$0 = 10; |
825 | another_func(whatAWeird_Formatting); | 874 | another_func(whatAWeird_Formatting); |
826 | } | 875 | } |
827 | "#, | 876 | "#, |
@@ -839,7 +888,7 @@ fn some_fn() { | |||
839 | check_no_diagnostics( | 888 | check_no_diagnostics( |
840 | r#" | 889 | r#" |
841 | fn foo() { | 890 | fn foo() { |
842 | const ANOTHER_ITEM<|>: &str = "some_item"; | 891 | const ANOTHER_ITEM$0: &str = "some_item"; |
843 | } | 892 | } |
844 | "#, | 893 | "#, |
845 | ); | 894 | ); |
@@ -852,7 +901,7 @@ fn foo() { | |||
852 | pub struct TestStruct; | 901 | pub struct TestStruct; |
853 | 902 | ||
854 | impl TestStruct { | 903 | impl TestStruct { |
855 | pub fn SomeFn<|>() -> TestStruct { | 904 | pub fn SomeFn$0() -> TestStruct { |
856 | TestStruct | 905 | TestStruct |
857 | } | 906 | } |
858 | } | 907 | } |
@@ -871,7 +920,7 @@ impl TestStruct { | |||
871 | 920 | ||
872 | #[test] | 921 | #[test] |
873 | fn test_single_incorrect_case_diagnostic_in_function_name_issue_6970() { | 922 | fn test_single_incorrect_case_diagnostic_in_function_name_issue_6970() { |
874 | let input = r#"fn FOO<|>() {}"#; | 923 | let input = r#"fn FOO$0() {}"#; |
875 | let expected = r#"fn foo() {}"#; | 924 | let expected = r#"fn foo() {}"#; |
876 | 925 | ||
877 | let (analysis, file_position) = fixture::position(input); | 926 | let (analysis, file_position) = fixture::position(input); |
diff --git a/crates/ide/src/diagnostics/field_shorthand.rs b/crates/ide/src/diagnostics/field_shorthand.rs index f41bcd619..16c6ea827 100644 --- a/crates/ide/src/diagnostics/field_shorthand.rs +++ b/crates/ide/src/diagnostics/field_shorthand.rs | |||
@@ -120,7 +120,7 @@ fn main() { A { 0: 0 } } | |||
120 | struct A { a: &'static str } | 120 | struct A { a: &'static str } |
121 | fn main() { | 121 | fn main() { |
122 | let a = "haha"; | 122 | let a = "haha"; |
123 | A { a<|>: a } | 123 | A { a$0: a } |
124 | } | 124 | } |
125 | "#, | 125 | "#, |
126 | r#" | 126 | r#" |
@@ -138,7 +138,7 @@ struct A { a: &'static str, b: &'static str } | |||
138 | fn main() { | 138 | fn main() { |
139 | let a = "haha"; | 139 | let a = "haha"; |
140 | let b = "bb"; | 140 | let b = "bb"; |
141 | A { a<|>: a, b } | 141 | A { a$0: a, b } |
142 | } | 142 | } |
143 | "#, | 143 | "#, |
144 | r#" | 144 | r#" |
@@ -171,7 +171,7 @@ fn f(a: A) { let A { 0: 0 } = a; } | |||
171 | r#" | 171 | r#" |
172 | struct A { a: &'static str } | 172 | struct A { a: &'static str } |
173 | fn f(a: A) { | 173 | fn f(a: A) { |
174 | let A { a<|>: a } = a; | 174 | let A { a$0: a } = a; |
175 | } | 175 | } |
176 | "#, | 176 | "#, |
177 | r#" | 177 | r#" |
@@ -186,7 +186,7 @@ fn f(a: A) { | |||
186 | r#" | 186 | r#" |
187 | struct A { a: &'static str, b: &'static str } | 187 | struct A { a: &'static str, b: &'static str } |
188 | fn f(a: A) { | 188 | fn f(a: A) { |
189 | let A { a<|>: a, b } = a; | 189 | let A { a$0: a, b } = a; |
190 | } | 190 | } |
191 | "#, | 191 | "#, |
192 | r#" | 192 | r#" |
diff --git a/crates/ide/src/diagnostics/fixes.rs b/crates/ide/src/diagnostics/fixes.rs index ec0f840e9..d7ad88ed5 100644 --- a/crates/ide/src/diagnostics/fixes.rs +++ b/crates/ide/src/diagnostics/fixes.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use hir::{ | 3 | use hir::{ |
4 | db::AstDatabase, | 4 | db::AstDatabase, |
5 | diagnostics::{ | 5 | diagnostics::{ |
6 | Diagnostic, IncorrectCase, MissingFields, MissingOkInTailExpr, NoSuchField, | 6 | Diagnostic, IncorrectCase, MissingFields, MissingOkOrSomeInTailExpr, NoSuchField, |
7 | RemoveThisSemicolon, UnresolvedModule, | 7 | RemoveThisSemicolon, UnresolvedModule, |
8 | }, | 8 | }, |
9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, | 9 | HasSource, HirDisplay, InFile, Semantics, VariantDef, |
@@ -94,15 +94,17 @@ impl DiagnosticWithFix for MissingFields { | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | impl DiagnosticWithFix for MissingOkInTailExpr { | 97 | impl DiagnosticWithFix for MissingOkOrSomeInTailExpr { |
98 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> { | 98 | fn fix(&self, sema: &Semantics<RootDatabase>) -> Option<Fix> { |
99 | let root = sema.db.parse_or_expand(self.file)?; | 99 | let root = sema.db.parse_or_expand(self.file)?; |
100 | let tail_expr = self.expr.to_node(&root); | 100 | let tail_expr = self.expr.to_node(&root); |
101 | let tail_expr_range = tail_expr.syntax().text_range(); | 101 | let tail_expr_range = tail_expr.syntax().text_range(); |
102 | let edit = TextEdit::replace(tail_expr_range, format!("Ok({})", tail_expr.syntax())); | 102 | let replacement = format!("{}({})", self.required, tail_expr.syntax()); |
103 | let edit = TextEdit::replace(tail_expr_range, replacement); | ||
103 | let source_change = | 104 | let source_change = |
104 | SourceFileEdit { file_id: self.file.original_file(sema.db), edit }.into(); | 105 | SourceFileEdit { file_id: self.file.original_file(sema.db), edit }.into(); |
105 | Some(Fix::new("Wrap with ok", source_change, tail_expr_range)) | 106 | let name = if self.required == "Ok" { "Wrap with Ok" } else { "Wrap with Some" }; |
107 | Some(Fix::new(name, source_change, tail_expr_range)) | ||
106 | } | 108 | } |
107 | } | 109 | } |
108 | 110 | ||
@@ -156,7 +158,6 @@ fn missing_record_expr_field_fix( | |||
156 | let record_fields = match VariantDef::from(def_id) { | 158 | let record_fields = match VariantDef::from(def_id) { |
157 | VariantDef::Struct(s) => { | 159 | VariantDef::Struct(s) => { |
158 | module = s.module(sema.db); | 160 | module = s.module(sema.db); |
159 | #[allow(deprecated)] | ||
160 | let source = s.source(sema.db)?; | 161 | let source = s.source(sema.db)?; |
161 | def_file_id = source.file_id; | 162 | def_file_id = source.file_id; |
162 | let fields = source.value.field_list()?; | 163 | let fields = source.value.field_list()?; |
@@ -164,14 +165,12 @@ fn missing_record_expr_field_fix( | |||
164 | } | 165 | } |
165 | VariantDef::Union(u) => { | 166 | VariantDef::Union(u) => { |
166 | module = u.module(sema.db); | 167 | module = u.module(sema.db); |
167 | #[allow(deprecated)] | ||
168 | let source = u.source(sema.db)?; | 168 | let source = u.source(sema.db)?; |
169 | def_file_id = source.file_id; | 169 | def_file_id = source.file_id; |
170 | source.value.record_field_list()? | 170 | source.value.record_field_list()? |
171 | } | 171 | } |
172 | VariantDef::Variant(e) => { | 172 | VariantDef::Variant(e) => { |
173 | module = e.module(sema.db); | 173 | module = e.module(sema.db); |
174 | #[allow(deprecated)] | ||
175 | let source = e.source(sema.db)?; | 174 | let source = e.source(sema.db)?; |
176 | def_file_id = source.file_id; | 175 | def_file_id = source.file_id; |
177 | let fields = source.value.field_list()?; | 176 | let fields = source.value.field_list()?; |
diff --git a/crates/ide/src/display/short_label.rs b/crates/ide/src/display/short_label.rs index ea49d9f97..990f740b8 100644 --- a/crates/ide/src/display/short_label.rs +++ b/crates/ide/src/display/short_label.rs | |||
@@ -87,6 +87,17 @@ impl ShortLabel for ast::Variant { | |||
87 | } | 87 | } |
88 | } | 88 | } |
89 | 89 | ||
90 | impl ShortLabel for ast::ConstParam { | ||
91 | fn short_label(&self) -> Option<String> { | ||
92 | let mut buf = "const ".to_owned(); | ||
93 | buf.push_str(self.name()?.text().as_str()); | ||
94 | if let Some(type_ref) = self.ty() { | ||
95 | format_to!(buf, ": {}", type_ref.syntax()); | ||
96 | } | ||
97 | Some(buf) | ||
98 | } | ||
99 | } | ||
100 | |||
90 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> | 101 | fn short_label_from_ty<T>(node: &T, ty: Option<ast::Type>, prefix: &str) -> Option<String> |
91 | where | 102 | where |
92 | T: NameOwner + VisibilityOwner, | 103 | T: NameOwner + VisibilityOwner, |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 367fac05e..1ff818de2 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -464,7 +464,7 @@ mod tests { | |||
464 | fn test_doc_url_struct() { | 464 | fn test_doc_url_struct() { |
465 | check( | 465 | check( |
466 | r#" | 466 | r#" |
467 | pub struct Fo<|>o; | 467 | pub struct Fo$0o; |
468 | "#, | 468 | "#, |
469 | expect![[r#"https://docs.rs/test/*/test/struct.Foo.html"#]], | 469 | expect![[r#"https://docs.rs/test/*/test/struct.Foo.html"#]], |
470 | ); | 470 | ); |
@@ -474,7 +474,7 @@ pub struct Fo<|>o; | |||
474 | fn test_doc_url_fn() { | 474 | fn test_doc_url_fn() { |
475 | check( | 475 | check( |
476 | r#" | 476 | r#" |
477 | pub fn fo<|>o() {} | 477 | pub fn fo$0o() {} |
478 | "#, | 478 | "#, |
479 | expect![[r##"https://docs.rs/test/*/test/fn.foo.html#method.foo"##]], | 479 | expect![[r##"https://docs.rs/test/*/test/fn.foo.html#method.foo"##]], |
480 | ); | 480 | ); |
@@ -487,7 +487,7 @@ pub fn fo<|>o() {} | |||
487 | pub struct Foo; | 487 | pub struct Foo; |
488 | 488 | ||
489 | impl Foo { | 489 | impl Foo { |
490 | pub fn met<|>hod() {} | 490 | pub fn met$0hod() {} |
491 | } | 491 | } |
492 | 492 | ||
493 | "#, | 493 | "#, |
@@ -500,7 +500,7 @@ impl Foo { | |||
500 | check( | 500 | check( |
501 | r#" | 501 | r#" |
502 | pub trait Bar { | 502 | pub trait Bar { |
503 | fn met<|>hod() {} | 503 | fn met$0hod() {} |
504 | } | 504 | } |
505 | 505 | ||
506 | "#, | 506 | "#, |
@@ -513,7 +513,7 @@ pub trait Bar { | |||
513 | check( | 513 | check( |
514 | r#" | 514 | r#" |
515 | pub trait Foo { | 515 | pub trait Foo { |
516 | fn met<|>hod(); | 516 | fn met$0hod(); |
517 | } | 517 | } |
518 | 518 | ||
519 | "#, | 519 | "#, |
@@ -526,7 +526,7 @@ pub trait Foo { | |||
526 | check( | 526 | check( |
527 | r#" | 527 | r#" |
528 | pub struct Foo { | 528 | pub struct Foo { |
529 | pub fie<|>ld: () | 529 | pub fie$0ld: () |
530 | } | 530 | } |
531 | 531 | ||
532 | "#, | 532 | "#, |
@@ -539,7 +539,7 @@ pub struct Foo { | |||
539 | check( | 539 | check( |
540 | r#" | 540 | r#" |
541 | pub mod foo { | 541 | pub mod foo { |
542 | pub mod ba<|>r {} | 542 | pub mod ba$0r {} |
543 | } | 543 | } |
544 | "#, | 544 | "#, |
545 | expect![[r#"https://docs.rs/test/*/test/foo/bar/index.html"#]], | 545 | expect![[r#"https://docs.rs/test/*/test/foo/bar/index.html"#]], |
@@ -564,7 +564,7 @@ pub mod wrapper { | |||
564 | } | 564 | } |
565 | 565 | ||
566 | fn foo() { | 566 | fn foo() { |
567 | let bar: wrapper::It<|>em; | 567 | let bar: wrapper::It$0em; |
568 | } | 568 | } |
569 | "#, | 569 | "#, |
570 | expect![[r#"https://docs.rs/test/*/test/wrapper/module/struct.Item.html"#]], | 570 | expect![[r#"https://docs.rs/test/*/test/wrapper/module/struct.Item.html"#]], |
diff --git a/crates/ide/src/expand_macro.rs b/crates/ide/src/expand_macro.rs index 8d75e0f05..ffb3a6f7d 100644 --- a/crates/ide/src/expand_macro.rs +++ b/crates/ide/src/expand_macro.rs | |||
@@ -144,7 +144,7 @@ macro_rules! foo { | |||
144 | macro_rules! baz { | 144 | macro_rules! baz { |
145 | () => { foo!(); } | 145 | () => { foo!(); } |
146 | } | 146 | } |
147 | f<|>oo!(); | 147 | f$0oo!(); |
148 | "#, | 148 | "#, |
149 | expect![[r#" | 149 | expect![[r#" |
150 | foo | 150 | foo |
@@ -165,7 +165,7 @@ macro_rules! foo { | |||
165 | } | 165 | } |
166 | } | 166 | } |
167 | } | 167 | } |
168 | f<|>oo!(); | 168 | f$0oo!(); |
169 | "#, | 169 | "#, |
170 | expect![[r#" | 170 | expect![[r#" |
171 | foo | 171 | foo |
@@ -192,7 +192,7 @@ macro_rules! match_ast { | |||
192 | } | 192 | } |
193 | 193 | ||
194 | fn main() { | 194 | fn main() { |
195 | mat<|>ch_ast! { | 195 | mat$0ch_ast! { |
196 | match container { | 196 | match container { |
197 | ast::TraitDef(it) => {}, | 197 | ast::TraitDef(it) => {}, |
198 | ast::ImplDef(it) => {}, | 198 | ast::ImplDef(it) => {}, |
@@ -226,7 +226,7 @@ macro_rules! match_ast { | |||
226 | 226 | ||
227 | fn main() { | 227 | fn main() { |
228 | let p = f(|it| { | 228 | let p = f(|it| { |
229 | let res = mat<|>ch_ast! { match c {}}; | 229 | let res = mat$0ch_ast! { match c {}}; |
230 | Some(res) | 230 | Some(res) |
231 | })?; | 231 | })?; |
232 | } | 232 | } |
@@ -250,7 +250,7 @@ macro_rules! foo { | |||
250 | } | 250 | } |
251 | 251 | ||
252 | fn main() { | 252 | fn main() { |
253 | let res = fo<|>o!(); | 253 | let res = fo$0o!(); |
254 | } | 254 | } |
255 | "#, | 255 | "#, |
256 | expect![[r#" | 256 | expect![[r#" |
@@ -272,7 +272,7 @@ macro_rules! foo { | |||
272 | } | 272 | } |
273 | 273 | ||
274 | fn main() { | 274 | fn main() { |
275 | let res = fo<|>o!(); | 275 | let res = fo$0o!(); |
276 | } | 276 | } |
277 | "#, | 277 | "#, |
278 | expect![[r#" | 278 | expect![[r#" |
diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs index 6f3022dfd..56418c960 100644 --- a/crates/ide/src/extend_selection.rs +++ b/crates/ide/src/extend_selection.rs | |||
@@ -334,29 +334,29 @@ mod tests { | |||
334 | 334 | ||
335 | #[test] | 335 | #[test] |
336 | fn test_extend_selection_arith() { | 336 | fn test_extend_selection_arith() { |
337 | do_check(r#"fn foo() { <|>1 + 1 }"#, &["1", "1 + 1", "{ 1 + 1 }"]); | 337 | do_check(r#"fn foo() { $01 + 1 }"#, &["1", "1 + 1", "{ 1 + 1 }"]); |
338 | } | 338 | } |
339 | 339 | ||
340 | #[test] | 340 | #[test] |
341 | fn test_extend_selection_list() { | 341 | fn test_extend_selection_list() { |
342 | do_check(r#"fn foo(<|>x: i32) {}"#, &["x", "x: i32"]); | 342 | do_check(r#"fn foo($0x: i32) {}"#, &["x", "x: i32"]); |
343 | do_check(r#"fn foo(<|>x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); | 343 | do_check(r#"fn foo($0x: i32, y: i32) {}"#, &["x", "x: i32", "x: i32, "]); |
344 | do_check(r#"fn foo(<|>x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,", "(x: i32,y: i32)"]); | 344 | do_check(r#"fn foo($0x: i32,y: i32) {}"#, &["x", "x: i32", "x: i32,", "(x: i32,y: i32)"]); |
345 | do_check(r#"fn foo(x: i32, <|>y: i32) {}"#, &["y", "y: i32", ", y: i32"]); | 345 | do_check(r#"fn foo(x: i32, $0y: i32) {}"#, &["y", "y: i32", ", y: i32"]); |
346 | do_check(r#"fn foo(x: i32, <|>y: i32, ) {}"#, &["y", "y: i32", "y: i32, "]); | 346 | do_check(r#"fn foo(x: i32, $0y: i32, ) {}"#, &["y", "y: i32", "y: i32, "]); |
347 | do_check(r#"fn foo(x: i32,<|>y: i32) {}"#, &["y", "y: i32", ",y: i32"]); | 347 | do_check(r#"fn foo(x: i32,$0y: i32) {}"#, &["y", "y: i32", ",y: i32"]); |
348 | 348 | ||
349 | do_check(r#"const FOO: [usize; 2] = [ 22<|> , 33];"#, &["22", "22 , "]); | 349 | do_check(r#"const FOO: [usize; 2] = [ 22$0 , 33];"#, &["22", "22 , "]); |
350 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|>];"#, &["33", ", 33"]); | 350 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33$0];"#, &["33", ", 33"]); |
351 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33<|> ,];"#, &["33", "33 ,", "[ 22 , 33 ,]"]); | 351 | do_check(r#"const FOO: [usize; 2] = [ 22 , 33$0 ,];"#, &["33", "33 ,", "[ 22 , 33 ,]"]); |
352 | 352 | ||
353 | do_check(r#"fn main() { (1, 2<|>) }"#, &["2", ", 2", "(1, 2)"]); | 353 | do_check(r#"fn main() { (1, 2$0) }"#, &["2", ", 2", "(1, 2)"]); |
354 | 354 | ||
355 | do_check( | 355 | do_check( |
356 | r#" | 356 | r#" |
357 | const FOO: [usize; 2] = [ | 357 | const FOO: [usize; 2] = [ |
358 | 22, | 358 | 22, |
359 | <|>33, | 359 | $033, |
360 | ]"#, | 360 | ]"#, |
361 | &["33", "33,"], | 361 | &["33", "33,"], |
362 | ); | 362 | ); |
@@ -365,7 +365,7 @@ const FOO: [usize; 2] = [ | |||
365 | r#" | 365 | r#" |
366 | const FOO: [usize; 2] = [ | 366 | const FOO: [usize; 2] = [ |
367 | 22 | 367 | 22 |
368 | , 33<|>, | 368 | , 33$0, |
369 | ]"#, | 369 | ]"#, |
370 | &["33", "33,"], | 370 | &["33", "33,"], |
371 | ); | 371 | ); |
@@ -376,7 +376,7 @@ const FOO: [usize; 2] = [ | |||
376 | do_check( | 376 | do_check( |
377 | r#" | 377 | r#" |
378 | impl S { | 378 | impl S { |
379 | <|> fn foo() { | 379 | $0 fn foo() { |
380 | 380 | ||
381 | } | 381 | } |
382 | }"#, | 382 | }"#, |
@@ -393,7 +393,7 @@ struct A; | |||
393 | /// bla | 393 | /// bla |
394 | /// bla | 394 | /// bla |
395 | struct B { | 395 | struct B { |
396 | <|> | 396 | $0 |
397 | } | 397 | } |
398 | "#, | 398 | "#, |
399 | &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"], | 399 | &["\n \n", "{\n \n}", "/// bla\n/// bla\nstruct B {\n \n}"], |
@@ -407,7 +407,7 @@ struct B { | |||
407 | fn bar(){} | 407 | fn bar(){} |
408 | 408 | ||
409 | // fn foo() { | 409 | // fn foo() { |
410 | // 1 + <|>1 | 410 | // 1 + $01 |
411 | // } | 411 | // } |
412 | 412 | ||
413 | // fn foo(){} | 413 | // fn foo(){} |
@@ -419,7 +419,7 @@ fn bar(){} | |||
419 | r#" | 419 | r#" |
420 | // #[derive(Debug, Clone, Copy, PartialEq, Eq)] | 420 | // #[derive(Debug, Clone, Copy, PartialEq, Eq)] |
421 | // pub enum Direction { | 421 | // pub enum Direction { |
422 | // <|> Next, | 422 | // $0 Next, |
423 | // Prev | 423 | // Prev |
424 | // } | 424 | // } |
425 | "#, | 425 | "#, |
@@ -433,27 +433,27 @@ fn bar(){} | |||
433 | r#" | 433 | r#" |
434 | /* | 434 | /* |
435 | foo | 435 | foo |
436 | _bar1<|>*/ | 436 | _bar1$0*/ |
437 | "#, | 437 | "#, |
438 | &["_bar1", "/*\nfoo\n_bar1*/"], | 438 | &["_bar1", "/*\nfoo\n_bar1*/"], |
439 | ); | 439 | ); |
440 | 440 | ||
441 | do_check(r#"//!<|>foo_2 bar"#, &["foo_2", "//!foo_2 bar"]); | 441 | do_check(r#"//!$0foo_2 bar"#, &["foo_2", "//!foo_2 bar"]); |
442 | 442 | ||
443 | do_check(r#"/<|>/foo bar"#, &["//foo bar"]); | 443 | do_check(r#"/$0/foo bar"#, &["//foo bar"]); |
444 | } | 444 | } |
445 | 445 | ||
446 | #[test] | 446 | #[test] |
447 | fn test_extend_selection_prefer_idents() { | 447 | fn test_extend_selection_prefer_idents() { |
448 | do_check( | 448 | do_check( |
449 | r#" | 449 | r#" |
450 | fn main() { foo<|>+bar;} | 450 | fn main() { foo$0+bar;} |
451 | "#, | 451 | "#, |
452 | &["foo", "foo+bar"], | 452 | &["foo", "foo+bar"], |
453 | ); | 453 | ); |
454 | do_check( | 454 | do_check( |
455 | r#" | 455 | r#" |
456 | fn main() { foo+<|>bar;} | 456 | fn main() { foo+$0bar;} |
457 | "#, | 457 | "#, |
458 | &["bar", "foo+bar"], | 458 | &["bar", "foo+bar"], |
459 | ); | 459 | ); |
@@ -461,18 +461,18 @@ fn main() { foo+<|>bar;} | |||
461 | 461 | ||
462 | #[test] | 462 | #[test] |
463 | fn test_extend_selection_prefer_lifetimes() { | 463 | fn test_extend_selection_prefer_lifetimes() { |
464 | do_check(r#"fn foo<<|>'a>() {}"#, &["'a", "<'a>"]); | 464 | do_check(r#"fn foo<$0'a>() {}"#, &["'a", "<'a>"]); |
465 | do_check(r#"fn foo<'a<|>>() {}"#, &["'a", "<'a>"]); | 465 | do_check(r#"fn foo<'a$0>() {}"#, &["'a", "<'a>"]); |
466 | } | 466 | } |
467 | 467 | ||
468 | #[test] | 468 | #[test] |
469 | fn test_extend_selection_select_first_word() { | 469 | fn test_extend_selection_select_first_word() { |
470 | do_check(r#"// foo bar b<|>az quxx"#, &["baz", "// foo bar baz quxx"]); | 470 | do_check(r#"// foo bar b$0az quxx"#, &["baz", "// foo bar baz quxx"]); |
471 | do_check( | 471 | do_check( |
472 | r#" | 472 | r#" |
473 | impl S { | 473 | impl S { |
474 | fn foo() { | 474 | fn foo() { |
475 | // hel<|>lo world | 475 | // hel$0lo world |
476 | } | 476 | } |
477 | } | 477 | } |
478 | "#, | 478 | "#, |
@@ -486,7 +486,7 @@ fn foo() { | |||
486 | r#" | 486 | r#" |
487 | fn bar(){} | 487 | fn bar(){} |
488 | 488 | ||
489 | " fn f<|>oo() {" | 489 | " fn f$0oo() {" |
490 | "#, | 490 | "#, |
491 | &["foo", "\" fn foo() {\""], | 491 | &["foo", "\" fn foo() {\""], |
492 | ); | 492 | ); |
@@ -499,7 +499,7 @@ fn bar(){} | |||
499 | fn foo<R>() | 499 | fn foo<R>() |
500 | where | 500 | where |
501 | R: req::Request + 'static, | 501 | R: req::Request + 'static, |
502 | R::Params: DeserializeOwned<|> + panic::UnwindSafe + 'static, | 502 | R::Params: DeserializeOwned$0 + panic::UnwindSafe + 'static, |
503 | R::Result: Serialize + 'static, | 503 | R::Result: Serialize + 'static, |
504 | "#, | 504 | "#, |
505 | &[ | 505 | &[ |
@@ -510,26 +510,26 @@ fn foo<R>() | |||
510 | "R::Params: DeserializeOwned + panic::UnwindSafe + 'static,", | 510 | "R::Params: DeserializeOwned + panic::UnwindSafe + 'static,", |
511 | ], | 511 | ], |
512 | ); | 512 | ); |
513 | do_check(r#"fn foo<T>() where T: <|>Copy"#, &["Copy"]); | 513 | do_check(r#"fn foo<T>() where T: $0Copy"#, &["Copy"]); |
514 | do_check(r#"fn foo<T>() where T: <|>Copy + Display"#, &["Copy", "Copy + "]); | 514 | do_check(r#"fn foo<T>() where T: $0Copy + Display"#, &["Copy", "Copy + "]); |
515 | do_check(r#"fn foo<T>() where T: <|>Copy +Display"#, &["Copy", "Copy +"]); | 515 | do_check(r#"fn foo<T>() where T: $0Copy +Display"#, &["Copy", "Copy +"]); |
516 | do_check(r#"fn foo<T>() where T: <|>Copy+Display"#, &["Copy", "Copy+"]); | 516 | do_check(r#"fn foo<T>() where T: $0Copy+Display"#, &["Copy", "Copy+"]); |
517 | do_check(r#"fn foo<T>() where T: Copy + <|>Display"#, &["Display", "+ Display"]); | 517 | do_check(r#"fn foo<T>() where T: Copy + $0Display"#, &["Display", "+ Display"]); |
518 | do_check(r#"fn foo<T>() where T: Copy + <|>Display + Sync"#, &["Display", "Display + "]); | 518 | do_check(r#"fn foo<T>() where T: Copy + $0Display + Sync"#, &["Display", "Display + "]); |
519 | do_check(r#"fn foo<T>() where T: Copy +<|>Display"#, &["Display", "+Display"]); | 519 | do_check(r#"fn foo<T>() where T: Copy +$0Display"#, &["Display", "+Display"]); |
520 | } | 520 | } |
521 | 521 | ||
522 | #[test] | 522 | #[test] |
523 | fn test_extend_trait_bounds_list_inline() { | 523 | fn test_extend_trait_bounds_list_inline() { |
524 | do_check(r#"fn foo<T: <|>Copy>() {}"#, &["Copy"]); | 524 | do_check(r#"fn foo<T: $0Copy>() {}"#, &["Copy"]); |
525 | do_check(r#"fn foo<T: <|>Copy + Display>() {}"#, &["Copy", "Copy + "]); | 525 | do_check(r#"fn foo<T: $0Copy + Display>() {}"#, &["Copy", "Copy + "]); |
526 | do_check(r#"fn foo<T: <|>Copy +Display>() {}"#, &["Copy", "Copy +"]); | 526 | do_check(r#"fn foo<T: $0Copy +Display>() {}"#, &["Copy", "Copy +"]); |
527 | do_check(r#"fn foo<T: <|>Copy+Display>() {}"#, &["Copy", "Copy+"]); | 527 | do_check(r#"fn foo<T: $0Copy+Display>() {}"#, &["Copy", "Copy+"]); |
528 | do_check(r#"fn foo<T: Copy + <|>Display>() {}"#, &["Display", "+ Display"]); | 528 | do_check(r#"fn foo<T: Copy + $0Display>() {}"#, &["Display", "+ Display"]); |
529 | do_check(r#"fn foo<T: Copy + <|>Display + Sync>() {}"#, &["Display", "Display + "]); | 529 | do_check(r#"fn foo<T: Copy + $0Display + Sync>() {}"#, &["Display", "Display + "]); |
530 | do_check(r#"fn foo<T: Copy +<|>Display>() {}"#, &["Display", "+Display"]); | 530 | do_check(r#"fn foo<T: Copy +$0Display>() {}"#, &["Display", "+Display"]); |
531 | do_check( | 531 | do_check( |
532 | r#"fn foo<T: Copy<|> + Display, U: Copy>() {}"#, | 532 | r#"fn foo<T: Copy$0 + Display, U: Copy>() {}"#, |
533 | &[ | 533 | &[ |
534 | "Copy", | 534 | "Copy", |
535 | "Copy + ", | 535 | "Copy + ", |
@@ -544,19 +544,19 @@ fn foo<R>() | |||
544 | #[test] | 544 | #[test] |
545 | fn test_extend_selection_on_tuple_in_type() { | 545 | fn test_extend_selection_on_tuple_in_type() { |
546 | do_check( | 546 | do_check( |
547 | r#"fn main() { let _: (krate, <|>_crate_def_map, module_id) = (); }"#, | 547 | r#"fn main() { let _: (krate, $0_crate_def_map, module_id) = (); }"#, |
548 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | 548 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], |
549 | ); | 549 | ); |
550 | // white space variations | 550 | // white space variations |
551 | do_check( | 551 | do_check( |
552 | r#"fn main() { let _: (krate,<|>_crate_def_map,module_id) = (); }"#, | 552 | r#"fn main() { let _: (krate,$0_crate_def_map,module_id) = (); }"#, |
553 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | 553 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], |
554 | ); | 554 | ); |
555 | do_check( | 555 | do_check( |
556 | r#" | 556 | r#" |
557 | fn main() { let _: ( | 557 | fn main() { let _: ( |
558 | krate, | 558 | krate, |
559 | _crate<|>_def_map, | 559 | _crate$0_def_map, |
560 | module_id | 560 | module_id |
561 | ) = (); }"#, | 561 | ) = (); }"#, |
562 | &[ | 562 | &[ |
@@ -570,19 +570,19 @@ fn main() { let _: ( | |||
570 | #[test] | 570 | #[test] |
571 | fn test_extend_selection_on_tuple_in_rvalue() { | 571 | fn test_extend_selection_on_tuple_in_rvalue() { |
572 | do_check( | 572 | do_check( |
573 | r#"fn main() { let var = (krate, _crate_def_map<|>, module_id); }"#, | 573 | r#"fn main() { let var = (krate, _crate_def_map$0, module_id); }"#, |
574 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | 574 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], |
575 | ); | 575 | ); |
576 | // white space variations | 576 | // white space variations |
577 | do_check( | 577 | do_check( |
578 | r#"fn main() { let var = (krate,_crate<|>_def_map,module_id); }"#, | 578 | r#"fn main() { let var = (krate,_crate$0_def_map,module_id); }"#, |
579 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | 579 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], |
580 | ); | 580 | ); |
581 | do_check( | 581 | do_check( |
582 | r#" | 582 | r#" |
583 | fn main() { let var = ( | 583 | fn main() { let var = ( |
584 | krate, | 584 | krate, |
585 | _crate_def_map<|>, | 585 | _crate_def_map$0, |
586 | module_id | 586 | module_id |
587 | ); }"#, | 587 | ); }"#, |
588 | &[ | 588 | &[ |
@@ -596,19 +596,19 @@ fn main() { let var = ( | |||
596 | #[test] | 596 | #[test] |
597 | fn test_extend_selection_on_tuple_pat() { | 597 | fn test_extend_selection_on_tuple_pat() { |
598 | do_check( | 598 | do_check( |
599 | r#"fn main() { let (krate, _crate_def_map<|>, module_id) = var; }"#, | 599 | r#"fn main() { let (krate, _crate_def_map$0, module_id) = var; }"#, |
600 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], | 600 | &["_crate_def_map", "_crate_def_map, ", "(krate, _crate_def_map, module_id)"], |
601 | ); | 601 | ); |
602 | // white space variations | 602 | // white space variations |
603 | do_check( | 603 | do_check( |
604 | r#"fn main() { let (krate,_crate<|>_def_map,module_id) = var; }"#, | 604 | r#"fn main() { let (krate,_crate$0_def_map,module_id) = var; }"#, |
605 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], | 605 | &["_crate_def_map", "_crate_def_map,", "(krate,_crate_def_map,module_id)"], |
606 | ); | 606 | ); |
607 | do_check( | 607 | do_check( |
608 | r#" | 608 | r#" |
609 | fn main() { let ( | 609 | fn main() { let ( |
610 | krate, | 610 | krate, |
611 | _crate_def_map<|>, | 611 | _crate_def_map$0, |
612 | module_id | 612 | module_id |
613 | ) = var; }"#, | 613 | ) = var; }"#, |
614 | &[ | 614 | &[ |
@@ -623,7 +623,7 @@ fn main() { let ( | |||
623 | fn extend_selection_inside_macros() { | 623 | fn extend_selection_inside_macros() { |
624 | do_check( | 624 | do_check( |
625 | r#"macro_rules! foo { ($item:item) => {$item} } | 625 | r#"macro_rules! foo { ($item:item) => {$item} } |
626 | foo!{fn hello(na<|>me:usize){}}"#, | 626 | foo!{fn hello(na$0me:usize){}}"#, |
627 | &[ | 627 | &[ |
628 | "name", | 628 | "name", |
629 | "name:usize", | 629 | "name:usize", |
@@ -640,7 +640,7 @@ fn main() { let ( | |||
640 | do_check( | 640 | do_check( |
641 | r#" macro_rules! foo2 { ($item:item) => {$item} } | 641 | r#" macro_rules! foo2 { ($item:item) => {$item} } |
642 | macro_rules! foo { ($item:item) => {foo2!($item);} } | 642 | macro_rules! foo { ($item:item) => {foo2!($item);} } |
643 | foo!{fn hello(na<|>me:usize){}}"#, | 643 | foo!{fn hello(na$0me:usize){}}"#, |
644 | &[ | 644 | &[ |
645 | "name", | 645 | "name", |
646 | "name:usize", | 646 | "name:usize", |
diff --git a/crates/ide/src/fixture.rs b/crates/ide/src/fixture.rs index eb57f9224..cc8218885 100644 --- a/crates/ide/src/fixture.rs +++ b/crates/ide/src/fixture.rs | |||
@@ -20,12 +20,12 @@ pub(crate) fn files(ra_fixture: &str) -> (Analysis, Vec<FileId>) { | |||
20 | (host.analysis(), change_fixture.files) | 20 | (host.analysis(), change_fixture.files) |
21 | } | 21 | } |
22 | 22 | ||
23 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | 23 | /// Creates analysis from a multi-file fixture, returns positions marked with $0. |
24 | pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) { | 24 | pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) { |
25 | let mut host = AnalysisHost::default(); | 25 | let mut host = AnalysisHost::default(); |
26 | let change_fixture = ChangeFixture::parse(ra_fixture); | 26 | let change_fixture = ChangeFixture::parse(ra_fixture); |
27 | host.db.apply_change(change_fixture.change); | 27 | host.db.apply_change(change_fixture.change); |
28 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 28 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
29 | let offset = match range_or_offset { | 29 | let offset = match range_or_offset { |
30 | RangeOrOffset::Range(_) => panic!(), | 30 | RangeOrOffset::Range(_) => panic!(), |
31 | RangeOrOffset::Offset(it) => it, | 31 | RangeOrOffset::Offset(it) => it, |
@@ -33,12 +33,12 @@ pub(crate) fn position(ra_fixture: &str) -> (Analysis, FilePosition) { | |||
33 | (host.analysis(), FilePosition { file_id, offset }) | 33 | (host.analysis(), FilePosition { file_id, offset }) |
34 | } | 34 | } |
35 | 35 | ||
36 | /// Creates analysis for a single file, returns range marked with a pair of <|>. | 36 | /// Creates analysis for a single file, returns range marked with a pair of $0. |
37 | pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) { | 37 | pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) { |
38 | let mut host = AnalysisHost::default(); | 38 | let mut host = AnalysisHost::default(); |
39 | let change_fixture = ChangeFixture::parse(ra_fixture); | 39 | let change_fixture = ChangeFixture::parse(ra_fixture); |
40 | host.db.apply_change(change_fixture.change); | 40 | host.db.apply_change(change_fixture.change); |
41 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 41 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
42 | let range = match range_or_offset { | 42 | let range = match range_or_offset { |
43 | RangeOrOffset::Range(it) => it, | 43 | RangeOrOffset::Range(it) => it, |
44 | RangeOrOffset::Offset(_) => panic!(), | 44 | RangeOrOffset::Offset(_) => panic!(), |
@@ -46,12 +46,12 @@ pub(crate) fn range(ra_fixture: &str) -> (Analysis, FileRange) { | |||
46 | (host.analysis(), FileRange { file_id, range }) | 46 | (host.analysis(), FileRange { file_id, range }) |
47 | } | 47 | } |
48 | 48 | ||
49 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | 49 | /// Creates analysis from a multi-file fixture, returns positions marked with $0. |
50 | pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) { | 50 | pub(crate) fn annotations(ra_fixture: &str) -> (Analysis, FilePosition, Vec<(FileRange, String)>) { |
51 | let mut host = AnalysisHost::default(); | 51 | let mut host = AnalysisHost::default(); |
52 | let change_fixture = ChangeFixture::parse(ra_fixture); | 52 | let change_fixture = ChangeFixture::parse(ra_fixture); |
53 | host.db.apply_change(change_fixture.change); | 53 | host.db.apply_change(change_fixture.change); |
54 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 54 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
55 | let offset = match range_or_offset { | 55 | let offset = match range_or_offset { |
56 | RangeOrOffset::Range(_) => panic!(), | 56 | RangeOrOffset::Range(_) => panic!(), |
57 | RangeOrOffset::Offset(it) => it, | 57 | RangeOrOffset::Offset(it) => it, |
diff --git a/crates/ide/src/fn_references.rs b/crates/ide/src/fn_references.rs index 5cbbe306e..f6e5a522b 100644 --- a/crates/ide/src/fn_references.rs +++ b/crates/ide/src/fn_references.rs | |||
@@ -34,7 +34,7 @@ mod tests { | |||
34 | fn test_find_all_methods() { | 34 | fn test_find_all_methods() { |
35 | let (analysis, pos) = fixture::position( | 35 | let (analysis, pos) = fixture::position( |
36 | r#" | 36 | r#" |
37 | fn private_fn() {<|>} | 37 | fn private_fn() {$0} |
38 | 38 | ||
39 | pub fn pub_fn() {} | 39 | pub fn pub_fn() {} |
40 | 40 | ||
@@ -51,7 +51,7 @@ mod tests { | |||
51 | let (analysis, pos) = fixture::position( | 51 | let (analysis, pos) = fixture::position( |
52 | r#" | 52 | r#" |
53 | trait Foo { | 53 | trait Foo { |
54 | fn bar() {<|>} | 54 | fn bar() {$0} |
55 | fn baz() {} | 55 | fn baz() {} |
56 | } | 56 | } |
57 | "#, | 57 | "#, |
@@ -67,7 +67,7 @@ mod tests { | |||
67 | r#" | 67 | r#" |
68 | //- /lib.rs | 68 | //- /lib.rs |
69 | #[test] | 69 | #[test] |
70 | fn foo() {<|>} | 70 | fn foo() {$0} |
71 | 71 | ||
72 | pub fn pub_fn() {} | 72 | pub fn pub_fn() {} |
73 | 73 | ||
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 912144f8b..95b4cb9e3 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -166,7 +166,7 @@ mod tests { | |||
166 | check( | 166 | check( |
167 | r#" | 167 | r#" |
168 | //- /main.rs crate:main deps:std | 168 | //- /main.rs crate:main deps:std |
169 | extern crate std<|>; | 169 | extern crate std$0; |
170 | //- /std/lib.rs crate:std | 170 | //- /std/lib.rs crate:std |
171 | // empty | 171 | // empty |
172 | //^ file | 172 | //^ file |
@@ -179,7 +179,7 @@ mod tests { | |||
179 | check( | 179 | check( |
180 | r#" | 180 | r#" |
181 | //- /main.rs crate:main deps:std | 181 | //- /main.rs crate:main deps:std |
182 | extern crate std as abc<|>; | 182 | extern crate std as abc$0; |
183 | //- /std/lib.rs crate:std | 183 | //- /std/lib.rs crate:std |
184 | // empty | 184 | // empty |
185 | //^ file | 185 | //^ file |
@@ -193,7 +193,7 @@ mod tests { | |||
193 | r#" | 193 | r#" |
194 | struct Foo; | 194 | struct Foo; |
195 | //^^^ | 195 | //^^^ |
196 | enum E { X(Foo<|>) } | 196 | enum E { X(Foo$0) } |
197 | "#, | 197 | "#, |
198 | ); | 198 | ); |
199 | } | 199 | } |
@@ -204,7 +204,7 @@ enum E { X(Foo<|>) } | |||
204 | r#" | 204 | r#" |
205 | struct Foo; | 205 | struct Foo; |
206 | //^^^ | 206 | //^^^ |
207 | enum E { X(<|>Foo) } | 207 | enum E { X($0Foo) } |
208 | "#, | 208 | "#, |
209 | ); | 209 | ); |
210 | } | 210 | } |
@@ -217,7 +217,7 @@ enum E { X(<|>Foo) } | |||
217 | use a::Foo; | 217 | use a::Foo; |
218 | mod a; | 218 | mod a; |
219 | mod b; | 219 | mod b; |
220 | enum E { X(Foo<|>) } | 220 | enum E { X(Foo$0) } |
221 | 221 | ||
222 | //- /a.rs | 222 | //- /a.rs |
223 | struct Foo; | 223 | struct Foo; |
@@ -233,7 +233,7 @@ struct Foo; | |||
233 | check( | 233 | check( |
234 | r#" | 234 | r#" |
235 | //- /lib.rs | 235 | //- /lib.rs |
236 | mod <|>foo; | 236 | mod $0foo; |
237 | 237 | ||
238 | //- /foo.rs | 238 | //- /foo.rs |
239 | // empty | 239 | // empty |
@@ -244,7 +244,7 @@ mod <|>foo; | |||
244 | check( | 244 | check( |
245 | r#" | 245 | r#" |
246 | //- /lib.rs | 246 | //- /lib.rs |
247 | mod <|>foo; | 247 | mod $0foo; |
248 | 248 | ||
249 | //- /foo/mod.rs | 249 | //- /foo/mod.rs |
250 | // empty | 250 | // empty |
@@ -260,7 +260,7 @@ mod <|>foo; | |||
260 | macro_rules! foo { () => { () } } | 260 | macro_rules! foo { () => { () } } |
261 | //^^^ | 261 | //^^^ |
262 | fn bar() { | 262 | fn bar() { |
263 | <|>foo!(); | 263 | $0foo!(); |
264 | } | 264 | } |
265 | "#, | 265 | "#, |
266 | ); | 266 | ); |
@@ -273,7 +273,7 @@ fn bar() { | |||
273 | //- /lib.rs | 273 | //- /lib.rs |
274 | use foo::foo; | 274 | use foo::foo; |
275 | fn bar() { | 275 | fn bar() { |
276 | <|>foo!(); | 276 | $0foo!(); |
277 | } | 277 | } |
278 | 278 | ||
279 | //- /foo/lib.rs | 279 | //- /foo/lib.rs |
@@ -289,7 +289,7 @@ macro_rules! foo { () => { () } } | |||
289 | check( | 289 | check( |
290 | r#" | 290 | r#" |
291 | //- /lib.rs | 291 | //- /lib.rs |
292 | use foo::foo<|>; | 292 | use foo::foo$0; |
293 | 293 | ||
294 | //- /foo/lib.rs | 294 | //- /foo/lib.rs |
295 | #[macro_export] | 295 | #[macro_export] |
@@ -312,7 +312,7 @@ define_fn!(foo); | |||
312 | //^^^ | 312 | //^^^ |
313 | 313 | ||
314 | fn bar() { | 314 | fn bar() { |
315 | <|>foo(); | 315 | $0foo(); |
316 | } | 316 | } |
317 | "#, | 317 | "#, |
318 | ); | 318 | ); |
@@ -331,7 +331,7 @@ macro_rules! define_fn { | |||
331 | //^^^^^^^^^^^^^ | 331 | //^^^^^^^^^^^^^ |
332 | 332 | ||
333 | fn bar() { | 333 | fn bar() { |
334 | <|>foo(); | 334 | $0foo(); |
335 | } | 335 | } |
336 | "#, | 336 | "#, |
337 | ); | 337 | ); |
@@ -347,7 +347,7 @@ macro_rules! foo {() => {0}} | |||
347 | 347 | ||
348 | fn bar() { | 348 | fn bar() { |
349 | match (0,1) { | 349 | match (0,1) { |
350 | (<|>foo!(), _) => {} | 350 | ($0foo!(), _) => {} |
351 | } | 351 | } |
352 | } | 352 | } |
353 | "#, | 353 | "#, |
@@ -363,7 +363,7 @@ macro_rules! foo {() => {0}} | |||
363 | //^^^ | 363 | //^^^ |
364 | fn bar() { | 364 | fn bar() { |
365 | match 0 { | 365 | match 0 { |
366 | <|>foo!() => {} | 366 | $0foo!() => {} |
367 | } | 367 | } |
368 | } | 368 | } |
369 | "#, | 369 | "#, |
@@ -375,7 +375,7 @@ fn bar() { | |||
375 | check( | 375 | check( |
376 | r#" | 376 | r#" |
377 | //- /lib.rs crate:main deps:foo | 377 | //- /lib.rs crate:main deps:foo |
378 | use foo as bar<|>; | 378 | use foo as bar$0; |
379 | 379 | ||
380 | //- /foo/lib.rs crate:foo | 380 | //- /foo/lib.rs crate:foo |
381 | // empty | 381 | // empty |
@@ -389,7 +389,7 @@ use foo as bar<|>; | |||
389 | check( | 389 | check( |
390 | r#" | 390 | r#" |
391 | //- /lib.rs crate:main deps:foo | 391 | //- /lib.rs crate:main deps:foo |
392 | use foo::foo as bar<|>; | 392 | use foo::foo as bar$0; |
393 | 393 | ||
394 | //- /foo/lib.rs crate:foo | 394 | //- /foo/lib.rs crate:foo |
395 | #[macro_export] | 395 | #[macro_export] |
@@ -410,7 +410,7 @@ impl Foo { | |||
410 | } | 410 | } |
411 | 411 | ||
412 | fn bar(foo: &Foo) { | 412 | fn bar(foo: &Foo) { |
413 | foo.frobnicate<|>(); | 413 | foo.frobnicate$0(); |
414 | } | 414 | } |
415 | "#, | 415 | "#, |
416 | ); | 416 | ); |
@@ -425,7 +425,7 @@ struct Foo { | |||
425 | } //^^^^ | 425 | } //^^^^ |
426 | 426 | ||
427 | fn bar(foo: &Foo) { | 427 | fn bar(foo: &Foo) { |
428 | foo.spam<|>; | 428 | foo.spam$0; |
429 | } | 429 | } |
430 | "#, | 430 | "#, |
431 | ); | 431 | ); |
@@ -442,7 +442,7 @@ struct Foo { | |||
442 | 442 | ||
443 | fn bar() -> Foo { | 443 | fn bar() -> Foo { |
444 | Foo { | 444 | Foo { |
445 | spam<|>: 0, | 445 | spam$0: 0, |
446 | } | 446 | } |
447 | } | 447 | } |
448 | "#, | 448 | "#, |
@@ -459,7 +459,7 @@ struct Foo { | |||
459 | } //^^^^ | 459 | } //^^^^ |
460 | 460 | ||
461 | fn bar(foo: Foo) -> Foo { | 461 | fn bar(foo: Foo) -> Foo { |
462 | let Foo { spam<|>: _, } = foo | 462 | let Foo { spam$0: _, } = foo |
463 | } | 463 | } |
464 | "#, | 464 | "#, |
465 | ); | 465 | ); |
@@ -474,7 +474,7 @@ struct Foo { spam: u32 } | |||
474 | //^^^^ | 474 | //^^^^ |
475 | 475 | ||
476 | fn bar() -> Foo { | 476 | fn bar() -> Foo { |
477 | Foo { spam<|>: m!() } | 477 | Foo { spam$0: m!() } |
478 | } | 478 | } |
479 | ", | 479 | ", |
480 | ); | 480 | ); |
@@ -489,7 +489,7 @@ struct Foo(u32); | |||
489 | 489 | ||
490 | fn bar() { | 490 | fn bar() { |
491 | let foo = Foo(0); | 491 | let foo = Foo(0); |
492 | foo.<|>0; | 492 | foo.$00; |
493 | } | 493 | } |
494 | "#, | 494 | "#, |
495 | ); | 495 | ); |
@@ -505,7 +505,7 @@ impl Foo { | |||
505 | } //^^^^^^^^^^ | 505 | } //^^^^^^^^^^ |
506 | 506 | ||
507 | fn bar(foo: &Foo) { | 507 | fn bar(foo: &Foo) { |
508 | Foo::frobnicate<|>(); | 508 | Foo::frobnicate$0(); |
509 | } | 509 | } |
510 | "#, | 510 | "#, |
511 | ); | 511 | ); |
@@ -520,7 +520,7 @@ trait Foo { | |||
520 | } //^^^^^^^^^^ | 520 | } //^^^^^^^^^^ |
521 | 521 | ||
522 | fn bar() { | 522 | fn bar() { |
523 | Foo::frobnicate<|>(); | 523 | Foo::frobnicate$0(); |
524 | } | 524 | } |
525 | "#, | 525 | "#, |
526 | ); | 526 | ); |
@@ -537,7 +537,7 @@ trait Trait { | |||
537 | impl Trait for Foo {} | 537 | impl Trait for Foo {} |
538 | 538 | ||
539 | fn bar() { | 539 | fn bar() { |
540 | Foo::frobnicate<|>(); | 540 | Foo::frobnicate$0(); |
541 | } | 541 | } |
542 | "#, | 542 | "#, |
543 | ); | 543 | ); |
@@ -551,7 +551,7 @@ struct Foo; | |||
551 | impl Foo { | 551 | impl Foo { |
552 | //^^^ | 552 | //^^^ |
553 | pub fn new() -> Self { | 553 | pub fn new() -> Self { |
554 | Self<|> {} | 554 | Self$0 {} |
555 | } | 555 | } |
556 | } | 556 | } |
557 | "#, | 557 | "#, |
@@ -561,7 +561,7 @@ impl Foo { | |||
561 | struct Foo; | 561 | struct Foo; |
562 | impl Foo { | 562 | impl Foo { |
563 | //^^^ | 563 | //^^^ |
564 | pub fn new() -> Self<|> { | 564 | pub fn new() -> Self$0 { |
565 | Self {} | 565 | Self {} |
566 | } | 566 | } |
567 | } | 567 | } |
@@ -573,7 +573,7 @@ impl Foo { | |||
573 | enum Foo { A } | 573 | enum Foo { A } |
574 | impl Foo { | 574 | impl Foo { |
575 | //^^^ | 575 | //^^^ |
576 | pub fn new() -> Self<|> { | 576 | pub fn new() -> Self$0 { |
577 | Foo::A | 577 | Foo::A |
578 | } | 578 | } |
579 | } | 579 | } |
@@ -585,7 +585,7 @@ impl Foo { | |||
585 | enum Foo { A } | 585 | enum Foo { A } |
586 | impl Foo { | 586 | impl Foo { |
587 | //^^^ | 587 | //^^^ |
588 | pub fn thing(a: &Self<|>) { | 588 | pub fn thing(a: &Self$0) { |
589 | } | 589 | } |
590 | } | 590 | } |
591 | "#, | 591 | "#, |
@@ -603,7 +603,7 @@ trait Make { | |||
603 | impl Make for Foo { | 603 | impl Make for Foo { |
604 | //^^^ | 604 | //^^^ |
605 | fn new() -> Self { | 605 | fn new() -> Self { |
606 | Self<|> {} | 606 | Self$0 {} |
607 | } | 607 | } |
608 | } | 608 | } |
609 | "#, | 609 | "#, |
@@ -617,7 +617,7 @@ trait Make { | |||
617 | } | 617 | } |
618 | impl Make for Foo { | 618 | impl Make for Foo { |
619 | //^^^ | 619 | //^^^ |
620 | fn new() -> Self<|> { | 620 | fn new() -> Self$0 { |
621 | Self {} | 621 | Self {} |
622 | } | 622 | } |
623 | } | 623 | } |
@@ -629,7 +629,7 @@ impl Make for Foo { | |||
629 | fn goto_def_when_used_on_definition_name_itself() { | 629 | fn goto_def_when_used_on_definition_name_itself() { |
630 | check( | 630 | check( |
631 | r#" | 631 | r#" |
632 | struct Foo<|> { value: u32 } | 632 | struct Foo$0 { value: u32 } |
633 | //^^^ | 633 | //^^^ |
634 | "#, | 634 | "#, |
635 | ); | 635 | ); |
@@ -637,21 +637,21 @@ struct Foo<|> { value: u32 } | |||
637 | check( | 637 | check( |
638 | r#" | 638 | r#" |
639 | struct Foo { | 639 | struct Foo { |
640 | field<|>: string, | 640 | field$0: string, |
641 | } //^^^^^ | 641 | } //^^^^^ |
642 | "#, | 642 | "#, |
643 | ); | 643 | ); |
644 | 644 | ||
645 | check( | 645 | check( |
646 | r#" | 646 | r#" |
647 | fn foo_test<|>() { } | 647 | fn foo_test$0() { } |
648 | //^^^^^^^^ | 648 | //^^^^^^^^ |
649 | "#, | 649 | "#, |
650 | ); | 650 | ); |
651 | 651 | ||
652 | check( | 652 | check( |
653 | r#" | 653 | r#" |
654 | enum Foo<|> { Variant } | 654 | enum Foo$0 { Variant } |
655 | //^^^ | 655 | //^^^ |
656 | "#, | 656 | "#, |
657 | ); | 657 | ); |
@@ -660,7 +660,7 @@ enum Foo<|> { Variant } | |||
660 | r#" | 660 | r#" |
661 | enum Foo { | 661 | enum Foo { |
662 | Variant1, | 662 | Variant1, |
663 | Variant2<|>, | 663 | Variant2$0, |
664 | //^^^^^^^^ | 664 | //^^^^^^^^ |
665 | Variant3, | 665 | Variant3, |
666 | } | 666 | } |
@@ -669,35 +669,35 @@ enum Foo { | |||
669 | 669 | ||
670 | check( | 670 | check( |
671 | r#" | 671 | r#" |
672 | static INNER<|>: &str = ""; | 672 | static INNER$0: &str = ""; |
673 | //^^^^^ | 673 | //^^^^^ |
674 | "#, | 674 | "#, |
675 | ); | 675 | ); |
676 | 676 | ||
677 | check( | 677 | check( |
678 | r#" | 678 | r#" |
679 | const INNER<|>: &str = ""; | 679 | const INNER$0: &str = ""; |
680 | //^^^^^ | 680 | //^^^^^ |
681 | "#, | 681 | "#, |
682 | ); | 682 | ); |
683 | 683 | ||
684 | check( | 684 | check( |
685 | r#" | 685 | r#" |
686 | type Thing<|> = Option<()>; | 686 | type Thing$0 = Option<()>; |
687 | //^^^^^ | 687 | //^^^^^ |
688 | "#, | 688 | "#, |
689 | ); | 689 | ); |
690 | 690 | ||
691 | check( | 691 | check( |
692 | r#" | 692 | r#" |
693 | trait Foo<|> { } | 693 | trait Foo$0 { } |
694 | //^^^ | 694 | //^^^ |
695 | "#, | 695 | "#, |
696 | ); | 696 | ); |
697 | 697 | ||
698 | check( | 698 | check( |
699 | r#" | 699 | r#" |
700 | mod bar<|> { } | 700 | mod bar$0 { } |
701 | //^^^ | 701 | //^^^ |
702 | "#, | 702 | "#, |
703 | ); | 703 | ); |
@@ -714,7 +714,7 @@ fn foo() {} | |||
714 | //^^^ | 714 | //^^^ |
715 | id! { | 715 | id! { |
716 | fn bar() { | 716 | fn bar() { |
717 | fo<|>o(); | 717 | fo$0o(); |
718 | } | 718 | } |
719 | } | 719 | } |
720 | mod confuse_index { fn foo(); } | 720 | mod confuse_index { fn foo(); } |
@@ -743,7 +743,7 @@ pub mod __export { | |||
743 | fn foo() -> i8 {} | 743 | fn foo() -> i8 {} |
744 | //^^^ | 744 | //^^^ |
745 | fn test() { | 745 | fn test() { |
746 | format!("{}", fo<|>o()) | 746 | format!("{}", fo$0o()) |
747 | } | 747 | } |
748 | "#, | 748 | "#, |
749 | ); | 749 | ); |
@@ -761,7 +761,7 @@ macro_rules! include {} | |||
761 | //^^^^^^^^^^^^^^^^^^^ | 761 | //^^^^^^^^^^^^^^^^^^^ |
762 | 762 | ||
763 | fn f() { | 763 | fn f() { |
764 | foo<|>(); | 764 | foo$0(); |
765 | } | 765 | } |
766 | 766 | ||
767 | mod confuse_index { | 767 | mod confuse_index { |
@@ -778,7 +778,7 @@ fn foo() {} | |||
778 | fn goto_for_type_param() { | 778 | fn goto_for_type_param() { |
779 | check( | 779 | check( |
780 | r#" | 780 | r#" |
781 | struct Foo<T: Clone> { t: <|>T } | 781 | struct Foo<T: Clone> { t: $0T } |
782 | //^ | 782 | //^ |
783 | "#, | 783 | "#, |
784 | ); | 784 | ); |
@@ -796,7 +796,7 @@ fn foo() { | |||
796 | let x = 1; | 796 | let x = 1; |
797 | //^ | 797 | //^ |
798 | id!({ | 798 | id!({ |
799 | let y = <|>x; | 799 | let y = $0x; |
800 | let z = y; | 800 | let z = y; |
801 | }); | 801 | }); |
802 | } | 802 | } |
@@ -814,7 +814,7 @@ fn foo() { | |||
814 | id!({ | 814 | id!({ |
815 | let y = x; | 815 | let y = x; |
816 | //^ | 816 | //^ |
817 | let z = <|>y; | 817 | let z = $0y; |
818 | }); | 818 | }); |
819 | } | 819 | } |
820 | "#, | 820 | "#, |
@@ -829,7 +829,7 @@ fn main() { | |||
829 | fn foo() { | 829 | fn foo() { |
830 | let x = 92; | 830 | let x = 92; |
831 | //^ | 831 | //^ |
832 | <|>x; | 832 | $0x; |
833 | } | 833 | } |
834 | } | 834 | } |
835 | "#, | 835 | "#, |
@@ -843,7 +843,7 @@ fn main() { | |||
843 | fn bar() { | 843 | fn bar() { |
844 | macro_rules! foo { () => { () } } | 844 | macro_rules! foo { () => { () } } |
845 | //^^^ | 845 | //^^^ |
846 | <|>foo!(); | 846 | $0foo!(); |
847 | } | 847 | } |
848 | "#, | 848 | "#, |
849 | ); | 849 | ); |
@@ -857,7 +857,7 @@ struct Foo { x: i32 } | |||
857 | fn main() { | 857 | fn main() { |
858 | let x = 92; | 858 | let x = 92; |
859 | //^ | 859 | //^ |
860 | Foo { x<|> }; | 860 | Foo { x$0 }; |
861 | } | 861 | } |
862 | "#, | 862 | "#, |
863 | ) | 863 | ) |
@@ -872,7 +872,7 @@ enum Foo { | |||
872 | } //^ | 872 | } //^ |
873 | fn baz(foo: Foo) { | 873 | fn baz(foo: Foo) { |
874 | match foo { | 874 | match foo { |
875 | Foo::Bar { x<|> } => x | 875 | Foo::Bar { x$0 } => x |
876 | }; | 876 | }; |
877 | } | 877 | } |
878 | "#, | 878 | "#, |
@@ -887,7 +887,7 @@ enum Foo { Bar } | |||
887 | //^^^ | 887 | //^^^ |
888 | impl Foo { | 888 | impl Foo { |
889 | fn baz(self) { | 889 | fn baz(self) { |
890 | match self { Self::Bar<|> => {} } | 890 | match self { Self::Bar$0 => {} } |
891 | } | 891 | } |
892 | } | 892 | } |
893 | "#, | 893 | "#, |
@@ -902,7 +902,7 @@ enum Foo { Bar { val: i32 } } | |||
902 | //^^^ | 902 | //^^^ |
903 | impl Foo { | 903 | impl Foo { |
904 | fn baz(self) -> i32 { | 904 | fn baz(self) -> i32 { |
905 | match self { Self::Bar<|> { val } => {} } | 905 | match self { Self::Bar$0 { val } => {} } |
906 | } | 906 | } |
907 | } | 907 | } |
908 | "#, | 908 | "#, |
@@ -916,7 +916,7 @@ impl Foo { | |||
916 | enum Foo { Bar } | 916 | enum Foo { Bar } |
917 | //^^^ | 917 | //^^^ |
918 | impl Foo { | 918 | impl Foo { |
919 | fn baz(self) { Self::Bar<|>; } | 919 | fn baz(self) { Self::Bar$0; } |
920 | } | 920 | } |
921 | "#, | 921 | "#, |
922 | ); | 922 | ); |
@@ -929,7 +929,7 @@ impl Foo { | |||
929 | enum Foo { Bar { val: i32 } } | 929 | enum Foo { Bar { val: i32 } } |
930 | //^^^ | 930 | //^^^ |
931 | impl Foo { | 931 | impl Foo { |
932 | fn baz(self) { Self::Bar<|> {val: 4}; } | 932 | fn baz(self) { Self::Bar$0 {val: 4}; } |
933 | } | 933 | } |
934 | "#, | 934 | "#, |
935 | ); | 935 | ); |
@@ -939,7 +939,7 @@ impl Foo { | |||
939 | fn goto_def_for_type_alias_generic_parameter() { | 939 | fn goto_def_for_type_alias_generic_parameter() { |
940 | check( | 940 | check( |
941 | r#" | 941 | r#" |
942 | type Alias<T> = T<|>; | 942 | type Alias<T> = T$0; |
943 | //^ | 943 | //^ |
944 | "#, | 944 | "#, |
945 | ) | 945 | ) |
@@ -950,7 +950,7 @@ type Alias<T> = T<|>; | |||
950 | check( | 950 | check( |
951 | r#" | 951 | r#" |
952 | //- /lib.rs | 952 | //- /lib.rs |
953 | foo::module<|>::mac!(); | 953 | foo::module$0::mac!(); |
954 | 954 | ||
955 | //- /foo/lib.rs | 955 | //- /foo/lib.rs |
956 | pub mod module { | 956 | pub mod module { |
@@ -972,7 +972,7 @@ trait Iterator { | |||
972 | //^^^^ | 972 | //^^^^ |
973 | } | 973 | } |
974 | 974 | ||
975 | fn f() -> impl Iterator<Item<|> = u8> {} | 975 | fn f() -> impl Iterator<Item$0 = u8> {} |
976 | "#, | 976 | "#, |
977 | ); | 977 | ); |
978 | } | 978 | } |
@@ -987,7 +987,7 @@ trait Iterator { | |||
987 | type B; | 987 | type B; |
988 | } | 988 | } |
989 | 989 | ||
990 | fn f() -> impl Iterator<A<|> = u8, B = ()> {} | 990 | fn f() -> impl Iterator<A$0 = u8, B = ()> {} |
991 | "#, | 991 | "#, |
992 | ); | 992 | ); |
993 | check( | 993 | check( |
@@ -998,7 +998,7 @@ trait Iterator { | |||
998 | //^ | 998 | //^ |
999 | } | 999 | } |
1000 | 1000 | ||
1001 | fn f() -> impl Iterator<A = u8, B<|> = ()> {} | 1001 | fn f() -> impl Iterator<A = u8, B$0 = ()> {} |
1002 | "#, | 1002 | "#, |
1003 | ); | 1003 | ); |
1004 | } | 1004 | } |
@@ -1012,7 +1012,7 @@ trait Iterator { | |||
1012 | //^^^^ | 1012 | //^^^^ |
1013 | } | 1013 | } |
1014 | 1014 | ||
1015 | fn g() -> <() as Iterator<Item<|> = ()>>::Item {} | 1015 | fn g() -> <() as Iterator<Item$0 = ()>>::Item {} |
1016 | "#, | 1016 | "#, |
1017 | ); | 1017 | ); |
1018 | } | 1018 | } |
@@ -1027,7 +1027,7 @@ trait Iterator { | |||
1027 | type B; | 1027 | type B; |
1028 | } | 1028 | } |
1029 | 1029 | ||
1030 | fn g() -> <() as Iterator<A<|> = (), B = u8>>::B {} | 1030 | fn g() -> <() as Iterator<A$0 = (), B = u8>>::B {} |
1031 | "#, | 1031 | "#, |
1032 | ); | 1032 | ); |
1033 | check( | 1033 | check( |
@@ -1038,7 +1038,7 @@ trait Iterator { | |||
1038 | //^ | 1038 | //^ |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | fn g() -> <() as Iterator<A = (), B<|> = u8>>::A {} | 1041 | fn g() -> <() as Iterator<A = (), B$0 = u8>>::A {} |
1042 | "#, | 1042 | "#, |
1043 | ); | 1043 | ); |
1044 | } | 1044 | } |
@@ -1052,7 +1052,7 @@ struct Foo {} | |||
1052 | impl Foo { | 1052 | impl Foo { |
1053 | fn bar(self: &Foo) { | 1053 | fn bar(self: &Foo) { |
1054 | //^^^^ | 1054 | //^^^^ |
1055 | let foo = sel<|>f; | 1055 | let foo = sel$0f; |
1056 | } | 1056 | } |
1057 | }"#, | 1057 | }"#, |
1058 | ) | 1058 | ) |
@@ -1065,7 +1065,7 @@ impl Foo { | |||
1065 | struct Foo {} | 1065 | struct Foo {} |
1066 | 1066 | ||
1067 | impl Foo { | 1067 | impl Foo { |
1068 | fn bar(&self<|>) { | 1068 | fn bar(&self$0) { |
1069 | //^^^^ | 1069 | //^^^^ |
1070 | } | 1070 | } |
1071 | }"#, | 1071 | }"#, |
@@ -1076,7 +1076,7 @@ impl Foo { | |||
1076 | fn goto_lifetime_param_on_decl() { | 1076 | fn goto_lifetime_param_on_decl() { |
1077 | check( | 1077 | check( |
1078 | r#" | 1078 | r#" |
1079 | fn foo<'foobar<|>>(_: &'foobar ()) { | 1079 | fn foo<'foobar$0>(_: &'foobar ()) { |
1080 | //^^^^^^^ | 1080 | //^^^^^^^ |
1081 | }"#, | 1081 | }"#, |
1082 | ) | 1082 | ) |
@@ -1086,7 +1086,7 @@ fn foo<'foobar<|>>(_: &'foobar ()) { | |||
1086 | fn goto_lifetime_param_decl() { | 1086 | fn goto_lifetime_param_decl() { |
1087 | check( | 1087 | check( |
1088 | r#" | 1088 | r#" |
1089 | fn foo<'foobar>(_: &'foobar<|> ()) { | 1089 | fn foo<'foobar>(_: &'foobar$0 ()) { |
1090 | //^^^^^^^ | 1090 | //^^^^^^^ |
1091 | }"#, | 1091 | }"#, |
1092 | ) | 1092 | ) |
@@ -1097,7 +1097,7 @@ fn foo<'foobar>(_: &'foobar<|> ()) { | |||
1097 | check( | 1097 | check( |
1098 | r#" | 1098 | r#" |
1099 | fn foo<'foobar>(_: &'foobar ()) { | 1099 | fn foo<'foobar>(_: &'foobar ()) { |
1100 | fn foo<'foobar>(_: &'foobar<|> ()) {} | 1100 | fn foo<'foobar>(_: &'foobar$0 ()) {} |
1101 | //^^^^^^^ | 1101 | //^^^^^^^ |
1102 | }"#, | 1102 | }"#, |
1103 | ) | 1103 | ) |
@@ -1108,13 +1108,13 @@ fn foo<'foobar>(_: &'foobar ()) { | |||
1108 | fn goto_lifetime_hrtb() { | 1108 | fn goto_lifetime_hrtb() { |
1109 | check( | 1109 | check( |
1110 | r#"trait Foo<T> {} | 1110 | r#"trait Foo<T> {} |
1111 | fn foo<T>() where for<'a> T: Foo<&'a<|> (u8, u16)>, {} | 1111 | fn foo<T>() where for<'a> T: Foo<&'a$0 (u8, u16)>, {} |
1112 | //^^ | 1112 | //^^ |
1113 | "#, | 1113 | "#, |
1114 | ); | 1114 | ); |
1115 | check( | 1115 | check( |
1116 | r#"trait Foo<T> {} | 1116 | r#"trait Foo<T> {} |
1117 | fn foo<T>() where for<'a<|>> T: Foo<&'a (u8, u16)>, {} | 1117 | fn foo<T>() where for<'a$0> T: Foo<&'a (u8, u16)>, {} |
1118 | //^^ | 1118 | //^^ |
1119 | "#, | 1119 | "#, |
1120 | ); | 1120 | ); |
@@ -1125,7 +1125,7 @@ fn foo<T>() where for<'a<|>> T: Foo<&'a (u8, u16)>, {} | |||
1125 | fn goto_lifetime_hrtb_for_type() { | 1125 | fn goto_lifetime_hrtb_for_type() { |
1126 | check( | 1126 | check( |
1127 | r#"trait Foo<T> {} | 1127 | r#"trait Foo<T> {} |
1128 | fn foo<T>() where T: for<'a> Foo<&'a<|> (u8, u16)>, {} | 1128 | fn foo<T>() where T: for<'a> Foo<&'a$0 (u8, u16)>, {} |
1129 | //^^ | 1129 | //^^ |
1130 | "#, | 1130 | "#, |
1131 | ); | 1131 | ); |
@@ -1139,7 +1139,7 @@ fn foo<'foo>(_: &'foo ()) { | |||
1139 | 'foo: { | 1139 | 'foo: { |
1140 | //^^^^ | 1140 | //^^^^ |
1141 | 'bar: loop { | 1141 | 'bar: loop { |
1142 | break 'foo<|>; | 1142 | break 'foo$0; |
1143 | } | 1143 | } |
1144 | } | 1144 | } |
1145 | }"#, | 1145 | }"#, |
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs index da9378a97..761a98b2c 100644 --- a/crates/ide/src/goto_implementation.rs +++ b/crates/ide/src/goto_implementation.rs | |||
@@ -107,7 +107,7 @@ mod tests { | |||
107 | fn goto_implementation_works() { | 107 | fn goto_implementation_works() { |
108 | check( | 108 | check( |
109 | r#" | 109 | r#" |
110 | struct Foo<|>; | 110 | struct Foo$0; |
111 | impl Foo {} | 111 | impl Foo {} |
112 | //^^^ | 112 | //^^^ |
113 | "#, | 113 | "#, |
@@ -118,7 +118,7 @@ impl Foo {} | |||
118 | fn goto_implementation_works_multiple_blocks() { | 118 | fn goto_implementation_works_multiple_blocks() { |
119 | check( | 119 | check( |
120 | r#" | 120 | r#" |
121 | struct Foo<|>; | 121 | struct Foo$0; |
122 | impl Foo {} | 122 | impl Foo {} |
123 | //^^^ | 123 | //^^^ |
124 | impl Foo {} | 124 | impl Foo {} |
@@ -131,7 +131,7 @@ impl Foo {} | |||
131 | fn goto_implementation_works_multiple_mods() { | 131 | fn goto_implementation_works_multiple_mods() { |
132 | check( | 132 | check( |
133 | r#" | 133 | r#" |
134 | struct Foo<|>; | 134 | struct Foo$0; |
135 | mod a { | 135 | mod a { |
136 | impl super::Foo {} | 136 | impl super::Foo {} |
137 | //^^^^^^^^^^ | 137 | //^^^^^^^^^^ |
@@ -149,7 +149,7 @@ mod b { | |||
149 | check( | 149 | check( |
150 | r#" | 150 | r#" |
151 | //- /lib.rs | 151 | //- /lib.rs |
152 | struct Foo<|>; | 152 | struct Foo$0; |
153 | mod a; | 153 | mod a; |
154 | mod b; | 154 | mod b; |
155 | //- /a.rs | 155 | //- /a.rs |
@@ -166,7 +166,7 @@ impl crate::Foo {} | |||
166 | fn goto_implementation_for_trait() { | 166 | fn goto_implementation_for_trait() { |
167 | check( | 167 | check( |
168 | r#" | 168 | r#" |
169 | trait T<|> {} | 169 | trait T$0 {} |
170 | struct Foo; | 170 | struct Foo; |
171 | impl T for Foo {} | 171 | impl T for Foo {} |
172 | //^^^ | 172 | //^^^ |
@@ -179,7 +179,7 @@ impl T for Foo {} | |||
179 | check( | 179 | check( |
180 | r#" | 180 | r#" |
181 | //- /lib.rs | 181 | //- /lib.rs |
182 | trait T<|> {}; | 182 | trait T$0 {}; |
183 | struct Foo; | 183 | struct Foo; |
184 | mod a; | 184 | mod a; |
185 | mod b; | 185 | mod b; |
@@ -199,7 +199,7 @@ impl crate::T for crate::Foo {} | |||
199 | r#" | 199 | r#" |
200 | //- /lib.rs | 200 | //- /lib.rs |
201 | trait T {} | 201 | trait T {} |
202 | struct Foo<|>; | 202 | struct Foo$0; |
203 | impl Foo {} | 203 | impl Foo {} |
204 | //^^^ | 204 | //^^^ |
205 | impl T for Foo {} | 205 | impl T for Foo {} |
@@ -216,7 +216,7 @@ impl T for &Foo {} | |||
216 | r#" | 216 | r#" |
217 | #[derive(Copy)] | 217 | #[derive(Copy)] |
218 | //^^^^^^^^^^^^^^^ | 218 | //^^^^^^^^^^^^^^^ |
219 | struct Foo<|>; | 219 | struct Foo$0; |
220 | 220 | ||
221 | mod marker { | 221 | mod marker { |
222 | trait Copy {} | 222 | trait Copy {} |
diff --git a/crates/ide/src/goto_type_definition.rs b/crates/ide/src/goto_type_definition.rs index 7e84e06be..369a59820 100644 --- a/crates/ide/src/goto_type_definition.rs +++ b/crates/ide/src/goto_type_definition.rs | |||
@@ -76,7 +76,7 @@ mod tests { | |||
76 | struct Foo; | 76 | struct Foo; |
77 | //^^^ | 77 | //^^^ |
78 | fn foo() { | 78 | fn foo() { |
79 | let f: Foo; f<|> | 79 | let f: Foo; f$0 |
80 | } | 80 | } |
81 | "#, | 81 | "#, |
82 | ); | 82 | ); |
@@ -89,7 +89,7 @@ fn foo() { | |||
89 | struct Foo; | 89 | struct Foo; |
90 | //^^^ | 90 | //^^^ |
91 | fn foo() { | 91 | fn foo() { |
92 | let f: &Foo; f<|> | 92 | let f: &Foo; f$0 |
93 | } | 93 | } |
94 | "#, | 94 | "#, |
95 | ); | 95 | ); |
@@ -103,7 +103,7 @@ macro_rules! id { ($($tt:tt)*) => { $($tt)* } } | |||
103 | struct Foo {} | 103 | struct Foo {} |
104 | //^^^ | 104 | //^^^ |
105 | id! { | 105 | id! { |
106 | fn bar() { let f<|> = Foo {}; } | 106 | fn bar() { let f$0 = Foo {}; } |
107 | } | 107 | } |
108 | "#, | 108 | "#, |
109 | ); | 109 | ); |
@@ -115,7 +115,7 @@ id! { | |||
115 | r#" | 115 | r#" |
116 | struct Foo; | 116 | struct Foo; |
117 | //^^^ | 117 | //^^^ |
118 | fn foo(<|>f: Foo) {} | 118 | fn foo($0f: Foo) {} |
119 | "#, | 119 | "#, |
120 | ); | 120 | ); |
121 | } | 121 | } |
@@ -129,7 +129,7 @@ struct Foo; | |||
129 | struct Bar(Foo); | 129 | struct Bar(Foo); |
130 | fn foo() { | 130 | fn foo() { |
131 | let bar = Bar(Foo); | 131 | let bar = Bar(Foo); |
132 | bar.<|>0; | 132 | bar.$00; |
133 | } | 133 | } |
134 | "#, | 134 | "#, |
135 | ); | 135 | ); |
@@ -142,7 +142,7 @@ fn foo() { | |||
142 | struct Foo; | 142 | struct Foo; |
143 | //^^^ | 143 | //^^^ |
144 | impl Foo { | 144 | impl Foo { |
145 | fn f(&self<|>) {} | 145 | fn f(&self$0) {} |
146 | } | 146 | } |
147 | "#, | 147 | "#, |
148 | ) | 148 | ) |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 2737c900f..8cb4a51d8 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | doc_links::{remove_links, rewrite_links}, | 17 | doc_links::{remove_links, rewrite_links}, |
18 | markdown_remove::remove_markdown, | 18 | markdown_remove::remove_markdown, |
19 | markup::Markup, | 19 | markup::Markup, |
20 | runnables::runnable, | 20 | runnables::{runnable, runnable_fn}, |
21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |
22 | }; | 22 | }; |
23 | 23 | ||
@@ -31,19 +31,6 @@ pub struct HoverConfig { | |||
31 | pub markdown: bool, | 31 | pub markdown: bool, |
32 | } | 32 | } |
33 | 33 | ||
34 | impl Default for HoverConfig { | ||
35 | fn default() -> Self { | ||
36 | Self { | ||
37 | implementations: true, | ||
38 | run: true, | ||
39 | debug: true, | ||
40 | goto_type_def: true, | ||
41 | links_in_hover: true, | ||
42 | markdown: true, | ||
43 | } | ||
44 | } | ||
45 | } | ||
46 | |||
47 | impl HoverConfig { | 34 | impl HoverConfig { |
48 | pub const NO_ACTIONS: Self = Self { | 35 | pub const NO_ACTIONS: Self = Self { |
49 | implementations: false, | 36 | implementations: false, |
@@ -70,7 +57,7 @@ impl HoverConfig { | |||
70 | #[derive(Debug, Clone)] | 57 | #[derive(Debug, Clone)] |
71 | pub enum HoverAction { | 58 | pub enum HoverAction { |
72 | Runnable(Runnable), | 59 | Runnable(Runnable), |
73 | Implementaion(FilePosition), | 60 | Implementation(FilePosition), |
74 | GoToType(Vec<HoverGotoTypeData>), | 61 | GoToType(Vec<HoverGotoTypeData>), |
75 | } | 62 | } |
76 | 63 | ||
@@ -116,12 +103,13 @@ pub(crate) fn hover( | |||
116 | }; | 103 | }; |
117 | if let Some(definition) = definition { | 104 | if let Some(definition) = definition { |
118 | if let Some(markup) = hover_for_definition(db, definition) { | 105 | if let Some(markup) = hover_for_definition(db, definition) { |
106 | let markup = markup.as_str(); | ||
119 | let markup = if !markdown { | 107 | let markup = if !markdown { |
120 | remove_markdown(&markup.as_str()) | 108 | remove_markdown(markup) |
121 | } else if links_in_hover { | 109 | } else if links_in_hover { |
122 | rewrite_links(db, &markup.as_str(), &definition) | 110 | rewrite_links(db, markup, &definition) |
123 | } else { | 111 | } else { |
124 | remove_links(&markup.as_str()) | 112 | remove_links(markup) |
125 | }; | 113 | }; |
126 | res.markup = Markup::from(markup); | 114 | res.markup = Markup::from(markup); |
127 | if let Some(action) = show_implementations_action(db, definition) { | 115 | if let Some(action) = show_implementations_action(db, definition) { |
@@ -175,22 +163,24 @@ pub(crate) fn hover( | |||
175 | 163 | ||
176 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | 164 | fn show_implementations_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { |
177 | fn to_action(nav_target: NavigationTarget) -> HoverAction { | 165 | fn to_action(nav_target: NavigationTarget) -> HoverAction { |
178 | HoverAction::Implementaion(FilePosition { | 166 | HoverAction::Implementation(FilePosition { |
179 | file_id: nav_target.file_id, | 167 | file_id: nav_target.file_id, |
180 | offset: nav_target.focus_or_full_range().start(), | 168 | offset: nav_target.focus_or_full_range().start(), |
181 | }) | 169 | }) |
182 | } | 170 | } |
183 | 171 | ||
184 | match def { | 172 | let adt = match def { |
185 | Definition::ModuleDef(it) => match it { | 173 | Definition::ModuleDef(ModuleDef::Trait(it)) => return it.try_to_nav(db).map(to_action), |
186 | ModuleDef::Adt(Adt::Struct(it)) => Some(to_action(it.try_to_nav(db)?)), | 174 | Definition::ModuleDef(ModuleDef::Adt(it)) => Some(it), |
187 | ModuleDef::Adt(Adt::Union(it)) => Some(to_action(it.try_to_nav(db)?)), | 175 | Definition::SelfType(it) => it.target_ty(db).as_adt(), |
188 | ModuleDef::Adt(Adt::Enum(it)) => Some(to_action(it.try_to_nav(db)?)), | ||
189 | ModuleDef::Trait(it) => Some(to_action(it.try_to_nav(db)?)), | ||
190 | _ => None, | ||
191 | }, | ||
192 | _ => None, | 176 | _ => None, |
177 | }?; | ||
178 | match adt { | ||
179 | Adt::Struct(it) => it.try_to_nav(db), | ||
180 | Adt::Union(it) => it.try_to_nav(db), | ||
181 | Adt::Enum(it) => it.try_to_nav(db), | ||
193 | } | 182 | } |
183 | .map(to_action) | ||
194 | } | 184 | } |
195 | 185 | ||
196 | fn runnable_action( | 186 | fn runnable_action( |
@@ -201,22 +191,20 @@ fn runnable_action( | |||
201 | match def { | 191 | match def { |
202 | Definition::ModuleDef(it) => match it { | 192 | Definition::ModuleDef(it) => match it { |
203 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { | 193 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { |
204 | ModuleSource::Module(it) => runnable(&sema, it.syntax().clone(), file_id) | 194 | ModuleSource::Module(it) => { |
205 | .map(|it| HoverAction::Runnable(it)), | 195 | runnable(&sema, it.syntax().clone()).map(|it| HoverAction::Runnable(it)) |
196 | } | ||
206 | _ => None, | 197 | _ => None, |
207 | }, | 198 | }, |
208 | ModuleDef::Function(it) => { | 199 | ModuleDef::Function(func) => { |
209 | #[allow(deprecated)] | 200 | let src = func.source(sema.db)?; |
210 | let src = it.source(sema.db)?; | ||
211 | if src.file_id != file_id.into() { | 201 | if src.file_id != file_id.into() { |
212 | mark::hit!(hover_macro_generated_struct_fn_doc_comment); | 202 | mark::hit!(hover_macro_generated_struct_fn_doc_comment); |
213 | mark::hit!(hover_macro_generated_struct_fn_doc_attr); | 203 | mark::hit!(hover_macro_generated_struct_fn_doc_attr); |
214 | |||
215 | return None; | 204 | return None; |
216 | } | 205 | } |
217 | 206 | ||
218 | runnable(&sema, src.value.syntax().clone(), file_id) | 207 | runnable_fn(&sema, func).map(HoverAction::Runnable) |
219 | .map(|it| HoverAction::Runnable(it)) | ||
220 | } | 208 | } |
221 | _ => None, | 209 | _ => None, |
222 | }, | 210 | }, |
@@ -225,45 +213,46 @@ fn runnable_action( | |||
225 | } | 213 | } |
226 | 214 | ||
227 | fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | 215 | fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { |
228 | match def { | 216 | let mut targets: Vec<ModuleDef> = Vec::new(); |
229 | Definition::Local(it) => { | 217 | let mut push_new_def = |item: ModuleDef| { |
230 | let mut targets: Vec<ModuleDef> = Vec::new(); | 218 | if !targets.contains(&item) { |
231 | let mut push_new_def = |item: ModuleDef| { | 219 | targets.push(item); |
232 | if !targets.contains(&item) { | ||
233 | targets.push(item); | ||
234 | } | ||
235 | }; | ||
236 | |||
237 | it.ty(db).walk(db, |t| { | ||
238 | if let Some(adt) = t.as_adt() { | ||
239 | push_new_def(adt.into()); | ||
240 | } else if let Some(trait_) = t.as_dyn_trait() { | ||
241 | push_new_def(trait_.into()); | ||
242 | } else if let Some(traits) = t.as_impl_traits(db) { | ||
243 | traits.into_iter().for_each(|it| push_new_def(it.into())); | ||
244 | } else if let Some(trait_) = t.as_associated_type_parent_trait(db) { | ||
245 | push_new_def(trait_.into()); | ||
246 | } | ||
247 | }); | ||
248 | |||
249 | let targets = targets | ||
250 | .into_iter() | ||
251 | .filter_map(|it| { | ||
252 | Some(HoverGotoTypeData { | ||
253 | mod_path: render_path( | ||
254 | db, | ||
255 | it.module(db)?, | ||
256 | it.name(db).map(|name| name.to_string()), | ||
257 | ), | ||
258 | nav: it.try_to_nav(db)?, | ||
259 | }) | ||
260 | }) | ||
261 | .collect(); | ||
262 | |||
263 | Some(HoverAction::GoToType(targets)) | ||
264 | } | 220 | } |
265 | _ => None, | 221 | }; |
222 | |||
223 | if let Definition::TypeParam(it) = def { | ||
224 | it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); | ||
225 | } else { | ||
226 | let ty = match def { | ||
227 | Definition::Local(it) => it.ty(db), | ||
228 | Definition::ConstParam(it) => it.ty(db), | ||
229 | _ => return None, | ||
230 | }; | ||
231 | |||
232 | ty.walk(db, |t| { | ||
233 | if let Some(adt) = t.as_adt() { | ||
234 | push_new_def(adt.into()); | ||
235 | } else if let Some(trait_) = t.as_dyn_trait() { | ||
236 | push_new_def(trait_.into()); | ||
237 | } else if let Some(traits) = t.as_impl_traits(db) { | ||
238 | traits.into_iter().for_each(|it| push_new_def(it.into())); | ||
239 | } else if let Some(trait_) = t.as_associated_type_parent_trait(db) { | ||
240 | push_new_def(trait_.into()); | ||
241 | } | ||
242 | }); | ||
266 | } | 243 | } |
244 | |||
245 | let targets = targets | ||
246 | .into_iter() | ||
247 | .filter_map(|it| { | ||
248 | Some(HoverGotoTypeData { | ||
249 | mod_path: render_path(db, it.module(db)?, it.name(db).map(|name| name.to_string())), | ||
250 | nav: it.try_to_nav(db)?, | ||
251 | }) | ||
252 | }) | ||
253 | .collect(); | ||
254 | |||
255 | Some(HoverAction::GoToType(targets)) | ||
267 | } | 256 | } |
268 | 257 | ||
269 | fn hover_markup( | 258 | fn hover_markup( |
@@ -331,7 +320,6 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
331 | from_def_source_labeled(db, it, Some(label), mod_path) | 320 | from_def_source_labeled(db, it, Some(label), mod_path) |
332 | } | 321 | } |
333 | Definition::Field(def) => { | 322 | Definition::Field(def) => { |
334 | #[allow(deprecated)] | ||
335 | let src = def.source(db)?.value; | 323 | let src = def.source(db)?.value; |
336 | if let FieldSource::Named(it) = src { | 324 | if let FieldSource::Named(it) = src { |
337 | from_def_source_labeled(db, def, it.short_label(), mod_path) | 325 | from_def_source_labeled(db, def, it.short_label(), mod_path) |
@@ -370,10 +358,8 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
370 | } | 358 | } |
371 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 359 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
372 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 360 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
373 | Definition::TypeParam(_) | Definition::ConstParam(_) => { | 361 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), |
374 | // FIXME: Hover for generic param | 362 | Definition::ConstParam(it) => from_def_source(db, it, None), |
375 | None | ||
376 | } | ||
377 | }; | 363 | }; |
378 | 364 | ||
379 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 365 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
@@ -381,7 +367,6 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
381 | D: HasSource<Ast = A> + HasAttrs + Copy, | 367 | D: HasSource<Ast = A> + HasAttrs + Copy, |
382 | A: ShortLabel, | 368 | A: ShortLabel, |
383 | { | 369 | { |
384 | #[allow(deprecated)] | ||
385 | let short_label = def.source(db)?.value.short_label(); | 370 | let short_label = def.source(db)?.value.short_label(); |
386 | from_def_source_labeled(db, def, short_label, mod_path) | 371 | from_def_source_labeled(db, def, short_label, mod_path) |
387 | } | 372 | } |
@@ -472,7 +457,7 @@ mod tests { | |||
472 | pub fn foo() -> u32 { 1 } | 457 | pub fn foo() -> u32 { 1 } |
473 | 458 | ||
474 | fn main() { | 459 | fn main() { |
475 | let foo_test = foo()<|>; | 460 | let foo_test = foo()$0; |
476 | } | 461 | } |
477 | "#, | 462 | "#, |
478 | expect![[r#" | 463 | expect![[r#" |
@@ -491,7 +476,7 @@ fn main() { | |||
491 | pub fn foo() -> u32 { 1 } | 476 | pub fn foo() -> u32 { 1 } |
492 | 477 | ||
493 | fn main() { | 478 | fn main() { |
494 | let foo_test = foo()<|>; | 479 | let foo_test = foo()$0; |
495 | } | 480 | } |
496 | "#, | 481 | "#, |
497 | expect![[r#" | 482 | expect![[r#" |
@@ -521,7 +506,7 @@ fn main() { | |||
521 | Option::Some(*memo + value) | 506 | Option::Some(*memo + value) |
522 | }; | 507 | }; |
523 | let number = 5u32; | 508 | let number = 5u32; |
524 | let mut iter<|> = scan(OtherStruct { i: num }, closure, number); | 509 | let mut iter$0 = scan(OtherStruct { i: num }, closure, number); |
525 | } | 510 | } |
526 | "#, | 511 | "#, |
527 | expect![[r#" | 512 | expect![[r#" |
@@ -541,7 +526,7 @@ fn main() { | |||
541 | r#" | 526 | r#" |
542 | pub fn foo() -> u32 { 1 } | 527 | pub fn foo() -> u32 { 1 } |
543 | 528 | ||
544 | fn main() { let foo_test = fo<|>o(); } | 529 | fn main() { let foo_test = fo$0o(); } |
545 | "#, | 530 | "#, |
546 | expect![[r#" | 531 | expect![[r#" |
547 | *foo* | 532 | *foo* |
@@ -573,7 +558,7 @@ mod a; | |||
573 | mod b; | 558 | mod b; |
574 | mod c; | 559 | mod c; |
575 | 560 | ||
576 | fn main() { let foo_test = fo<|>o(); } | 561 | fn main() { let foo_test = fo$0o(); } |
577 | "#, | 562 | "#, |
578 | expect![[r#" | 563 | expect![[r#" |
579 | *foo* | 564 | *foo* |
@@ -590,7 +575,7 @@ fn main() { let foo_test = fo<|>o(); } | |||
590 | r#" | 575 | r#" |
591 | pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { } | 576 | pub fn foo<'a, T: AsRef<str>>(b: &'a T) -> &'a str { } |
592 | 577 | ||
593 | fn main() { let foo_test = fo<|>o(); } | 578 | fn main() { let foo_test = fo$0o(); } |
594 | "#, | 579 | "#, |
595 | expect![[r#" | 580 | expect![[r#" |
596 | *foo* | 581 | *foo* |
@@ -610,7 +595,7 @@ fn main() { let foo_test = fo<|>o(); } | |||
610 | fn hover_shows_fn_signature_on_fn_name() { | 595 | fn hover_shows_fn_signature_on_fn_name() { |
611 | check( | 596 | check( |
612 | r#" | 597 | r#" |
613 | pub fn foo<|>(a: u32, b: u32) -> u32 {} | 598 | pub fn foo$0(a: u32, b: u32) -> u32 {} |
614 | 599 | ||
615 | fn main() { } | 600 | fn main() { } |
616 | "#, | 601 | "#, |
@@ -638,7 +623,7 @@ fn main() { } | |||
638 | /// # | 623 | /// # |
639 | /// foo(Path::new("hello, world!")) | 624 | /// foo(Path::new("hello, world!")) |
640 | /// ``` | 625 | /// ``` |
641 | pub fn foo<|>(_: &Path) {} | 626 | pub fn foo$0(_: &Path) {} |
642 | 627 | ||
643 | fn main() { } | 628 | fn main() { } |
644 | "#, | 629 | "#, |
@@ -671,7 +656,7 @@ fn main() { } | |||
671 | check( | 656 | check( |
672 | r##" | 657 | r##" |
673 | #[doc = r#"Raw string doc attr"#] | 658 | #[doc = r#"Raw string doc attr"#] |
674 | pub fn foo<|>(_: &Path) {} | 659 | pub fn foo$0(_: &Path) {} |
675 | 660 | ||
676 | fn main() { } | 661 | fn main() { } |
677 | "##, | 662 | "##, |
@@ -701,7 +686,7 @@ fn main() { } | |||
701 | struct Foo { field_a: u32 } | 686 | struct Foo { field_a: u32 } |
702 | 687 | ||
703 | fn main() { | 688 | fn main() { |
704 | let foo = Foo { field_a<|>: 0, }; | 689 | let foo = Foo { field_a$0: 0, }; |
705 | } | 690 | } |
706 | "#, | 691 | "#, |
707 | expect![[r#" | 692 | expect![[r#" |
@@ -720,7 +705,7 @@ fn main() { | |||
720 | // Hovering over the field in the definition | 705 | // Hovering over the field in the definition |
721 | check( | 706 | check( |
722 | r#" | 707 | r#" |
723 | struct Foo { field_a<|>: u32 } | 708 | struct Foo { field_a$0: u32 } |
724 | 709 | ||
725 | fn main() { | 710 | fn main() { |
726 | let foo = Foo { field_a: 0 }; | 711 | let foo = Foo { field_a: 0 }; |
@@ -743,7 +728,7 @@ fn main() { | |||
743 | #[test] | 728 | #[test] |
744 | fn hover_const_static() { | 729 | fn hover_const_static() { |
745 | check( | 730 | check( |
746 | r#"const foo<|>: u32 = 123;"#, | 731 | r#"const foo$0: u32 = 123;"#, |
747 | expect![[r#" | 732 | expect![[r#" |
748 | *foo* | 733 | *foo* |
749 | 734 | ||
@@ -757,7 +742,7 @@ fn main() { | |||
757 | "#]], | 742 | "#]], |
758 | ); | 743 | ); |
759 | check( | 744 | check( |
760 | r#"static foo<|>: u32 = 456;"#, | 745 | r#"static foo$0: u32 = 456;"#, |
761 | expect![[r#" | 746 | expect![[r#" |
762 | *foo* | 747 | *foo* |
763 | 748 | ||
@@ -779,7 +764,7 @@ fn main() { | |||
779 | struct Test<K, T = u8> { k: K, t: T } | 764 | struct Test<K, T = u8> { k: K, t: T } |
780 | 765 | ||
781 | fn main() { | 766 | fn main() { |
782 | let zz<|> = Test { t: 23u8, k: 33 }; | 767 | let zz$0 = Test { t: 23u8, k: 33 }; |
783 | }"#, | 768 | }"#, |
784 | expect![[r#" | 769 | expect![[r#" |
785 | *zz* | 770 | *zz* |
@@ -798,7 +783,7 @@ fn main() { | |||
798 | enum Option<T> { Some(T) } | 783 | enum Option<T> { Some(T) } |
799 | use Option::Some; | 784 | use Option::Some; |
800 | 785 | ||
801 | fn main() { So<|>me(12); } | 786 | fn main() { So$0me(12); } |
802 | "#, | 787 | "#, |
803 | expect![[r#" | 788 | expect![[r#" |
804 | *Some* | 789 | *Some* |
@@ -818,7 +803,7 @@ fn main() { So<|>me(12); } | |||
818 | enum Option<T> { Some(T) } | 803 | enum Option<T> { Some(T) } |
819 | use Option::Some; | 804 | use Option::Some; |
820 | 805 | ||
821 | fn main() { let b<|>ar = Some(12); } | 806 | fn main() { let b$0ar = Some(12); } |
822 | "#, | 807 | "#, |
823 | expect![[r#" | 808 | expect![[r#" |
824 | *bar* | 809 | *bar* |
@@ -836,7 +821,7 @@ fn main() { let b<|>ar = Some(12); } | |||
836 | r#" | 821 | r#" |
837 | enum Option<T> { | 822 | enum Option<T> { |
838 | /// The None variant | 823 | /// The None variant |
839 | Non<|>e | 824 | Non$0e |
840 | } | 825 | } |
841 | "#, | 826 | "#, |
842 | expect![[r#" | 827 | expect![[r#" |
@@ -863,7 +848,7 @@ enum Option<T> { | |||
863 | Some(T) | 848 | Some(T) |
864 | } | 849 | } |
865 | fn main() { | 850 | fn main() { |
866 | let s = Option::Som<|>e(12); | 851 | let s = Option::Som$0e(12); |
867 | } | 852 | } |
868 | "#, | 853 | "#, |
869 | expect![[r#" | 854 | expect![[r#" |
@@ -887,7 +872,7 @@ fn main() { | |||
887 | #[test] | 872 | #[test] |
888 | fn hover_for_local_variable() { | 873 | fn hover_for_local_variable() { |
889 | check( | 874 | check( |
890 | r#"fn func(foo: i32) { fo<|>o; }"#, | 875 | r#"fn func(foo: i32) { fo$0o; }"#, |
891 | expect![[r#" | 876 | expect![[r#" |
892 | *foo* | 877 | *foo* |
893 | 878 | ||
@@ -901,7 +886,7 @@ fn main() { | |||
901 | #[test] | 886 | #[test] |
902 | fn hover_for_local_variable_pat() { | 887 | fn hover_for_local_variable_pat() { |
903 | check( | 888 | check( |
904 | r#"fn func(fo<|>o: i32) {}"#, | 889 | r#"fn func(fo$0o: i32) {}"#, |
905 | expect![[r#" | 890 | expect![[r#" |
906 | *foo* | 891 | *foo* |
907 | 892 | ||
@@ -915,7 +900,7 @@ fn main() { | |||
915 | #[test] | 900 | #[test] |
916 | fn hover_local_var_edge() { | 901 | fn hover_local_var_edge() { |
917 | check( | 902 | check( |
918 | r#"fn func(foo: i32) { if true { <|>foo; }; }"#, | 903 | r#"fn func(foo: i32) { if true { $0foo; }; }"#, |
919 | expect![[r#" | 904 | expect![[r#" |
920 | *foo* | 905 | *foo* |
921 | 906 | ||
@@ -929,7 +914,7 @@ fn main() { | |||
929 | #[test] | 914 | #[test] |
930 | fn hover_for_param_edge() { | 915 | fn hover_for_param_edge() { |
931 | check( | 916 | check( |
932 | r#"fn func(<|>foo: i32) {}"#, | 917 | r#"fn func($0foo: i32) {}"#, |
933 | expect![[r#" | 918 | expect![[r#" |
934 | *foo* | 919 | *foo* |
935 | 920 | ||
@@ -949,7 +934,7 @@ fn main() { | |||
949 | trait DerefMut { | 934 | trait DerefMut { |
950 | type Target: ?Sized; | 935 | type Target: ?Sized; |
951 | } | 936 | } |
952 | fn f(_x<|>: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#, | 937 | fn f(_x$0: impl Deref<Target=u8> + DerefMut<Target=u8>) {}"#, |
953 | expect![[r#" | 938 | expect![[r#" |
954 | *_x* | 939 | *_x* |
955 | 940 | ||
@@ -970,7 +955,7 @@ impl Thing { | |||
970 | fn new() -> Thing { Thing { x: 0 } } | 955 | fn new() -> Thing { Thing { x: 0 } } |
971 | } | 956 | } |
972 | 957 | ||
973 | fn main() { let foo_<|>test = Thing::new(); } | 958 | fn main() { let foo_$0test = Thing::new(); } |
974 | "#, | 959 | "#, |
975 | expect![[r#" | 960 | expect![[r#" |
976 | *foo_test* | 961 | *foo_test* |
@@ -994,7 +979,7 @@ mod wrapper { | |||
994 | } | 979 | } |
995 | } | 980 | } |
996 | 981 | ||
997 | fn main() { let foo_test = wrapper::Thing::new<|>(); } | 982 | fn main() { let foo_test = wrapper::Thing::new$0(); } |
998 | "#, | 983 | "#, |
999 | expect![[r#" | 984 | expect![[r#" |
1000 | *new* | 985 | *new* |
@@ -1021,7 +1006,7 @@ impl X { | |||
1021 | 1006 | ||
1022 | fn main() { | 1007 | fn main() { |
1023 | match 1 { | 1008 | match 1 { |
1024 | X::C<|> => {}, | 1009 | X::C$0 => {}, |
1025 | 2 => {}, | 1010 | 2 => {}, |
1026 | _ => {} | 1011 | _ => {} |
1027 | }; | 1012 | }; |
@@ -1047,7 +1032,7 @@ fn main() { | |||
1047 | r#" | 1032 | r#" |
1048 | struct Thing { x: u32 } | 1033 | struct Thing { x: u32 } |
1049 | impl Thing { | 1034 | impl Thing { |
1050 | fn new() -> Self { Self<|> { x: 0 } } | 1035 | fn new() -> Self { Self$0 { x: 0 } } |
1051 | } | 1036 | } |
1052 | "#, | 1037 | "#, |
1053 | expect![[r#" | 1038 | expect![[r#" |
@@ -1066,7 +1051,7 @@ impl Thing { | |||
1066 | r#" | 1051 | r#" |
1067 | struct Thing { x: u32 } | 1052 | struct Thing { x: u32 } |
1068 | impl Thing { | 1053 | impl Thing { |
1069 | fn new() -> Self<|> { Self { x: 0 } } | 1054 | fn new() -> Self$0 { Self { x: 0 } } |
1070 | } | 1055 | } |
1071 | "#, | 1056 | "#, |
1072 | expect![[r#" | 1057 | expect![[r#" |
@@ -1085,7 +1070,7 @@ impl Thing { | |||
1085 | r#" | 1070 | r#" |
1086 | enum Thing { A } | 1071 | enum Thing { A } |
1087 | impl Thing { | 1072 | impl Thing { |
1088 | pub fn new() -> Self<|> { Thing::A } | 1073 | pub fn new() -> Self$0 { Thing::A } |
1089 | } | 1074 | } |
1090 | "#, | 1075 | "#, |
1091 | expect![[r#" | 1076 | expect![[r#" |
@@ -1104,7 +1089,7 @@ impl Thing { | |||
1104 | r#" | 1089 | r#" |
1105 | enum Thing { A } | 1090 | enum Thing { A } |
1106 | impl Thing { | 1091 | impl Thing { |
1107 | pub fn thing(a: Self<|>) {} | 1092 | pub fn thing(a: Self$0) {} |
1108 | } | 1093 | } |
1109 | "#, | 1094 | "#, |
1110 | expect![[r#" | 1095 | expect![[r#" |
@@ -1129,7 +1114,7 @@ fn x() {} | |||
1129 | 1114 | ||
1130 | fn y() { | 1115 | fn y() { |
1131 | let x = 0i32; | 1116 | let x = 0i32; |
1132 | x<|>; | 1117 | x$0; |
1133 | } | 1118 | } |
1134 | "#, | 1119 | "#, |
1135 | expect![[r#" | 1120 | expect![[r#" |
@@ -1148,7 +1133,7 @@ fn y() { | |||
1148 | r#" | 1133 | r#" |
1149 | macro_rules! foo { () => {} } | 1134 | macro_rules! foo { () => {} } |
1150 | 1135 | ||
1151 | fn f() { fo<|>o!(); } | 1136 | fn f() { fo$0o!(); } |
1152 | "#, | 1137 | "#, |
1153 | expect![[r#" | 1138 | expect![[r#" |
1154 | *foo* | 1139 | *foo* |
@@ -1167,7 +1152,7 @@ fn f() { fo<|>o!(); } | |||
1167 | #[test] | 1152 | #[test] |
1168 | fn test_hover_tuple_field() { | 1153 | fn test_hover_tuple_field() { |
1169 | check( | 1154 | check( |
1170 | r#"struct TS(String, i32<|>);"#, | 1155 | r#"struct TS(String, i32$0);"#, |
1171 | expect![[r#" | 1156 | expect![[r#" |
1172 | *i32* | 1157 | *i32* |
1173 | 1158 | ||
@@ -1185,7 +1170,7 @@ fn f() { fo<|>o!(); } | |||
1185 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } | 1170 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } |
1186 | fn foo() {} | 1171 | fn foo() {} |
1187 | id! { | 1172 | id! { |
1188 | fn bar() { fo<|>o(); } | 1173 | fn bar() { fo$0o(); } |
1189 | } | 1174 | } |
1190 | "#, | 1175 | "#, |
1191 | expect![[r#" | 1176 | expect![[r#" |
@@ -1207,7 +1192,7 @@ id! { | |||
1207 | check( | 1192 | check( |
1208 | r#" | 1193 | r#" |
1209 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } | 1194 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } |
1210 | fn foo(bar:u32) { let a = id!(ba<|>r); } | 1195 | fn foo(bar:u32) { let a = id!(ba$0r); } |
1211 | "#, | 1196 | "#, |
1212 | expect![[r#" | 1197 | expect![[r#" |
1213 | *bar* | 1198 | *bar* |
@@ -1225,7 +1210,7 @@ fn foo(bar:u32) { let a = id!(ba<|>r); } | |||
1225 | r#" | 1210 | r#" |
1226 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } | 1211 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } |
1227 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } | 1212 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } |
1228 | fn foo(bar:u32) { let a = id!(ba<|>r); } | 1213 | fn foo(bar:u32) { let a = id!(ba$0r); } |
1229 | "#, | 1214 | "#, |
1230 | expect![[r#" | 1215 | expect![[r#" |
1231 | *bar* | 1216 | *bar* |
@@ -1244,7 +1229,7 @@ fn foo(bar:u32) { let a = id!(ba<|>r); } | |||
1244 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } | 1229 | macro_rules! id_deep { ($($tt:tt)*) => { $($tt)* } } |
1245 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } | 1230 | macro_rules! id { ($($tt:tt)*) => { id_deep!($($tt)*) } } |
1246 | fn bar() -> u32 { 0 } | 1231 | fn bar() -> u32 { 0 } |
1247 | fn foo() { let a = id!([0u32, bar(<|>)] ); } | 1232 | fn foo() { let a = id!([0u32, bar($0)] ); } |
1248 | "#, | 1233 | "#, |
1249 | expect![[r#" | 1234 | expect![[r#" |
1250 | *bar()* | 1235 | *bar()* |
@@ -1262,7 +1247,7 @@ fn foo() { let a = id!([0u32, bar(<|>)] ); } | |||
1262 | macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } } | 1247 | macro_rules! arr { ($($tt:tt)*) => { [$($tt)*)] } } |
1263 | fn foo() { | 1248 | fn foo() { |
1264 | let mastered_for_itunes = ""; | 1249 | let mastered_for_itunes = ""; |
1265 | let _ = arr!("Tr<|>acks", &mastered_for_itunes); | 1250 | let _ = arr!("Tr$0acks", &mastered_for_itunes); |
1266 | } | 1251 | } |
1267 | "#, | 1252 | "#, |
1268 | expect![[r#" | 1253 | expect![[r#" |
@@ -1283,7 +1268,7 @@ macro_rules! assert {} | |||
1283 | 1268 | ||
1284 | fn bar() -> bool { true } | 1269 | fn bar() -> bool { true } |
1285 | fn foo() { | 1270 | fn foo() { |
1286 | assert!(ba<|>r()); | 1271 | assert!(ba$0r()); |
1287 | } | 1272 | } |
1288 | "#, | 1273 | "#, |
1289 | expect![[r#" | 1274 | expect![[r#" |
@@ -1308,7 +1293,7 @@ fn foo() { | |||
1308 | macro_rules! format {} | 1293 | macro_rules! format {} |
1309 | 1294 | ||
1310 | fn foo() { | 1295 | fn foo() { |
1311 | format!("hel<|>lo {}", 0); | 1296 | format!("hel$0lo {}", 0); |
1312 | } | 1297 | } |
1313 | "#, | 1298 | "#, |
1314 | ); | 1299 | ); |
@@ -1321,7 +1306,7 @@ fn foo() { | |||
1321 | /// <- `\u{3000}` here | 1306 | /// <- `\u{3000}` here |
1322 | fn foo() { } | 1307 | fn foo() { } |
1323 | 1308 | ||
1324 | fn bar() { fo<|>o(); } | 1309 | fn bar() { fo$0o(); } |
1325 | ", | 1310 | ", |
1326 | expect![[r#" | 1311 | expect![[r#" |
1327 | *foo* | 1312 | *foo* |
@@ -1344,7 +1329,7 @@ fn bar() { fo<|>o(); } | |||
1344 | #[test] | 1329 | #[test] |
1345 | fn test_hover_function_show_qualifiers() { | 1330 | fn test_hover_function_show_qualifiers() { |
1346 | check( | 1331 | check( |
1347 | r#"async fn foo<|>() {}"#, | 1332 | r#"async fn foo$0() {}"#, |
1348 | expect![[r#" | 1333 | expect![[r#" |
1349 | *foo* | 1334 | *foo* |
1350 | 1335 | ||
@@ -1358,7 +1343,7 @@ fn bar() { fo<|>o(); } | |||
1358 | "#]], | 1343 | "#]], |
1359 | ); | 1344 | ); |
1360 | check( | 1345 | check( |
1361 | r#"pub const unsafe fn foo<|>() {}"#, | 1346 | r#"pub const unsafe fn foo$0() {}"#, |
1362 | expect![[r#" | 1347 | expect![[r#" |
1363 | *foo* | 1348 | *foo* |
1364 | 1349 | ||
@@ -1372,7 +1357,7 @@ fn bar() { fo<|>o(); } | |||
1372 | "#]], | 1357 | "#]], |
1373 | ); | 1358 | ); |
1374 | check( | 1359 | check( |
1375 | r#"pub(crate) async unsafe extern "C" fn foo<|>() {}"#, | 1360 | r#"pub(crate) async unsafe extern "C" fn foo$0() {}"#, |
1376 | expect![[r#" | 1361 | expect![[r#" |
1377 | *foo* | 1362 | *foo* |
1378 | 1363 | ||
@@ -1390,10 +1375,10 @@ fn bar() { fo<|>o(); } | |||
1390 | #[test] | 1375 | #[test] |
1391 | fn test_hover_trait_show_qualifiers() { | 1376 | fn test_hover_trait_show_qualifiers() { |
1392 | check_actions( | 1377 | check_actions( |
1393 | r"unsafe trait foo<|>() {}", | 1378 | r"unsafe trait foo$0() {}", |
1394 | expect![[r#" | 1379 | expect![[r#" |
1395 | [ | 1380 | [ |
1396 | Implementaion( | 1381 | Implementation( |
1397 | FilePosition { | 1382 | FilePosition { |
1398 | file_id: FileId( | 1383 | file_id: FileId( |
1399 | 0, | 1384 | 0, |
@@ -1411,7 +1396,7 @@ fn bar() { fo<|>o(); } | |||
1411 | check( | 1396 | check( |
1412 | r#" | 1397 | r#" |
1413 | //- /main.rs crate:main deps:std | 1398 | //- /main.rs crate:main deps:std |
1414 | extern crate st<|>d; | 1399 | extern crate st$0d; |
1415 | //- /std/lib.rs crate:std | 1400 | //- /std/lib.rs crate:std |
1416 | //! Standard library for this test | 1401 | //! Standard library for this test |
1417 | //! | 1402 | //! |
@@ -1429,7 +1414,7 @@ extern crate st<|>d; | |||
1429 | check( | 1414 | check( |
1430 | r#" | 1415 | r#" |
1431 | //- /main.rs crate:main deps:std | 1416 | //- /main.rs crate:main deps:std |
1432 | extern crate std as ab<|>c; | 1417 | extern crate std as ab$0c; |
1433 | //- /std/lib.rs crate:std | 1418 | //- /std/lib.rs crate:std |
1434 | //! Standard library for this test | 1419 | //! Standard library for this test |
1435 | //! | 1420 | //! |
@@ -1450,7 +1435,7 @@ extern crate std as ab<|>c; | |||
1450 | fn test_hover_mod_with_same_name_as_function() { | 1435 | fn test_hover_mod_with_same_name_as_function() { |
1451 | check( | 1436 | check( |
1452 | r#" | 1437 | r#" |
1453 | use self::m<|>y::Bar; | 1438 | use self::m$0y::Bar; |
1454 | mod my { pub struct Bar; } | 1439 | mod my { pub struct Bar; } |
1455 | 1440 | ||
1456 | fn my() {} | 1441 | fn my() {} |
@@ -1476,7 +1461,7 @@ fn my() {} | |||
1476 | /// bar docs | 1461 | /// bar docs |
1477 | struct Bar; | 1462 | struct Bar; |
1478 | 1463 | ||
1479 | fn foo() { let bar = Ba<|>r; } | 1464 | fn foo() { let bar = Ba$0r; } |
1480 | "#, | 1465 | "#, |
1481 | expect![[r#" | 1466 | expect![[r#" |
1482 | *Bar* | 1467 | *Bar* |
@@ -1503,7 +1488,7 @@ fn foo() { let bar = Ba<|>r; } | |||
1503 | #[doc = "bar docs"] | 1488 | #[doc = "bar docs"] |
1504 | struct Bar; | 1489 | struct Bar; |
1505 | 1490 | ||
1506 | fn foo() { let bar = Ba<|>r; } | 1491 | fn foo() { let bar = Ba$0r; } |
1507 | "#, | 1492 | "#, |
1508 | expect![[r#" | 1493 | expect![[r#" |
1509 | *Bar* | 1494 | *Bar* |
@@ -1532,7 +1517,7 @@ fn foo() { let bar = Ba<|>r; } | |||
1532 | #[doc = "bar docs 2"] | 1517 | #[doc = "bar docs 2"] |
1533 | struct Bar; | 1518 | struct Bar; |
1534 | 1519 | ||
1535 | fn foo() { let bar = Ba<|>r; } | 1520 | fn foo() { let bar = Ba$0r; } |
1536 | "#, | 1521 | "#, |
1537 | expect![[r#" | 1522 | expect![[r#" |
1538 | *Bar* | 1523 | *Bar* |
@@ -1560,7 +1545,7 @@ fn foo() { let bar = Ba<|>r; } | |||
1560 | r#" | 1545 | r#" |
1561 | pub struct Foo; | 1546 | pub struct Foo; |
1562 | /// [Foo](struct.Foo.html) | 1547 | /// [Foo](struct.Foo.html) |
1563 | pub struct B<|>ar | 1548 | pub struct B$0ar |
1564 | "#, | 1549 | "#, |
1565 | expect![[r#" | 1550 | expect![[r#" |
1566 | *Bar* | 1551 | *Bar* |
@@ -1586,7 +1571,7 @@ pub struct B<|>ar | |||
1586 | r#" | 1571 | r#" |
1587 | pub struct Foo; | 1572 | pub struct Foo; |
1588 | /// [struct Foo](struct.Foo.html) | 1573 | /// [struct Foo](struct.Foo.html) |
1589 | pub struct B<|>ar | 1574 | pub struct B$0ar |
1590 | "#, | 1575 | "#, |
1591 | expect![[r#" | 1576 | expect![[r#" |
1592 | *Bar* | 1577 | *Bar* |
@@ -1614,7 +1599,7 @@ pub struct B<|>ar | |||
1614 | pub struct Foo; | 1599 | pub struct Foo; |
1615 | pub struct Bar { | 1600 | pub struct Bar { |
1616 | /// [Foo](struct.Foo.html) | 1601 | /// [Foo](struct.Foo.html) |
1617 | fie<|>ld: () | 1602 | fie$0ld: () |
1618 | } | 1603 | } |
1619 | "#, | 1604 | "#, |
1620 | expect![[r#" | 1605 | expect![[r#" |
@@ -1643,7 +1628,7 @@ pub mod foo { | |||
1643 | pub struct Foo; | 1628 | pub struct Foo; |
1644 | } | 1629 | } |
1645 | /// [Foo](foo::Foo) | 1630 | /// [Foo](foo::Foo) |
1646 | pub struct B<|>ar | 1631 | pub struct B$0ar |
1647 | "#, | 1632 | "#, |
1648 | expect![[r#" | 1633 | expect![[r#" |
1649 | *Bar* | 1634 | *Bar* |
@@ -1673,7 +1658,7 @@ pub mod foo { | |||
1673 | pub struct Foo; | 1658 | pub struct Foo; |
1674 | } | 1659 | } |
1675 | /// [Foo](foo::Foo) | 1660 | /// [Foo](foo::Foo) |
1676 | pub struct B<|>ar | 1661 | pub struct B$0ar |
1677 | "#, | 1662 | "#, |
1678 | expect![[r#" | 1663 | expect![[r#" |
1679 | *Bar* | 1664 | *Bar* |
@@ -1699,7 +1684,7 @@ pub struct B<|>ar | |||
1699 | r#" | 1684 | r#" |
1700 | pub struct Foo; | 1685 | pub struct Foo; |
1701 | /// [Foo] | 1686 | /// [Foo] |
1702 | pub struct B<|>ar | 1687 | pub struct B$0ar |
1703 | "#, | 1688 | "#, |
1704 | expect![[r#" | 1689 | expect![[r#" |
1705 | *Bar* | 1690 | *Bar* |
@@ -1725,7 +1710,7 @@ pub struct B<|>ar | |||
1725 | r#" | 1710 | r#" |
1726 | pub struct Foo; | 1711 | pub struct Foo; |
1727 | /// [`Foo`] | 1712 | /// [`Foo`] |
1728 | pub struct B<|>ar | 1713 | pub struct B$0ar |
1729 | "#, | 1714 | "#, |
1730 | expect![[r#" | 1715 | expect![[r#" |
1731 | *Bar* | 1716 | *Bar* |
@@ -1752,7 +1737,7 @@ pub struct B<|>ar | |||
1752 | pub struct Foo; | 1737 | pub struct Foo; |
1753 | fn Foo() {} | 1738 | fn Foo() {} |
1754 | /// [Foo()] | 1739 | /// [Foo()] |
1755 | pub struct B<|>ar | 1740 | pub struct B$0ar |
1756 | "#, | 1741 | "#, |
1757 | expect![[r#" | 1742 | expect![[r#" |
1758 | *Bar* | 1743 | *Bar* |
@@ -1778,7 +1763,7 @@ pub struct B<|>ar | |||
1778 | r#" | 1763 | r#" |
1779 | pub struct Foo; | 1764 | pub struct Foo; |
1780 | /// [`struct Foo`] | 1765 | /// [`struct Foo`] |
1781 | pub struct B<|>ar | 1766 | pub struct B$0ar |
1782 | "#, | 1767 | "#, |
1783 | expect![[r#" | 1768 | expect![[r#" |
1784 | *Bar* | 1769 | *Bar* |
@@ -1804,7 +1789,7 @@ pub struct B<|>ar | |||
1804 | r#" | 1789 | r#" |
1805 | pub struct Foo; | 1790 | pub struct Foo; |
1806 | /// [`struct@Foo`] | 1791 | /// [`struct@Foo`] |
1807 | pub struct B<|>ar | 1792 | pub struct B$0ar |
1808 | "#, | 1793 | "#, |
1809 | expect![[r#" | 1794 | expect![[r#" |
1810 | *Bar* | 1795 | *Bar* |
@@ -1832,7 +1817,7 @@ pub struct Foo; | |||
1832 | /// [my Foo][foo] | 1817 | /// [my Foo][foo] |
1833 | /// | 1818 | /// |
1834 | /// [foo]: Foo | 1819 | /// [foo]: Foo |
1835 | pub struct B<|>ar | 1820 | pub struct B$0ar |
1836 | "#, | 1821 | "#, |
1837 | expect![[r#" | 1822 | expect![[r#" |
1838 | *Bar* | 1823 | *Bar* |
@@ -1858,7 +1843,7 @@ pub struct B<|>ar | |||
1858 | r#" | 1843 | r#" |
1859 | pub struct Foo; | 1844 | pub struct Foo; |
1860 | /// [external](https://www.google.com) | 1845 | /// [external](https://www.google.com) |
1861 | pub struct B<|>ar | 1846 | pub struct B$0ar |
1862 | "#, | 1847 | "#, |
1863 | expect![[r#" | 1848 | expect![[r#" |
1864 | *Bar* | 1849 | *Bar* |
@@ -1885,7 +1870,7 @@ pub struct B<|>ar | |||
1885 | r#" | 1870 | r#" |
1886 | pub struct Foo; | 1871 | pub struct Foo; |
1887 | /// [baz](Baz) | 1872 | /// [baz](Baz) |
1888 | pub struct B<|>ar | 1873 | pub struct B$0ar |
1889 | "#, | 1874 | "#, |
1890 | expect![[r#" | 1875 | expect![[r#" |
1891 | *Bar* | 1876 | *Bar* |
@@ -1911,7 +1896,7 @@ pub struct B<|>ar | |||
1911 | r#" | 1896 | r#" |
1912 | enum E { | 1897 | enum E { |
1913 | /// [E] | 1898 | /// [E] |
1914 | V<|> { field: i32 } | 1899 | V$0 { field: i32 } |
1915 | } | 1900 | } |
1916 | "#, | 1901 | "#, |
1917 | expect![[r#" | 1902 | expect![[r#" |
@@ -1938,7 +1923,7 @@ enum E { | |||
1938 | r#" | 1923 | r#" |
1939 | struct S { | 1924 | struct S { |
1940 | /// [`S`] | 1925 | /// [`S`] |
1941 | field<|>: i32 | 1926 | field$0: i32 |
1942 | } | 1927 | } |
1943 | "#, | 1928 | "#, |
1944 | expect![[r#" | 1929 | expect![[r#" |
@@ -1984,7 +1969,7 @@ struct S { | |||
1984 | /// | 1969 | /// |
1985 | /// [`Result`]: ../../std/result/enum.Result.html | 1970 | /// [`Result`]: ../../std/result/enum.Result.html |
1986 | /// [^example]: https://www.example.com/ | 1971 | /// [^example]: https://www.example.com/ |
1987 | pub fn fo<|>o() {} | 1972 | pub fn fo$0o() {} |
1988 | "#, | 1973 | "#, |
1989 | expect![[r#" | 1974 | expect![[r#" |
1990 | *foo* | 1975 | *foo* |
@@ -2041,7 +2026,7 @@ macro_rules! bar { | |||
2041 | 2026 | ||
2042 | bar!(); | 2027 | bar!(); |
2043 | 2028 | ||
2044 | fn foo() { let bar = Bar; bar.fo<|>o(); } | 2029 | fn foo() { let bar = Bar; bar.fo$0o(); } |
2045 | "#, | 2030 | "#, |
2046 | expect![[r#" | 2031 | expect![[r#" |
2047 | *foo* | 2032 | *foo* |
@@ -2079,7 +2064,7 @@ macro_rules! bar { | |||
2079 | 2064 | ||
2080 | bar!(); | 2065 | bar!(); |
2081 | 2066 | ||
2082 | fn foo() { let bar = Bar; bar.fo<|>o(); } | 2067 | fn foo() { let bar = Bar; bar.fo$0o(); } |
2083 | "#, | 2068 | "#, |
2084 | expect![[r#" | 2069 | expect![[r#" |
2085 | *foo* | 2070 | *foo* |
@@ -2102,10 +2087,10 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2102 | #[test] | 2087 | #[test] |
2103 | fn test_hover_trait_has_impl_action() { | 2088 | fn test_hover_trait_has_impl_action() { |
2104 | check_actions( | 2089 | check_actions( |
2105 | r#"trait foo<|>() {}"#, | 2090 | r#"trait foo$0() {}"#, |
2106 | expect![[r#" | 2091 | expect![[r#" |
2107 | [ | 2092 | [ |
2108 | Implementaion( | 2093 | Implementation( |
2109 | FilePosition { | 2094 | FilePosition { |
2110 | file_id: FileId( | 2095 | file_id: FileId( |
2111 | 0, | 2096 | 0, |
@@ -2121,10 +2106,10 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2121 | #[test] | 2106 | #[test] |
2122 | fn test_hover_struct_has_impl_action() { | 2107 | fn test_hover_struct_has_impl_action() { |
2123 | check_actions( | 2108 | check_actions( |
2124 | r"struct foo<|>() {}", | 2109 | r"struct foo$0() {}", |
2125 | expect![[r#" | 2110 | expect![[r#" |
2126 | [ | 2111 | [ |
2127 | Implementaion( | 2112 | Implementation( |
2128 | FilePosition { | 2113 | FilePosition { |
2129 | file_id: FileId( | 2114 | file_id: FileId( |
2130 | 0, | 2115 | 0, |
@@ -2140,10 +2125,10 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2140 | #[test] | 2125 | #[test] |
2141 | fn test_hover_union_has_impl_action() { | 2126 | fn test_hover_union_has_impl_action() { |
2142 | check_actions( | 2127 | check_actions( |
2143 | r#"union foo<|>() {}"#, | 2128 | r#"union foo$0() {}"#, |
2144 | expect![[r#" | 2129 | expect![[r#" |
2145 | [ | 2130 | [ |
2146 | Implementaion( | 2131 | Implementation( |
2147 | FilePosition { | 2132 | FilePosition { |
2148 | file_id: FileId( | 2133 | file_id: FileId( |
2149 | 0, | 2134 | 0, |
@@ -2159,10 +2144,10 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2159 | #[test] | 2144 | #[test] |
2160 | fn test_hover_enum_has_impl_action() { | 2145 | fn test_hover_enum_has_impl_action() { |
2161 | check_actions( | 2146 | check_actions( |
2162 | r"enum foo<|>() { A, B }", | 2147 | r"enum foo$0() { A, B }", |
2163 | expect![[r#" | 2148 | expect![[r#" |
2164 | [ | 2149 | [ |
2165 | Implementaion( | 2150 | Implementation( |
2166 | FilePosition { | 2151 | FilePosition { |
2167 | file_id: FileId( | 2152 | file_id: FileId( |
2168 | 0, | 2153 | 0, |
@@ -2176,11 +2161,30 @@ fn foo() { let bar = Bar; bar.fo<|>o(); } | |||
2176 | } | 2161 | } |
2177 | 2162 | ||
2178 | #[test] | 2163 | #[test] |
2164 | fn test_hover_self_has_impl_action() { | ||
2165 | check_actions( | ||
2166 | r#"struct foo where Self$0:;"#, | ||
2167 | expect![[r#" | ||
2168 | [ | ||
2169 | Implementation( | ||
2170 | FilePosition { | ||
2171 | file_id: FileId( | ||
2172 | 0, | ||
2173 | ), | ||
2174 | offset: 7, | ||
2175 | }, | ||
2176 | ), | ||
2177 | ] | ||
2178 | "#]], | ||
2179 | ); | ||
2180 | } | ||
2181 | |||
2182 | #[test] | ||
2179 | fn test_hover_test_has_action() { | 2183 | fn test_hover_test_has_action() { |
2180 | check_actions( | 2184 | check_actions( |
2181 | r#" | 2185 | r#" |
2182 | #[test] | 2186 | #[test] |
2183 | fn foo_<|>test() {} | 2187 | fn foo_$0test() {} |
2184 | "#, | 2188 | "#, |
2185 | expect![[r#" | 2189 | expect![[r#" |
2186 | [ | 2190 | [ |
@@ -2215,7 +2219,7 @@ fn foo_<|>test() {} | |||
2215 | fn test_hover_test_mod_has_action() { | 2219 | fn test_hover_test_mod_has_action() { |
2216 | check_actions( | 2220 | check_actions( |
2217 | r#" | 2221 | r#" |
2218 | mod tests<|> { | 2222 | mod tests$0 { |
2219 | #[test] | 2223 | #[test] |
2220 | fn foo_test() {} | 2224 | fn foo_test() {} |
2221 | } | 2225 | } |
@@ -2250,7 +2254,7 @@ mod tests<|> { | |||
2250 | r#" | 2254 | r#" |
2251 | struct S{ f1: u32 } | 2255 | struct S{ f1: u32 } |
2252 | 2256 | ||
2253 | fn main() { let s<|>t = S{ f1:0 }; } | 2257 | fn main() { let s$0t = S{ f1:0 }; } |
2254 | "#, | 2258 | "#, |
2255 | expect![[r#" | 2259 | expect![[r#" |
2256 | [ | 2260 | [ |
@@ -2283,7 +2287,7 @@ fn main() { let s<|>t = S{ f1:0 }; } | |||
2283 | struct Arg(u32); | 2287 | struct Arg(u32); |
2284 | struct S<T>{ f1: T } | 2288 | struct S<T>{ f1: T } |
2285 | 2289 | ||
2286 | fn main() { let s<|>t = S{ f1:Arg(0) }; } | 2290 | fn main() { let s$0t = S{ f1:Arg(0) }; } |
2287 | "#, | 2291 | "#, |
2288 | expect![[r#" | 2292 | expect![[r#" |
2289 | [ | 2293 | [ |
@@ -2329,7 +2333,7 @@ fn main() { let s<|>t = S{ f1:Arg(0) }; } | |||
2329 | struct Arg(u32); | 2333 | struct Arg(u32); |
2330 | struct S<T>{ f1: T } | 2334 | struct S<T>{ f1: T } |
2331 | 2335 | ||
2332 | fn main() { let s<|>t = S{ f1: S{ f1: Arg(0) } }; } | 2336 | fn main() { let s$0t = S{ f1: S{ f1: Arg(0) } }; } |
2333 | "#, | 2337 | "#, |
2334 | expect![[r#" | 2338 | expect![[r#" |
2335 | [ | 2339 | [ |
@@ -2378,7 +2382,7 @@ mod M { | |||
2378 | pub struct C(u32); | 2382 | pub struct C(u32); |
2379 | } | 2383 | } |
2380 | 2384 | ||
2381 | fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | 2385 | fn main() { let s$0t = (A(1), B(2), M::C(3) ); } |
2382 | "#, | 2386 | "#, |
2383 | expect![[r#" | 2387 | expect![[r#" |
2384 | [ | 2388 | [ |
@@ -2437,7 +2441,7 @@ fn main() { let s<|>t = (A(1), B(2), M::C(3) ); } | |||
2437 | trait Foo {} | 2441 | trait Foo {} |
2438 | fn foo() -> impl Foo {} | 2442 | fn foo() -> impl Foo {} |
2439 | 2443 | ||
2440 | fn main() { let s<|>t = foo(); } | 2444 | fn main() { let s$0t = foo(); } |
2441 | "#, | 2445 | "#, |
2442 | expect![[r#" | 2446 | expect![[r#" |
2443 | [ | 2447 | [ |
@@ -2471,7 +2475,7 @@ trait Foo<T> {} | |||
2471 | struct S; | 2475 | struct S; |
2472 | fn foo() -> impl Foo<S> {} | 2476 | fn foo() -> impl Foo<S> {} |
2473 | 2477 | ||
2474 | fn main() { let s<|>t = foo(); } | 2478 | fn main() { let s$0t = foo(); } |
2475 | "#, | 2479 | "#, |
2476 | expect![[r#" | 2480 | expect![[r#" |
2477 | [ | 2481 | [ |
@@ -2518,7 +2522,7 @@ trait Foo {} | |||
2518 | trait Bar {} | 2522 | trait Bar {} |
2519 | fn foo() -> impl Foo + Bar {} | 2523 | fn foo() -> impl Foo + Bar {} |
2520 | 2524 | ||
2521 | fn main() { let s<|>t = foo(); } | 2525 | fn main() { let s$0t = foo(); } |
2522 | "#, | 2526 | "#, |
2523 | expect![[r#" | 2527 | expect![[r#" |
2524 | [ | 2528 | [ |
@@ -2568,7 +2572,7 @@ struct S2 {} | |||
2568 | 2572 | ||
2569 | fn foo() -> impl Foo<S1> + Bar<S2> {} | 2573 | fn foo() -> impl Foo<S1> + Bar<S2> {} |
2570 | 2574 | ||
2571 | fn main() { let s<|>t = foo(); } | 2575 | fn main() { let s$0t = foo(); } |
2572 | "#, | 2576 | "#, |
2573 | expect![[r#" | 2577 | expect![[r#" |
2574 | [ | 2578 | [ |
@@ -2638,7 +2642,7 @@ fn main() { let s<|>t = foo(); } | |||
2638 | check_actions( | 2642 | check_actions( |
2639 | r#" | 2643 | r#" |
2640 | trait Foo {} | 2644 | trait Foo {} |
2641 | fn foo(ar<|>g: &impl Foo) {} | 2645 | fn foo(ar$0g: &impl Foo) {} |
2642 | "#, | 2646 | "#, |
2643 | expect![[r#" | 2647 | expect![[r#" |
2644 | [ | 2648 | [ |
@@ -2672,7 +2676,7 @@ trait Foo {} | |||
2672 | trait Bar<T> {} | 2676 | trait Bar<T> {} |
2673 | struct S{} | 2677 | struct S{} |
2674 | 2678 | ||
2675 | fn foo(ar<|>g: &impl Foo + Bar<S>) {} | 2679 | fn foo(ar$0g: &impl Foo + Bar<S>) {} |
2676 | "#, | 2680 | "#, |
2677 | expect![[r#" | 2681 | expect![[r#" |
2678 | [ | 2682 | [ |
@@ -2730,7 +2734,7 @@ fn foo(ar<|>g: &impl Foo + Bar<S>) {} | |||
2730 | r#" | 2734 | r#" |
2731 | struct S; | 2735 | struct S; |
2732 | fn foo() { | 2736 | fn foo() { |
2733 | let fo<|>o = async { S }; | 2737 | let fo$0o = async { S }; |
2734 | } | 2738 | } |
2735 | 2739 | ||
2736 | #[prelude_import] use future::*; | 2740 | #[prelude_import] use future::*; |
@@ -2782,7 +2786,7 @@ mod future { | |||
2782 | r#" | 2786 | r#" |
2783 | trait Foo<T> {} | 2787 | trait Foo<T> {} |
2784 | struct S {} | 2788 | struct S {} |
2785 | fn foo(ar<|>g: &impl Foo<S>) {} | 2789 | fn foo(ar$0g: &impl Foo<S>) {} |
2786 | "#, | 2790 | "#, |
2787 | expect![[r#" | 2791 | expect![[r#" |
2788 | [ | 2792 | [ |
@@ -2832,7 +2836,7 @@ impl Foo for S {} | |||
2832 | struct B<T>{} | 2836 | struct B<T>{} |
2833 | fn foo() -> B<dyn Foo> {} | 2837 | fn foo() -> B<dyn Foo> {} |
2834 | 2838 | ||
2835 | fn main() { let s<|>t = foo(); } | 2839 | fn main() { let s$0t = foo(); } |
2836 | "#, | 2840 | "#, |
2837 | expect![[r#" | 2841 | expect![[r#" |
2838 | [ | 2842 | [ |
@@ -2876,7 +2880,7 @@ fn main() { let s<|>t = foo(); } | |||
2876 | check_actions( | 2880 | check_actions( |
2877 | r#" | 2881 | r#" |
2878 | trait Foo {} | 2882 | trait Foo {} |
2879 | fn foo(ar<|>g: &dyn Foo) {} | 2883 | fn foo(ar$0g: &dyn Foo) {} |
2880 | "#, | 2884 | "#, |
2881 | expect![[r#" | 2885 | expect![[r#" |
2882 | [ | 2886 | [ |
@@ -2908,7 +2912,7 @@ fn foo(ar<|>g: &dyn Foo) {} | |||
2908 | r#" | 2912 | r#" |
2909 | trait Foo<T> {} | 2913 | trait Foo<T> {} |
2910 | struct S {} | 2914 | struct S {} |
2911 | fn foo(ar<|>g: &dyn Foo<S>) {} | 2915 | fn foo(ar$0g: &dyn Foo<S>) {} |
2912 | "#, | 2916 | "#, |
2913 | expect![[r#" | 2917 | expect![[r#" |
2914 | [ | 2918 | [ |
@@ -2956,7 +2960,7 @@ trait DynTrait<T> {} | |||
2956 | struct B<T> {} | 2960 | struct B<T> {} |
2957 | struct S {} | 2961 | struct S {} |
2958 | 2962 | ||
2959 | fn foo(a<|>rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} | 2963 | fn foo(a$0rg: &impl ImplTrait<B<dyn DynTrait<B<S>>>>) {} |
2960 | "#, | 2964 | "#, |
2961 | expect![[r#" | 2965 | expect![[r#" |
2962 | [ | 2966 | [ |
@@ -3037,7 +3041,7 @@ impl Foo for S { type Item = Bar; } | |||
3037 | 3041 | ||
3038 | fn test() -> impl Foo { S {} } | 3042 | fn test() -> impl Foo { S {} } |
3039 | 3043 | ||
3040 | fn main() { let s<|>t = test().get(); } | 3044 | fn main() { let s$0t = test().get(); } |
3041 | "#, | 3045 | "#, |
3042 | expect![[r#" | 3046 | expect![[r#" |
3043 | [ | 3047 | [ |
@@ -3064,6 +3068,71 @@ fn main() { let s<|>t = test().get(); } | |||
3064 | } | 3068 | } |
3065 | 3069 | ||
3066 | #[test] | 3070 | #[test] |
3071 | fn test_hover_const_param_has_goto_type_action() { | ||
3072 | check_actions( | ||
3073 | r#" | ||
3074 | struct Bar; | ||
3075 | struct Foo<const BAR: Bar>; | ||
3076 | |||
3077 | impl<const BAR: Bar> Foo<BAR$0> {} | ||
3078 | "#, | ||
3079 | expect![[r#" | ||
3080 | [ | ||
3081 | GoToType( | ||
3082 | [ | ||
3083 | HoverGotoTypeData { | ||
3084 | mod_path: "test::Bar", | ||
3085 | nav: NavigationTarget { | ||
3086 | file_id: FileId( | ||
3087 | 0, | ||
3088 | ), | ||
3089 | full_range: 0..11, | ||
3090 | focus_range: 7..10, | ||
3091 | name: "Bar", | ||
3092 | kind: Struct, | ||
3093 | description: "struct Bar", | ||
3094 | }, | ||
3095 | }, | ||
3096 | ], | ||
3097 | ), | ||
3098 | ] | ||
3099 | "#]], | ||
3100 | ); | ||
3101 | } | ||
3102 | |||
3103 | #[test] | ||
3104 | fn test_hover_type_param_has_goto_type_action() { | ||
3105 | check_actions( | ||
3106 | r#" | ||
3107 | trait Foo {} | ||
3108 | |||
3109 | fn foo<T: Foo>(t: T$0){} | ||
3110 | "#, | ||
3111 | expect![[r#" | ||
3112 | [ | ||
3113 | GoToType( | ||
3114 | [ | ||
3115 | HoverGotoTypeData { | ||
3116 | mod_path: "test::Foo", | ||
3117 | nav: NavigationTarget { | ||
3118 | file_id: FileId( | ||
3119 | 0, | ||
3120 | ), | ||
3121 | full_range: 0..12, | ||
3122 | focus_range: 6..9, | ||
3123 | name: "Foo", | ||
3124 | kind: Trait, | ||
3125 | description: "trait Foo", | ||
3126 | }, | ||
3127 | }, | ||
3128 | ], | ||
3129 | ), | ||
3130 | ] | ||
3131 | "#]], | ||
3132 | ); | ||
3133 | } | ||
3134 | |||
3135 | #[test] | ||
3067 | fn hover_displays_normalized_crate_names() { | 3136 | fn hover_displays_normalized_crate_names() { |
3068 | check( | 3137 | check( |
3069 | r#" | 3138 | r#" |
@@ -3077,7 +3146,7 @@ pub mod wrapper { | |||
3077 | } | 3146 | } |
3078 | 3147 | ||
3079 | //- /main.rs crate:main deps:name-with-dashes | 3148 | //- /main.rs crate:main deps:name-with-dashes |
3080 | fn main() { let foo_test = name_with_dashes::wrapper::Thing::new<|>(); } | 3149 | fn main() { let foo_test = name_with_dashes::wrapper::Thing::new$0(); } |
3081 | "#, | 3150 | "#, |
3082 | expect![[r#" | 3151 | expect![[r#" |
3083 | *new* | 3152 | *new* |
@@ -3103,7 +3172,7 @@ struct S { | |||
3103 | 3172 | ||
3104 | fn main() { | 3173 | fn main() { |
3105 | let s = S { f: 0 }; | 3174 | let s = S { f: 0 }; |
3106 | let S { f<|> } = &s; | 3175 | let S { f$0 } = &s; |
3107 | } | 3176 | } |
3108 | "#, | 3177 | "#, |
3109 | expect![[r#" | 3178 | expect![[r#" |
@@ -3122,7 +3191,7 @@ fn main() { | |||
3122 | r#" | 3191 | r#" |
3123 | struct Foo {} | 3192 | struct Foo {} |
3124 | impl Foo { | 3193 | impl Foo { |
3125 | fn bar(&sel<|>f) {} | 3194 | fn bar(&sel$0f) {} |
3126 | } | 3195 | } |
3127 | "#, | 3196 | "#, |
3128 | expect![[r#" | 3197 | expect![[r#" |
@@ -3141,7 +3210,7 @@ impl Foo { | |||
3141 | struct Arc<T>(T); | 3210 | struct Arc<T>(T); |
3142 | struct Foo {} | 3211 | struct Foo {} |
3143 | impl Foo { | 3212 | impl Foo { |
3144 | fn bar(sel<|>f: Arc<Foo>) {} | 3213 | fn bar(sel$0f: Arc<Foo>) {} |
3145 | } | 3214 | } |
3146 | "#, | 3215 | "#, |
3147 | expect![[r#" | 3216 | expect![[r#" |
@@ -3158,7 +3227,7 @@ impl Foo { | |||
3158 | check( | 3227 | check( |
3159 | r#" | 3228 | r#" |
3160 | /// Be quick; | 3229 | /// Be quick; |
3161 | mod Foo<|> { | 3230 | mod Foo$0 { |
3162 | //! time is mana | 3231 | //! time is mana |
3163 | 3232 | ||
3164 | /// This comment belongs to the function | 3233 | /// This comment belongs to the function |
@@ -3189,7 +3258,7 @@ mod Foo<|> { | |||
3189 | check( | 3258 | check( |
3190 | r#" | 3259 | r#" |
3191 | #[doc = "Be quick;"] | 3260 | #[doc = "Be quick;"] |
3192 | mod Foo<|> { | 3261 | mod Foo$0 { |
3193 | #![doc = "time is mana"] | 3262 | #![doc = "time is mana"] |
3194 | 3263 | ||
3195 | #[doc = "This comment belongs to the function"] | 3264 | #[doc = "This comment belongs to the function"] |
@@ -3220,7 +3289,7 @@ mod Foo<|> { | |||
3220 | check_hover_no_result( | 3289 | check_hover_no_result( |
3221 | r#" | 3290 | r#" |
3222 | fn no_hover() { | 3291 | fn no_hover() { |
3223 | // no<|>hover | 3292 | // no$0hover |
3224 | } | 3293 | } |
3225 | "#, | 3294 | "#, |
3226 | ); | 3295 | ); |
@@ -3231,7 +3300,7 @@ fn no_hover() { | |||
3231 | check( | 3300 | check( |
3232 | r#" | 3301 | r#" |
3233 | fn foo() { | 3302 | fn foo() { |
3234 | 'label<|>: loop {} | 3303 | 'label$0: loop {} |
3235 | } | 3304 | } |
3236 | "#, | 3305 | "#, |
3237 | expect![[r#" | 3306 | expect![[r#" |
@@ -3247,7 +3316,7 @@ fn foo() { | |||
3247 | #[test] | 3316 | #[test] |
3248 | fn hover_lifetime() { | 3317 | fn hover_lifetime() { |
3249 | check( | 3318 | check( |
3250 | r#"fn foo<'lifetime>(_: &'lifetime<|> ()) {}"#, | 3319 | r#"fn foo<'lifetime>(_: &'lifetime$0 ()) {}"#, |
3251 | expect![[r#" | 3320 | expect![[r#" |
3252 | *'lifetime* | 3321 | *'lifetime* |
3253 | 3322 | ||
@@ -3257,4 +3326,68 @@ fn foo() { | |||
3257 | "#]], | 3326 | "#]], |
3258 | ); | 3327 | ); |
3259 | } | 3328 | } |
3329 | |||
3330 | #[test] | ||
3331 | fn hover_type_param() { | ||
3332 | check( | ||
3333 | r#" | ||
3334 | struct Foo<T>(T); | ||
3335 | trait Copy {} | ||
3336 | trait Clone {} | ||
3337 | trait Sized {} | ||
3338 | impl<T: Copy + Clone> Foo<T$0> where T: Sized {} | ||
3339 | "#, | ||
3340 | expect![[r#" | ||
3341 | *T* | ||
3342 | |||
3343 | ```rust | ||
3344 | T: Copy + Clone + Sized | ||
3345 | ``` | ||
3346 | "#]], | ||
3347 | ); | ||
3348 | check( | ||
3349 | r#" | ||
3350 | struct Foo<T>(T); | ||
3351 | impl<T> Foo<T$0> {} | ||
3352 | "#, | ||
3353 | expect![[r#" | ||
3354 | *T* | ||
3355 | |||
3356 | ```rust | ||
3357 | T | ||
3358 | ``` | ||
3359 | "#]], | ||
3360 | ); | ||
3361 | // lifetimes aren't being substituted yet | ||
3362 | check( | ||
3363 | r#" | ||
3364 | struct Foo<T>(T); | ||
3365 | impl<T: 'static> Foo<T$0> {} | ||
3366 | "#, | ||
3367 | expect![[r#" | ||
3368 | *T* | ||
3369 | |||
3370 | ```rust | ||
3371 | T: {error} | ||
3372 | ``` | ||
3373 | "#]], | ||
3374 | ); | ||
3375 | } | ||
3376 | |||
3377 | #[test] | ||
3378 | fn hover_const_param() { | ||
3379 | check( | ||
3380 | r#" | ||
3381 | struct Foo<const LEN: usize>; | ||
3382 | impl<const LEN: usize> Foo<LEN$0> {} | ||
3383 | "#, | ||
3384 | expect![[r#" | ||
3385 | *LEN* | ||
3386 | |||
3387 | ```rust | ||
3388 | const LEN: usize | ||
3389 | ``` | ||
3390 | "#]], | ||
3391 | ); | ||
3392 | } | ||
3260 | } | 3393 | } |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index 65df7979c..fe60abfc8 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -18,12 +18,6 @@ pub struct InlayHintsConfig { | |||
18 | pub max_length: Option<usize>, | 18 | pub max_length: Option<usize>, |
19 | } | 19 | } |
20 | 20 | ||
21 | impl Default for InlayHintsConfig { | ||
22 | fn default() -> Self { | ||
23 | Self { type_hints: true, parameter_hints: true, chaining_hints: true, max_length: None } | ||
24 | } | ||
25 | } | ||
26 | |||
27 | #[derive(Clone, Debug, PartialEq, Eq)] | 21 | #[derive(Clone, Debug, PartialEq, Eq)] |
28 | pub enum InlayKind { | 22 | pub enum InlayKind { |
29 | TypeHint, | 23 | TypeHint, |
@@ -433,8 +427,15 @@ mod tests { | |||
433 | 427 | ||
434 | use crate::{fixture, inlay_hints::InlayHintsConfig}; | 428 | use crate::{fixture, inlay_hints::InlayHintsConfig}; |
435 | 429 | ||
430 | const TEST_CONFIG: InlayHintsConfig = InlayHintsConfig { | ||
431 | type_hints: true, | ||
432 | parameter_hints: true, | ||
433 | chaining_hints: true, | ||
434 | max_length: None, | ||
435 | }; | ||
436 | |||
436 | fn check(ra_fixture: &str) { | 437 | fn check(ra_fixture: &str) { |
437 | check_with_config(InlayHintsConfig::default(), ra_fixture); | 438 | check_with_config(TEST_CONFIG, ra_fixture); |
438 | } | 439 | } |
439 | 440 | ||
440 | fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) { | 441 | fn check_with_config(config: InlayHintsConfig, ra_fixture: &str) { |
@@ -748,7 +749,7 @@ fn main() { | |||
748 | #[test] | 749 | #[test] |
749 | fn hint_truncation() { | 750 | fn hint_truncation() { |
750 | check_with_config( | 751 | check_with_config( |
751 | InlayHintsConfig { max_length: Some(8), ..Default::default() }, | 752 | InlayHintsConfig { max_length: Some(8), ..TEST_CONFIG }, |
752 | r#" | 753 | r#" |
753 | struct Smol<T>(T); | 754 | struct Smol<T>(T); |
754 | 755 | ||
@@ -831,7 +832,7 @@ fn main() { | |||
831 | #[test] | 832 | #[test] |
832 | fn omitted_parameters_hints_heuristics() { | 833 | fn omitted_parameters_hints_heuristics() { |
833 | check_with_config( | 834 | check_with_config( |
834 | InlayHintsConfig { max_length: Some(8), ..Default::default() }, | 835 | InlayHintsConfig { max_length: Some(8), ..TEST_CONFIG }, |
835 | r#" | 836 | r#" |
836 | fn map(f: i32) {} | 837 | fn map(f: i32) {} |
837 | fn filter(predicate: i32) {} | 838 | fn filter(predicate: i32) {} |
@@ -924,7 +925,7 @@ fn main() { | |||
924 | #[test] | 925 | #[test] |
925 | fn unit_structs_have_no_type_hints() { | 926 | fn unit_structs_have_no_type_hints() { |
926 | check_with_config( | 927 | check_with_config( |
927 | InlayHintsConfig { max_length: Some(8), ..Default::default() }, | 928 | InlayHintsConfig { max_length: Some(8), ..TEST_CONFIG }, |
928 | r#" | 929 | r#" |
929 | enum Result<T, E> { Ok(T), Err(E) } | 930 | enum Result<T, E> { Ok(T), Err(E) } |
930 | use Result::*; | 931 | use Result::*; |
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs index b5a6f66fd..05380f2a1 100644 --- a/crates/ide/src/join_lines.rs +++ b/crates/ide/src/join_lines.rs | |||
@@ -104,7 +104,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextS | |||
104 | // Special case that turns something like: | 104 | // Special case that turns something like: |
105 | // | 105 | // |
106 | // ``` | 106 | // ``` |
107 | // my_function({<|> | 107 | // my_function({$0 |
108 | // <some-expr> | 108 | // <some-expr> |
109 | // }) | 109 | // }) |
110 | // ``` | 110 | // ``` |
@@ -116,7 +116,7 @@ fn remove_newline(edit: &mut TextEditBuilder, token: &SyntaxToken, offset: TextS | |||
116 | // ditto for | 116 | // ditto for |
117 | // | 117 | // |
118 | // ``` | 118 | // ``` |
119 | // use foo::{<|> | 119 | // use foo::{$0 |
120 | // bar | 120 | // bar |
121 | // }; | 121 | // }; |
122 | // ``` | 122 | // ``` |
@@ -198,8 +198,8 @@ mod tests { | |||
198 | 198 | ||
199 | use super::*; | 199 | use super::*; |
200 | 200 | ||
201 | fn check_join_lines(before: &str, after: &str) { | 201 | fn check_join_lines(ra_fixture_before: &str, ra_fixture_after: &str) { |
202 | let (before_cursor_pos, before) = extract_offset(before); | 202 | let (before_cursor_pos, before) = extract_offset(ra_fixture_before); |
203 | let file = SourceFile::parse(&before).ok().unwrap(); | 203 | let file = SourceFile::parse(&before).ok().unwrap(); |
204 | 204 | ||
205 | let range = TextRange::empty(before_cursor_pos); | 205 | let range = TextRange::empty(before_cursor_pos); |
@@ -214,7 +214,7 @@ mod tests { | |||
214 | .apply_to_offset(before_cursor_pos) | 214 | .apply_to_offset(before_cursor_pos) |
215 | .expect("cursor position is affected by the edit"); | 215 | .expect("cursor position is affected by the edit"); |
216 | let actual = add_cursor(&actual, actual_cursor_pos); | 216 | let actual = add_cursor(&actual, actual_cursor_pos); |
217 | assert_eq_text!(after, &actual); | 217 | assert_eq_text!(ra_fixture_after, &actual); |
218 | } | 218 | } |
219 | 219 | ||
220 | #[test] | 220 | #[test] |
@@ -222,13 +222,13 @@ mod tests { | |||
222 | check_join_lines( | 222 | check_join_lines( |
223 | r" | 223 | r" |
224 | fn foo() { | 224 | fn foo() { |
225 | <|>foo(1, | 225 | $0foo(1, |
226 | ) | 226 | ) |
227 | } | 227 | } |
228 | ", | 228 | ", |
229 | r" | 229 | r" |
230 | fn foo() { | 230 | fn foo() { |
231 | <|>foo(1) | 231 | $0foo(1) |
232 | } | 232 | } |
233 | ", | 233 | ", |
234 | ); | 234 | ); |
@@ -239,14 +239,14 @@ fn foo() { | |||
239 | check_join_lines( | 239 | check_join_lines( |
240 | r" | 240 | r" |
241 | pub fn reparse(&self, edit: &AtomTextEdit) -> File { | 241 | pub fn reparse(&self, edit: &AtomTextEdit) -> File { |
242 | <|>self.incremental_reparse(edit).unwrap_or_else(|| { | 242 | $0self.incremental_reparse(edit).unwrap_or_else(|| { |
243 | self.full_reparse(edit) | 243 | self.full_reparse(edit) |
244 | }) | 244 | }) |
245 | } | 245 | } |
246 | ", | 246 | ", |
247 | r" | 247 | r" |
248 | pub fn reparse(&self, edit: &AtomTextEdit) -> File { | 248 | pub fn reparse(&self, edit: &AtomTextEdit) -> File { |
249 | <|>self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) | 249 | $0self.incremental_reparse(edit).unwrap_or_else(|| self.full_reparse(edit)) |
250 | } | 250 | } |
251 | ", | 251 | ", |
252 | ); | 252 | ); |
@@ -257,13 +257,13 @@ pub fn reparse(&self, edit: &AtomTextEdit) -> File { | |||
257 | check_join_lines( | 257 | check_join_lines( |
258 | r" | 258 | r" |
259 | fn foo() { | 259 | fn foo() { |
260 | foo(<|>{ | 260 | foo($0{ |
261 | 92 | 261 | 92 |
262 | }) | 262 | }) |
263 | }", | 263 | }", |
264 | r" | 264 | r" |
265 | fn foo() { | 265 | fn foo() { |
266 | foo(<|>92) | 266 | foo($092) |
267 | }", | 267 | }", |
268 | ); | 268 | ); |
269 | } | 269 | } |
@@ -274,7 +274,7 @@ fn foo() { | |||
274 | fn foo() { | 274 | fn foo() { |
275 | loop { | 275 | loop { |
276 | match x { | 276 | match x { |
277 | 92 => <|>{ | 277 | 92 => $0{ |
278 | continue; | 278 | continue; |
279 | } | 279 | } |
280 | } | 280 | } |
@@ -285,7 +285,7 @@ fn foo() { | |||
285 | fn foo() { | 285 | fn foo() { |
286 | loop { | 286 | loop { |
287 | match x { | 287 | match x { |
288 | 92 => <|>continue, | 288 | 92 => $0continue, |
289 | } | 289 | } |
290 | } | 290 | } |
291 | } | 291 | } |
@@ -299,7 +299,7 @@ fn foo() { | |||
299 | r" | 299 | r" |
300 | fn foo(e: Result<U, V>) { | 300 | fn foo(e: Result<U, V>) { |
301 | match e { | 301 | match e { |
302 | Ok(u) => <|>{ | 302 | Ok(u) => $0{ |
303 | u.foo() | 303 | u.foo() |
304 | } | 304 | } |
305 | Err(v) => v, | 305 | Err(v) => v, |
@@ -308,7 +308,7 @@ fn foo(e: Result<U, V>) { | |||
308 | r" | 308 | r" |
309 | fn foo(e: Result<U, V>) { | 309 | fn foo(e: Result<U, V>) { |
310 | match e { | 310 | match e { |
311 | Ok(u) => <|>u.foo(), | 311 | Ok(u) => $0u.foo(), |
312 | Err(v) => v, | 312 | Err(v) => v, |
313 | } | 313 | } |
314 | }", | 314 | }", |
@@ -321,7 +321,7 @@ fn foo(e: Result<U, V>) { | |||
321 | r" | 321 | r" |
322 | fn foo() { | 322 | fn foo() { |
323 | match ty { | 323 | match ty { |
324 | <|> Some(ty) => { | 324 | $0 Some(ty) => { |
325 | match ty { | 325 | match ty { |
326 | _ => false, | 326 | _ => false, |
327 | } | 327 | } |
@@ -333,7 +333,7 @@ fn foo() { | |||
333 | r" | 333 | r" |
334 | fn foo() { | 334 | fn foo() { |
335 | match ty { | 335 | match ty { |
336 | <|> Some(ty) => match ty { | 336 | $0 Some(ty) => match ty { |
337 | _ => false, | 337 | _ => false, |
338 | }, | 338 | }, |
339 | _ => true, | 339 | _ => true, |
@@ -350,7 +350,7 @@ fn foo() { | |||
350 | r" | 350 | r" |
351 | fn foo(e: Result<U, V>) { | 351 | fn foo(e: Result<U, V>) { |
352 | match e { | 352 | match e { |
353 | Ok(u) => <|>{ | 353 | Ok(u) => $0{ |
354 | u.foo() | 354 | u.foo() |
355 | }, | 355 | }, |
356 | Err(v) => v, | 356 | Err(v) => v, |
@@ -359,7 +359,7 @@ fn foo(e: Result<U, V>) { | |||
359 | r" | 359 | r" |
360 | fn foo(e: Result<U, V>) { | 360 | fn foo(e: Result<U, V>) { |
361 | match e { | 361 | match e { |
362 | Ok(u) => <|>u.foo(), | 362 | Ok(u) => $0u.foo(), |
363 | Err(v) => v, | 363 | Err(v) => v, |
364 | } | 364 | } |
365 | }", | 365 | }", |
@@ -370,7 +370,7 @@ fn foo(e: Result<U, V>) { | |||
370 | r" | 370 | r" |
371 | fn foo(e: Result<U, V>) { | 371 | fn foo(e: Result<U, V>) { |
372 | match e { | 372 | match e { |
373 | Ok(u) => <|>{ | 373 | Ok(u) => $0{ |
374 | u.foo() | 374 | u.foo() |
375 | } , | 375 | } , |
376 | Err(v) => v, | 376 | Err(v) => v, |
@@ -379,7 +379,7 @@ fn foo(e: Result<U, V>) { | |||
379 | r" | 379 | r" |
380 | fn foo(e: Result<U, V>) { | 380 | fn foo(e: Result<U, V>) { |
381 | match e { | 381 | match e { |
382 | Ok(u) => <|>u.foo() , | 382 | Ok(u) => $0u.foo() , |
383 | Err(v) => v, | 383 | Err(v) => v, |
384 | } | 384 | } |
385 | }", | 385 | }", |
@@ -390,7 +390,7 @@ fn foo(e: Result<U, V>) { | |||
390 | r" | 390 | r" |
391 | fn foo(e: Result<U, V>) { | 391 | fn foo(e: Result<U, V>) { |
392 | match e { | 392 | match e { |
393 | Ok(u) => <|>{ | 393 | Ok(u) => $0{ |
394 | u.foo() | 394 | u.foo() |
395 | } | 395 | } |
396 | , | 396 | , |
@@ -400,7 +400,7 @@ fn foo(e: Result<U, V>) { | |||
400 | r" | 400 | r" |
401 | fn foo(e: Result<U, V>) { | 401 | fn foo(e: Result<U, V>) { |
402 | match e { | 402 | match e { |
403 | Ok(u) => <|>u.foo() | 403 | Ok(u) => $0u.foo() |
404 | , | 404 | , |
405 | Err(v) => v, | 405 | Err(v) => v, |
406 | } | 406 | } |
@@ -414,13 +414,13 @@ fn foo(e: Result<U, V>) { | |||
414 | check_join_lines( | 414 | check_join_lines( |
415 | r" | 415 | r" |
416 | fn foo() { | 416 | fn foo() { |
417 | let x = (<|>{ | 417 | let x = ($0{ |
418 | 4 | 418 | 4 |
419 | },); | 419 | },); |
420 | }", | 420 | }", |
421 | r" | 421 | r" |
422 | fn foo() { | 422 | fn foo() { |
423 | let x = (<|>4,); | 423 | let x = ($04,); |
424 | }", | 424 | }", |
425 | ); | 425 | ); |
426 | 426 | ||
@@ -428,13 +428,13 @@ fn foo() { | |||
428 | check_join_lines( | 428 | check_join_lines( |
429 | r" | 429 | r" |
430 | fn foo() { | 430 | fn foo() { |
431 | let x = (<|>{ | 431 | let x = ($0{ |
432 | 4 | 432 | 4 |
433 | } ,); | 433 | } ,); |
434 | }", | 434 | }", |
435 | r" | 435 | r" |
436 | fn foo() { | 436 | fn foo() { |
437 | let x = (<|>4 ,); | 437 | let x = ($04 ,); |
438 | }", | 438 | }", |
439 | ); | 439 | ); |
440 | 440 | ||
@@ -442,14 +442,14 @@ fn foo() { | |||
442 | check_join_lines( | 442 | check_join_lines( |
443 | r" | 443 | r" |
444 | fn foo() { | 444 | fn foo() { |
445 | let x = (<|>{ | 445 | let x = ($0{ |
446 | 4 | 446 | 4 |
447 | } | 447 | } |
448 | ,); | 448 | ,); |
449 | }", | 449 | }", |
450 | r" | 450 | r" |
451 | fn foo() { | 451 | fn foo() { |
452 | let x = (<|>4 | 452 | let x = ($04 |
453 | ,); | 453 | ,); |
454 | }", | 454 | }", |
455 | ); | 455 | ); |
@@ -460,11 +460,11 @@ fn foo() { | |||
460 | // No space after the '{' | 460 | // No space after the '{' |
461 | check_join_lines( | 461 | check_join_lines( |
462 | r" | 462 | r" |
463 | <|>use syntax::{ | 463 | $0use syntax::{ |
464 | TextSize, TextRange, | 464 | TextSize, TextRange, |
465 | };", | 465 | };", |
466 | r" | 466 | r" |
467 | <|>use syntax::{TextSize, TextRange, | 467 | $0use syntax::{TextSize, TextRange, |
468 | };", | 468 | };", |
469 | ); | 469 | ); |
470 | } | 470 | } |
@@ -475,11 +475,11 @@ fn foo() { | |||
475 | check_join_lines( | 475 | check_join_lines( |
476 | r" | 476 | r" |
477 | use syntax::{ | 477 | use syntax::{ |
478 | <|> TextSize, TextRange | 478 | $0 TextSize, TextRange |
479 | };", | 479 | };", |
480 | r" | 480 | r" |
481 | use syntax::{ | 481 | use syntax::{ |
482 | <|> TextSize, TextRange};", | 482 | $0 TextSize, TextRange};", |
483 | ); | 483 | ); |
484 | } | 484 | } |
485 | 485 | ||
@@ -489,11 +489,11 @@ use syntax::{ | |||
489 | check_join_lines( | 489 | check_join_lines( |
490 | r" | 490 | r" |
491 | use syntax::{ | 491 | use syntax::{ |
492 | <|> TextSize, TextRange, | 492 | $0 TextSize, TextRange, |
493 | };", | 493 | };", |
494 | r" | 494 | r" |
495 | use syntax::{ | 495 | use syntax::{ |
496 | <|> TextSize, TextRange};", | 496 | $0 TextSize, TextRange};", |
497 | ); | 497 | ); |
498 | } | 498 | } |
499 | 499 | ||
@@ -502,14 +502,14 @@ use syntax::{ | |||
502 | check_join_lines( | 502 | check_join_lines( |
503 | r" | 503 | r" |
504 | use syntax::{ | 504 | use syntax::{ |
505 | algo::<|>{ | 505 | algo::$0{ |
506 | find_token_at_offset, | 506 | find_token_at_offset, |
507 | }, | 507 | }, |
508 | ast, | 508 | ast, |
509 | };", | 509 | };", |
510 | r" | 510 | r" |
511 | use syntax::{ | 511 | use syntax::{ |
512 | algo::<|>find_token_at_offset, | 512 | algo::$0find_token_at_offset, |
513 | ast, | 513 | ast, |
514 | };", | 514 | };", |
515 | ); | 515 | ); |
@@ -520,13 +520,13 @@ use syntax::{ | |||
520 | check_join_lines( | 520 | check_join_lines( |
521 | r" | 521 | r" |
522 | fn foo() { | 522 | fn foo() { |
523 | // Hello<|> | 523 | // Hello$0 |
524 | // world! | 524 | // world! |
525 | } | 525 | } |
526 | ", | 526 | ", |
527 | r" | 527 | r" |
528 | fn foo() { | 528 | fn foo() { |
529 | // Hello<|> world! | 529 | // Hello$0 world! |
530 | } | 530 | } |
531 | ", | 531 | ", |
532 | ); | 532 | ); |
@@ -537,13 +537,13 @@ fn foo() { | |||
537 | check_join_lines( | 537 | check_join_lines( |
538 | r" | 538 | r" |
539 | fn foo() { | 539 | fn foo() { |
540 | /// Hello<|> | 540 | /// Hello$0 |
541 | /// world! | 541 | /// world! |
542 | } | 542 | } |
543 | ", | 543 | ", |
544 | r" | 544 | r" |
545 | fn foo() { | 545 | fn foo() { |
546 | /// Hello<|> world! | 546 | /// Hello$0 world! |
547 | } | 547 | } |
548 | ", | 548 | ", |
549 | ); | 549 | ); |
@@ -554,13 +554,13 @@ fn foo() { | |||
554 | check_join_lines( | 554 | check_join_lines( |
555 | r" | 555 | r" |
556 | fn foo() { | 556 | fn foo() { |
557 | //! Hello<|> | 557 | //! Hello$0 |
558 | //! world! | 558 | //! world! |
559 | } | 559 | } |
560 | ", | 560 | ", |
561 | r" | 561 | r" |
562 | fn foo() { | 562 | fn foo() { |
563 | //! Hello<|> world! | 563 | //! Hello$0 world! |
564 | } | 564 | } |
565 | ", | 565 | ", |
566 | ); | 566 | ); |
@@ -571,13 +571,13 @@ fn foo() { | |||
571 | check_join_lines( | 571 | check_join_lines( |
572 | r" | 572 | r" |
573 | fn foo() { | 573 | fn foo() { |
574 | // Hello<|> | 574 | // Hello$0 |
575 | /* world! */ | 575 | /* world! */ |
576 | } | 576 | } |
577 | ", | 577 | ", |
578 | r" | 578 | r" |
579 | fn foo() { | 579 | fn foo() { |
580 | // Hello<|> world! */ | 580 | // Hello$0 world! */ |
581 | } | 581 | } |
582 | ", | 582 | ", |
583 | ); | 583 | ); |
@@ -588,7 +588,7 @@ fn foo() { | |||
588 | check_join_lines( | 588 | check_join_lines( |
589 | r" | 589 | r" |
590 | fn foo() { | 590 | fn foo() { |
591 | // The<|> | 591 | // The$0 |
592 | /* quick | 592 | /* quick |
593 | brown | 593 | brown |
594 | fox! */ | 594 | fox! */ |
@@ -596,7 +596,7 @@ fn foo() { | |||
596 | ", | 596 | ", |
597 | r" | 597 | r" |
598 | fn foo() { | 598 | fn foo() { |
599 | // The<|> quick | 599 | // The$0 quick |
600 | brown | 600 | brown |
601 | fox! */ | 601 | fox! */ |
602 | } | 602 | } |
@@ -604,8 +604,8 @@ fn foo() { | |||
604 | ); | 604 | ); |
605 | } | 605 | } |
606 | 606 | ||
607 | fn check_join_lines_sel(before: &str, after: &str) { | 607 | fn check_join_lines_sel(ra_fixture_before: &str, ra_fixture_after: &str) { |
608 | let (sel, before) = extract_range(before); | 608 | let (sel, before) = extract_range(ra_fixture_before); |
609 | let parse = SourceFile::parse(&before); | 609 | let parse = SourceFile::parse(&before); |
610 | let result = join_lines(&parse.tree(), sel); | 610 | let result = join_lines(&parse.tree(), sel); |
611 | let actual = { | 611 | let actual = { |
@@ -613,7 +613,7 @@ fn foo() { | |||
613 | result.apply(&mut actual); | 613 | result.apply(&mut actual); |
614 | actual | 614 | actual |
615 | }; | 615 | }; |
616 | assert_eq_text!(after, &actual); | 616 | assert_eq_text!(ra_fixture_after, &actual); |
617 | } | 617 | } |
618 | 618 | ||
619 | #[test] | 619 | #[test] |
@@ -621,10 +621,10 @@ fn foo() { | |||
621 | check_join_lines_sel( | 621 | check_join_lines_sel( |
622 | r" | 622 | r" |
623 | fn foo() { | 623 | fn foo() { |
624 | <|>foo(1, | 624 | $0foo(1, |
625 | 2, | 625 | 2, |
626 | 3, | 626 | 3, |
627 | <|>) | 627 | $0) |
628 | } | 628 | } |
629 | ", | 629 | ", |
630 | r" | 630 | r" |
@@ -639,9 +639,9 @@ fn foo() { | |||
639 | fn test_join_lines_selection_struct() { | 639 | fn test_join_lines_selection_struct() { |
640 | check_join_lines_sel( | 640 | check_join_lines_sel( |
641 | r" | 641 | r" |
642 | struct Foo <|>{ | 642 | struct Foo $0{ |
643 | f: u32, | 643 | f: u32, |
644 | }<|> | 644 | }$0 |
645 | ", | 645 | ", |
646 | r" | 646 | r" |
647 | struct Foo { f: u32 } | 647 | struct Foo { f: u32 } |
@@ -654,9 +654,9 @@ struct Foo { f: u32 } | |||
654 | check_join_lines_sel( | 654 | check_join_lines_sel( |
655 | r" | 655 | r" |
656 | fn foo() { | 656 | fn foo() { |
657 | join(<|>type_params.type_params() | 657 | join($0type_params.type_params() |
658 | .filter_map(|it| it.name()) | 658 | .filter_map(|it| it.name()) |
659 | .map(|it| it.text())<|>) | 659 | .map(|it| it.text())$0) |
660 | }", | 660 | }", |
661 | r" | 661 | r" |
662 | fn foo() { | 662 | fn foo() { |
@@ -671,9 +671,9 @@ fn foo() { | |||
671 | r" | 671 | r" |
672 | pub fn handle_find_matching_brace() { | 672 | pub fn handle_find_matching_brace() { |
673 | params.offsets | 673 | params.offsets |
674 | .map(|offset| <|>{ | 674 | .map(|offset| $0{ |
675 | world.analysis().matching_brace(&file, offset).unwrap_or(offset) | 675 | world.analysis().matching_brace(&file, offset).unwrap_or(offset) |
676 | }<|>) | 676 | }$0) |
677 | .collect(); | 677 | .collect(); |
678 | }", | 678 | }", |
679 | r" | 679 | r" |
@@ -691,7 +691,7 @@ pub fn handle_find_matching_brace() { | |||
691 | r" | 691 | r" |
692 | fn main() { | 692 | fn main() { |
693 | let _ = { | 693 | let _ = { |
694 | // <|>foo | 694 | // $0foo |
695 | // bar | 695 | // bar |
696 | 92 | 696 | 92 |
697 | }; | 697 | }; |
@@ -700,7 +700,7 @@ fn main() { | |||
700 | r" | 700 | r" |
701 | fn main() { | 701 | fn main() { |
702 | let _ = { | 702 | let _ = { |
703 | // <|>foo bar | 703 | // $0foo bar |
704 | 92 | 704 | 92 |
705 | }; | 705 | }; |
706 | } | 706 | } |
@@ -712,12 +712,12 @@ fn main() { | |||
712 | fn join_lines_mandatory_blocks_block() { | 712 | fn join_lines_mandatory_blocks_block() { |
713 | check_join_lines( | 713 | check_join_lines( |
714 | r" | 714 | r" |
715 | <|>fn foo() { | 715 | $0fn foo() { |
716 | 92 | 716 | 92 |
717 | } | 717 | } |
718 | ", | 718 | ", |
719 | r" | 719 | r" |
720 | <|>fn foo() { 92 | 720 | $0fn foo() { 92 |
721 | } | 721 | } |
722 | ", | 722 | ", |
723 | ); | 723 | ); |
@@ -725,14 +725,14 @@ fn main() { | |||
725 | check_join_lines( | 725 | check_join_lines( |
726 | r" | 726 | r" |
727 | fn foo() { | 727 | fn foo() { |
728 | <|>if true { | 728 | $0if true { |
729 | 92 | 729 | 92 |
730 | } | 730 | } |
731 | } | 731 | } |
732 | ", | 732 | ", |
733 | r" | 733 | r" |
734 | fn foo() { | 734 | fn foo() { |
735 | <|>if true { 92 | 735 | $0if true { 92 |
736 | } | 736 | } |
737 | } | 737 | } |
738 | ", | 738 | ", |
@@ -741,14 +741,14 @@ fn foo() { | |||
741 | check_join_lines( | 741 | check_join_lines( |
742 | r" | 742 | r" |
743 | fn foo() { | 743 | fn foo() { |
744 | <|>loop { | 744 | $0loop { |
745 | 92 | 745 | 92 |
746 | } | 746 | } |
747 | } | 747 | } |
748 | ", | 748 | ", |
749 | r" | 749 | r" |
750 | fn foo() { | 750 | fn foo() { |
751 | <|>loop { 92 | 751 | $0loop { 92 |
752 | } | 752 | } |
753 | } | 753 | } |
754 | ", | 754 | ", |
@@ -757,14 +757,14 @@ fn foo() { | |||
757 | check_join_lines( | 757 | check_join_lines( |
758 | r" | 758 | r" |
759 | fn foo() { | 759 | fn foo() { |
760 | <|>unsafe { | 760 | $0unsafe { |
761 | 92 | 761 | 92 |
762 | } | 762 | } |
763 | } | 763 | } |
764 | ", | 764 | ", |
765 | r" | 765 | r" |
766 | fn foo() { | 766 | fn foo() { |
767 | <|>unsafe { 92 | 767 | $0unsafe { 92 |
768 | } | 768 | } |
769 | } | 769 | } |
770 | ", | 770 | ", |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index a450794f3..cea2a13c8 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -80,10 +80,10 @@ pub use crate::{ | |||
80 | HighlightedRange, | 80 | HighlightedRange, |
81 | }, | 81 | }, |
82 | }; | 82 | }; |
83 | pub use assists::{Assist, AssistConfig, AssistId, AssistKind}; | 83 | pub use assists::{Assist, AssistConfig, AssistId, AssistKind, InsertUseConfig}; |
84 | pub use completion::{ | 84 | pub use completion::{ |
85 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionResolveCapability, | 85 | CompletionConfig, CompletionItem, CompletionItemKind, CompletionScore, ImportEdit, |
86 | CompletionScore, ImportEdit, InsertTextFormat, | 86 | InsertTextFormat, |
87 | }; | 87 | }; |
88 | pub use hir::{Documentation, Semantics}; | 88 | pub use hir::{Documentation, Semantics}; |
89 | pub use ide_db::base_db::{ | 89 | pub use ide_db::base_db::{ |
diff --git a/crates/ide/src/matching_brace.rs b/crates/ide/src/matching_brace.rs index d70248afe..1bfa1439d 100644 --- a/crates/ide/src/matching_brace.rs +++ b/crates/ide/src/matching_brace.rs | |||
@@ -58,15 +58,15 @@ mod tests { | |||
58 | assert_eq_text!(after, &actual); | 58 | assert_eq_text!(after, &actual); |
59 | } | 59 | } |
60 | 60 | ||
61 | do_check("struct Foo { a: i32, }<|>", "struct Foo <|>{ a: i32, }"); | 61 | do_check("struct Foo { a: i32, }$0", "struct Foo $0{ a: i32, }"); |
62 | do_check("fn main() { |x: i32|<|> x * 2;}", "fn main() { <|>|x: i32| x * 2;}"); | 62 | do_check("fn main() { |x: i32|$0 x * 2;}", "fn main() { $0|x: i32| x * 2;}"); |
63 | do_check("fn main() { <|>|x: i32| x * 2;}", "fn main() { |x: i32<|>| x * 2;}"); | 63 | do_check("fn main() { $0|x: i32| x * 2;}", "fn main() { |x: i32$0| x * 2;}"); |
64 | 64 | ||
65 | { | 65 | { |
66 | mark::check!(pipes_not_braces); | 66 | mark::check!(pipes_not_braces); |
67 | do_check( | 67 | do_check( |
68 | "fn main() { match 92 { 1 | 2 |<|> 3 => 92 } }", | 68 | "fn main() { match 92 { 1 | 2 |$0 3 => 92 } }", |
69 | "fn main() { match 92 { 1 | 2 |<|> 3 => 92 } }", | 69 | "fn main() { match 92 { 1 | 2 |$0 3 => 92 } }", |
70 | ); | 70 | ); |
71 | } | 71 | } |
72 | } | 72 | } |
diff --git a/crates/ide/src/parent_module.rs b/crates/ide/src/parent_module.rs index be344a09b..d343638fb 100644 --- a/crates/ide/src/parent_module.rs +++ b/crates/ide/src/parent_module.rs | |||
@@ -74,7 +74,7 @@ mod tests { | |||
74 | //- /lib.rs | 74 | //- /lib.rs |
75 | mod foo; | 75 | mod foo; |
76 | //- /foo.rs | 76 | //- /foo.rs |
77 | <|>// empty | 77 | $0// empty |
78 | ", | 78 | ", |
79 | ); | 79 | ); |
80 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | 80 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); |
@@ -90,7 +90,7 @@ mod tests { | |||
90 | mod foo; | 90 | mod foo; |
91 | 91 | ||
92 | //- /foo.rs | 92 | //- /foo.rs |
93 | mod <|>bar; | 93 | mod $0bar; |
94 | 94 | ||
95 | //- /foo/bar.rs | 95 | //- /foo/bar.rs |
96 | // empty | 96 | // empty |
@@ -107,7 +107,7 @@ mod tests { | |||
107 | //- /lib.rs | 107 | //- /lib.rs |
108 | mod foo { | 108 | mod foo { |
109 | mod bar { | 109 | mod bar { |
110 | mod baz { <|> } | 110 | mod baz { $0 } |
111 | } | 111 | } |
112 | } | 112 | } |
113 | ", | 113 | ", |
@@ -123,7 +123,7 @@ mod tests { | |||
123 | //- /main.rs | 123 | //- /main.rs |
124 | mod foo; | 124 | mod foo; |
125 | //- /foo.rs | 125 | //- /foo.rs |
126 | <|> | 126 | $0 |
127 | "#, | 127 | "#, |
128 | ); | 128 | ); |
129 | assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1); | 129 | assert_eq!(analysis.crate_for(file_id).unwrap().len(), 1); |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index fa58fc319..c95ed669c 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -331,7 +331,7 @@ mod tests { | |||
331 | fn test_struct_literal_after_space() { | 331 | fn test_struct_literal_after_space() { |
332 | check( | 332 | check( |
333 | r#" | 333 | r#" |
334 | struct Foo <|>{ | 334 | struct Foo $0{ |
335 | a: i32, | 335 | a: i32, |
336 | } | 336 | } |
337 | impl Foo { | 337 | impl Foo { |
@@ -354,7 +354,7 @@ fn main() { | |||
354 | fn test_struct_literal_before_space() { | 354 | fn test_struct_literal_before_space() { |
355 | check( | 355 | check( |
356 | r#" | 356 | r#" |
357 | struct Foo<|> {} | 357 | struct Foo$0 {} |
358 | fn main() { | 358 | fn main() { |
359 | let f: Foo; | 359 | let f: Foo; |
360 | f = Foo {}; | 360 | f = Foo {}; |
@@ -373,7 +373,7 @@ struct Foo<|> {} | |||
373 | fn test_struct_literal_with_generic_type() { | 373 | fn test_struct_literal_with_generic_type() { |
374 | check( | 374 | check( |
375 | r#" | 375 | r#" |
376 | struct Foo<T> <|>{} | 376 | struct Foo<T> $0{} |
377 | fn main() { | 377 | fn main() { |
378 | let f: Foo::<i32>; | 378 | let f: Foo::<i32>; |
379 | f = Foo {}; | 379 | f = Foo {}; |
@@ -391,7 +391,7 @@ struct Foo<T> <|>{} | |||
391 | fn test_struct_literal_for_tuple() { | 391 | fn test_struct_literal_for_tuple() { |
392 | check( | 392 | check( |
393 | r#" | 393 | r#" |
394 | struct Foo<|>(i32); | 394 | struct Foo$0(i32); |
395 | 395 | ||
396 | fn main() { | 396 | fn main() { |
397 | let f: Foo; | 397 | let f: Foo; |
@@ -410,7 +410,7 @@ fn main() { | |||
410 | fn test_enum_after_space() { | 410 | fn test_enum_after_space() { |
411 | check( | 411 | check( |
412 | r#" | 412 | r#" |
413 | enum Foo <|>{ | 413 | enum Foo $0{ |
414 | A, | 414 | A, |
415 | B, | 415 | B, |
416 | } | 416 | } |
@@ -431,7 +431,7 @@ fn main() { | |||
431 | fn test_enum_before_space() { | 431 | fn test_enum_before_space() { |
432 | check( | 432 | check( |
433 | r#" | 433 | r#" |
434 | enum Foo<|> { | 434 | enum Foo$0 { |
435 | A, | 435 | A, |
436 | B, | 436 | B, |
437 | } | 437 | } |
@@ -453,7 +453,7 @@ fn main() { | |||
453 | fn test_enum_with_generic_type() { | 453 | fn test_enum_with_generic_type() { |
454 | check( | 454 | check( |
455 | r#" | 455 | r#" |
456 | enum Foo<T> <|>{ | 456 | enum Foo<T> $0{ |
457 | A(T), | 457 | A(T), |
458 | B, | 458 | B, |
459 | } | 459 | } |
@@ -474,7 +474,7 @@ fn main() { | |||
474 | fn test_enum_for_tuple() { | 474 | fn test_enum_for_tuple() { |
475 | check( | 475 | check( |
476 | r#" | 476 | r#" |
477 | enum Foo<|>{ | 477 | enum Foo$0{ |
478 | A(i8), | 478 | A(i8), |
479 | B(i8), | 479 | B(i8), |
480 | } | 480 | } |
@@ -498,7 +498,7 @@ fn main() { | |||
498 | fn main() { | 498 | fn main() { |
499 | let mut i = 1; | 499 | let mut i = 1; |
500 | let j = 1; | 500 | let j = 1; |
501 | i = i<|> + j; | 501 | i = i$0 + j; |
502 | 502 | ||
503 | { | 503 | { |
504 | i = 0; | 504 | i = 0; |
@@ -522,7 +522,7 @@ fn main() { | |||
522 | check( | 522 | check( |
523 | r#" | 523 | r#" |
524 | fn foo() { | 524 | fn foo() { |
525 | let spam<|> = 92; | 525 | let spam$0 = 92; |
526 | spam + spam | 526 | spam + spam |
527 | } | 527 | } |
528 | fn bar() { | 528 | fn bar() { |
@@ -543,7 +543,7 @@ fn bar() { | |||
543 | fn test_find_all_refs_for_param_inside() { | 543 | fn test_find_all_refs_for_param_inside() { |
544 | check( | 544 | check( |
545 | r#" | 545 | r#" |
546 | fn foo(i : u32) -> u32 { i<|> } | 546 | fn foo(i : u32) -> u32 { i$0 } |
547 | "#, | 547 | "#, |
548 | expect![[r#" | 548 | expect![[r#" |
549 | i ValueParam FileId(0) 7..8 Other | 549 | i ValueParam FileId(0) 7..8 Other |
@@ -557,7 +557,7 @@ fn foo(i : u32) -> u32 { i<|> } | |||
557 | fn test_find_all_refs_for_fn_param() { | 557 | fn test_find_all_refs_for_fn_param() { |
558 | check( | 558 | check( |
559 | r#" | 559 | r#" |
560 | fn foo(i<|> : u32) -> u32 { i } | 560 | fn foo(i$0 : u32) -> u32 { i } |
561 | "#, | 561 | "#, |
562 | expect![[r#" | 562 | expect![[r#" |
563 | i ValueParam FileId(0) 7..8 Other | 563 | i ValueParam FileId(0) 7..8 Other |
@@ -573,7 +573,7 @@ fn foo(i<|> : u32) -> u32 { i } | |||
573 | r#" | 573 | r#" |
574 | //- /lib.rs | 574 | //- /lib.rs |
575 | struct Foo { | 575 | struct Foo { |
576 | pub spam<|>: u32, | 576 | pub spam$0: u32, |
577 | } | 577 | } |
578 | 578 | ||
579 | fn main(s: Foo) { | 579 | fn main(s: Foo) { |
@@ -594,7 +594,7 @@ fn main(s: Foo) { | |||
594 | r#" | 594 | r#" |
595 | struct Foo; | 595 | struct Foo; |
596 | impl Foo { | 596 | impl Foo { |
597 | fn f<|>(&self) { } | 597 | fn f$0(&self) { } |
598 | } | 598 | } |
599 | "#, | 599 | "#, |
600 | expect![[r#" | 600 | expect![[r#" |
@@ -610,7 +610,7 @@ impl Foo { | |||
610 | r#" | 610 | r#" |
611 | enum Foo { | 611 | enum Foo { |
612 | A, | 612 | A, |
613 | B<|>, | 613 | B$0, |
614 | C, | 614 | C, |
615 | } | 615 | } |
616 | "#, | 616 | "#, |
@@ -627,7 +627,7 @@ enum Foo { | |||
627 | r#" | 627 | r#" |
628 | enum Foo { | 628 | enum Foo { |
629 | A, | 629 | A, |
630 | B { field<|>: u8 }, | 630 | B { field$0: u8 }, |
631 | C, | 631 | C, |
632 | } | 632 | } |
633 | "#, | 633 | "#, |
@@ -669,7 +669,7 @@ pub struct Bar { | |||
669 | } | 669 | } |
670 | 670 | ||
671 | fn f() { | 671 | fn f() { |
672 | let i = foo::Foo<|> { n: 5 }; | 672 | let i = foo::Foo$0 { n: 5 }; |
673 | } | 673 | } |
674 | "#, | 674 | "#, |
675 | expect![[r#" | 675 | expect![[r#" |
@@ -689,7 +689,7 @@ fn f() { | |||
689 | check( | 689 | check( |
690 | r#" | 690 | r#" |
691 | //- /lib.rs | 691 | //- /lib.rs |
692 | mod foo<|>; | 692 | mod foo$0; |
693 | 693 | ||
694 | use foo::Foo; | 694 | use foo::Foo; |
695 | 695 | ||
@@ -726,7 +726,7 @@ fn f() { | |||
726 | } | 726 | } |
727 | 727 | ||
728 | //- /foo/some.rs | 728 | //- /foo/some.rs |
729 | pub(super) struct Foo<|> { | 729 | pub(super) struct Foo$0 { |
730 | pub n: u32, | 730 | pub n: u32, |
731 | } | 731 | } |
732 | "#, | 732 | "#, |
@@ -746,7 +746,7 @@ pub(super) struct Foo<|> { | |||
746 | mod foo; | 746 | mod foo; |
747 | mod bar; | 747 | mod bar; |
748 | 748 | ||
749 | pub fn quux<|>() {} | 749 | pub fn quux$0() {} |
750 | 750 | ||
751 | //- /foo.rs | 751 | //- /foo.rs |
752 | fn f() { super::quux(); } | 752 | fn f() { super::quux(); } |
@@ -782,7 +782,7 @@ pub(super) struct Foo<|> { | |||
782 | check( | 782 | check( |
783 | r#" | 783 | r#" |
784 | #[macro_export] | 784 | #[macro_export] |
785 | macro_rules! m1<|> { () => (()) } | 785 | macro_rules! m1$0 { () => (()) } |
786 | 786 | ||
787 | fn foo() { | 787 | fn foo() { |
788 | m1(); | 788 | m1(); |
@@ -803,7 +803,7 @@ fn foo() { | |||
803 | check( | 803 | check( |
804 | r#" | 804 | r#" |
805 | fn foo() { | 805 | fn foo() { |
806 | let mut i<|> = 0; | 806 | let mut i$0 = 0; |
807 | i = i + 1; | 807 | i = i + 1; |
808 | } | 808 | } |
809 | "#, | 809 | "#, |
@@ -826,7 +826,7 @@ struct S { | |||
826 | 826 | ||
827 | fn foo() { | 827 | fn foo() { |
828 | let mut s = S{f: 0}; | 828 | let mut s = S{f: 0}; |
829 | s.f<|> = 0; | 829 | s.f$0 = 0; |
830 | } | 830 | } |
831 | "#, | 831 | "#, |
832 | expect![[r#" | 832 | expect![[r#" |
@@ -843,7 +843,7 @@ fn foo() { | |||
843 | check( | 843 | check( |
844 | r#" | 844 | r#" |
845 | fn foo() { | 845 | fn foo() { |
846 | let i<|>; | 846 | let i$0; |
847 | i = 1; | 847 | i = 1; |
848 | } | 848 | } |
849 | "#, | 849 | "#, |
@@ -863,7 +863,7 @@ mod foo { | |||
863 | pub struct Foo; | 863 | pub struct Foo; |
864 | 864 | ||
865 | impl Foo { | 865 | impl Foo { |
866 | pub fn new<|>() -> Foo { Foo } | 866 | pub fn new$0() -> Foo { Foo } |
867 | } | 867 | } |
868 | } | 868 | } |
869 | 869 | ||
@@ -886,7 +886,7 @@ fn main() { | |||
886 | //- /lib.rs | 886 | //- /lib.rs |
887 | mod foo { mod bar; } | 887 | mod foo { mod bar; } |
888 | 888 | ||
889 | fn f<|>() {} | 889 | fn f$0() {} |
890 | 890 | ||
891 | //- /foo/bar.rs | 891 | //- /foo/bar.rs |
892 | use crate::f; | 892 | use crate::f; |
@@ -907,7 +907,7 @@ fn g() { f(); } | |||
907 | check( | 907 | check( |
908 | r#" | 908 | r#" |
909 | struct S { | 909 | struct S { |
910 | field<|>: u8, | 910 | field$0: u8, |
911 | } | 911 | } |
912 | 912 | ||
913 | fn f(s: S) { | 913 | fn f(s: S) { |
@@ -930,7 +930,7 @@ fn f(s: S) { | |||
930 | r#" | 930 | r#" |
931 | enum En { | 931 | enum En { |
932 | Variant { | 932 | Variant { |
933 | field<|>: u8, | 933 | field$0: u8, |
934 | } | 934 | } |
935 | } | 935 | } |
936 | 936 | ||
@@ -955,7 +955,7 @@ fn f(e: En) { | |||
955 | mod m { | 955 | mod m { |
956 | pub enum En { | 956 | pub enum En { |
957 | Variant { | 957 | Variant { |
958 | field<|>: u8, | 958 | field$0: u8, |
959 | } | 959 | } |
960 | } | 960 | } |
961 | } | 961 | } |
@@ -980,7 +980,7 @@ struct Foo { bar: i32 } | |||
980 | 980 | ||
981 | impl Foo { | 981 | impl Foo { |
982 | fn foo(self) { | 982 | fn foo(self) { |
983 | let x = self<|>.bar; | 983 | let x = self$0.bar; |
984 | if true { | 984 | if true { |
985 | let _ = match () { | 985 | let _ = match () { |
986 | () => self, | 986 | () => self, |
@@ -1032,7 +1032,7 @@ impl Foo { | |||
1032 | r#" | 1032 | r#" |
1033 | trait Foo<'a> {} | 1033 | trait Foo<'a> {} |
1034 | impl<'a> Foo<'a> for &'a () {} | 1034 | impl<'a> Foo<'a> for &'a () {} |
1035 | fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> { | 1035 | fn foo<'a, 'b: 'a>(x: &'a$0 ()) -> &'a () where &'a (): Foo<'a> { |
1036 | fn bar<'a>(_: &'a ()) {} | 1036 | fn bar<'a>(_: &'a ()) {} |
1037 | x | 1037 | x |
1038 | } | 1038 | } |
@@ -1053,7 +1053,7 @@ fn foo<'a, 'b: 'a>(x: &'a<|> ()) -> &'a () where &'a (): Foo<'a> { | |||
1053 | fn test_find_lifetimes_type_alias() { | 1053 | fn test_find_lifetimes_type_alias() { |
1054 | check( | 1054 | check( |
1055 | r#" | 1055 | r#" |
1056 | type Foo<'a, T> where T: 'a<|> = &'a T; | 1056 | type Foo<'a, T> where T: 'a$0 = &'a T; |
1057 | "#, | 1057 | "#, |
1058 | expect![[r#" | 1058 | expect![[r#" |
1059 | 'a LifetimeParam FileId(0) 9..11 9..11 Lifetime | 1059 | 'a LifetimeParam FileId(0) 9..11 9..11 Lifetime |
@@ -1072,7 +1072,7 @@ trait Foo<'a> { | |||
1072 | fn foo() -> &'a (); | 1072 | fn foo() -> &'a (); |
1073 | } | 1073 | } |
1074 | impl<'a> Foo<'a> for &'a () { | 1074 | impl<'a> Foo<'a> for &'a () { |
1075 | fn foo() -> &'a<|> () { | 1075 | fn foo() -> &'a$0 () { |
1076 | unimplemented!() | 1076 | unimplemented!() |
1077 | } | 1077 | } |
1078 | } | 1078 | } |
@@ -1093,7 +1093,7 @@ impl<'a> Foo<'a> for &'a () { | |||
1093 | r#" | 1093 | r#" |
1094 | macro_rules! foo {($i:ident) => {$i} } | 1094 | macro_rules! foo {($i:ident) => {$i} } |
1095 | fn main() { | 1095 | fn main() { |
1096 | let a<|> = "test"; | 1096 | let a$0 = "test"; |
1097 | foo!(a); | 1097 | foo!(a); |
1098 | } | 1098 | } |
1099 | "#, | 1099 | "#, |
@@ -1112,7 +1112,7 @@ fn main() { | |||
1112 | macro_rules! foo {($i:ident) => {$i} } | 1112 | macro_rules! foo {($i:ident) => {$i} } |
1113 | fn main() { | 1113 | fn main() { |
1114 | let a = "test"; | 1114 | let a = "test"; |
1115 | foo!(a<|>); | 1115 | foo!(a$0); |
1116 | } | 1116 | } |
1117 | "#, | 1117 | "#, |
1118 | expect![[r#" | 1118 | expect![[r#" |
@@ -1130,7 +1130,7 @@ fn main() { | |||
1130 | fn foo<'a>() -> &'a () { | 1130 | fn foo<'a>() -> &'a () { |
1131 | 'a: loop { | 1131 | 'a: loop { |
1132 | 'b: loop { | 1132 | 'b: loop { |
1133 | continue 'a<|>; | 1133 | continue 'a$0; |
1134 | } | 1134 | } |
1135 | break 'a; | 1135 | break 'a; |
1136 | } | 1136 | } |
@@ -1149,7 +1149,7 @@ fn foo<'a>() -> &'a () { | |||
1149 | fn test_find_const_param() { | 1149 | fn test_find_const_param() { |
1150 | check( | 1150 | check( |
1151 | r#" | 1151 | r#" |
1152 | fn foo<const FOO<|>: usize>() -> usize { | 1152 | fn foo<const FOO$0: usize>() -> usize { |
1153 | FOO | 1153 | FOO |
1154 | } | 1154 | } |
1155 | "#, | 1155 | "#, |
diff --git a/crates/ide/src/references/rename.rs b/crates/ide/src/references/rename.rs index 854bf194e..53d79333c 100644 --- a/crates/ide/src/references/rename.rs +++ b/crates/ide/src/references/rename.rs | |||
@@ -493,19 +493,19 @@ mod tests { | |||
493 | 493 | ||
494 | #[test] | 494 | #[test] |
495 | fn test_rename_to_underscore() { | 495 | fn test_rename_to_underscore() { |
496 | check("_", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let _ = 1; }"#); | 496 | check("_", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let _ = 1; }"#); |
497 | } | 497 | } |
498 | 498 | ||
499 | #[test] | 499 | #[test] |
500 | fn test_rename_to_raw_identifier() { | 500 | fn test_rename_to_raw_identifier() { |
501 | check("r#fn", r#"fn main() { let i<|> = 1; }"#, r#"fn main() { let r#fn = 1; }"#); | 501 | check("r#fn", r#"fn main() { let i$0 = 1; }"#, r#"fn main() { let r#fn = 1; }"#); |
502 | } | 502 | } |
503 | 503 | ||
504 | #[test] | 504 | #[test] |
505 | fn test_rename_to_invalid_identifier1() { | 505 | fn test_rename_to_invalid_identifier1() { |
506 | check( | 506 | check( |
507 | "invalid!", | 507 | "invalid!", |
508 | r#"fn main() { let i<|> = 1; }"#, | 508 | r#"fn main() { let i$0 = 1; }"#, |
509 | "error: Invalid name `invalid!`: not an identifier", | 509 | "error: Invalid name `invalid!`: not an identifier", |
510 | ); | 510 | ); |
511 | } | 511 | } |
@@ -514,7 +514,7 @@ mod tests { | |||
514 | fn test_rename_to_invalid_identifier2() { | 514 | fn test_rename_to_invalid_identifier2() { |
515 | check( | 515 | check( |
516 | "multiple tokens", | 516 | "multiple tokens", |
517 | r#"fn main() { let i<|> = 1; }"#, | 517 | r#"fn main() { let i$0 = 1; }"#, |
518 | "error: Invalid name `multiple tokens`: not an identifier", | 518 | "error: Invalid name `multiple tokens`: not an identifier", |
519 | ); | 519 | ); |
520 | } | 520 | } |
@@ -523,7 +523,7 @@ mod tests { | |||
523 | fn test_rename_to_invalid_identifier3() { | 523 | fn test_rename_to_invalid_identifier3() { |
524 | check( | 524 | check( |
525 | "let", | 525 | "let", |
526 | r#"fn main() { let i<|> = 1; }"#, | 526 | r#"fn main() { let i$0 = 1; }"#, |
527 | "error: Invalid name `let`: not an identifier", | 527 | "error: Invalid name `let`: not an identifier", |
528 | ); | 528 | ); |
529 | } | 529 | } |
@@ -532,7 +532,7 @@ mod tests { | |||
532 | fn test_rename_to_invalid_identifier_lifetime() { | 532 | fn test_rename_to_invalid_identifier_lifetime() { |
533 | check( | 533 | check( |
534 | "'foo", | 534 | "'foo", |
535 | r#"fn main() { let i<|> = 1; }"#, | 535 | r#"fn main() { let i$0 = 1; }"#, |
536 | "error: Invalid name `'foo`: not an identifier", | 536 | "error: Invalid name `'foo`: not an identifier", |
537 | ); | 537 | ); |
538 | } | 538 | } |
@@ -541,7 +541,7 @@ mod tests { | |||
541 | fn test_rename_to_invalid_identifier_lifetime2() { | 541 | fn test_rename_to_invalid_identifier_lifetime2() { |
542 | check( | 542 | check( |
543 | "foo", | 543 | "foo", |
544 | r#"fn main<'a>(_: &'a<|> ()) {}"#, | 544 | r#"fn main<'a>(_: &'a$0 ()) {}"#, |
545 | "error: Invalid name `foo`: not a lifetime identifier", | 545 | "error: Invalid name `foo`: not a lifetime identifier", |
546 | ); | 546 | ); |
547 | } | 547 | } |
@@ -554,7 +554,7 @@ mod tests { | |||
554 | fn main() { | 554 | fn main() { |
555 | let mut i = 1; | 555 | let mut i = 1; |
556 | let j = 1; | 556 | let j = 1; |
557 | i = i<|> + j; | 557 | i = i$0 + j; |
558 | 558 | ||
559 | { i = 0; } | 559 | { i = 0; } |
560 | 560 | ||
@@ -579,7 +579,7 @@ fn main() { | |||
579 | fn test_rename_unresolved_reference() { | 579 | fn test_rename_unresolved_reference() { |
580 | check( | 580 | check( |
581 | "new_name", | 581 | "new_name", |
582 | r#"fn main() { let _ = unresolved_ref<|>; }"#, | 582 | r#"fn main() { let _ = unresolved_ref$0; }"#, |
583 | "error: No references found at position", | 583 | "error: No references found at position", |
584 | ); | 584 | ); |
585 | } | 585 | } |
@@ -591,7 +591,7 @@ fn main() { | |||
591 | r#" | 591 | r#" |
592 | macro_rules! foo {($i:ident) => {$i} } | 592 | macro_rules! foo {($i:ident) => {$i} } |
593 | fn main() { | 593 | fn main() { |
594 | let a<|> = "test"; | 594 | let a$0 = "test"; |
595 | foo!(a); | 595 | foo!(a); |
596 | } | 596 | } |
597 | "#, | 597 | "#, |
@@ -613,7 +613,7 @@ fn main() { | |||
613 | macro_rules! foo {($i:ident) => {$i} } | 613 | macro_rules! foo {($i:ident) => {$i} } |
614 | fn main() { | 614 | fn main() { |
615 | let a = "test"; | 615 | let a = "test"; |
616 | foo!(a<|>); | 616 | foo!(a$0); |
617 | } | 617 | } |
618 | "#, | 618 | "#, |
619 | r#" | 619 | r#" |
@@ -634,7 +634,7 @@ fn main() { | |||
634 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 634 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
635 | define_fn!(foo); | 635 | define_fn!(foo); |
636 | fn main() { | 636 | fn main() { |
637 | fo<|>o(); | 637 | fo$0o(); |
638 | } | 638 | } |
639 | "#, | 639 | "#, |
640 | r#" | 640 | r#" |
@@ -653,7 +653,7 @@ fn main() { | |||
653 | "bar", | 653 | "bar", |
654 | r#" | 654 | r#" |
655 | macro_rules! define_fn {($id:ident) => { fn $id{} }} | 655 | macro_rules! define_fn {($id:ident) => { fn $id{} }} |
656 | define_fn!(fo<|>o); | 656 | define_fn!(fo$0o); |
657 | fn main() { | 657 | fn main() { |
658 | foo(); | 658 | foo(); |
659 | } | 659 | } |
@@ -670,17 +670,17 @@ fn main() { | |||
670 | 670 | ||
671 | #[test] | 671 | #[test] |
672 | fn test_rename_for_param_inside() { | 672 | fn test_rename_for_param_inside() { |
673 | check("j", r#"fn foo(i : u32) -> u32 { i<|> }"#, r#"fn foo(j : u32) -> u32 { j }"#); | 673 | check("j", r#"fn foo(i : u32) -> u32 { i$0 }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
674 | } | 674 | } |
675 | 675 | ||
676 | #[test] | 676 | #[test] |
677 | fn test_rename_refs_for_fn_param() { | 677 | fn test_rename_refs_for_fn_param() { |
678 | check("j", r#"fn foo(i<|> : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#); | 678 | check("j", r#"fn foo(i$0 : u32) -> u32 { i }"#, r#"fn foo(j : u32) -> u32 { j }"#); |
679 | } | 679 | } |
680 | 680 | ||
681 | #[test] | 681 | #[test] |
682 | fn test_rename_for_mut_param() { | 682 | fn test_rename_for_mut_param() { |
683 | check("j", r#"fn foo(mut i<|> : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#); | 683 | check("j", r#"fn foo(mut i$0 : u32) -> u32 { i }"#, r#"fn foo(mut j : u32) -> u32 { j }"#); |
684 | } | 684 | } |
685 | 685 | ||
686 | #[test] | 686 | #[test] |
@@ -688,7 +688,7 @@ fn main() { | |||
688 | check( | 688 | check( |
689 | "j", | 689 | "j", |
690 | r#" | 690 | r#" |
691 | struct Foo { i<|>: i32 } | 691 | struct Foo { i$0: i32 } |
692 | 692 | ||
693 | impl Foo { | 693 | impl Foo { |
694 | fn new(i: i32) -> Self { | 694 | fn new(i: i32) -> Self { |
@@ -714,7 +714,7 @@ impl Foo { | |||
714 | check( | 714 | check( |
715 | "j", | 715 | "j", |
716 | r#" | 716 | r#" |
717 | struct Foo { i<|>: i32 } | 717 | struct Foo { i$0: i32 } |
718 | 718 | ||
719 | impl Foo { | 719 | impl Foo { |
720 | fn new(i: i32) -> Self { | 720 | fn new(i: i32) -> Self { |
@@ -743,7 +743,7 @@ impl Foo { | |||
743 | struct Foo { i: i32 } | 743 | struct Foo { i: i32 } |
744 | 744 | ||
745 | impl Foo { | 745 | impl Foo { |
746 | fn new(i<|>: i32) -> Self { | 746 | fn new(i$0: i32) -> Self { |
747 | Self { i } | 747 | Self { i } |
748 | } | 748 | } |
749 | } | 749 | } |
@@ -765,7 +765,7 @@ impl Foo { | |||
765 | check( | 765 | check( |
766 | "j", | 766 | "j", |
767 | r#" | 767 | r#" |
768 | struct Foo { i<|>: i32 } | 768 | struct Foo { i$0: i32 } |
769 | struct Bar { i: i32 } | 769 | struct Bar { i: i32 } |
770 | 770 | ||
771 | impl Bar { | 771 | impl Bar { |
@@ -794,7 +794,7 @@ impl Bar { | |||
794 | r#" | 794 | r#" |
795 | struct Foo { i: i32 } | 795 | struct Foo { i: i32 } |
796 | 796 | ||
797 | fn baz(i<|>: i32) -> Self { | 797 | fn baz(i$0: i32) -> Self { |
798 | let x = Foo { i }; | 798 | let x = Foo { i }; |
799 | { | 799 | { |
800 | let i = 0; | 800 | let i = 0; |
@@ -825,7 +825,7 @@ fn baz(j: i32) -> Self { | |||
825 | mod bar; | 825 | mod bar; |
826 | 826 | ||
827 | //- /bar.rs | 827 | //- /bar.rs |
828 | mod foo<|>; | 828 | mod foo$0; |
829 | 829 | ||
830 | //- /bar/foo.rs | 830 | //- /bar/foo.rs |
831 | // empty | 831 | // empty |
@@ -883,7 +883,7 @@ fn main() {} | |||
883 | pub struct FooContent; | 883 | pub struct FooContent; |
884 | 884 | ||
885 | //- /bar.rs | 885 | //- /bar.rs |
886 | use crate::foo<|>::FooContent; | 886 | use crate::foo$0::FooContent; |
887 | "#, | 887 | "#, |
888 | expect![[r#" | 888 | expect![[r#" |
889 | RangeInfo { | 889 | RangeInfo { |
@@ -943,7 +943,7 @@ use crate::foo<|>::FooContent; | |||
943 | "foo2", | 943 | "foo2", |
944 | r#" | 944 | r#" |
945 | //- /lib.rs | 945 | //- /lib.rs |
946 | mod fo<|>o; | 946 | mod fo$0o; |
947 | //- /foo/mod.rs | 947 | //- /foo/mod.rs |
948 | // emtpy | 948 | // emtpy |
949 | "#, | 949 | "#, |
@@ -992,7 +992,7 @@ mod fo<|>o; | |||
992 | "bar", | 992 | "bar", |
993 | r#" | 993 | r#" |
994 | //- /lib.rs | 994 | //- /lib.rs |
995 | mod outer { mod fo<|>o; } | 995 | mod outer { mod fo$0o; } |
996 | 996 | ||
997 | //- /outer/foo.rs | 997 | //- /outer/foo.rs |
998 | // emtpy | 998 | // emtpy |
@@ -1041,7 +1041,7 @@ mod outer { mod fo<|>o; } | |||
1041 | check( | 1041 | check( |
1042 | "baz", | 1042 | "baz", |
1043 | r#" | 1043 | r#" |
1044 | mod <|>foo { pub fn bar() {} } | 1044 | mod $0foo { pub fn bar() {} } |
1045 | 1045 | ||
1046 | fn main() { foo::bar(); } | 1046 | fn main() { foo::bar(); } |
1047 | "#, | 1047 | "#, |
@@ -1065,7 +1065,7 @@ fn f() { | |||
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | //- /bar.rs | 1067 | //- /bar.rs |
1068 | pub mod foo<|>; | 1068 | pub mod foo$0; |
1069 | 1069 | ||
1070 | //- /bar/foo.rs | 1070 | //- /bar/foo.rs |
1071 | // pub fn fun() {} | 1071 | // pub fn fun() {} |
@@ -1128,7 +1128,7 @@ pub mod foo<|>; | |||
1128 | "Baz", | 1128 | "Baz", |
1129 | r#" | 1129 | r#" |
1130 | mod foo { | 1130 | mod foo { |
1131 | pub enum Foo { Bar<|> } | 1131 | pub enum Foo { Bar$0 } |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | fn func(f: foo::Foo) { | 1134 | fn func(f: foo::Foo) { |
@@ -1157,7 +1157,7 @@ fn func(f: foo::Foo) { | |||
1157 | "baz", | 1157 | "baz", |
1158 | r#" | 1158 | r#" |
1159 | mod foo { | 1159 | mod foo { |
1160 | pub struct Foo { pub bar<|>: uint } | 1160 | pub struct Foo { pub bar$0: uint } |
1161 | } | 1161 | } |
1162 | 1162 | ||
1163 | fn foo(f: foo::Foo) { | 1163 | fn foo(f: foo::Foo) { |
@@ -1184,7 +1184,7 @@ fn foo(f: foo::Foo) { | |||
1184 | struct Foo { i: i32 } | 1184 | struct Foo { i: i32 } |
1185 | 1185 | ||
1186 | impl Foo { | 1186 | impl Foo { |
1187 | fn f(foo<|>: &mut Foo) -> i32 { | 1187 | fn f(foo$0: &mut Foo) -> i32 { |
1188 | foo.i | 1188 | foo.i |
1189 | } | 1189 | } |
1190 | } | 1190 | } |
@@ -1205,7 +1205,7 @@ impl Foo { | |||
1205 | struct Foo { i: i32 } | 1205 | struct Foo { i: i32 } |
1206 | 1206 | ||
1207 | impl Foo { | 1207 | impl Foo { |
1208 | fn f(foo<|>: Foo) -> i32 { | 1208 | fn f(foo$0: Foo) -> i32 { |
1209 | foo.i | 1209 | foo.i |
1210 | } | 1210 | } |
1211 | } | 1211 | } |
@@ -1229,7 +1229,7 @@ impl Foo { | |||
1229 | r#" | 1229 | r#" |
1230 | struct Foo { i: i32 } | 1230 | struct Foo { i: i32 } |
1231 | 1231 | ||
1232 | fn f(foo<|>: &mut Foo) -> i32 { | 1232 | fn f(foo$0: &mut Foo) -> i32 { |
1233 | foo.i | 1233 | foo.i |
1234 | } | 1234 | } |
1235 | "#, | 1235 | "#, |
@@ -1242,7 +1242,7 @@ struct Foo { i: i32 } | |||
1242 | struct Bar; | 1242 | struct Bar; |
1243 | 1243 | ||
1244 | impl Bar { | 1244 | impl Bar { |
1245 | fn f(foo<|>: &mut Foo) -> i32 { | 1245 | fn f(foo$0: &mut Foo) -> i32 { |
1246 | foo.i | 1246 | foo.i |
1247 | } | 1247 | } |
1248 | } | 1248 | } |
@@ -1258,7 +1258,7 @@ impl Bar { | |||
1258 | r#" | 1258 | r#" |
1259 | struct Foo { i: i32 } | 1259 | struct Foo { i: i32 } |
1260 | impl Foo { | 1260 | impl Foo { |
1261 | fn f(x: (), foo<|>: &mut Foo) -> i32 { | 1261 | fn f(x: (), foo$0: &mut Foo) -> i32 { |
1262 | foo.i | 1262 | foo.i |
1263 | } | 1263 | } |
1264 | } | 1264 | } |
@@ -1274,7 +1274,7 @@ impl Foo { | |||
1274 | r#" | 1274 | r#" |
1275 | struct Foo { i: i32 } | 1275 | struct Foo { i: i32 } |
1276 | impl &Foo { | 1276 | impl &Foo { |
1277 | fn f(foo<|>: &Foo) -> i32 { | 1277 | fn f(foo$0: &Foo) -> i32 { |
1278 | foo.i | 1278 | foo.i |
1279 | } | 1279 | } |
1280 | } | 1280 | } |
@@ -1298,7 +1298,7 @@ impl &Foo { | |||
1298 | struct Foo { i: i32 } | 1298 | struct Foo { i: i32 } |
1299 | 1299 | ||
1300 | impl Foo { | 1300 | impl Foo { |
1301 | fn f(&mut <|>self) -> i32 { | 1301 | fn f(&mut $0self) -> i32 { |
1302 | self.i | 1302 | self.i |
1303 | } | 1303 | } |
1304 | } | 1304 | } |
@@ -1323,7 +1323,7 @@ impl Foo { | |||
1323 | struct Foo { i: i32 } | 1323 | struct Foo { i: i32 } |
1324 | 1324 | ||
1325 | impl Foo { | 1325 | impl Foo { |
1326 | fn f(<|>self) -> i32 { | 1326 | fn f($0self) -> i32 { |
1327 | self.i | 1327 | self.i |
1328 | } | 1328 | } |
1329 | } | 1329 | } |
@@ -1350,7 +1350,7 @@ struct Foo { i: i32 } | |||
1350 | impl Foo { | 1350 | impl Foo { |
1351 | fn f(&self) -> i32 { | 1351 | fn f(&self) -> i32 { |
1352 | let self_var = 1; | 1352 | let self_var = 1; |
1353 | self<|>.i | 1353 | self$0.i |
1354 | } | 1354 | } |
1355 | } | 1355 | } |
1356 | "#, | 1356 | "#, |
@@ -1373,7 +1373,7 @@ impl Foo { | |||
1373 | check( | 1373 | check( |
1374 | "bar", | 1374 | "bar", |
1375 | r#" | 1375 | r#" |
1376 | struct Foo { i<|>: i32 } | 1376 | struct Foo { i$0: i32 } |
1377 | 1377 | ||
1378 | fn foo(bar: i32) -> Foo { | 1378 | fn foo(bar: i32) -> Foo { |
1379 | Foo { i: bar } | 1379 | Foo { i: bar } |
@@ -1394,7 +1394,7 @@ fn foo(bar: i32) -> Foo { | |||
1394 | check( | 1394 | check( |
1395 | "baz", | 1395 | "baz", |
1396 | r#" | 1396 | r#" |
1397 | struct Foo { i<|>: i32 } | 1397 | struct Foo { i$0: i32 } |
1398 | 1398 | ||
1399 | fn foo(foo: Foo) { | 1399 | fn foo(foo: Foo) { |
1400 | let Foo { i: baz } = foo; | 1400 | let Foo { i: baz } = foo; |
@@ -1433,7 +1433,7 @@ struct Foo { | |||
1433 | 1433 | ||
1434 | fn foo(foo: Foo) { | 1434 | fn foo(foo: Foo) { |
1435 | let Foo { i: b } = foo; | 1435 | let Foo { i: b } = foo; |
1436 | let _ = b<|>; | 1436 | let _ = b$0; |
1437 | } | 1437 | } |
1438 | "#, | 1438 | "#, |
1439 | expected_fixture, | 1439 | expected_fixture, |
@@ -1447,7 +1447,7 @@ struct Foo { | |||
1447 | 1447 | ||
1448 | fn foo(foo: Foo) { | 1448 | fn foo(foo: Foo) { |
1449 | let Foo { i } = foo; | 1449 | let Foo { i } = foo; |
1450 | let _ = i<|>; | 1450 | let _ = i$0; |
1451 | } | 1451 | } |
1452 | "#, | 1452 | "#, |
1453 | expected_fixture, | 1453 | expected_fixture, |
@@ -1464,7 +1464,7 @@ struct Foo { | |||
1464 | } | 1464 | } |
1465 | 1465 | ||
1466 | fn foo(Foo { i }: foo) -> i32 { | 1466 | fn foo(Foo { i }: foo) -> i32 { |
1467 | i<|> | 1467 | i$0 |
1468 | } | 1468 | } |
1469 | "#, | 1469 | "#, |
1470 | r#" | 1470 | r#" |
@@ -1488,7 +1488,7 @@ trait Foo<'a> { | |||
1488 | fn foo() -> &'a (); | 1488 | fn foo() -> &'a (); |
1489 | } | 1489 | } |
1490 | impl<'a> Foo<'a> for &'a () { | 1490 | impl<'a> Foo<'a> for &'a () { |
1491 | fn foo() -> &'a<|> () { | 1491 | fn foo() -> &'a$0 () { |
1492 | unimplemented!() | 1492 | unimplemented!() |
1493 | } | 1493 | } |
1494 | } | 1494 | } |
@@ -1520,7 +1520,7 @@ fn main() { | |||
1520 | let test_variable = CustomOption::Some(22); | 1520 | let test_variable = CustomOption::Some(22); |
1521 | 1521 | ||
1522 | match test_variable { | 1522 | match test_variable { |
1523 | CustomOption::Some(foo<|>) if foo == 11 => {} | 1523 | CustomOption::Some(foo$0) if foo == 11 => {} |
1524 | _ => (), | 1524 | _ => (), |
1525 | } | 1525 | } |
1526 | }"#, | 1526 | }"#, |
@@ -1549,7 +1549,7 @@ fn main() { | |||
1549 | fn foo<'a>() -> &'a () { | 1549 | fn foo<'a>() -> &'a () { |
1550 | 'a: { | 1550 | 'a: { |
1551 | 'b: loop { | 1551 | 'b: loop { |
1552 | break 'a<|>; | 1552 | break 'a$0; |
1553 | } | 1553 | } |
1554 | } | 1554 | } |
1555 | } | 1555 | } |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index c893afc7c..557563d7e 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -2,11 +2,11 @@ use std::fmt; | |||
2 | 2 | ||
3 | use assists::utils::test_related_attribute; | 3 | use assists::utils::test_related_attribute; |
4 | use cfg::CfgExpr; | 4 | use cfg::CfgExpr; |
5 | use hir::{AsAssocItem, HasAttrs, InFile, Semantics}; | 5 | use hir::{AsAssocItem, HasAttrs, HasSource, Semantics}; |
6 | use ide_db::RootDatabase; | 6 | use ide_db::RootDatabase; |
7 | use itertools::Itertools; | 7 | use itertools::Itertools; |
8 | use syntax::{ | 8 | use syntax::{ |
9 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | 9 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner}, |
10 | match_ast, SyntaxNode, | 10 | match_ast, SyntaxNode, |
11 | }; | 11 | }; |
12 | 12 | ||
@@ -96,17 +96,16 @@ impl Runnable { | |||
96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
97 | let sema = Semantics::new(db); | 97 | let sema = Semantics::new(db); |
98 | let source_file = sema.parse(file_id); | 98 | let source_file = sema.parse(file_id); |
99 | source_file.syntax().descendants().filter_map(|i| runnable(&sema, i, file_id)).collect() | 99 | source_file.syntax().descendants().filter_map(|i| runnable(&sema, i)).collect() |
100 | } | 100 | } |
101 | 101 | ||
102 | pub(crate) fn runnable( | 102 | pub(crate) fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
103 | sema: &Semantics<RootDatabase>, | ||
104 | item: SyntaxNode, | ||
105 | file_id: FileId, | ||
106 | ) -> Option<Runnable> { | ||
107 | let runnable_item = match_ast! { | 103 | let runnable_item = match_ast! { |
108 | match (item.clone()) { | 104 | match (item.clone()) { |
109 | ast::Fn(it) => runnable_fn(sema, it, file_id), | 105 | ast::Fn(func) => { |
106 | let def = sema.to_def(&func)?; | ||
107 | runnable_fn(sema, def) | ||
108 | }, | ||
110 | ast::Module(it) => runnable_mod(sema, it), | 109 | ast::Module(it) => runnable_mod(sema, it), |
111 | _ => None, | 110 | _ => None, |
112 | } | 111 | } |
@@ -114,23 +113,23 @@ pub(crate) fn runnable( | |||
114 | runnable_item.or_else(|| runnable_doctest(sema, item)) | 113 | runnable_item.or_else(|| runnable_doctest(sema, item)) |
115 | } | 114 | } |
116 | 115 | ||
117 | fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) -> Option<Runnable> { | 116 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { |
118 | let def = sema.to_def(&func)?; | 117 | let func = def.source(sema.db)?; |
119 | let name_string = func.name()?.text().to_string(); | 118 | let name_string = def.name(sema.db).to_string(); |
120 | 119 | ||
121 | let kind = if name_string == "main" { | 120 | let kind = if name_string == "main" { |
122 | RunnableKind::Bin | 121 | RunnableKind::Bin |
123 | } else { | 122 | } else { |
124 | let canonical_path = sema.to_def(&func).and_then(|def| { | 123 | let canonical_path = { |
125 | let def: hir::ModuleDef = def.into(); | 124 | let def: hir::ModuleDef = def.into(); |
126 | def.canonical_path(sema.db) | 125 | def.canonical_path(sema.db) |
127 | }); | 126 | }; |
128 | let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string)); | 127 | let test_id = canonical_path.map(TestId::Path).unwrap_or(TestId::Name(name_string)); |
129 | 128 | ||
130 | if test_related_attribute(&func).is_some() { | 129 | if test_related_attribute(&func.value).is_some() { |
131 | let attr = TestAttr::from_fn(&func); | 130 | let attr = TestAttr::from_fn(&func.value); |
132 | RunnableKind::Test { test_id, attr } | 131 | RunnableKind::Test { test_id, attr } |
133 | } else if func.has_atom_attr("bench") { | 132 | } else if func.value.has_atom_attr("bench") { |
134 | RunnableKind::Bench { test_id } | 133 | RunnableKind::Bench { test_id } |
135 | } else { | 134 | } else { |
136 | return None; | 135 | return None; |
@@ -139,7 +138,7 @@ fn runnable_fn(sema: &Semantics<RootDatabase>, func: ast::Fn, file_id: FileId) - | |||
139 | 138 | ||
140 | let nav = NavigationTarget::from_named( | 139 | let nav = NavigationTarget::from_named( |
141 | sema.db, | 140 | sema.db, |
142 | InFile::new(file_id.into(), &func), | 141 | func.as_ref().map(|it| it as &dyn ast::NameOwner), |
143 | SymbolKind::Function, | 142 | SymbolKind::Function, |
144 | ); | 143 | ); |
145 | let cfg = def.attrs(sema.db).cfg(); | 144 | let cfg = def.attrs(sema.db).cfg(); |
@@ -330,7 +329,7 @@ mod tests { | |||
330 | check( | 329 | check( |
331 | r#" | 330 | r#" |
332 | //- /lib.rs | 331 | //- /lib.rs |
333 | <|> | 332 | $0 |
334 | fn main() {} | 333 | fn main() {} |
335 | 334 | ||
336 | #[test] | 335 | #[test] |
@@ -426,7 +425,7 @@ fn bench() {} | |||
426 | check( | 425 | check( |
427 | r#" | 426 | r#" |
428 | //- /lib.rs | 427 | //- /lib.rs |
429 | <|> | 428 | $0 |
430 | fn main() {} | 429 | fn main() {} |
431 | 430 | ||
432 | /// ``` | 431 | /// ``` |
@@ -574,7 +573,7 @@ struct StructWithRunnable(String); | |||
574 | check( | 573 | check( |
575 | r#" | 574 | r#" |
576 | //- /lib.rs | 575 | //- /lib.rs |
577 | <|> | 576 | $0 |
578 | fn main() {} | 577 | fn main() {} |
579 | 578 | ||
580 | struct Data; | 579 | struct Data; |
@@ -626,7 +625,7 @@ impl Data { | |||
626 | check( | 625 | check( |
627 | r#" | 626 | r#" |
628 | //- /lib.rs | 627 | //- /lib.rs |
629 | <|> | 628 | $0 |
630 | mod test_mod { | 629 | mod test_mod { |
631 | #[test] | 630 | #[test] |
632 | fn test_foo1() {} | 631 | fn test_foo1() {} |
@@ -680,7 +679,7 @@ mod test_mod { | |||
680 | check( | 679 | check( |
681 | r#" | 680 | r#" |
682 | //- /lib.rs | 681 | //- /lib.rs |
683 | <|> | 682 | $0 |
684 | mod root_tests { | 683 | mod root_tests { |
685 | mod nested_tests_0 { | 684 | mod nested_tests_0 { |
686 | mod nested_tests_1 { | 685 | mod nested_tests_1 { |
@@ -820,7 +819,7 @@ mod root_tests { | |||
820 | check( | 819 | check( |
821 | r#" | 820 | r#" |
822 | //- /lib.rs crate:foo cfg:feature=foo | 821 | //- /lib.rs crate:foo cfg:feature=foo |
823 | <|> | 822 | $0 |
824 | #[test] | 823 | #[test] |
825 | #[cfg(feature = "foo")] | 824 | #[cfg(feature = "foo")] |
826 | fn test_foo1() {} | 825 | fn test_foo1() {} |
@@ -865,7 +864,7 @@ fn test_foo1() {} | |||
865 | check( | 864 | check( |
866 | r#" | 865 | r#" |
867 | //- /lib.rs crate:foo cfg:feature=foo,feature=bar | 866 | //- /lib.rs crate:foo cfg:feature=foo,feature=bar |
868 | <|> | 867 | $0 |
869 | #[test] | 868 | #[test] |
870 | #[cfg(all(feature = "foo", feature = "bar"))] | 869 | #[cfg(all(feature = "foo", feature = "bar"))] |
871 | fn test_foo1() {} | 870 | fn test_foo1() {} |
@@ -920,7 +919,7 @@ fn test_foo1() {} | |||
920 | check( | 919 | check( |
921 | r#" | 920 | r#" |
922 | //- /lib.rs | 921 | //- /lib.rs |
923 | <|> | 922 | $0 |
924 | mod test_mod { | 923 | mod test_mod { |
925 | fn foo1() {} | 924 | fn foo1() {} |
926 | } | 925 | } |
@@ -939,7 +938,7 @@ mod test_mod { | |||
939 | //- /lib.rs | 938 | //- /lib.rs |
940 | mod foo; | 939 | mod foo; |
941 | //- /foo.rs | 940 | //- /foo.rs |
942 | struct Foo;<|> | 941 | struct Foo;$0 |
943 | impl Foo { | 942 | impl Foo { |
944 | /// ``` | 943 | /// ``` |
945 | /// let x = 5; | 944 | /// let x = 5; |
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/injection.rs index 6cbd683c6..d6be9708d 100644 --- a/crates/ide/src/syntax_highlighting/injection.rs +++ b/crates/ide/src/syntax_highlighting/injection.rs | |||
@@ -22,7 +22,8 @@ pub(super) fn highlight_injection( | |||
22 | return None; | 22 | return None; |
23 | } | 23 | } |
24 | let value = literal.value()?; | 24 | let value = literal.value()?; |
25 | let (analysis, tmp_file_id) = Analysis::from_single_file(value.into_owned()); | 25 | let marker_info = MarkerInfo::new(&*value); |
26 | let (analysis, tmp_file_id) = Analysis::from_single_file(marker_info.cleaned_text.clone()); | ||
26 | 27 | ||
27 | if let Some(range) = literal.open_quote_text_range() { | 28 | if let Some(range) = literal.open_quote_text_range() { |
28 | acc.add(HighlightedRange { | 29 | acc.add(HighlightedRange { |
@@ -33,9 +34,10 @@ pub(super) fn highlight_injection( | |||
33 | } | 34 | } |
34 | 35 | ||
35 | for mut h in analysis.highlight(tmp_file_id).unwrap() { | 36 | for mut h in analysis.highlight(tmp_file_id).unwrap() { |
36 | if let Some(r) = literal.map_range_up(h.range) { | 37 | let range = marker_info.map_range_up(h.range); |
37 | h.range = r; | 38 | if let Some(range) = literal.map_range_up(range) { |
38 | acc.add(h) | 39 | h.range = range; |
40 | acc.add(h); | ||
39 | } | 41 | } |
40 | } | 42 | } |
41 | 43 | ||
@@ -50,6 +52,52 @@ pub(super) fn highlight_injection( | |||
50 | Some(()) | 52 | Some(()) |
51 | } | 53 | } |
52 | 54 | ||
55 | /// Data to remove `$0` from string and map ranges | ||
56 | #[derive(Default, Debug)] | ||
57 | struct MarkerInfo { | ||
58 | cleaned_text: String, | ||
59 | markers: Vec<TextRange>, | ||
60 | } | ||
61 | |||
62 | impl MarkerInfo { | ||
63 | fn new(mut text: &str) -> Self { | ||
64 | let marker = "$0"; | ||
65 | |||
66 | let mut res = MarkerInfo::default(); | ||
67 | let mut offset: TextSize = 0.into(); | ||
68 | while !text.is_empty() { | ||
69 | let idx = text.find(marker).unwrap_or(text.len()); | ||
70 | let (chunk, next) = text.split_at(idx); | ||
71 | text = next; | ||
72 | res.cleaned_text.push_str(chunk); | ||
73 | offset += TextSize::of(chunk); | ||
74 | |||
75 | if let Some(next) = text.strip_prefix(marker) { | ||
76 | text = next; | ||
77 | |||
78 | let marker_len = TextSize::of(marker); | ||
79 | res.markers.push(TextRange::at(offset, marker_len)); | ||
80 | offset += marker_len; | ||
81 | } | ||
82 | } | ||
83 | res | ||
84 | } | ||
85 | fn map_range_up(&self, range: TextRange) -> TextRange { | ||
86 | TextRange::new( | ||
87 | self.map_offset_up(range.start(), true), | ||
88 | self.map_offset_up(range.end(), false), | ||
89 | ) | ||
90 | } | ||
91 | fn map_offset_up(&self, mut offset: TextSize, start: bool) -> TextSize { | ||
92 | for r in &self.markers { | ||
93 | if r.start() < offset || (start && r.start() == offset) { | ||
94 | offset += r.len() | ||
95 | } | ||
96 | } | ||
97 | offset | ||
98 | } | ||
99 | } | ||
100 | |||
53 | /// Mapping from extracted documentation code to original code | 101 | /// Mapping from extracted documentation code to original code |
54 | type RangesMap = BTreeMap<TextSize, TextSize>; | 102 | type RangesMap = BTreeMap<TextSize, TextSize>; |
55 | 103 | ||
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html new file mode 100644 index 000000000..a54d303b4 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/test_data/injection.html | |||
@@ -0,0 +1,48 @@ | |||
1 | |||
2 | <style> | ||
3 | body { margin: 0; } | ||
4 | pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; } | ||
5 | |||
6 | .lifetime { color: #DFAF8F; font-style: italic; } | ||
7 | .label { color: #DFAF8F; font-style: italic; } | ||
8 | .comment { color: #7F9F7F; } | ||
9 | .documentation { color: #629755; } | ||
10 | .injected { opacity: 0.65 ; } | ||
11 | .struct, .enum { color: #7CB8BB; } | ||
12 | .enum_variant { color: #BDE0F3; } | ||
13 | .string_literal { color: #CC9393; } | ||
14 | .field { color: #94BFF3; } | ||
15 | .function { color: #93E0E3; } | ||
16 | .function.unsafe { color: #BC8383; } | ||
17 | .operator.unsafe { color: #BC8383; } | ||
18 | .parameter { color: #94BFF3; } | ||
19 | .text { color: #DCDCCC; } | ||
20 | .type { color: #7CB8BB; } | ||
21 | .builtin_type { color: #8CD0D3; } | ||
22 | .type_param { color: #DFAF8F; } | ||
23 | .attribute { color: #94BFF3; } | ||
24 | .numeric_literal { color: #BFEBBF; } | ||
25 | .bool_literal { color: #BFE6EB; } | ||
26 | .macro { color: #94BFF3; } | ||
27 | .module { color: #AFD8AF; } | ||
28 | .value_param { color: #DCDCCC; } | ||
29 | .variable { color: #DCDCCC; } | ||
30 | .format_specifier { color: #CC696B; } | ||
31 | .mutable { text-decoration: underline; } | ||
32 | .escape_sequence { color: #94BFF3; } | ||
33 | .keyword { color: #F0DFAF; font-weight: bold; } | ||
34 | .keyword.unsafe { color: #BC8383; font-weight: bold; } | ||
35 | .control { font-style: italic; } | ||
36 | |||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | ||
38 | </style> | ||
39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">f</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | ||
40 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | ||
41 | <span class="function">f</span><span class="punctuation">(</span><span class="string_literal">r"</span> | ||
42 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | ||
43 | <span class="function">foo</span><span class="punctuation">(</span>$0<span class="punctuation">{</span> | ||
44 | <span class="numeric_literal">92</span> | ||
45 | <span class="punctuation">}</span>$0<span class="punctuation">)</span> | ||
46 | <span class="punctuation">}</span><span class="string_literal">"</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
47 | <span class="punctuation">}</span> | ||
48 | </code></pre> \ No newline at end of file | ||
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 30b5b648e..9e1a3974c 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -555,6 +555,25 @@ impl t for foo { | |||
555 | ) | 555 | ) |
556 | } | 556 | } |
557 | 557 | ||
558 | #[test] | ||
559 | fn test_injection() { | ||
560 | check_highlighting( | ||
561 | r##" | ||
562 | fn f(ra_fixture: &str) {} | ||
563 | fn main() { | ||
564 | f(r" | ||
565 | fn foo() { | ||
566 | foo(\$0{ | ||
567 | 92 | ||
568 | }\$0) | ||
569 | }"); | ||
570 | } | ||
571 | "##, | ||
572 | expect_file!["./test_data/injection.html"], | ||
573 | false, | ||
574 | ); | ||
575 | } | ||
576 | |||
558 | /// Highlights the code given by the `ra_fixture` argument, renders the | 577 | /// Highlights the code given by the `ra_fixture` argument, renders the |
559 | /// result as HTML, and compares it with the HTML file given as `snapshot`. | 578 | /// result as HTML, and compares it with the HTML file given as `snapshot`. |
560 | /// Note that the `snapshot` file is overwritten by the rendered HTML. | 579 | /// Note that the `snapshot` file is overwritten by the rendered HTML. |
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index 6dd05c05d..1f26f8043 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs | |||
@@ -85,7 +85,7 @@ fn syntax_tree_for_token(node: &SyntaxToken, text_range: TextRange) -> Option<St | |||
85 | .trim_end_matches('"') | 85 | .trim_end_matches('"') |
86 | .trim() | 86 | .trim() |
87 | // Remove custom markers | 87 | // Remove custom markers |
88 | .replace("<|>", ""); | 88 | .replace("$0", ""); |
89 | 89 | ||
90 | let parsed = SourceFile::parse(&text); | 90 | let parsed = SourceFile::parse(&text); |
91 | 91 | ||
@@ -182,7 +182,7 @@ [email protected] | |||
182 | 182 | ||
183 | #[test] | 183 | #[test] |
184 | fn test_syntax_tree_with_range() { | 184 | fn test_syntax_tree_with_range() { |
185 | let (analysis, range) = fixture::range(r#"<|>fn foo() {}<|>"#.trim()); | 185 | let (analysis, range) = fixture::range(r#"$0fn foo() {}$0"#.trim()); |
186 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); | 186 | let syn = analysis.syntax_tree(range.file_id, Some(range.range)).unwrap(); |
187 | 187 | ||
188 | assert_eq_text!( | 188 | assert_eq_text!( |
@@ -206,10 +206,10 @@ [email protected] | |||
206 | 206 | ||
207 | let (analysis, range) = fixture::range( | 207 | let (analysis, range) = fixture::range( |
208 | r#"fn test() { | 208 | r#"fn test() { |
209 | <|>assert!(" | 209 | $0assert!(" |
210 | fn foo() { | 210 | fn foo() { |
211 | } | 211 | } |
212 | ", "");<|> | 212 | ", "");$0 |
213 | }"# | 213 | }"# |
214 | .trim(), | 214 | .trim(), |
215 | ); | 215 | ); |
@@ -243,8 +243,8 @@ [email protected] | |||
243 | let (analysis, range) = fixture::range( | 243 | let (analysis, range) = fixture::range( |
244 | r#"fn test() { | 244 | r#"fn test() { |
245 | assert!(" | 245 | assert!(" |
246 | <|>fn foo() { | 246 | $0fn foo() { |
247 | }<|> | 247 | }$0 |
248 | fn bar() { | 248 | fn bar() { |
249 | } | 249 | } |
250 | ", ""); | 250 | ", ""); |
@@ -277,8 +277,8 @@ [email protected] | |||
277 | let (analysis, range) = fixture::range( | 277 | let (analysis, range) = fixture::range( |
278 | r###"fn test() { | 278 | r###"fn test() { |
279 | assert!(r#" | 279 | assert!(r#" |
280 | <|>fn foo() { | 280 | $0fn foo() { |
281 | }<|> | 281 | }$0 |
282 | fn bar() { | 282 | fn bar() { |
283 | } | 283 | } |
284 | "#, ""); | 284 | "#, ""); |
@@ -310,11 +310,11 @@ [email protected] | |||
310 | // With a raw string | 310 | // With a raw string |
311 | let (analysis, range) = fixture::range( | 311 | let (analysis, range) = fixture::range( |
312 | r###"fn test() { | 312 | r###"fn test() { |
313 | assert!(r<|>#" | 313 | assert!(r$0#" |
314 | fn foo() { | 314 | fn foo() { |
315 | } | 315 | } |
316 | fn bar() { | 316 | fn bar() { |
317 | }"<|>#, ""); | 317 | }"$0#, ""); |
318 | }"### | 318 | }"### |
319 | .trim(), | 319 | .trim(), |
320 | ); | 320 | ); |
diff --git a/crates/ide/src/typing.rs b/crates/ide/src/typing.rs index 43458a3a2..88c905003 100644 --- a/crates/ide/src/typing.rs +++ b/crates/ide/src/typing.rs | |||
@@ -170,7 +170,7 @@ mod tests { | |||
170 | fn test_on_eq_typed() { | 170 | fn test_on_eq_typed() { |
171 | // do_check(r" | 171 | // do_check(r" |
172 | // fn foo() { | 172 | // fn foo() { |
173 | // let foo =<|> | 173 | // let foo =$0 |
174 | // } | 174 | // } |
175 | // ", r" | 175 | // ", r" |
176 | // fn foo() { | 176 | // fn foo() { |
@@ -181,7 +181,7 @@ mod tests { | |||
181 | '=', | 181 | '=', |
182 | r" | 182 | r" |
183 | fn foo() { | 183 | fn foo() { |
184 | let foo <|> 1 + 1 | 184 | let foo $0 1 + 1 |
185 | } | 185 | } |
186 | ", | 186 | ", |
187 | r" | 187 | r" |
@@ -192,7 +192,7 @@ fn foo() { | |||
192 | ); | 192 | ); |
193 | // do_check(r" | 193 | // do_check(r" |
194 | // fn foo() { | 194 | // fn foo() { |
195 | // let foo =<|> | 195 | // let foo =$0 |
196 | // let bar = 1; | 196 | // let bar = 1; |
197 | // } | 197 | // } |
198 | // ", r" | 198 | // ", r" |
@@ -210,7 +210,7 @@ fn foo() { | |||
210 | r" | 210 | r" |
211 | fn main() { | 211 | fn main() { |
212 | xs.foo() | 212 | xs.foo() |
213 | <|> | 213 | $0 |
214 | } | 214 | } |
215 | ", | 215 | ", |
216 | r" | 216 | r" |
@@ -225,7 +225,7 @@ fn foo() { | |||
225 | r" | 225 | r" |
226 | fn main() { | 226 | fn main() { |
227 | xs.foo() | 227 | xs.foo() |
228 | <|> | 228 | $0 |
229 | } | 229 | } |
230 | ", | 230 | ", |
231 | ) | 231 | ) |
@@ -238,7 +238,7 @@ fn foo() { | |||
238 | r" | 238 | r" |
239 | fn main() { | 239 | fn main() { |
240 | xs.foo() | 240 | xs.foo() |
241 | <|>; | 241 | $0; |
242 | } | 242 | } |
243 | ", | 243 | ", |
244 | r" | 244 | r" |
@@ -253,7 +253,7 @@ fn foo() { | |||
253 | r" | 253 | r" |
254 | fn main() { | 254 | fn main() { |
255 | xs.foo() | 255 | xs.foo() |
256 | <|>; | 256 | $0; |
257 | } | 257 | } |
258 | ", | 258 | ", |
259 | ) | 259 | ) |
@@ -266,7 +266,7 @@ fn foo() { | |||
266 | r#" | 266 | r#" |
267 | fn main() { | 267 | fn main() { |
268 | let _ = foo | 268 | let _ = foo |
269 | <|> | 269 | $0 |
270 | bar() | 270 | bar() |
271 | } | 271 | } |
272 | "#, | 272 | "#, |
@@ -288,7 +288,7 @@ fn main() { | |||
288 | fn main() { | 288 | fn main() { |
289 | xs.foo() | 289 | xs.foo() |
290 | .first() | 290 | .first() |
291 | <|> | 291 | $0 |
292 | } | 292 | } |
293 | ", | 293 | ", |
294 | r" | 294 | r" |
@@ -305,7 +305,7 @@ fn main() { | |||
305 | fn main() { | 305 | fn main() { |
306 | xs.foo() | 306 | xs.foo() |
307 | .first() | 307 | .first() |
308 | <|> | 308 | $0 |
309 | } | 309 | } |
310 | ", | 310 | ", |
311 | ); | 311 | ); |
@@ -318,7 +318,7 @@ fn main() { | |||
318 | r" | 318 | r" |
319 | fn source_impl() { | 319 | fn source_impl() { |
320 | let var = enum_defvariant_list().unwrap() | 320 | let var = enum_defvariant_list().unwrap() |
321 | <|> | 321 | $0 |
322 | .nth(92) | 322 | .nth(92) |
323 | .unwrap(); | 323 | .unwrap(); |
324 | } | 324 | } |
@@ -337,7 +337,7 @@ fn main() { | |||
337 | r" | 337 | r" |
338 | fn source_impl() { | 338 | fn source_impl() { |
339 | let var = enum_defvariant_list().unwrap() | 339 | let var = enum_defvariant_list().unwrap() |
340 | <|> | 340 | $0 |
341 | .nth(92) | 341 | .nth(92) |
342 | .unwrap(); | 342 | .unwrap(); |
343 | } | 343 | } |
@@ -351,7 +351,7 @@ fn main() { | |||
351 | '.', | 351 | '.', |
352 | r" | 352 | r" |
353 | fn main() { | 353 | fn main() { |
354 | <|> | 354 | $0 |
355 | } | 355 | } |
356 | ", | 356 | ", |
357 | ); | 357 | ); |
@@ -359,7 +359,7 @@ fn main() { | |||
359 | '.', | 359 | '.', |
360 | r" | 360 | r" |
361 | fn main() { | 361 | fn main() { |
362 | <|> | 362 | $0 |
363 | } | 363 | } |
364 | ", | 364 | ", |
365 | ); | 365 | ); |
@@ -367,6 +367,6 @@ fn main() { | |||
367 | 367 | ||
368 | #[test] | 368 | #[test] |
369 | fn adds_space_after_return_type() { | 369 | fn adds_space_after_return_type() { |
370 | type_char('>', "fn foo() -<|>{ 92 }", "fn foo() -> { 92 }") | 370 | type_char('>', "fn foo() -$0{ 92 }", "fn foo() -> { 92 }") |
371 | } | 371 | } |
372 | } | 372 | } |
diff --git a/crates/ide/src/typing/on_enter.rs b/crates/ide/src/typing/on_enter.rs index f4ea30352..63cd51b69 100644 --- a/crates/ide/src/typing/on_enter.rs +++ b/crates/ide/src/typing/on_enter.rs | |||
@@ -136,7 +136,7 @@ mod tests { | |||
136 | fn continues_doc_comment() { | 136 | fn continues_doc_comment() { |
137 | do_check( | 137 | do_check( |
138 | r" | 138 | r" |
139 | /// Some docs<|> | 139 | /// Some docs$0 |
140 | fn foo() { | 140 | fn foo() { |
141 | } | 141 | } |
142 | ", | 142 | ", |
@@ -151,7 +151,7 @@ fn foo() { | |||
151 | do_check( | 151 | do_check( |
152 | r" | 152 | r" |
153 | impl S { | 153 | impl S { |
154 | /// Some<|> docs. | 154 | /// Some$0 docs. |
155 | fn foo() {} | 155 | fn foo() {} |
156 | } | 156 | } |
157 | ", | 157 | ", |
@@ -166,7 +166,7 @@ impl S { | |||
166 | 166 | ||
167 | do_check( | 167 | do_check( |
168 | r" | 168 | r" |
169 | ///<|> Some docs | 169 | ///$0 Some docs |
170 | fn foo() { | 170 | fn foo() { |
171 | } | 171 | } |
172 | ", | 172 | ", |
@@ -181,7 +181,7 @@ fn foo() { | |||
181 | 181 | ||
182 | #[test] | 182 | #[test] |
183 | fn does_not_continue_before_doc_comment() { | 183 | fn does_not_continue_before_doc_comment() { |
184 | do_check_noop(r"<|>//! docz"); | 184 | do_check_noop(r"$0//! docz"); |
185 | } | 185 | } |
186 | 186 | ||
187 | #[test] | 187 | #[test] |
@@ -189,7 +189,7 @@ fn foo() { | |||
189 | do_check( | 189 | do_check( |
190 | r" | 190 | r" |
191 | fn main() { | 191 | fn main() { |
192 | // Fix<|> me | 192 | // Fix$0 me |
193 | let x = 1 + 1; | 193 | let x = 1 + 1; |
194 | } | 194 | } |
195 | ", | 195 | ", |
@@ -208,7 +208,7 @@ fn main() { | |||
208 | do_check( | 208 | do_check( |
209 | r" | 209 | r" |
210 | fn main() { | 210 | fn main() { |
211 | // Fix<|> | 211 | // Fix$0 |
212 | // me | 212 | // me |
213 | let x = 1 + 1; | 213 | let x = 1 + 1; |
214 | } | 214 | } |
@@ -229,7 +229,7 @@ fn main() { | |||
229 | do_check_noop( | 229 | do_check_noop( |
230 | r" | 230 | r" |
231 | fn main() { | 231 | fn main() { |
232 | // Fix me<|> | 232 | // Fix me$0 |
233 | let x = 1 + 1; | 233 | let x = 1 + 1; |
234 | } | 234 | } |
235 | ", | 235 | ", |
@@ -242,7 +242,7 @@ fn main() { | |||
242 | do_check( | 242 | do_check( |
243 | r#" | 243 | r#" |
244 | fn main() { | 244 | fn main() { |
245 | // Fix me <|> | 245 | // Fix me $0 |
246 | let x = 1 + 1; | 246 | let x = 1 + 1; |
247 | } | 247 | } |
248 | "#, | 248 | "#, |
@@ -261,7 +261,7 @@ fn main() { | |||
261 | do_check( | 261 | do_check( |
262 | " | 262 | " |
263 | fn main() { | 263 | fn main() { |
264 | // Fix me \t\t <|> | 264 | // Fix me \t\t $0 |
265 | let x = 1 + 1; | 265 | let x = 1 + 1; |
266 | } | 266 | } |
267 | ", | 267 | ", |
diff --git a/crates/ide_db/Cargo.toml b/crates/ide_db/Cargo.toml index ebe53c8ee..d3d3dc688 100644 --- a/crates/ide_db/Cargo.toml +++ b/crates/ide_db/Cargo.toml | |||
@@ -32,4 +32,4 @@ test_utils = { path = "../test_utils", version = "0.0.0" } | |||
32 | hir = { path = "../hir", version = "0.0.0" } | 32 | hir = { path = "../hir", version = "0.0.0" } |
33 | 33 | ||
34 | [dev-dependencies] | 34 | [dev-dependencies] |
35 | expect-test = "1.0" | 35 | expect-test = "1.1" |
diff --git a/crates/ide_db/src/call_info/tests.rs b/crates/ide_db/src/call_info/tests.rs index 9335aeaa5..c714cf280 100644 --- a/crates/ide_db/src/call_info/tests.rs +++ b/crates/ide_db/src/call_info/tests.rs | |||
@@ -3,12 +3,12 @@ use base_db::{fixture::ChangeFixture, FilePosition}; | |||
3 | use expect_test::{expect, Expect}; | 3 | use expect_test::{expect, Expect}; |
4 | use test_utils::{mark, RangeOrOffset}; | 4 | use test_utils::{mark, RangeOrOffset}; |
5 | 5 | ||
6 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | 6 | /// Creates analysis from a multi-file fixture, returns positions marked with $0. |
7 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | 7 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { |
8 | let change_fixture = ChangeFixture::parse(ra_fixture); | 8 | let change_fixture = ChangeFixture::parse(ra_fixture); |
9 | let mut database = RootDatabase::default(); | 9 | let mut database = RootDatabase::default(); |
10 | database.apply_change(change_fixture.change); | 10 | database.apply_change(change_fixture.change); |
11 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 11 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
12 | let offset = match range_or_offset { | 12 | let offset = match range_or_offset { |
13 | RangeOrOffset::Range(_) => panic!(), | 13 | RangeOrOffset::Range(_) => panic!(), |
14 | RangeOrOffset::Offset(it) => it, | 14 | RangeOrOffset::Offset(it) => it, |
@@ -49,7 +49,7 @@ fn test_fn_signature_two_args() { | |||
49 | check( | 49 | check( |
50 | r#" | 50 | r#" |
51 | fn foo(x: u32, y: u32) -> u32 {x + y} | 51 | fn foo(x: u32, y: u32) -> u32 {x + y} |
52 | fn bar() { foo(<|>3, ); } | 52 | fn bar() { foo($03, ); } |
53 | "#, | 53 | "#, |
54 | expect![[r#" | 54 | expect![[r#" |
55 | fn foo(x: u32, y: u32) -> u32 | 55 | fn foo(x: u32, y: u32) -> u32 |
@@ -59,7 +59,7 @@ fn bar() { foo(<|>3, ); } | |||
59 | check( | 59 | check( |
60 | r#" | 60 | r#" |
61 | fn foo(x: u32, y: u32) -> u32 {x + y} | 61 | fn foo(x: u32, y: u32) -> u32 {x + y} |
62 | fn bar() { foo(3<|>, ); } | 62 | fn bar() { foo(3$0, ); } |
63 | "#, | 63 | "#, |
64 | expect![[r#" | 64 | expect![[r#" |
65 | fn foo(x: u32, y: u32) -> u32 | 65 | fn foo(x: u32, y: u32) -> u32 |
@@ -69,7 +69,7 @@ fn bar() { foo(3<|>, ); } | |||
69 | check( | 69 | check( |
70 | r#" | 70 | r#" |
71 | fn foo(x: u32, y: u32) -> u32 {x + y} | 71 | fn foo(x: u32, y: u32) -> u32 {x + y} |
72 | fn bar() { foo(3,<|> ); } | 72 | fn bar() { foo(3,$0 ); } |
73 | "#, | 73 | "#, |
74 | expect![[r#" | 74 | expect![[r#" |
75 | fn foo(x: u32, y: u32) -> u32 | 75 | fn foo(x: u32, y: u32) -> u32 |
@@ -79,7 +79,7 @@ fn bar() { foo(3,<|> ); } | |||
79 | check( | 79 | check( |
80 | r#" | 80 | r#" |
81 | fn foo(x: u32, y: u32) -> u32 {x + y} | 81 | fn foo(x: u32, y: u32) -> u32 {x + y} |
82 | fn bar() { foo(3, <|>); } | 82 | fn bar() { foo(3, $0); } |
83 | "#, | 83 | "#, |
84 | expect![[r#" | 84 | expect![[r#" |
85 | fn foo(x: u32, y: u32) -> u32 | 85 | fn foo(x: u32, y: u32) -> u32 |
@@ -93,7 +93,7 @@ fn test_fn_signature_two_args_empty() { | |||
93 | check( | 93 | check( |
94 | r#" | 94 | r#" |
95 | fn foo(x: u32, y: u32) -> u32 {x + y} | 95 | fn foo(x: u32, y: u32) -> u32 {x + y} |
96 | fn bar() { foo(<|>); } | 96 | fn bar() { foo($0); } |
97 | "#, | 97 | "#, |
98 | expect![[r#" | 98 | expect![[r#" |
99 | fn foo(x: u32, y: u32) -> u32 | 99 | fn foo(x: u32, y: u32) -> u32 |
@@ -110,7 +110,7 @@ fn foo<T, U: Copy + Display>(x: T, y: U) -> u32 | |||
110 | where T: Copy + Display, U: Debug | 110 | where T: Copy + Display, U: Debug |
111 | { x + y } | 111 | { x + y } |
112 | 112 | ||
113 | fn bar() { foo(<|>3, ); } | 113 | fn bar() { foo($03, ); } |
114 | "#, | 114 | "#, |
115 | expect![[r#" | 115 | expect![[r#" |
116 | fn foo(x: i32, y: {unknown}) -> u32 | 116 | fn foo(x: i32, y: {unknown}) -> u32 |
@@ -124,7 +124,7 @@ fn test_fn_signature_no_params() { | |||
124 | check( | 124 | check( |
125 | r#" | 125 | r#" |
126 | fn foo<T>() -> T where T: Copy + Display {} | 126 | fn foo<T>() -> T where T: Copy + Display {} |
127 | fn bar() { foo(<|>); } | 127 | fn bar() { foo($0); } |
128 | "#, | 128 | "#, |
129 | expect![[r#" | 129 | expect![[r#" |
130 | fn foo() -> {unknown} | 130 | fn foo() -> {unknown} |
@@ -140,7 +140,7 @@ fn test_fn_signature_for_impl() { | |||
140 | struct F; | 140 | struct F; |
141 | impl F { pub fn new() { } } | 141 | impl F { pub fn new() { } } |
142 | fn bar() { | 142 | fn bar() { |
143 | let _ : F = F::new(<|>); | 143 | let _ : F = F::new($0); |
144 | } | 144 | } |
145 | "#, | 145 | "#, |
146 | expect![[r#" | 146 | expect![[r#" |
@@ -159,7 +159,7 @@ impl S { pub fn do_it(&self) {} } | |||
159 | 159 | ||
160 | fn bar() { | 160 | fn bar() { |
161 | let s: S = S; | 161 | let s: S = S; |
162 | s.do_it(<|>); | 162 | s.do_it($0); |
163 | } | 163 | } |
164 | "#, | 164 | "#, |
165 | expect![[r#" | 165 | expect![[r#" |
@@ -178,7 +178,7 @@ impl S { | |||
178 | fn foo(&self, x: i32) {} | 178 | fn foo(&self, x: i32) {} |
179 | } | 179 | } |
180 | 180 | ||
181 | fn main() { S.foo(<|>); } | 181 | fn main() { S.foo($0); } |
182 | "#, | 182 | "#, |
183 | expect![[r#" | 183 | expect![[r#" |
184 | fn foo(&self, x: i32) | 184 | fn foo(&self, x: i32) |
@@ -196,7 +196,7 @@ impl S { | |||
196 | fn foo(&self, x: i32) {} | 196 | fn foo(&self, x: i32) {} |
197 | } | 197 | } |
198 | 198 | ||
199 | fn main() { S::foo(<|>); } | 199 | fn main() { S::foo($0); } |
200 | "#, | 200 | "#, |
201 | expect![[r#" | 201 | expect![[r#" |
202 | fn foo(self: &S, x: i32) | 202 | fn foo(self: &S, x: i32) |
@@ -216,7 +216,7 @@ fn foo(j: u32) -> u32 { | |||
216 | } | 216 | } |
217 | 217 | ||
218 | fn bar() { | 218 | fn bar() { |
219 | let _ = foo(<|>); | 219 | let _ = foo($0); |
220 | } | 220 | } |
221 | "#, | 221 | "#, |
222 | expect![[r#" | 222 | expect![[r#" |
@@ -246,7 +246,7 @@ pub fn add_one(x: i32) -> i32 { | |||
246 | } | 246 | } |
247 | 247 | ||
248 | pub fn do() { | 248 | pub fn do() { |
249 | add_one(<|> | 249 | add_one($0 |
250 | }"#, | 250 | }"#, |
251 | expect![[r##" | 251 | expect![[r##" |
252 | Adds one to the number given. | 252 | Adds one to the number given. |
@@ -287,7 +287,7 @@ impl addr { | |||
287 | 287 | ||
288 | pub fn do_it() { | 288 | pub fn do_it() { |
289 | addr {}; | 289 | addr {}; |
290 | addr::add_one(<|>); | 290 | addr::add_one($0); |
291 | } | 291 | } |
292 | "#, | 292 | "#, |
293 | expect![[r##" | 293 | expect![[r##" |
@@ -331,7 +331,7 @@ impl<E> WriteHandler<E> { | |||
331 | } | 331 | } |
332 | 332 | ||
333 | pub fn foo(mut r: WriteHandler<()>) { | 333 | pub fn foo(mut r: WriteHandler<()>) { |
334 | r.finished(<|>); | 334 | r.finished($0); |
335 | } | 335 | } |
336 | "#, | 336 | "#, |
337 | expect![[r#" | 337 | expect![[r#" |
@@ -351,7 +351,7 @@ fn call_info_bad_offset() { | |||
351 | check( | 351 | check( |
352 | r#" | 352 | r#" |
353 | fn foo(x: u32, y: u32) -> u32 {x + y} | 353 | fn foo(x: u32, y: u32) -> u32 {x + y} |
354 | fn bar() { foo <|> (3, ); } | 354 | fn bar() { foo $0 (3, ); } |
355 | "#, | 355 | "#, |
356 | expect![[""]], | 356 | expect![[""]], |
357 | ); | 357 | ); |
@@ -368,7 +368,7 @@ fn bar(_: u32) { } | |||
368 | 368 | ||
369 | fn main() { | 369 | fn main() { |
370 | let foo = Foo; | 370 | let foo = Foo; |
371 | std::thread::spawn(move || foo.bar(<|>)); | 371 | std::thread::spawn(move || foo.bar($0)); |
372 | } | 372 | } |
373 | "#, | 373 | "#, |
374 | expect![[r#" | 374 | expect![[r#" |
@@ -385,7 +385,7 @@ fn works_for_tuple_structs() { | |||
385 | /// A cool tuple struct | 385 | /// A cool tuple struct |
386 | struct S(u32, i32); | 386 | struct S(u32, i32); |
387 | fn main() { | 387 | fn main() { |
388 | let s = S(0, <|>); | 388 | let s = S(0, $0); |
389 | } | 389 | } |
390 | "#, | 390 | "#, |
391 | expect![[r#" | 391 | expect![[r#" |
@@ -403,7 +403,7 @@ fn generic_struct() { | |||
403 | r#" | 403 | r#" |
404 | struct S<T>(T); | 404 | struct S<T>(T); |
405 | fn main() { | 405 | fn main() { |
406 | let s = S(<|>); | 406 | let s = S($0); |
407 | } | 407 | } |
408 | "#, | 408 | "#, |
409 | expect![[r#" | 409 | expect![[r#" |
@@ -427,7 +427,7 @@ enum E { | |||
427 | } | 427 | } |
428 | 428 | ||
429 | fn main() { | 429 | fn main() { |
430 | let a = E::A(<|>); | 430 | let a = E::A($0); |
431 | } | 431 | } |
432 | "#, | 432 | "#, |
433 | expect![[r#" | 433 | expect![[r#" |
@@ -445,7 +445,7 @@ fn cant_call_struct_record() { | |||
445 | r#" | 445 | r#" |
446 | struct S { x: u32, y: i32 } | 446 | struct S { x: u32, y: i32 } |
447 | fn main() { | 447 | fn main() { |
448 | let s = S(<|>); | 448 | let s = S($0); |
449 | } | 449 | } |
450 | "#, | 450 | "#, |
451 | expect![[""]], | 451 | expect![[""]], |
@@ -466,7 +466,7 @@ enum E { | |||
466 | } | 466 | } |
467 | 467 | ||
468 | fn main() { | 468 | fn main() { |
469 | let a = E::C(<|>); | 469 | let a = E::C($0); |
470 | } | 470 | } |
471 | "#, | 471 | "#, |
472 | expect![[""]], | 472 | expect![[""]], |
@@ -480,7 +480,7 @@ fn fn_signature_for_call_in_macro() { | |||
480 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } | 480 | macro_rules! id { ($($tt:tt)*) => { $($tt)* } } |
481 | fn foo() { } | 481 | fn foo() { } |
482 | id! { | 482 | id! { |
483 | fn bar() { foo(<|>); } | 483 | fn bar() { foo($0); } |
484 | } | 484 | } |
485 | "#, | 485 | "#, |
486 | expect![[r#" | 486 | expect![[r#" |
@@ -497,7 +497,7 @@ fn call_info_for_lambdas() { | |||
497 | struct S; | 497 | struct S; |
498 | fn foo(s: S) -> i32 { 92 } | 498 | fn foo(s: S) -> i32 { 92 } |
499 | fn main() { | 499 | fn main() { |
500 | (|s| foo(s))(<|>) | 500 | (|s| foo(s))($0) |
501 | } | 501 | } |
502 | "#, | 502 | "#, |
503 | expect![[r#" | 503 | expect![[r#" |
@@ -512,7 +512,7 @@ fn call_info_for_fn_ptr() { | |||
512 | check( | 512 | check( |
513 | r#" | 513 | r#" |
514 | fn main(f: fn(i32, f64) -> char) { | 514 | fn main(f: fn(i32, f64) -> char) { |
515 | f(0, <|>) | 515 | f(0, $0) |
516 | } | 516 | } |
517 | "#, | 517 | "#, |
518 | expect![[r#" | 518 | expect![[r#" |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index cc5078bf0..be1c64b03 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -358,7 +358,7 @@ impl NameRefClass { | |||
358 | if let Some(path) = macro_call.path() { | 358 | if let Some(path) = macro_call.path() { |
359 | if path.qualifier().is_none() { | 359 | if path.qualifier().is_none() { |
360 | // Only use this to resolve single-segment macro calls like `foo!()`. Multi-segment | 360 | // Only use this to resolve single-segment macro calls like `foo!()`. Multi-segment |
361 | // paths are handled below (allowing `log<|>::info!` to resolve to the log crate). | 361 | // paths are handled below (allowing `log$0::info!` to resolve to the log crate). |
362 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { | 362 | if let Some(macro_def) = sema.resolve_macro_call(¯o_call) { |
363 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); | 363 | return Some(NameRefClass::Definition(Definition::Macro(macro_def))); |
364 | } | 364 | } |
diff --git a/crates/ide_db/src/helpers.rs b/crates/ide_db/src/helpers.rs index d988588ff..e3e5670f1 100644 --- a/crates/ide_db/src/helpers.rs +++ b/crates/ide_db/src/helpers.rs | |||
@@ -1,9 +1,10 @@ | |||
1 | //! A module with ide helpers for high-level ide features. | 1 | //! A module with ide helpers for high-level ide features. |
2 | use crate::RootDatabase; | 2 | pub mod insert_use; |
3 | |||
3 | use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait}; | 4 | use hir::{Crate, Enum, Module, ScopeDef, Semantics, Trait}; |
4 | use syntax::ast::{self, make}; | 5 | use syntax::ast::{self, make}; |
5 | 6 | ||
6 | pub mod insert_use; | 7 | use crate::RootDatabase; |
7 | 8 | ||
8 | /// Converts the mod path struct into its ast representation. | 9 | /// Converts the mod path struct into its ast representation. |
9 | pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { | 10 | pub fn mod_path_to_ast(path: &hir::ModPath) -> ast::Path { |
@@ -201,3 +202,18 @@ pub use prelude::*; | |||
201 | Some(def) | 202 | Some(def) |
202 | } | 203 | } |
203 | } | 204 | } |
205 | |||
206 | #[derive(Clone, Copy, Debug, PartialEq, Eq)] | ||
207 | pub struct SnippetCap { | ||
208 | _private: (), | ||
209 | } | ||
210 | |||
211 | impl SnippetCap { | ||
212 | pub const fn new(allow_snippets: bool) -> Option<SnippetCap> { | ||
213 | if allow_snippets { | ||
214 | Some(SnippetCap { _private: () }) | ||
215 | } else { | ||
216 | None | ||
217 | } | ||
218 | } | ||
219 | } | ||
diff --git a/crates/ide_db/src/imports_locator.rs b/crates/ide_db/src/imports_locator.rs index 0f4c2ca47..0782ab070 100644 --- a/crates/ide_db/src/imports_locator.rs +++ b/crates/ide_db/src/imports_locator.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! This module contains an import search funcionality that is provided to the assists module. | 1 | //! This module contains an import search funcionality that is provided to the assists module. |
2 | //! Later, this should be moved away to a separate crate that is accessible from the assists module. | 2 | //! Later, this should be moved away to a separate crate that is accessible from the assists module. |
3 | 3 | ||
4 | use hir::{import_map, Crate, MacroDef, ModuleDef, Semantics}; | 4 | use hir::{import_map, AsAssocItem, Crate, MacroDef, ModuleDef, Semantics}; |
5 | use syntax::{ast, AstNode, SyntaxKind::NAME}; | 5 | use syntax::{ast, AstNode, SyntaxKind::NAME}; |
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
@@ -40,8 +40,9 @@ pub fn find_similar_imports<'a>( | |||
40 | krate: Crate, | 40 | krate: Crate, |
41 | limit: Option<usize>, | 41 | limit: Option<usize>, |
42 | fuzzy_search_string: String, | 42 | fuzzy_search_string: String, |
43 | ignore_assoc_items: bool, | ||
43 | name_only: bool, | 44 | name_only: bool, |
44 | ) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> { | 45 | ) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> + 'a { |
45 | let _p = profile::span("find_similar_imports"); | 46 | let _p = profile::span("find_similar_imports"); |
46 | 47 | ||
47 | let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) | 48 | let mut external_query = import_map::Query::new(fuzzy_search_string.clone()) |
@@ -57,7 +58,21 @@ pub fn find_similar_imports<'a>( | |||
57 | external_query = external_query.limit(limit); | 58 | external_query = external_query.limit(limit); |
58 | } | 59 | } |
59 | 60 | ||
60 | find_imports(sema, krate, local_query, external_query) | 61 | let db = sema.db; |
62 | find_imports(sema, krate, local_query, external_query).filter(move |import_candidate| { | ||
63 | if ignore_assoc_items { | ||
64 | match import_candidate { | ||
65 | Either::Left(ModuleDef::Function(function)) => function.as_assoc_item(db).is_none(), | ||
66 | Either::Left(ModuleDef::Const(const_)) => const_.as_assoc_item(db).is_none(), | ||
67 | Either::Left(ModuleDef::TypeAlias(type_alias)) => { | ||
68 | type_alias.as_assoc_item(db).is_none() | ||
69 | } | ||
70 | _ => true, | ||
71 | } | ||
72 | } else { | ||
73 | true | ||
74 | } | ||
75 | }) | ||
61 | } | 76 | } |
62 | 77 | ||
63 | fn find_imports<'a>( | 78 | fn find_imports<'a>( |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 436c59d2c..37b06027c 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -137,7 +137,6 @@ impl Definition { | |||
137 | } | 137 | } |
138 | 138 | ||
139 | if let Definition::LifetimeParam(param) = self { | 139 | if let Definition::LifetimeParam(param) = self { |
140 | #[allow(deprecated)] | ||
141 | let range = match param.parent(db) { | 140 | let range = match param.parent(db) { |
142 | hir::GenericDef::Function(it) => { | 141 | hir::GenericDef::Function(it) => { |
143 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) | 142 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) |
diff --git a/crates/ide_db/src/traits/tests.rs b/crates/ide_db/src/traits/tests.rs index 09c7ac3ec..84bb25505 100644 --- a/crates/ide_db/src/traits/tests.rs +++ b/crates/ide_db/src/traits/tests.rs | |||
@@ -5,12 +5,12 @@ use hir::Semantics; | |||
5 | use syntax::ast::{self, AstNode}; | 5 | use syntax::ast::{self, AstNode}; |
6 | use test_utils::RangeOrOffset; | 6 | use test_utils::RangeOrOffset; |
7 | 7 | ||
8 | /// Creates analysis from a multi-file fixture, returns positions marked with <|>. | 8 | /// Creates analysis from a multi-file fixture, returns positions marked with $0. |
9 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { | 9 | pub(crate) fn position(ra_fixture: &str) -> (RootDatabase, FilePosition) { |
10 | let change_fixture = ChangeFixture::parse(ra_fixture); | 10 | let change_fixture = ChangeFixture::parse(ra_fixture); |
11 | let mut database = RootDatabase::default(); | 11 | let mut database = RootDatabase::default(); |
12 | database.apply_change(change_fixture.change); | 12 | database.apply_change(change_fixture.change); |
13 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker (<|>)"); | 13 | let (file_id, range_or_offset) = change_fixture.file_position.expect("expected a marker ($0)"); |
14 | let offset = match range_or_offset { | 14 | let offset = match range_or_offset { |
15 | RangeOrOffset::Range(_) => panic!(), | 15 | RangeOrOffset::Range(_) => panic!(), |
16 | RangeOrOffset::Offset(it) => it, | 16 | RangeOrOffset::Offset(it) => it, |
@@ -55,7 +55,7 @@ pub trait Foo { | |||
55 | fn bar(); | 55 | fn bar(); |
56 | } | 56 | } |
57 | impl Foo for u8 { | 57 | impl Foo for u8 { |
58 | <|> | 58 | $0 |
59 | } | 59 | } |
60 | "#, | 60 | "#, |
61 | expect![["Foo"]], | 61 | expect![["Foo"]], |
@@ -68,7 +68,7 @@ pub trait Foo { | |||
68 | impl Foo for u8 { | 68 | impl Foo for u8 { |
69 | fn bar() { | 69 | fn bar() { |
70 | fn baz() { | 70 | fn baz() { |
71 | <|> | 71 | $0 |
72 | } | 72 | } |
73 | baz(); | 73 | baz(); |
74 | } | 74 | } |
@@ -83,7 +83,7 @@ pub trait Foo { | |||
83 | } | 83 | } |
84 | pub struct Bar; | 84 | pub struct Bar; |
85 | impl Bar { | 85 | impl Bar { |
86 | <|> | 86 | $0 |
87 | } | 87 | } |
88 | "#, | 88 | "#, |
89 | expect![[""]], | 89 | expect![[""]], |
@@ -99,7 +99,7 @@ pub trait Foo { | |||
99 | fn bar(); | 99 | fn bar(); |
100 | } | 100 | } |
101 | impl Foo for u8 { | 101 | impl Foo for u8 { |
102 | <|> | 102 | $0 |
103 | }"#, | 103 | }"#, |
104 | expect![[r#" | 104 | expect![[r#" |
105 | FOO | 105 | FOO |
@@ -114,7 +114,7 @@ pub trait Foo { | |||
114 | } | 114 | } |
115 | impl Foo for u8 { | 115 | impl Foo for u8 { |
116 | const FOO: u8 = 10; | 116 | const FOO: u8 = 10; |
117 | <|> | 117 | $0 |
118 | }"#, | 118 | }"#, |
119 | expect![[r#" | 119 | expect![[r#" |
120 | bar"#]], | 120 | bar"#]], |
@@ -128,7 +128,7 @@ pub trait Foo { | |||
128 | } | 128 | } |
129 | impl Foo for u8 { | 129 | impl Foo for u8 { |
130 | const FOO: u8 = 10; | 130 | const FOO: u8 = 10; |
131 | fn bar() {<|>} | 131 | fn bar() {$0} |
132 | }"#, | 132 | }"#, |
133 | expect![[r#""#]], | 133 | expect![[r#""#]], |
134 | ); | 134 | ); |
@@ -137,7 +137,7 @@ impl Foo for u8 { | |||
137 | r#" | 137 | r#" |
138 | pub struct Foo; | 138 | pub struct Foo; |
139 | impl Foo { | 139 | impl Foo { |
140 | fn bar() {<|>} | 140 | fn bar() {$0} |
141 | }"#, | 141 | }"#, |
142 | expect![[r#""#]], | 142 | expect![[r#""#]], |
143 | ); | 143 | ); |
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs index 385b46601..c6d615c81 100644 --- a/crates/mbe/src/mbe_expander/matcher.rs +++ b/crates/mbe/src/mbe_expander/matcher.rs | |||
@@ -309,7 +309,7 @@ impl<'a> TtIter<'a> { | |||
309 | } | 309 | } |
310 | } | 310 | } |
311 | 311 | ||
312 | let buffer = TokenBuffer::new(&self.inner.as_slice()); | 312 | let buffer = TokenBuffer::from_tokens(&self.inner.as_slice()); |
313 | let mut src = SubtreeTokenSource::new(&buffer); | 313 | let mut src = SubtreeTokenSource::new(&buffer); |
314 | let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; | 314 | let mut sink = OffsetTokenSink { cursor: buffer.begin(), error: false }; |
315 | 315 | ||
@@ -336,11 +336,11 @@ impl<'a> TtIter<'a> { | |||
336 | err = Some(err!("no tokens consumed")); | 336 | err = Some(err!("no tokens consumed")); |
337 | } | 337 | } |
338 | let res = match res.len() { | 338 | let res = match res.len() { |
339 | 1 => Some(res[0].clone()), | 339 | 1 => Some(res[0].cloned()), |
340 | 0 => None, | 340 | 0 => None, |
341 | _ => Some(tt::TokenTree::Subtree(tt::Subtree { | 341 | _ => Some(tt::TokenTree::Subtree(tt::Subtree { |
342 | delimiter: None, | 342 | delimiter: None, |
343 | token_trees: res.into_iter().cloned().collect(), | 343 | token_trees: res.into_iter().map(|it| it.cloned()).collect(), |
344 | })), | 344 | })), |
345 | }; | 345 | }; |
346 | ExpandResult { value: res, err } | 346 | ExpandResult { value: res, err } |
diff --git a/crates/mbe/src/subtree_source.rs b/crates/mbe/src/subtree_source.rs index d10d4b70e..d7433bd35 100644 --- a/crates/mbe/src/subtree_source.rs +++ b/crates/mbe/src/subtree_source.rs | |||
@@ -1,129 +1,104 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use parser::{Token, TokenSource}; | 3 | use parser::{Token, TokenSource}; |
4 | use std::cell::{Cell, Ref, RefCell}; | ||
5 | use syntax::{lex_single_syntax_kind, SmolStr, SyntaxKind, SyntaxKind::*, T}; | 4 | use syntax::{lex_single_syntax_kind, SmolStr, SyntaxKind, SyntaxKind::*, T}; |
6 | use tt::buffer::{Cursor, TokenBuffer}; | 5 | use tt::buffer::TokenBuffer; |
7 | 6 | ||
8 | #[derive(Debug, Clone, Eq, PartialEq)] | 7 | #[derive(Debug, Clone, Eq, PartialEq)] |
9 | struct TtToken { | 8 | struct TtToken { |
10 | kind: SyntaxKind, | 9 | tt: Token, |
11 | is_joint_to_next: bool, | ||
12 | text: SmolStr, | 10 | text: SmolStr, |
13 | } | 11 | } |
14 | 12 | ||
15 | pub(crate) struct SubtreeTokenSource<'a> { | 13 | pub(crate) struct SubtreeTokenSource { |
16 | cached_cursor: Cell<Cursor<'a>>, | 14 | cached: Vec<TtToken>, |
17 | cached: RefCell<Vec<Option<TtToken>>>, | ||
18 | curr: (Token, usize), | 15 | curr: (Token, usize), |
19 | } | 16 | } |
20 | 17 | ||
21 | impl<'a> SubtreeTokenSource<'a> { | 18 | impl<'a> SubtreeTokenSource { |
22 | // Helper function used in test | 19 | // Helper function used in test |
23 | #[cfg(test)] | 20 | #[cfg(test)] |
24 | pub(crate) fn text(&self) -> SmolStr { | 21 | pub(crate) fn text(&self) -> SmolStr { |
25 | match *self.get(self.curr.1) { | 22 | match self.cached.get(self.curr.1) { |
26 | Some(ref tt) => tt.text.clone(), | 23 | Some(ref tt) => tt.text.clone(), |
27 | _ => SmolStr::new(""), | 24 | _ => SmolStr::new(""), |
28 | } | 25 | } |
29 | } | 26 | } |
30 | } | 27 | } |
31 | 28 | ||
32 | impl<'a> SubtreeTokenSource<'a> { | 29 | impl<'a> SubtreeTokenSource { |
33 | pub(crate) fn new(buffer: &'a TokenBuffer) -> SubtreeTokenSource<'a> { | 30 | pub(crate) fn new(buffer: &TokenBuffer) -> SubtreeTokenSource { |
34 | let cursor = buffer.begin(); | 31 | let mut current = buffer.begin(); |
32 | let mut cached = Vec::with_capacity(100); | ||
35 | 33 | ||
36 | let mut res = SubtreeTokenSource { | 34 | while !current.eof() { |
37 | curr: (Token { kind: EOF, is_jointed_to_next: false }, 0), | 35 | let cursor = current; |
38 | cached_cursor: Cell::new(cursor), | 36 | let tt = cursor.token_tree(); |
39 | cached: RefCell::new(Vec::with_capacity(10)), | ||
40 | }; | ||
41 | res.curr = (res.mk_token(0), 0); | ||
42 | res | ||
43 | } | ||
44 | 37 | ||
45 | fn mk_token(&self, pos: usize) -> Token { | 38 | // Check if it is lifetime |
46 | match *self.get(pos) { | 39 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(punct), _)) = tt { |
47 | Some(ref tt) => Token { kind: tt.kind, is_jointed_to_next: tt.is_joint_to_next }, | ||
48 | None => Token { kind: EOF, is_jointed_to_next: false }, | ||
49 | } | ||
50 | } | ||
51 | |||
52 | fn get(&self, pos: usize) -> Ref<Option<TtToken>> { | ||
53 | fn is_lifetime(c: Cursor) -> Option<(Cursor, SmolStr)> { | ||
54 | let tkn = c.token_tree(); | ||
55 | |||
56 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Punct(punct))) = tkn { | ||
57 | if punct.char == '\'' { | 40 | if punct.char == '\'' { |
58 | let next = c.bump(); | 41 | let next = cursor.bump(); |
59 | if let Some(tt::TokenTree::Leaf(tt::Leaf::Ident(ident))) = next.token_tree() { | 42 | if let Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Ident(ident), _)) = |
60 | let res_cursor = next.bump(); | 43 | next.token_tree() |
61 | let text = SmolStr::new("'".to_string() + &ident.to_string()); | 44 | { |
62 | 45 | let text = SmolStr::new("'".to_string() + &ident.text); | |
63 | return Some((res_cursor, text)); | 46 | cached.push(TtToken { |
47 | tt: Token { kind: LIFETIME_IDENT, is_jointed_to_next: false }, | ||
48 | text, | ||
49 | }); | ||
50 | current = next.bump(); | ||
51 | continue; | ||
64 | } else { | 52 | } else { |
65 | panic!("Next token must be ident : {:#?}", next.token_tree()); | 53 | panic!("Next token must be ident : {:#?}", next.token_tree()); |
66 | } | 54 | } |
67 | } | 55 | } |
68 | } | 56 | } |
69 | 57 | ||
70 | None | 58 | current = match tt { |
71 | } | 59 | Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { |
72 | 60 | cached.push(convert_leaf(&leaf)); | |
73 | if pos < self.cached.borrow().len() { | 61 | cursor.bump() |
74 | return Ref::map(self.cached.borrow(), |c| &c[pos]); | ||
75 | } | ||
76 | |||
77 | { | ||
78 | let mut cached = self.cached.borrow_mut(); | ||
79 | while pos >= cached.len() { | ||
80 | let cursor = self.cached_cursor.get(); | ||
81 | if cursor.eof() { | ||
82 | cached.push(None); | ||
83 | continue; | ||
84 | } | 62 | } |
85 | 63 | Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) => { | |
86 | if let Some((curr, text)) = is_lifetime(cursor) { | 64 | cached.push(convert_delim(subtree.delimiter_kind(), false)); |
87 | cached.push(Some(TtToken { | 65 | cursor.subtree().unwrap() |
88 | kind: LIFETIME_IDENT, | ||
89 | is_joint_to_next: false, | ||
90 | text, | ||
91 | })); | ||
92 | self.cached_cursor.set(curr); | ||
93 | continue; | ||
94 | } | 66 | } |
95 | 67 | None => { | |
96 | match cursor.token_tree() { | 68 | if let Some(subtree) = cursor.end() { |
97 | Some(tt::TokenTree::Leaf(leaf)) => { | 69 | cached.push(convert_delim(subtree.delimiter_kind(), true)); |
98 | cached.push(Some(convert_leaf(&leaf))); | 70 | cursor.bump() |
99 | self.cached_cursor.set(cursor.bump()); | 71 | } else { |
100 | } | 72 | continue; |
101 | Some(tt::TokenTree::Subtree(subtree)) => { | ||
102 | self.cached_cursor.set(cursor.subtree().unwrap()); | ||
103 | cached.push(Some(convert_delim(subtree.delimiter_kind(), false))); | ||
104 | } | ||
105 | None => { | ||
106 | if let Some(subtree) = cursor.end() { | ||
107 | cached.push(Some(convert_delim(subtree.delimiter_kind(), true))); | ||
108 | self.cached_cursor.set(cursor.bump()); | ||
109 | } | ||
110 | } | 73 | } |
111 | } | 74 | } |
112 | } | 75 | }; |
113 | } | 76 | } |
114 | 77 | ||
115 | Ref::map(self.cached.borrow(), |c| &c[pos]) | 78 | let mut res = SubtreeTokenSource { |
79 | curr: (Token { kind: EOF, is_jointed_to_next: false }, 0), | ||
80 | cached, | ||
81 | }; | ||
82 | res.curr = (res.token(0), 0); | ||
83 | res | ||
84 | } | ||
85 | |||
86 | fn token(&self, pos: usize) -> Token { | ||
87 | match self.cached.get(pos) { | ||
88 | Some(it) => it.tt, | ||
89 | None => Token { kind: EOF, is_jointed_to_next: false }, | ||
90 | } | ||
116 | } | 91 | } |
117 | } | 92 | } |
118 | 93 | ||
119 | impl<'a> TokenSource for SubtreeTokenSource<'a> { | 94 | impl<'a> TokenSource for SubtreeTokenSource { |
120 | fn current(&self) -> Token { | 95 | fn current(&self) -> Token { |
121 | self.curr.0 | 96 | self.curr.0 |
122 | } | 97 | } |
123 | 98 | ||
124 | /// Lookahead n token | 99 | /// Lookahead n token |
125 | fn lookahead_nth(&self, n: usize) -> Token { | 100 | fn lookahead_nth(&self, n: usize) -> Token { |
126 | self.mk_token(self.curr.1 + n) | 101 | self.token(self.curr.1 + n) |
127 | } | 102 | } |
128 | 103 | ||
129 | /// bump cursor to next token | 104 | /// bump cursor to next token |
@@ -131,13 +106,12 @@ impl<'a> TokenSource for SubtreeTokenSource<'a> { | |||
131 | if self.current().kind == EOF { | 106 | if self.current().kind == EOF { |
132 | return; | 107 | return; |
133 | } | 108 | } |
134 | 109 | self.curr = (self.token(self.curr.1 + 1), self.curr.1 + 1); | |
135 | self.curr = (self.mk_token(self.curr.1 + 1), self.curr.1 + 1); | ||
136 | } | 110 | } |
137 | 111 | ||
138 | /// Is the current token a specified keyword? | 112 | /// Is the current token a specified keyword? |
139 | fn is_keyword(&self, kw: &str) -> bool { | 113 | fn is_keyword(&self, kw: &str) -> bool { |
140 | match *self.get(self.curr.1) { | 114 | match self.cached.get(self.curr.1) { |
141 | Some(ref t) => t.text == *kw, | 115 | Some(ref t) => t.text == *kw, |
142 | _ => false, | 116 | _ => false, |
143 | } | 117 | } |
@@ -155,7 +129,7 @@ fn convert_delim(d: Option<tt::DelimiterKind>, closing: bool) -> TtToken { | |||
155 | let idx = closing as usize; | 129 | let idx = closing as usize; |
156 | let kind = kinds[idx]; | 130 | let kind = kinds[idx]; |
157 | let text = if !texts.is_empty() { &texts[idx..texts.len() - (1 - idx)] } else { "" }; | 131 | let text = if !texts.is_empty() { &texts[idx..texts.len() - (1 - idx)] } else { "" }; |
158 | TtToken { kind, is_joint_to_next: false, text: SmolStr::new(text) } | 132 | TtToken { tt: Token { kind, is_jointed_to_next: false }, text: SmolStr::new(text) } |
159 | } | 133 | } |
160 | 134 | ||
161 | fn convert_literal(l: &tt::Literal) -> TtToken { | 135 | fn convert_literal(l: &tt::Literal) -> TtToken { |
@@ -169,7 +143,7 @@ fn convert_literal(l: &tt::Literal) -> TtToken { | |||
169 | }) | 143 | }) |
170 | .unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &l)); | 144 | .unwrap_or_else(|| panic!("Fail to convert given literal {:#?}", &l)); |
171 | 145 | ||
172 | TtToken { kind, is_joint_to_next: false, text: l.text.clone() } | 146 | TtToken { tt: Token { kind, is_jointed_to_next: false }, text: l.text.clone() } |
173 | } | 147 | } |
174 | 148 | ||
175 | fn convert_ident(ident: &tt::Ident) -> TtToken { | 149 | fn convert_ident(ident: &tt::Ident) -> TtToken { |
@@ -180,7 +154,7 @@ fn convert_ident(ident: &tt::Ident) -> TtToken { | |||
180 | _ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT), | 154 | _ => SyntaxKind::from_keyword(ident.text.as_str()).unwrap_or(IDENT), |
181 | }; | 155 | }; |
182 | 156 | ||
183 | TtToken { kind, is_joint_to_next: false, text: ident.text.clone() } | 157 | TtToken { tt: Token { kind, is_jointed_to_next: false }, text: ident.text.clone() } |
184 | } | 158 | } |
185 | 159 | ||
186 | fn convert_punct(p: tt::Punct) -> TtToken { | 160 | fn convert_punct(p: tt::Punct) -> TtToken { |
@@ -194,7 +168,7 @@ fn convert_punct(p: tt::Punct) -> TtToken { | |||
194 | let s: &str = p.char.encode_utf8(&mut buf); | 168 | let s: &str = p.char.encode_utf8(&mut buf); |
195 | SmolStr::new(s) | 169 | SmolStr::new(s) |
196 | }; | 170 | }; |
197 | TtToken { kind, is_joint_to_next: p.spacing == tt::Spacing::Joint, text } | 171 | TtToken { tt: Token { kind, is_jointed_to_next: p.spacing == tt::Spacing::Joint }, text } |
198 | } | 172 | } |
199 | 173 | ||
200 | fn convert_leaf(leaf: &tt::Leaf) -> TtToken { | 174 | fn convert_leaf(leaf: &tt::Leaf) -> TtToken { |
@@ -208,6 +182,7 @@ fn convert_leaf(leaf: &tt::Leaf) -> TtToken { | |||
208 | #[cfg(test)] | 182 | #[cfg(test)] |
209 | mod tests { | 183 | mod tests { |
210 | use super::{convert_literal, TtToken}; | 184 | use super::{convert_literal, TtToken}; |
185 | use parser::Token; | ||
211 | use syntax::{SmolStr, SyntaxKind}; | 186 | use syntax::{SmolStr, SyntaxKind}; |
212 | 187 | ||
213 | #[test] | 188 | #[test] |
@@ -218,8 +193,7 @@ mod tests { | |||
218 | text: SmolStr::new("-42.0") | 193 | text: SmolStr::new("-42.0") |
219 | }), | 194 | }), |
220 | TtToken { | 195 | TtToken { |
221 | kind: SyntaxKind::FLOAT_NUMBER, | 196 | tt: Token { kind: SyntaxKind::FLOAT_NUMBER, is_jointed_to_next: false }, |
222 | is_joint_to_next: false, | ||
223 | text: SmolStr::new("-42.0") | 197 | text: SmolStr::new("-42.0") |
224 | } | 198 | } |
225 | ); | 199 | ); |
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs index 265c0d63d..671036e1c 100644 --- a/crates/mbe/src/syntax_bridge.rs +++ b/crates/mbe/src/syntax_bridge.rs | |||
@@ -70,15 +70,12 @@ pub fn token_tree_to_syntax_node( | |||
70 | tt: &tt::Subtree, | 70 | tt: &tt::Subtree, |
71 | fragment_kind: FragmentKind, | 71 | fragment_kind: FragmentKind, |
72 | ) -> Result<(Parse<SyntaxNode>, TokenMap), ExpandError> { | 72 | ) -> Result<(Parse<SyntaxNode>, TokenMap), ExpandError> { |
73 | let tmp; | 73 | let buffer = match tt { |
74 | let tokens = match tt { | 74 | tt::Subtree { delimiter: None, token_trees } => { |
75 | tt::Subtree { delimiter: None, token_trees } => token_trees.as_slice(), | 75 | TokenBuffer::from_tokens(token_trees.as_slice()) |
76 | _ => { | ||
77 | tmp = [tt.clone().into()]; | ||
78 | &tmp[..] | ||
79 | } | 76 | } |
77 | _ => TokenBuffer::from_subtree(tt), | ||
80 | }; | 78 | }; |
81 | let buffer = TokenBuffer::new(&tokens); | ||
82 | let mut token_source = SubtreeTokenSource::new(&buffer); | 79 | let mut token_source = SubtreeTokenSource::new(&buffer); |
83 | let mut tree_sink = TtTreeSink::new(buffer.begin()); | 80 | let mut tree_sink = TtTreeSink::new(buffer.begin()); |
84 | parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind); | 81 | parser::parse_fragment(&mut token_source, &mut tree_sink, fragment_kind); |
@@ -414,7 +411,7 @@ trait TokenConvertor { | |||
414 | fn id_alloc(&mut self) -> &mut TokenIdAlloc; | 411 | fn id_alloc(&mut self) -> &mut TokenIdAlloc; |
415 | } | 412 | } |
416 | 413 | ||
417 | impl<'a> SrcToken for (RawToken, &'a str) { | 414 | impl<'a> SrcToken for (&'a RawToken, &'a str) { |
418 | fn kind(&self) -> SyntaxKind { | 415 | fn kind(&self) -> SyntaxKind { |
419 | self.0.kind | 416 | self.0.kind |
420 | } | 417 | } |
@@ -431,7 +428,7 @@ impl<'a> SrcToken for (RawToken, &'a str) { | |||
431 | impl RawConvertor<'_> {} | 428 | impl RawConvertor<'_> {} |
432 | 429 | ||
433 | impl<'a> TokenConvertor for RawConvertor<'a> { | 430 | impl<'a> TokenConvertor for RawConvertor<'a> { |
434 | type Token = (RawToken, &'a str); | 431 | type Token = (&'a RawToken, &'a str); |
435 | 432 | ||
436 | fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>> { | 433 | fn convert_doc_comment(&self, token: &Self::Token) -> Option<Vec<tt::TokenTree>> { |
437 | convert_doc_comment(&doc_comment(token.1)) | 434 | convert_doc_comment(&doc_comment(token.1)) |
@@ -442,11 +439,11 @@ impl<'a> TokenConvertor for RawConvertor<'a> { | |||
442 | let range = TextRange::at(self.offset, token.len); | 439 | let range = TextRange::at(self.offset, token.len); |
443 | self.offset += token.len; | 440 | self.offset += token.len; |
444 | 441 | ||
445 | Some(((*token, &self.text[range]), range)) | 442 | Some(((token, &self.text[range]), range)) |
446 | } | 443 | } |
447 | 444 | ||
448 | fn peek(&self) -> Option<Self::Token> { | 445 | fn peek(&self) -> Option<Self::Token> { |
449 | let token = self.inner.as_slice().get(0).cloned(); | 446 | let token = self.inner.as_slice().get(0); |
450 | 447 | ||
451 | token.map(|it| { | 448 | token.map(|it| { |
452 | let range = TextRange::at(self.offset, it.len); | 449 | let range = TextRange::at(self.offset, it.len); |
@@ -601,17 +598,16 @@ impl<'a> TtTreeSink<'a> { | |||
601 | } | 598 | } |
602 | } | 599 | } |
603 | 600 | ||
604 | fn delim_to_str(d: Option<tt::DelimiterKind>, closing: bool) -> SmolStr { | 601 | fn delim_to_str(d: Option<tt::DelimiterKind>, closing: bool) -> &'static str { |
605 | let texts = match d { | 602 | let texts = match d { |
606 | Some(tt::DelimiterKind::Parenthesis) => "()", | 603 | Some(tt::DelimiterKind::Parenthesis) => "()", |
607 | Some(tt::DelimiterKind::Brace) => "{}", | 604 | Some(tt::DelimiterKind::Brace) => "{}", |
608 | Some(tt::DelimiterKind::Bracket) => "[]", | 605 | Some(tt::DelimiterKind::Bracket) => "[]", |
609 | None => return "".into(), | 606 | None => return "", |
610 | }; | 607 | }; |
611 | 608 | ||
612 | let idx = closing as usize; | 609 | let idx = closing as usize; |
613 | let text = &texts[idx..texts.len() - (1 - idx)]; | 610 | &texts[idx..texts.len() - (1 - idx)] |
614 | text.into() | ||
615 | } | 611 | } |
616 | 612 | ||
617 | impl<'a> TreeSink for TtTreeSink<'a> { | 613 | impl<'a> TreeSink for TtTreeSink<'a> { |
@@ -626,29 +622,32 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
626 | 622 | ||
627 | let mut last = self.cursor; | 623 | let mut last = self.cursor; |
628 | for _ in 0..n_tokens { | 624 | for _ in 0..n_tokens { |
625 | let tmp_str: SmolStr; | ||
629 | if self.cursor.eof() { | 626 | if self.cursor.eof() { |
630 | break; | 627 | break; |
631 | } | 628 | } |
632 | last = self.cursor; | 629 | last = self.cursor; |
633 | let text: SmolStr = match self.cursor.token_tree() { | 630 | let text: &str = match self.cursor.token_tree() { |
634 | Some(tt::TokenTree::Leaf(leaf)) => { | 631 | Some(tt::buffer::TokenTreeRef::Leaf(leaf, _)) => { |
635 | // Mark the range if needed | 632 | // Mark the range if needed |
636 | let (text, id) = match leaf { | 633 | let (text, id) = match leaf { |
637 | tt::Leaf::Ident(ident) => (ident.text.clone(), ident.id), | 634 | tt::Leaf::Ident(ident) => (&ident.text, ident.id), |
638 | tt::Leaf::Punct(punct) => { | 635 | tt::Leaf::Punct(punct) => { |
639 | assert!(punct.char.is_ascii()); | 636 | assert!(punct.char.is_ascii()); |
640 | let char = &(punct.char as u8); | 637 | let char = &(punct.char as u8); |
641 | let text = std::str::from_utf8(std::slice::from_ref(char)).unwrap(); | 638 | tmp_str = SmolStr::new_inline( |
642 | (SmolStr::new_inline(text), punct.id) | 639 | std::str::from_utf8(std::slice::from_ref(char)).unwrap(), |
640 | ); | ||
641 | (&tmp_str, punct.id) | ||
643 | } | 642 | } |
644 | tt::Leaf::Literal(lit) => (lit.text.clone(), lit.id), | 643 | tt::Leaf::Literal(lit) => (&lit.text, lit.id), |
645 | }; | 644 | }; |
646 | let range = TextRange::at(self.text_pos, TextSize::of(text.as_str())); | 645 | let range = TextRange::at(self.text_pos, TextSize::of(text.as_str())); |
647 | self.token_map.insert(id, range); | 646 | self.token_map.insert(id, range); |
648 | self.cursor = self.cursor.bump(); | 647 | self.cursor = self.cursor.bump(); |
649 | text | 648 | text |
650 | } | 649 | } |
651 | Some(tt::TokenTree::Subtree(subtree)) => { | 650 | Some(tt::buffer::TokenTreeRef::Subtree(subtree, _)) => { |
652 | self.cursor = self.cursor.subtree().unwrap(); | 651 | self.cursor = self.cursor.subtree().unwrap(); |
653 | if let Some(id) = subtree.delimiter.map(|it| it.id) { | 652 | if let Some(id) = subtree.delimiter.map(|it| it.id) { |
654 | self.open_delims.insert(id, self.text_pos); | 653 | self.open_delims.insert(id, self.text_pos); |
@@ -672,7 +671,7 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
672 | } | 671 | } |
673 | }; | 672 | }; |
674 | self.buf += &text; | 673 | self.buf += &text; |
675 | self.text_pos += TextSize::of(text.as_str()); | 674 | self.text_pos += TextSize::of(text); |
676 | } | 675 | } |
677 | 676 | ||
678 | let text = SmolStr::new(self.buf.as_str()); | 677 | let text = SmolStr::new(self.buf.as_str()); |
@@ -682,8 +681,8 @@ impl<'a> TreeSink for TtTreeSink<'a> { | |||
682 | // Add whitespace between adjoint puncts | 681 | // Add whitespace between adjoint puncts |
683 | let next = last.bump(); | 682 | let next = last.bump(); |
684 | if let ( | 683 | if let ( |
685 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(curr))), | 684 | Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(curr), _)), |
686 | Some(tt::TokenTree::Leaf(tt::Leaf::Punct(_))), | 685 | Some(tt::buffer::TokenTreeRef::Leaf(tt::Leaf::Punct(_), _)), |
687 | ) = (last.token_tree(), next.token_tree()) | 686 | ) = (last.token_tree(), next.token_tree()) |
688 | { | 687 | { |
689 | // Note: We always assume the semi-colon would be the last token in | 688 | // Note: We always assume the semi-colon would be the last token in |
@@ -742,7 +741,7 @@ mod tests { | |||
742 | ) | 741 | ) |
743 | .expand_tt("literals!(foo);"); | 742 | .expand_tt("literals!(foo);"); |
744 | let tts = &[expansion.into()]; | 743 | let tts = &[expansion.into()]; |
745 | let buffer = tt::buffer::TokenBuffer::new(tts); | 744 | let buffer = tt::buffer::TokenBuffer::from_tokens(tts); |
746 | let mut tt_src = SubtreeTokenSource::new(&buffer); | 745 | let mut tt_src = SubtreeTokenSource::new(&buffer); |
747 | let mut tokens = vec![]; | 746 | let mut tokens = vec![]; |
748 | while tt_src.current().kind != EOF { | 747 | while tt_src.current().kind != EOF { |
diff --git a/crates/parser/src/grammar.rs b/crates/parser/src/grammar.rs index 63cc90027..bb9ffea8b 100644 --- a/crates/parser/src/grammar.rs +++ b/crates/parser/src/grammar.rs | |||
@@ -66,6 +66,10 @@ pub(crate) mod fragments { | |||
66 | expressions::stmt(p, expressions::StmtWithSemi::No) | 66 | expressions::stmt(p, expressions::StmtWithSemi::No) |
67 | } | 67 | } |
68 | 68 | ||
69 | pub(crate) fn stmt_optional_semi(p: &mut Parser) { | ||
70 | expressions::stmt(p, expressions::StmtWithSemi::Optional) | ||
71 | } | ||
72 | |||
69 | pub(crate) fn opt_visibility(p: &mut Parser) { | 73 | pub(crate) fn opt_visibility(p: &mut Parser) { |
70 | let _ = super::opt_visibility(p); | 74 | let _ = super::opt_visibility(p); |
71 | } | 75 | } |
diff --git a/crates/parser/src/lib.rs b/crates/parser/src/lib.rs index 811e740f9..9dfe63028 100644 --- a/crates/parser/src/lib.rs +++ b/crates/parser/src/lib.rs | |||
@@ -88,6 +88,7 @@ pub enum FragmentKind { | |||
88 | Path, | 88 | Path, |
89 | Expr, | 89 | Expr, |
90 | Statement, | 90 | Statement, |
91 | StatementOptionalSemi, | ||
91 | Type, | 92 | Type, |
92 | Pattern, | 93 | Pattern, |
93 | Item, | 94 | Item, |
@@ -118,6 +119,7 @@ pub fn parse_fragment( | |||
118 | FragmentKind::Visibility => grammar::fragments::opt_visibility, | 119 | FragmentKind::Visibility => grammar::fragments::opt_visibility, |
119 | FragmentKind::MetaItem => grammar::fragments::meta_item, | 120 | FragmentKind::MetaItem => grammar::fragments::meta_item, |
120 | FragmentKind::Statement => grammar::fragments::stmt, | 121 | FragmentKind::Statement => grammar::fragments::stmt, |
122 | FragmentKind::StatementOptionalSemi => grammar::fragments::stmt_optional_semi, | ||
121 | FragmentKind::Items => grammar::fragments::macro_items, | 123 | FragmentKind::Items => grammar::fragments::macro_items, |
122 | FragmentKind::Statements => grammar::fragments::macro_stmts, | 124 | FragmentKind::Statements => grammar::fragments::macro_stmts, |
123 | FragmentKind::Attr => grammar::fragments::attr, | 125 | FragmentKind::Attr => grammar::fragments::attr, |
diff --git a/crates/proc_macro_srv/Cargo.toml b/crates/proc_macro_srv/Cargo.toml index df9a55c10..f78c17194 100644 --- a/crates/proc_macro_srv/Cargo.toml +++ b/crates/proc_macro_srv/Cargo.toml | |||
@@ -21,7 +21,6 @@ test_utils = { path = "../test_utils", version = "0.0.0" } | |||
21 | 21 | ||
22 | [dev-dependencies] | 22 | [dev-dependencies] |
23 | cargo_metadata = "=0.12.0" | 23 | cargo_metadata = "=0.12.0" |
24 | difference = "2.0.0" | ||
25 | 24 | ||
26 | # used as proc macro test targets | 25 | # used as proc macro test targets |
27 | serde_derive = "1.0.106" | 26 | serde_derive = "1.0.106" |
diff --git a/crates/profile/src/stop_watch.rs b/crates/profile/src/stop_watch.rs index 5e276190e..cb6915d45 100644 --- a/crates/profile/src/stop_watch.rs +++ b/crates/profile/src/stop_watch.rs | |||
@@ -76,7 +76,11 @@ impl fmt::Display for StopWatchSpan { | |||
76 | instructions /= 1000; | 76 | instructions /= 1000; |
77 | prefix = "m" | 77 | prefix = "m" |
78 | } | 78 | } |
79 | write!(f, ", {}{}i", instructions, prefix)?; | 79 | if instructions > 10000 { |
80 | instructions /= 1000; | ||
81 | prefix = "g" | ||
82 | } | ||
83 | write!(f, ", {}{}instr", instructions, prefix)?; | ||
80 | } | 84 | } |
81 | if let Some(memory) = self.memory { | 85 | if let Some(memory) = self.memory { |
82 | write!(f, ", {}", memory)?; | 86 | write!(f, ", {}", memory)?; |
diff --git a/crates/project_model/src/cargo_workspace.rs b/crates/project_model/src/cargo_workspace.rs index 1700cb8a7..2ee4e88b2 100644 --- a/crates/project_model/src/cargo_workspace.rs +++ b/crates/project_model/src/cargo_workspace.rs | |||
@@ -3,9 +3,10 @@ | |||
3 | use std::{ | 3 | use std::{ |
4 | convert::TryInto, | 4 | convert::TryInto, |
5 | ffi::OsStr, | 5 | ffi::OsStr, |
6 | io::BufReader, | ||
6 | ops, | 7 | ops, |
7 | path::{Path, PathBuf}, | 8 | path::{Path, PathBuf}, |
8 | process::Command, | 9 | process::{Command, Stdio}, |
9 | }; | 10 | }; |
10 | 11 | ||
11 | use anyhow::{Context, Result}; | 12 | use anyhow::{Context, Result}; |
@@ -15,6 +16,7 @@ use cargo_metadata::{BuildScript, CargoOpt, Message, MetadataCommand, PackageId} | |||
15 | use itertools::Itertools; | 16 | use itertools::Itertools; |
16 | use paths::{AbsPath, AbsPathBuf}; | 17 | use paths::{AbsPath, AbsPathBuf}; |
17 | use rustc_hash::FxHashMap; | 18 | use rustc_hash::FxHashMap; |
19 | use stdx::JodChild; | ||
18 | 20 | ||
19 | use crate::cfg_flag::CfgFlag; | 21 | use crate::cfg_flag::CfgFlag; |
20 | use crate::utf8_stdout; | 22 | use crate::utf8_stdout; |
@@ -80,19 +82,35 @@ pub type Package = Idx<PackageData>; | |||
80 | 82 | ||
81 | pub type Target = Idx<TargetData>; | 83 | pub type Target = Idx<TargetData>; |
82 | 84 | ||
85 | /// Information associated with a cargo crate | ||
83 | #[derive(Debug, Clone, Eq, PartialEq)] | 86 | #[derive(Debug, Clone, Eq, PartialEq)] |
84 | pub struct PackageData { | 87 | pub struct PackageData { |
88 | /// Version given in the `Cargo.toml` | ||
85 | pub version: String, | 89 | pub version: String, |
90 | /// Name as given in the `Cargo.toml` | ||
86 | pub name: String, | 91 | pub name: String, |
92 | /// Path containing the `Cargo.toml` | ||
87 | pub manifest: AbsPathBuf, | 93 | pub manifest: AbsPathBuf, |
94 | /// Targets provided by the crate (lib, bin, example, test, ...) | ||
88 | pub targets: Vec<Target>, | 95 | pub targets: Vec<Target>, |
96 | /// Is this package a member of the current workspace | ||
89 | pub is_member: bool, | 97 | pub is_member: bool, |
98 | /// List of packages this package depends on | ||
90 | pub dependencies: Vec<PackageDependency>, | 99 | pub dependencies: Vec<PackageDependency>, |
100 | /// Rust edition for this package | ||
91 | pub edition: Edition, | 101 | pub edition: Edition, |
102 | /// List of features to activate | ||
92 | pub features: Vec<String>, | 103 | pub features: Vec<String>, |
104 | /// List of config flags defined by this package's build script | ||
93 | pub cfgs: Vec<CfgFlag>, | 105 | pub cfgs: Vec<CfgFlag>, |
106 | /// List of cargo-related environment variables with their value | ||
107 | /// | ||
108 | /// If the package has a build script which defines environment variables, | ||
109 | /// they can also be found here. | ||
94 | pub envs: Vec<(String, String)>, | 110 | pub envs: Vec<(String, String)>, |
111 | /// Directory where a build script might place its output | ||
95 | pub out_dir: Option<AbsPathBuf>, | 112 | pub out_dir: Option<AbsPathBuf>, |
113 | /// Path to the proc-macro library file if this package exposes proc-macros | ||
96 | pub proc_macro_dylib_path: Option<AbsPathBuf>, | 114 | pub proc_macro_dylib_path: Option<AbsPathBuf>, |
97 | } | 115 | } |
98 | 116 | ||
@@ -102,12 +120,18 @@ pub struct PackageDependency { | |||
102 | pub name: String, | 120 | pub name: String, |
103 | } | 121 | } |
104 | 122 | ||
123 | /// Information associated with a package's target | ||
105 | #[derive(Debug, Clone, Eq, PartialEq)] | 124 | #[derive(Debug, Clone, Eq, PartialEq)] |
106 | pub struct TargetData { | 125 | pub struct TargetData { |
126 | /// Package that provided this target | ||
107 | pub package: Package, | 127 | pub package: Package, |
128 | /// Name as given in the `Cargo.toml` or generated from the file name | ||
108 | pub name: String, | 129 | pub name: String, |
130 | /// Path to the main source file of the target | ||
109 | pub root: AbsPathBuf, | 131 | pub root: AbsPathBuf, |
132 | /// Kind of target | ||
110 | pub kind: TargetKind, | 133 | pub kind: TargetKind, |
134 | /// Is this target a proc-macro | ||
111 | pub is_proc_macro: bool, | 135 | pub is_proc_macro: bool, |
112 | } | 136 | } |
113 | 137 | ||
@@ -149,6 +173,7 @@ impl CargoWorkspace { | |||
149 | pub fn from_cargo_metadata( | 173 | pub fn from_cargo_metadata( |
150 | cargo_toml: &AbsPath, | 174 | cargo_toml: &AbsPath, |
151 | config: &CargoConfig, | 175 | config: &CargoConfig, |
176 | progress: &dyn Fn(String), | ||
152 | ) -> Result<CargoWorkspace> { | 177 | ) -> Result<CargoWorkspace> { |
153 | let mut meta = MetadataCommand::new(); | 178 | let mut meta = MetadataCommand::new(); |
154 | meta.cargo_path(toolchain::cargo()); | 179 | meta.cargo_path(toolchain::cargo()); |
@@ -198,6 +223,9 @@ impl CargoWorkspace { | |||
198 | meta.other_options(vec![String::from("--filter-platform"), target]); | 223 | meta.other_options(vec![String::from("--filter-platform"), target]); |
199 | } | 224 | } |
200 | 225 | ||
226 | // FIXME: Currently MetadataCommand is not based on parse_stream, | ||
227 | // So we just report it as a whole | ||
228 | progress("metadata".to_string()); | ||
201 | let mut meta = meta.exec().with_context(|| { | 229 | let mut meta = meta.exec().with_context(|| { |
202 | let cwd: Option<AbsPathBuf> = | 230 | let cwd: Option<AbsPathBuf> = |
203 | std::env::current_dir().ok().and_then(|p| p.try_into().ok()); | 231 | std::env::current_dir().ok().and_then(|p| p.try_into().ok()); |
@@ -221,7 +249,7 @@ impl CargoWorkspace { | |||
221 | let mut envs = FxHashMap::default(); | 249 | let mut envs = FxHashMap::default(); |
222 | let mut proc_macro_dylib_paths = FxHashMap::default(); | 250 | let mut proc_macro_dylib_paths = FxHashMap::default(); |
223 | if config.load_out_dirs_from_check { | 251 | if config.load_out_dirs_from_check { |
224 | let resources = load_extern_resources(cargo_toml, config)?; | 252 | let resources = load_extern_resources(cargo_toml, config, progress)?; |
225 | out_dir_by_id = resources.out_dirs; | 253 | out_dir_by_id = resources.out_dirs; |
226 | cfgs = resources.cfgs; | 254 | cfgs = resources.cfgs; |
227 | envs = resources.env; | 255 | envs = resources.env; |
@@ -346,6 +374,7 @@ pub(crate) struct ExternResources { | |||
346 | pub(crate) fn load_extern_resources( | 374 | pub(crate) fn load_extern_resources( |
347 | cargo_toml: &Path, | 375 | cargo_toml: &Path, |
348 | cargo_features: &CargoConfig, | 376 | cargo_features: &CargoConfig, |
377 | progress: &dyn Fn(String), | ||
349 | ) -> Result<ExternResources> { | 378 | ) -> Result<ExternResources> { |
350 | let mut cmd = Command::new(toolchain::cargo()); | 379 | let mut cmd = Command::new(toolchain::cargo()); |
351 | cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml); | 380 | cmd.args(&["check", "--message-format=json", "--manifest-path"]).arg(cargo_toml); |
@@ -373,11 +402,14 @@ pub(crate) fn load_extern_resources( | |||
373 | } | 402 | } |
374 | } | 403 | } |
375 | 404 | ||
376 | let output = cmd.output()?; | 405 | cmd.stdout(Stdio::piped()).stderr(Stdio::null()).stdin(Stdio::null()); |
377 | 406 | ||
378 | let mut res = ExternResources::default(); | 407 | let mut child = cmd.spawn().map(JodChild)?; |
408 | let child_stdout = child.stdout.take().unwrap(); | ||
409 | let stdout = BufReader::new(child_stdout); | ||
379 | 410 | ||
380 | for message in cargo_metadata::Message::parse_stream(output.stdout.as_slice()) { | 411 | let mut res = ExternResources::default(); |
412 | for message in cargo_metadata::Message::parse_stream(stdout) { | ||
381 | if let Ok(message) = message { | 413 | if let Ok(message) = message { |
382 | match message { | 414 | match message { |
383 | Message::BuildScriptExecuted(BuildScript { | 415 | Message::BuildScriptExecuted(BuildScript { |
@@ -410,6 +442,8 @@ pub(crate) fn load_extern_resources( | |||
410 | res.env.insert(package_id, env); | 442 | res.env.insert(package_id, env); |
411 | } | 443 | } |
412 | Message::CompilerArtifact(message) => { | 444 | Message::CompilerArtifact(message) => { |
445 | progress(format!("metadata {}", message.target.name)); | ||
446 | |||
413 | if message.target.kind.contains(&"proc-macro".to_string()) { | 447 | if message.target.kind.contains(&"proc-macro".to_string()) { |
414 | let package_id = message.package_id; | 448 | let package_id = message.package_id; |
415 | // Skip rmeta file | 449 | // Skip rmeta file |
@@ -420,7 +454,9 @@ pub(crate) fn load_extern_resources( | |||
420 | } | 454 | } |
421 | } | 455 | } |
422 | } | 456 | } |
423 | Message::CompilerMessage(_) => (), | 457 | Message::CompilerMessage(message) => { |
458 | progress(message.target.name.clone()); | ||
459 | } | ||
424 | Message::Unknown => (), | 460 | Message::Unknown => (), |
425 | Message::BuildFinished(_) => {} | 461 | Message::BuildFinished(_) => {} |
426 | Message::TextLine(_) => {} | 462 | Message::TextLine(_) => {} |
diff --git a/crates/project_model/src/lib.rs b/crates/project_model/src/lib.rs index 24aa9b8fa..aabb7a47d 100644 --- a/crates/project_model/src/lib.rs +++ b/crates/project_model/src/lib.rs | |||
@@ -1,9 +1,9 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | mod cargo_workspace; | 3 | mod cargo_workspace; |
4 | mod cfg_flag; | ||
4 | mod project_json; | 5 | mod project_json; |
5 | mod sysroot; | 6 | mod sysroot; |
6 | mod cfg_flag; | ||
7 | mod workspace; | 7 | mod workspace; |
8 | 8 | ||
9 | use std::{ | 9 | use std::{ |
@@ -17,7 +17,10 @@ use paths::{AbsPath, AbsPathBuf}; | |||
17 | use rustc_hash::FxHashSet; | 17 | use rustc_hash::FxHashSet; |
18 | 18 | ||
19 | pub use crate::{ | 19 | pub use crate::{ |
20 | cargo_workspace::{CargoConfig, CargoWorkspace, Package, Target, TargetKind}, | 20 | cargo_workspace::{ |
21 | CargoConfig, CargoWorkspace, Package, PackageData, PackageDependency, Target, TargetData, | ||
22 | TargetKind, | ||
23 | }, | ||
21 | project_json::{ProjectJson, ProjectJsonData}, | 24 | project_json::{ProjectJson, ProjectJsonData}, |
22 | sysroot::Sysroot, | 25 | sysroot::Sysroot, |
23 | workspace::{PackageRoot, ProjectWorkspace}, | 26 | workspace::{PackageRoot, ProjectWorkspace}, |
diff --git a/crates/project_model/src/project_json.rs b/crates/project_model/src/project_json.rs index af884eb84..41a2ac03e 100644 --- a/crates/project_model/src/project_json.rs +++ b/crates/project_model/src/project_json.rs | |||
@@ -110,13 +110,13 @@ impl ProjectJson { | |||
110 | } | 110 | } |
111 | } | 111 | } |
112 | 112 | ||
113 | #[derive(Deserialize)] | 113 | #[derive(Deserialize, Debug, Clone)] |
114 | pub struct ProjectJsonData { | 114 | pub struct ProjectJsonData { |
115 | sysroot_src: Option<PathBuf>, | 115 | sysroot_src: Option<PathBuf>, |
116 | crates: Vec<CrateData>, | 116 | crates: Vec<CrateData>, |
117 | } | 117 | } |
118 | 118 | ||
119 | #[derive(Deserialize)] | 119 | #[derive(Deserialize, Debug, Clone)] |
120 | struct CrateData { | 120 | struct CrateData { |
121 | display_name: Option<String>, | 121 | display_name: Option<String>, |
122 | root_module: PathBuf, | 122 | root_module: PathBuf, |
@@ -132,7 +132,7 @@ struct CrateData { | |||
132 | source: Option<CrateSource>, | 132 | source: Option<CrateSource>, |
133 | } | 133 | } |
134 | 134 | ||
135 | #[derive(Deserialize)] | 135 | #[derive(Deserialize, Debug, Clone)] |
136 | #[serde(rename = "edition")] | 136 | #[serde(rename = "edition")] |
137 | enum EditionData { | 137 | enum EditionData { |
138 | #[serde(rename = "2015")] | 138 | #[serde(rename = "2015")] |
@@ -153,7 +153,7 @@ impl From<EditionData> for Edition { | |||
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
156 | #[derive(Deserialize)] | 156 | #[derive(Deserialize, Debug, Clone)] |
157 | struct DepData { | 157 | struct DepData { |
158 | /// Identifies a crate by position in the crates array. | 158 | /// Identifies a crate by position in the crates array. |
159 | #[serde(rename = "crate")] | 159 | #[serde(rename = "crate")] |
@@ -162,7 +162,7 @@ struct DepData { | |||
162 | name: CrateName, | 162 | name: CrateName, |
163 | } | 163 | } |
164 | 164 | ||
165 | #[derive(Deserialize)] | 165 | #[derive(Deserialize, Debug, Clone)] |
166 | struct CrateSource { | 166 | struct CrateSource { |
167 | include_dirs: Vec<PathBuf>, | 167 | include_dirs: Vec<PathBuf>, |
168 | exclude_dirs: Vec<PathBuf>, | 168 | exclude_dirs: Vec<PathBuf>, |
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs index 68a235ce3..06a0be284 100644 --- a/crates/project_model/src/workspace.rs +++ b/crates/project_model/src/workspace.rs | |||
@@ -64,7 +64,11 @@ impl fmt::Debug for ProjectWorkspace { | |||
64 | } | 64 | } |
65 | 65 | ||
66 | impl ProjectWorkspace { | 66 | impl ProjectWorkspace { |
67 | pub fn load(manifest: ProjectManifest, config: &CargoConfig) -> Result<ProjectWorkspace> { | 67 | pub fn load( |
68 | manifest: ProjectManifest, | ||
69 | config: &CargoConfig, | ||
70 | progress: &dyn Fn(String), | ||
71 | ) -> Result<ProjectWorkspace> { | ||
68 | let res = match manifest { | 72 | let res = match manifest { |
69 | ProjectManifest::ProjectJson(project_json) => { | 73 | ProjectManifest::ProjectJson(project_json) => { |
70 | let file = fs::read_to_string(&project_json).with_context(|| { | 74 | let file = fs::read_to_string(&project_json).with_context(|| { |
@@ -84,15 +88,14 @@ impl ProjectWorkspace { | |||
84 | cmd | 88 | cmd |
85 | })?; | 89 | })?; |
86 | 90 | ||
87 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, config).with_context( | 91 | let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, config, progress) |
88 | || { | 92 | .with_context(|| { |
89 | format!( | 93 | format!( |
90 | "Failed to read Cargo metadata from Cargo.toml file {}, {}", | 94 | "Failed to read Cargo metadata from Cargo.toml file {}, {}", |
91 | cargo_toml.display(), | 95 | cargo_toml.display(), |
92 | cargo_version | 96 | cargo_version |
93 | ) | 97 | ) |
94 | }, | 98 | })?; |
95 | )?; | ||
96 | let sysroot = if config.no_sysroot { | 99 | let sysroot = if config.no_sysroot { |
97 | Sysroot::default() | 100 | Sysroot::default() |
98 | } else { | 101 | } else { |
@@ -105,9 +108,12 @@ impl ProjectWorkspace { | |||
105 | }; | 108 | }; |
106 | 109 | ||
107 | let rustc = if let Some(rustc_dir) = &config.rustc_source { | 110 | let rustc = if let Some(rustc_dir) = &config.rustc_source { |
108 | Some(CargoWorkspace::from_cargo_metadata(&rustc_dir, config).with_context( | 111 | Some( |
109 | || format!("Failed to read Cargo metadata for Rust sources"), | 112 | CargoWorkspace::from_cargo_metadata(&rustc_dir, config, progress) |
110 | )?) | 113 | .with_context(|| { |
114 | format!("Failed to read Cargo metadata for Rust sources") | ||
115 | })?, | ||
116 | ) | ||
111 | } else { | 117 | } else { |
112 | None | 118 | None |
113 | }; | 119 | }; |
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml index 0a63593fb..af7b86ead 100644 --- a/crates/rust-analyzer/Cargo.toml +++ b/crates/rust-analyzer/Cargo.toml | |||
@@ -62,7 +62,7 @@ proc_macro_srv = { path = "../proc_macro_srv", version = "0.0.0" } | |||
62 | winapi = "0.3.8" | 62 | winapi = "0.3.8" |
63 | 63 | ||
64 | [dev-dependencies] | 64 | [dev-dependencies] |
65 | expect-test = "1.0" | 65 | expect-test = "1.1" |
66 | test_utils = { path = "../test_utils" } | 66 | test_utils = { path = "../test_utils" } |
67 | mbe = { path = "../mbe" } | 67 | mbe = { path = "../mbe" } |
68 | tt = { path = "../tt" } | 68 | tt = { path = "../tt" } |
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs index defdcbd74..3af3c59d8 100644 --- a/crates/rust-analyzer/src/bin/main.rs +++ b/crates/rust-analyzer/src/bin/main.rs | |||
@@ -8,11 +8,7 @@ use std::{convert::TryFrom, env, fs, path::PathBuf, process}; | |||
8 | 8 | ||
9 | use lsp_server::Connection; | 9 | use lsp_server::Connection; |
10 | use project_model::ProjectManifest; | 10 | use project_model::ProjectManifest; |
11 | use rust_analyzer::{ | 11 | use rust_analyzer::{cli, config::Config, from_json, Result}; |
12 | cli, | ||
13 | config::{Config, LinkedProject}, | ||
14 | from_json, Result, | ||
15 | }; | ||
16 | use vfs::AbsPathBuf; | 12 | use vfs::AbsPathBuf; |
17 | 13 | ||
18 | #[cfg(all(feature = "mimalloc"))] | 14 | #[cfg(all(feature = "mimalloc"))] |
@@ -138,13 +134,12 @@ fn run_server() -> Result<()> { | |||
138 | } | 134 | } |
139 | }; | 135 | }; |
140 | 136 | ||
141 | let mut config = Config::new(root_path); | 137 | let mut config = Config::new(root_path, initialize_params.capabilities); |
142 | if let Some(json) = initialize_params.initialization_options { | 138 | if let Some(json) = initialize_params.initialization_options { |
143 | config.update(json); | 139 | config.update(json); |
144 | } | 140 | } |
145 | config.update_caps(&initialize_params.capabilities); | ||
146 | 141 | ||
147 | if config.linked_projects.is_empty() { | 142 | if config.linked_projects().is_empty() { |
148 | let workspace_roots = initialize_params | 143 | let workspace_roots = initialize_params |
149 | .workspace_folders | 144 | .workspace_folders |
150 | .map(|workspaces| { | 145 | .map(|workspaces| { |
@@ -163,7 +158,7 @@ fn run_server() -> Result<()> { | |||
163 | log::error!("failed to find any projects in {:?}", workspace_roots); | 158 | log::error!("failed to find any projects in {:?}", workspace_roots); |
164 | } | 159 | } |
165 | 160 | ||
166 | config.linked_projects = discovered.into_iter().map(LinkedProject::from).collect(); | 161 | config.discovered_projects = Some(discovered); |
167 | } | 162 | } |
168 | 163 | ||
169 | config | 164 | config |
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs index 80e46bf7f..3db0d55c5 100644 --- a/crates/rust-analyzer/src/caps.rs +++ b/crates/rust-analyzer/src/caps.rs | |||
@@ -1,7 +1,6 @@ | |||
1 | //! Advertizes the capabilities of the LSP Server. | 1 | //! Advertizes the capabilities of the LSP Server. |
2 | use std::env; | 2 | use std::env; |
3 | 3 | ||
4 | use ide::CompletionResolveCapability; | ||
5 | use lsp_types::{ | 4 | use lsp_types::{ |
6 | CallHierarchyServerCapability, ClientCapabilities, CodeActionKind, CodeActionOptions, | 5 | CallHierarchyServerCapability, ClientCapabilities, CodeActionKind, CodeActionOptions, |
7 | CodeActionProviderCapability, CodeLensOptions, CompletionOptions, | 6 | CodeActionProviderCapability, CodeLensOptions, CompletionOptions, |
@@ -14,7 +13,6 @@ use lsp_types::{ | |||
14 | WorkDoneProgressOptions, WorkspaceFileOperationsServerCapabilities, | 13 | WorkDoneProgressOptions, WorkspaceFileOperationsServerCapabilities, |
15 | WorkspaceServerCapabilities, | 14 | WorkspaceServerCapabilities, |
16 | }; | 15 | }; |
17 | use rustc_hash::FxHashSet; | ||
18 | use serde_json::json; | 16 | use serde_json::json; |
19 | 17 | ||
20 | use crate::semantic_tokens; | 18 | use crate::semantic_tokens; |
@@ -118,37 +116,31 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti | |||
118 | } | 116 | } |
119 | 117 | ||
120 | fn completions_resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> { | 118 | fn completions_resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> { |
121 | if enabled_completions_resolve_capabilities(client_caps)?.is_empty() { | 119 | if completion_item_edit_resolve(client_caps) { |
120 | Some(true) | ||
121 | } else { | ||
122 | log::info!("No `additionalTextEdits` completion resolve capability was found in the client capabilities, autoimport completion is disabled"); | 122 | log::info!("No `additionalTextEdits` completion resolve capability was found in the client capabilities, autoimport completion is disabled"); |
123 | None | 123 | None |
124 | } else { | ||
125 | Some(true) | ||
126 | } | 124 | } |
127 | } | 125 | } |
128 | 126 | ||
129 | /// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports. | 127 | /// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports. |
130 | pub(crate) fn enabled_completions_resolve_capabilities( | 128 | pub(crate) fn completion_item_edit_resolve(caps: &ClientCapabilities) -> bool { |
131 | caps: &ClientCapabilities, | 129 | (|| { |
132 | ) -> Option<FxHashSet<CompletionResolveCapability>> { | 130 | Some( |
133 | Some( | 131 | caps.text_document |
134 | caps.text_document | 132 | .as_ref()? |
135 | .as_ref()? | 133 | .completion |
136 | .completion | 134 | .as_ref()? |
137 | .as_ref()? | 135 | .completion_item |
138 | .completion_item | 136 | .as_ref()? |
139 | .as_ref()? | 137 | .resolve_support |
140 | .resolve_support | 138 | .as_ref()? |
141 | .as_ref()? | 139 | .properties |
142 | .properties | 140 | .iter() |
143 | .iter() | 141 | .any(|cap_string| cap_string.as_str() == "additionalTextEdits"), |
144 | .filter_map(|cap_string| match cap_string.as_str() { | 142 | ) |
145 | "additionalTextEdits" => Some(CompletionResolveCapability::AdditionalTextEdits), | 143 | })() == Some(true) |
146 | "detail" => Some(CompletionResolveCapability::Detail), | ||
147 | "documentation" => Some(CompletionResolveCapability::Documentation), | ||
148 | _unsupported => None, | ||
149 | }) | ||
150 | .collect(), | ||
151 | ) | ||
152 | } | 144 | } |
153 | 145 | ||
154 | fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability { | 146 | fn code_action_capabilities(client_caps: &ClientCapabilities) -> CodeActionProviderCapability { |
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs index 8a8b4a32c..5af0802a2 100644 --- a/crates/rust-analyzer/src/cargo_target_spec.rs +++ b/crates/rust-analyzer/src/cargo_target_spec.rs | |||
@@ -84,14 +84,15 @@ impl CargoTargetSpec { | |||
84 | } | 84 | } |
85 | } | 85 | } |
86 | 86 | ||
87 | if snap.config.cargo.all_features { | 87 | let cargo_config = snap.config.cargo(); |
88 | if cargo_config.all_features { | ||
88 | args.push("--all-features".to_string()); | 89 | args.push("--all-features".to_string()); |
89 | } else { | 90 | } else { |
90 | let mut features = Vec::new(); | 91 | let mut features = Vec::new(); |
91 | if let Some(cfg) = cfg.as_ref() { | 92 | if let Some(cfg) = cfg.as_ref() { |
92 | required_features(cfg, &mut features); | 93 | required_features(cfg, &mut features); |
93 | } | 94 | } |
94 | for feature in &snap.config.cargo.features { | 95 | for feature in cargo_config.features { |
95 | features.push(feature.clone()); | 96 | features.push(feature.clone()); |
96 | } | 97 | } |
97 | features.dedup(); | 98 | features.dedup(); |
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 5a8484c62..7d3fda7a8 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs | |||
@@ -6,9 +6,12 @@ use anyhow::{bail, format_err, Result}; | |||
6 | use ide::{ | 6 | use ide::{ |
7 | Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, | 7 | Analysis, AnalysisHost, Change, CompletionConfig, DiagnosticsConfig, FilePosition, LineCol, |
8 | }; | 8 | }; |
9 | use ide_db::base_db::{ | 9 | use ide_db::{ |
10 | salsa::{Database, Durability}, | 10 | base_db::{ |
11 | FileId, | 11 | salsa::{Database, Durability}, |
12 | FileId, | ||
13 | }, | ||
14 | helpers::SnippetCap, | ||
12 | }; | 15 | }; |
13 | use vfs::AbsPathBuf; | 16 | use vfs::AbsPathBuf; |
14 | 17 | ||
@@ -87,7 +90,14 @@ impl BenchCmd { | |||
87 | let file_position = FilePosition { file_id, offset }; | 90 | let file_position = FilePosition { file_id, offset }; |
88 | 91 | ||
89 | if is_completion { | 92 | if is_completion { |
90 | let options = CompletionConfig::default(); | 93 | let options = CompletionConfig { |
94 | enable_postfix_completions: true, | ||
95 | enable_autoimport_completions: true, | ||
96 | add_call_parenthesis: true, | ||
97 | add_call_argument_snippets: true, | ||
98 | snippet_cap: SnippetCap::new(true), | ||
99 | merge: None, | ||
100 | }; | ||
91 | let res = do_work(&mut host, file_id, |analysis| { | 101 | let res = do_work(&mut host, file_id, |analysis| { |
92 | analysis.completions(&options, file_position) | 102 | analysis.completions(&options, file_position) |
93 | }); | 103 | }); |
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs index e5ab6c73b..31a16ca46 100644 --- a/crates/rust-analyzer/src/cli/load_cargo.rs +++ b/crates/rust-analyzer/src/cli/load_cargo.rs | |||
@@ -21,6 +21,7 @@ pub fn load_cargo( | |||
21 | let ws = ProjectWorkspace::load( | 21 | let ws = ProjectWorkspace::load( |
22 | root, | 22 | root, |
23 | &CargoConfig { load_out_dirs_from_check, ..Default::default() }, | 23 | &CargoConfig { load_out_dirs_from_check, ..Default::default() }, |
24 | &|_| {}, | ||
24 | )?; | 25 | )?; |
25 | 26 | ||
26 | let (sender, receiver) = unbounded(); | 27 | let (sender, receiver) = unbounded(); |
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs index 685a9fdf0..2d3e25cbf 100644 --- a/crates/rust-analyzer/src/config.rs +++ b/crates/rust-analyzer/src/config.rs | |||
@@ -7,12 +7,15 @@ | |||
7 | //! configure the server itself, feature flags are passed into analysis, and | 7 | //! configure the server itself, feature flags are passed into analysis, and |
8 | //! tweak things like automatic insertion of `()` in completions. | 8 | //! tweak things like automatic insertion of `()` in completions. |
9 | 9 | ||
10 | use std::{convert::TryFrom, ffi::OsString, path::PathBuf}; | 10 | use std::{convert::TryFrom, ffi::OsString, iter, path::PathBuf}; |
11 | 11 | ||
12 | use flycheck::FlycheckConfig; | 12 | use flycheck::FlycheckConfig; |
13 | use hir::PrefixKind; | 13 | use hir::PrefixKind; |
14 | use ide::{AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig}; | 14 | use ide::{ |
15 | use ide_db::helpers::insert_use::MergeBehavior; | 15 | AssistConfig, CompletionConfig, DiagnosticsConfig, HoverConfig, InlayHintsConfig, |
16 | InsertUseConfig, | ||
17 | }; | ||
18 | use ide_db::helpers::{insert_use::MergeBehavior, SnippetCap}; | ||
16 | use itertools::Itertools; | 19 | use itertools::Itertools; |
17 | use lsp_types::{ClientCapabilities, MarkupKind}; | 20 | use lsp_types::{ClientCapabilities, MarkupKind}; |
18 | use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest}; | 21 | use project_model::{CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest}; |
@@ -20,12 +23,13 @@ use rustc_hash::FxHashSet; | |||
20 | use serde::{de::DeserializeOwned, Deserialize}; | 23 | use serde::{de::DeserializeOwned, Deserialize}; |
21 | use vfs::AbsPathBuf; | 24 | use vfs::AbsPathBuf; |
22 | 25 | ||
23 | use crate::{caps::enabled_completions_resolve_capabilities, diagnostics::DiagnosticsMapConfig}; | 26 | use crate::{caps::completion_item_edit_resolve, diagnostics::DiagnosticsMapConfig}; |
24 | 27 | ||
25 | config_data! { | 28 | config_data! { |
26 | struct ConfigData { | 29 | struct ConfigData { |
27 | /// The strategy to use when inserting new imports or merging imports. | 30 | /// The strategy to use when inserting new imports or merging imports. |
28 | assist_importMergeBehaviour: MergeBehaviorDef = "\"full\"", | 31 | assist_importMergeBehavior | |
32 | assist_importMergeBehaviour: MergeBehaviorDef = "\"full\"", | ||
29 | /// The path structure for newly inserted paths to use. | 33 | /// The path structure for newly inserted paths to use. |
30 | assist_importPrefix: ImportPrefixDef = "\"plain\"", | 34 | assist_importPrefix: ImportPrefixDef = "\"plain\"", |
31 | 35 | ||
@@ -148,13 +152,19 @@ config_data! { | |||
148 | /// of projects.\n\nElements must be paths pointing to `Cargo.toml`, | 152 | /// of projects.\n\nElements must be paths pointing to `Cargo.toml`, |
149 | /// `rust-project.json`, or JSON objects in `rust-project.json` format. | 153 | /// `rust-project.json`, or JSON objects in `rust-project.json` format. |
150 | linkedProjects: Vec<ManifestOrProjectJson> = "[]", | 154 | linkedProjects: Vec<ManifestOrProjectJson> = "[]", |
155 | |||
151 | /// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128. | 156 | /// Number of syntax trees rust-analyzer keeps in memory. Defaults to 128. |
152 | lruCapacity: Option<usize> = "null", | 157 | lruCapacity: Option<usize> = "null", |
158 | |||
153 | /// Whether to show `can't find Cargo.toml` error message. | 159 | /// Whether to show `can't find Cargo.toml` error message. |
154 | notifications_cargoTomlNotFound: bool = "true", | 160 | notifications_cargoTomlNotFound: bool = "true", |
161 | |||
155 | /// Enable Proc macro support, `#rust-analyzer.cargo.loadOutDirsFromCheck#` must be | 162 | /// Enable Proc macro support, `#rust-analyzer.cargo.loadOutDirsFromCheck#` must be |
156 | /// enabled. | 163 | /// enabled. |
157 | procMacro_enable: bool = "false", | 164 | procMacro_enable: bool = "false", |
165 | /// Internal config, path to proc-macro server executable (typically, | ||
166 | /// this is rust-analyzer itself, but we override this in tests). | ||
167 | procMacro_server: Option<PathBuf> = "null", | ||
158 | 168 | ||
159 | /// Command to be executed instead of 'cargo' for runnables. | 169 | /// Command to be executed instead of 'cargo' for runnables. |
160 | runnables_overrideCargo: Option<String> = "null", | 170 | runnables_overrideCargo: Option<String> = "null", |
@@ -163,7 +173,7 @@ config_data! { | |||
163 | runnables_cargoExtraArgs: Vec<String> = "[]", | 173 | runnables_cargoExtraArgs: Vec<String> = "[]", |
164 | 174 | ||
165 | /// Path to the rust compiler sources, for usage in rustc_private projects. | 175 | /// Path to the rust compiler sources, for usage in rustc_private projects. |
166 | rustcSource : Option<String> = "null", | 176 | rustcSource : Option<PathBuf> = "null", |
167 | 177 | ||
168 | /// Additional arguments to `rustfmt`. | 178 | /// Additional arguments to `rustfmt`. |
169 | rustfmt_extraArgs: Vec<String> = "[]", | 179 | rustfmt_extraArgs: Vec<String> = "[]", |
@@ -173,34 +183,17 @@ config_data! { | |||
173 | } | 183 | } |
174 | } | 184 | } |
175 | 185 | ||
186 | impl Default for ConfigData { | ||
187 | fn default() -> Self { | ||
188 | ConfigData::from_json(serde_json::Value::Null) | ||
189 | } | ||
190 | } | ||
191 | |||
176 | #[derive(Debug, Clone)] | 192 | #[derive(Debug, Clone)] |
177 | pub struct Config { | 193 | pub struct Config { |
178 | pub client_caps: ClientCapsConfig, | 194 | caps: lsp_types::ClientCapabilities, |
179 | 195 | data: ConfigData, | |
180 | pub publish_diagnostics: bool, | 196 | pub discovered_projects: Option<Vec<ProjectManifest>>, |
181 | pub diagnostics: DiagnosticsConfig, | ||
182 | pub diagnostics_map: DiagnosticsMapConfig, | ||
183 | pub lru_capacity: Option<usize>, | ||
184 | pub proc_macro_srv: Option<(PathBuf, Vec<OsString>)>, | ||
185 | pub files: FilesConfig, | ||
186 | pub notifications: NotificationsConfig, | ||
187 | |||
188 | pub cargo_autoreload: bool, | ||
189 | pub cargo: CargoConfig, | ||
190 | pub rustfmt: RustfmtConfig, | ||
191 | pub flycheck: Option<FlycheckConfig>, | ||
192 | pub runnables: RunnablesConfig, | ||
193 | |||
194 | pub inlay_hints: InlayHintsConfig, | ||
195 | pub completion: CompletionConfig, | ||
196 | pub assist: AssistConfig, | ||
197 | pub call_info_full: bool, | ||
198 | pub lens: LensConfig, | ||
199 | pub hover: HoverConfig, | ||
200 | pub semantic_tokens_refresh: bool, | ||
201 | pub code_lens_refresh: bool, | ||
202 | |||
203 | pub linked_projects: Vec<LinkedProject>, | ||
204 | pub root_path: AbsPathBuf, | 197 | pub root_path: AbsPathBuf, |
205 | } | 198 | } |
206 | 199 | ||
@@ -230,12 +223,6 @@ pub struct LensConfig { | |||
230 | pub method_refs: bool, | 223 | pub method_refs: bool, |
231 | } | 224 | } |
232 | 225 | ||
233 | impl Default for LensConfig { | ||
234 | fn default() -> Self { | ||
235 | Self { run: true, debug: true, implementations: true, method_refs: false } | ||
236 | } | ||
237 | } | ||
238 | |||
239 | impl LensConfig { | 226 | impl LensConfig { |
240 | pub fn any(&self) -> bool { | 227 | pub fn any(&self) -> bool { |
241 | self.implementations || self.runnable() || self.references() | 228 | self.implementations || self.runnable() || self.references() |
@@ -278,7 +265,7 @@ pub enum RustfmtConfig { | |||
278 | } | 265 | } |
279 | 266 | ||
280 | /// Configuration for runnable items, such as `main` function or tests. | 267 | /// Configuration for runnable items, such as `main` function or tests. |
281 | #[derive(Debug, Clone, Default)] | 268 | #[derive(Debug, Clone)] |
282 | pub struct RunnablesConfig { | 269 | pub struct RunnablesConfig { |
283 | /// Custom command to be executed instead of `cargo` for runnables. | 270 | /// Custom command to be executed instead of `cargo` for runnables. |
284 | pub override_cargo: Option<String>, | 271 | pub override_cargo: Option<String>, |
@@ -286,325 +273,354 @@ pub struct RunnablesConfig { | |||
286 | pub cargo_extra_args: Vec<String>, | 273 | pub cargo_extra_args: Vec<String>, |
287 | } | 274 | } |
288 | 275 | ||
289 | #[derive(Debug, Clone, Default)] | ||
290 | pub struct ClientCapsConfig { | ||
291 | pub location_link: bool, | ||
292 | pub line_folding_only: bool, | ||
293 | pub hierarchical_symbols: bool, | ||
294 | pub code_action_literals: bool, | ||
295 | pub work_done_progress: bool, | ||
296 | pub code_action_group: bool, | ||
297 | pub code_action_resolve: bool, | ||
298 | pub hover_actions: bool, | ||
299 | pub status_notification: bool, | ||
300 | pub signature_help_label_offsets: bool, | ||
301 | } | ||
302 | |||
303 | impl Config { | 276 | impl Config { |
304 | pub fn new(root_path: AbsPathBuf) -> Self { | 277 | pub fn new(root_path: AbsPathBuf, caps: ClientCapabilities) -> Self { |
305 | // Defaults here don't matter, we'll immediately re-write them with | 278 | Config { caps, data: ConfigData::default(), discovered_projects: None, root_path } |
306 | // ConfigData. | ||
307 | let mut res = Config { | ||
308 | client_caps: ClientCapsConfig::default(), | ||
309 | |||
310 | publish_diagnostics: false, | ||
311 | diagnostics: DiagnosticsConfig::default(), | ||
312 | diagnostics_map: DiagnosticsMapConfig::default(), | ||
313 | lru_capacity: None, | ||
314 | proc_macro_srv: None, | ||
315 | files: FilesConfig { watcher: FilesWatcher::Notify, exclude: Vec::new() }, | ||
316 | notifications: NotificationsConfig { cargo_toml_not_found: false }, | ||
317 | |||
318 | cargo_autoreload: false, | ||
319 | cargo: CargoConfig::default(), | ||
320 | rustfmt: RustfmtConfig::Rustfmt { extra_args: Vec::new() }, | ||
321 | flycheck: Some(FlycheckConfig::CargoCommand { | ||
322 | command: String::new(), | ||
323 | target_triple: None, | ||
324 | no_default_features: false, | ||
325 | all_targets: false, | ||
326 | all_features: false, | ||
327 | extra_args: Vec::new(), | ||
328 | features: Vec::new(), | ||
329 | }), | ||
330 | runnables: RunnablesConfig::default(), | ||
331 | |||
332 | inlay_hints: InlayHintsConfig { | ||
333 | type_hints: false, | ||
334 | parameter_hints: false, | ||
335 | chaining_hints: false, | ||
336 | max_length: None, | ||
337 | }, | ||
338 | completion: CompletionConfig::default(), | ||
339 | assist: AssistConfig::default(), | ||
340 | call_info_full: false, | ||
341 | lens: LensConfig::default(), | ||
342 | hover: HoverConfig::default(), | ||
343 | semantic_tokens_refresh: false, | ||
344 | code_lens_refresh: false, | ||
345 | linked_projects: Vec::new(), | ||
346 | root_path, | ||
347 | }; | ||
348 | res.do_update(serde_json::json!({})); | ||
349 | res | ||
350 | } | 279 | } |
351 | pub fn update(&mut self, json: serde_json::Value) { | 280 | pub fn update(&mut self, json: serde_json::Value) { |
352 | log::info!("updating config from JSON: {:#}", json); | 281 | log::info!("updating config from JSON: {:#}", json); |
353 | if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { | 282 | if json.is_null() || json.as_object().map_or(false, |it| it.is_empty()) { |
354 | return; | 283 | return; |
355 | } | 284 | } |
356 | self.do_update(json); | 285 | self.data = ConfigData::from_json(json); |
357 | log::info!("updated config: {:#?}", self); | ||
358 | } | 286 | } |
359 | fn do_update(&mut self, json: serde_json::Value) { | ||
360 | let data = ConfigData::from_json(json); | ||
361 | 287 | ||
362 | self.publish_diagnostics = data.diagnostics_enable; | 288 | pub fn json_schema() -> serde_json::Value { |
363 | self.diagnostics = DiagnosticsConfig { | 289 | ConfigData::json_schema() |
364 | disable_experimental: !data.diagnostics_enableExperimental, | 290 | } |
365 | disabled: data.diagnostics_disabled, | 291 | } |
366 | }; | ||
367 | self.diagnostics_map = DiagnosticsMapConfig { | ||
368 | warnings_as_info: data.diagnostics_warningsAsInfo, | ||
369 | warnings_as_hint: data.diagnostics_warningsAsHint, | ||
370 | }; | ||
371 | self.lru_capacity = data.lruCapacity; | ||
372 | self.files.watcher = match data.files_watcher.as_str() { | ||
373 | "notify" => FilesWatcher::Notify, | ||
374 | "client" | _ => FilesWatcher::Client, | ||
375 | }; | ||
376 | self.notifications = | ||
377 | NotificationsConfig { cargo_toml_not_found: data.notifications_cargoTomlNotFound }; | ||
378 | self.cargo_autoreload = data.cargo_autoreload; | ||
379 | |||
380 | let rustc_source = if let Some(rustc_source) = data.rustcSource { | ||
381 | let rustpath: PathBuf = rustc_source.into(); | ||
382 | AbsPathBuf::try_from(rustpath) | ||
383 | .map_err(|_| { | ||
384 | log::error!("rustc source directory must be an absolute path"); | ||
385 | }) | ||
386 | .ok() | ||
387 | } else { | ||
388 | None | ||
389 | }; | ||
390 | |||
391 | self.cargo = CargoConfig { | ||
392 | no_default_features: data.cargo_noDefaultFeatures, | ||
393 | all_features: data.cargo_allFeatures, | ||
394 | features: data.cargo_features.clone(), | ||
395 | load_out_dirs_from_check: data.cargo_loadOutDirsFromCheck, | ||
396 | target: data.cargo_target.clone(), | ||
397 | rustc_source: rustc_source, | ||
398 | no_sysroot: data.cargo_noSysroot, | ||
399 | }; | ||
400 | self.runnables = RunnablesConfig { | ||
401 | override_cargo: data.runnables_overrideCargo, | ||
402 | cargo_extra_args: data.runnables_cargoExtraArgs, | ||
403 | }; | ||
404 | |||
405 | self.proc_macro_srv = if data.procMacro_enable { | ||
406 | std::env::current_exe().ok().map(|path| (path, vec!["proc-macro".into()])) | ||
407 | } else { | ||
408 | None | ||
409 | }; | ||
410 | 292 | ||
411 | self.rustfmt = match data.rustfmt_overrideCommand { | 293 | macro_rules! try_ { |
412 | Some(mut args) if !args.is_empty() => { | 294 | ($expr:expr) => { |
413 | let command = args.remove(0); | 295 | || -> _ { Some($expr) }() |
414 | RustfmtConfig::CustomCommand { command, args } | 296 | }; |
415 | } | 297 | } |
416 | Some(_) | None => RustfmtConfig::Rustfmt { extra_args: data.rustfmt_extraArgs }, | 298 | macro_rules! try_or { |
417 | }; | 299 | ($expr:expr, $or:expr) => { |
300 | try_!($expr).unwrap_or($or) | ||
301 | }; | ||
302 | } | ||
418 | 303 | ||
419 | self.flycheck = if data.checkOnSave_enable { | 304 | impl Config { |
420 | let flycheck_config = match data.checkOnSave_overrideCommand { | 305 | pub fn linked_projects(&self) -> Vec<LinkedProject> { |
421 | Some(mut args) if !args.is_empty() => { | 306 | if self.data.linkedProjects.is_empty() { |
422 | let command = args.remove(0); | 307 | self.discovered_projects |
423 | FlycheckConfig::CustomCommand { command, args } | 308 | .as_ref() |
424 | } | 309 | .into_iter() |
425 | Some(_) | None => FlycheckConfig::CargoCommand { | 310 | .flatten() |
426 | command: data.checkOnSave_command, | 311 | .cloned() |
427 | target_triple: data.checkOnSave_target.or(data.cargo_target), | 312 | .map(LinkedProject::from) |
428 | all_targets: data.checkOnSave_allTargets, | 313 | .collect() |
429 | no_default_features: data | ||
430 | .checkOnSave_noDefaultFeatures | ||
431 | .unwrap_or(data.cargo_noDefaultFeatures), | ||
432 | all_features: data.checkOnSave_allFeatures.unwrap_or(data.cargo_allFeatures), | ||
433 | features: data.checkOnSave_features.unwrap_or(data.cargo_features), | ||
434 | extra_args: data.checkOnSave_extraArgs, | ||
435 | }, | ||
436 | }; | ||
437 | Some(flycheck_config) | ||
438 | } else { | 314 | } else { |
439 | None | 315 | self.data |
440 | }; | 316 | .linkedProjects |
441 | 317 | .iter() | |
442 | self.inlay_hints = InlayHintsConfig { | 318 | .filter_map(|linked_project| { |
443 | type_hints: data.inlayHints_typeHints, | 319 | let res = match linked_project { |
444 | parameter_hints: data.inlayHints_parameterHints, | 320 | ManifestOrProjectJson::Manifest(it) => { |
445 | chaining_hints: data.inlayHints_chainingHints, | 321 | let path = self.root_path.join(it); |
446 | max_length: data.inlayHints_maxLength, | 322 | ProjectManifest::from_manifest_file(path) |
447 | }; | 323 | .map_err(|e| log::error!("failed to load linked project: {}", e)) |
448 | 324 | .ok()? | |
449 | self.assist.insert_use.merge = match data.assist_importMergeBehaviour { | 325 | .into() |
450 | MergeBehaviorDef::None => None, | ||
451 | MergeBehaviorDef::Full => Some(MergeBehavior::Full), | ||
452 | MergeBehaviorDef::Last => Some(MergeBehavior::Last), | ||
453 | }; | ||
454 | self.assist.insert_use.prefix_kind = match data.assist_importPrefix { | ||
455 | ImportPrefixDef::Plain => PrefixKind::Plain, | ||
456 | ImportPrefixDef::ByCrate => PrefixKind::ByCrate, | ||
457 | ImportPrefixDef::BySelf => PrefixKind::BySelf, | ||
458 | }; | ||
459 | |||
460 | self.completion.enable_postfix_completions = data.completion_postfix_enable; | ||
461 | self.completion.enable_autoimport_completions = data.completion_autoimport_enable; | ||
462 | self.completion.add_call_parenthesis = data.completion_addCallParenthesis; | ||
463 | self.completion.add_call_argument_snippets = data.completion_addCallArgumentSnippets; | ||
464 | self.completion.merge = self.assist.insert_use.merge; | ||
465 | |||
466 | self.call_info_full = data.callInfo_full; | ||
467 | |||
468 | self.lens = LensConfig { | ||
469 | run: data.lens_enable && data.lens_run, | ||
470 | debug: data.lens_enable && data.lens_debug, | ||
471 | implementations: data.lens_enable && data.lens_implementations, | ||
472 | method_refs: data.lens_enable && data.lens_methodReferences, | ||
473 | }; | ||
474 | |||
475 | if !data.linkedProjects.is_empty() { | ||
476 | self.linked_projects.clear(); | ||
477 | for linked_project in data.linkedProjects { | ||
478 | let linked_project = match linked_project { | ||
479 | ManifestOrProjectJson::Manifest(it) => { | ||
480 | let path = self.root_path.join(it); | ||
481 | match ProjectManifest::from_manifest_file(path) { | ||
482 | Ok(it) => it.into(), | ||
483 | Err(e) => { | ||
484 | log::error!("failed to load linked project: {}", e); | ||
485 | continue; | ||
486 | } | ||
487 | } | 326 | } |
488 | } | 327 | ManifestOrProjectJson::ProjectJson(it) => { |
489 | ManifestOrProjectJson::ProjectJson(it) => { | 328 | ProjectJson::new(&self.root_path, it.clone()).into() |
490 | ProjectJson::new(&self.root_path, it).into() | 329 | } |
491 | } | 330 | }; |
492 | }; | 331 | Some(res) |
493 | self.linked_projects.push(linked_project); | 332 | }) |
494 | } | 333 | .collect() |
495 | } | 334 | } |
496 | |||
497 | self.hover = HoverConfig { | ||
498 | implementations: data.hoverActions_enable && data.hoverActions_implementations, | ||
499 | run: data.hoverActions_enable && data.hoverActions_run, | ||
500 | debug: data.hoverActions_enable && data.hoverActions_debug, | ||
501 | goto_type_def: data.hoverActions_enable && data.hoverActions_gotoTypeDef, | ||
502 | links_in_hover: data.hoverActions_linksInHover, | ||
503 | markdown: true, | ||
504 | }; | ||
505 | } | 335 | } |
506 | 336 | ||
507 | pub fn update_caps(&mut self, caps: &ClientCapabilities) { | 337 | pub fn location_link(&self) -> bool { |
508 | if let Some(doc_caps) = caps.text_document.as_ref() { | 338 | try_or!(self.caps.text_document.as_ref()?.definition?.link_support?, false) |
509 | if let Some(value) = doc_caps.hover.as_ref().and_then(|it| it.content_format.as_ref()) { | 339 | } |
510 | self.hover.markdown = value.contains(&MarkupKind::Markdown) | 340 | pub fn line_folding_only(&self) -> bool { |
511 | } | 341 | try_or!(self.caps.text_document.as_ref()?.folding_range.as_ref()?.line_folding_only?, false) |
512 | if let Some(value) = doc_caps.definition.as_ref().and_then(|it| it.link_support) { | 342 | } |
513 | self.client_caps.location_link = value; | 343 | pub fn hierarchical_symbols(&self) -> bool { |
514 | } | 344 | try_or!( |
515 | if let Some(value) = doc_caps.folding_range.as_ref().and_then(|it| it.line_folding_only) | 345 | self.caps |
516 | { | 346 | .text_document |
517 | self.client_caps.line_folding_only = value | 347 | .as_ref()? |
518 | } | ||
519 | if let Some(value) = doc_caps | ||
520 | .document_symbol | 348 | .document_symbol |
521 | .as_ref() | 349 | .as_ref()? |
522 | .and_then(|it| it.hierarchical_document_symbol_support) | 350 | .hierarchical_document_symbol_support?, |
523 | { | 351 | false |
524 | self.client_caps.hierarchical_symbols = value | 352 | ) |
525 | } | 353 | } |
526 | if let Some(value) = | 354 | pub fn code_action_literals(&self) -> bool { |
527 | doc_caps.code_action.as_ref().map(|it| it.code_action_literal_support.is_some()) | 355 | try_!(self |
528 | { | 356 | .caps |
529 | self.client_caps.code_action_literals = value; | 357 | .text_document |
530 | } | 358 | .as_ref()? |
531 | if let Some(value) = doc_caps | 359 | .code_action |
360 | .as_ref()? | ||
361 | .code_action_literal_support | ||
362 | .as_ref()?) | ||
363 | .is_some() | ||
364 | } | ||
365 | pub fn work_done_progress(&self) -> bool { | ||
366 | try_or!(self.caps.window.as_ref()?.work_done_progress?, false) | ||
367 | } | ||
368 | pub fn code_action_resolve(&self) -> bool { | ||
369 | try_or!( | ||
370 | self.caps | ||
371 | .text_document | ||
372 | .as_ref()? | ||
373 | .code_action | ||
374 | .as_ref()? | ||
375 | .resolve_support | ||
376 | .as_ref()? | ||
377 | .properties | ||
378 | .as_slice(), | ||
379 | &[] | ||
380 | ) | ||
381 | .iter() | ||
382 | .any(|it| it == "edit") | ||
383 | } | ||
384 | pub fn signature_help_label_offsets(&self) -> bool { | ||
385 | try_or!( | ||
386 | self.caps | ||
387 | .text_document | ||
388 | .as_ref()? | ||
532 | .signature_help | 389 | .signature_help |
533 | .as_ref() | 390 | .as_ref()? |
534 | .and_then(|it| it.signature_information.as_ref()) | 391 | .signature_information |
535 | .and_then(|it| it.parameter_information.as_ref()) | 392 | .as_ref()? |
536 | .and_then(|it| it.label_offset_support) | 393 | .parameter_information |
537 | { | 394 | .as_ref()? |
538 | self.client_caps.signature_help_label_offsets = value; | 395 | .label_offset_support?, |
539 | } | 396 | false |
397 | ) | ||
398 | } | ||
540 | 399 | ||
541 | self.completion.allow_snippets(false); | 400 | fn experimental(&self, index: &'static str) -> bool { |
542 | self.completion.active_resolve_capabilities = | 401 | try_or!(self.caps.experimental.as_ref()?.get(index)?.as_bool()?, false) |
543 | enabled_completions_resolve_capabilities(caps).unwrap_or_default(); | 402 | } |
544 | if let Some(completion) = &doc_caps.completion { | 403 | pub fn code_action_group(&self) -> bool { |
545 | if let Some(completion_item) = &completion.completion_item { | 404 | self.experimental("codeActionGroup") |
546 | if let Some(value) = completion_item.snippet_support { | 405 | } |
547 | self.completion.allow_snippets(value); | 406 | pub fn hover_actions(&self) -> bool { |
548 | } | 407 | self.experimental("hoverActions") |
549 | } | 408 | } |
550 | } | 409 | pub fn status_notification(&self) -> bool { |
410 | self.experimental("statusNotification") | ||
411 | } | ||
551 | 412 | ||
552 | if let Some(code_action) = &doc_caps.code_action { | 413 | pub fn publish_diagnostics(&self) -> bool { |
553 | if let Some(resolve_support) = &code_action.resolve_support { | 414 | self.data.diagnostics_enable |
554 | if resolve_support.properties.iter().any(|it| it == "edit") { | 415 | } |
555 | self.client_caps.code_action_resolve = true; | 416 | pub fn diagnostics(&self) -> DiagnosticsConfig { |
556 | } | 417 | DiagnosticsConfig { |
557 | } | 418 | disable_experimental: !self.data.diagnostics_enableExperimental, |
558 | } | 419 | disabled: self.data.diagnostics_disabled.clone(), |
559 | } | 420 | } |
560 | 421 | } | |
561 | if let Some(window_caps) = caps.window.as_ref() { | 422 | pub fn diagnostics_map(&self) -> DiagnosticsMapConfig { |
562 | if let Some(value) = window_caps.work_done_progress { | 423 | DiagnosticsMapConfig { |
563 | self.client_caps.work_done_progress = value; | 424 | warnings_as_info: self.data.diagnostics_warningsAsInfo.clone(), |
564 | } | 425 | warnings_as_hint: self.data.diagnostics_warningsAsHint.clone(), |
565 | } | 426 | } |
566 | 427 | } | |
567 | self.assist.allow_snippets(false); | 428 | pub fn lru_capacity(&self) -> Option<usize> { |
568 | if let Some(experimental) = &caps.experimental { | 429 | self.data.lruCapacity |
569 | let get_bool = | 430 | } |
570 | |index: &str| experimental.get(index).and_then(|it| it.as_bool()) == Some(true); | 431 | pub fn proc_macro_srv(&self) -> Option<(PathBuf, Vec<OsString>)> { |
571 | 432 | if !self.data.procMacro_enable { | |
572 | let snippet_text_edit = get_bool("snippetTextEdit"); | 433 | return None; |
573 | self.assist.allow_snippets(snippet_text_edit); | ||
574 | |||
575 | self.client_caps.code_action_group = get_bool("codeActionGroup"); | ||
576 | self.client_caps.hover_actions = get_bool("hoverActions"); | ||
577 | self.client_caps.status_notification = get_bool("statusNotification"); | ||
578 | } | 434 | } |
579 | 435 | ||
580 | if let Some(workspace_caps) = caps.workspace.as_ref() { | 436 | let path = self.data.procMacro_server.clone().or_else(|| std::env::current_exe().ok())?; |
581 | if let Some(refresh_support) = | 437 | Some((path, vec!["proc-macro".into()])) |
582 | workspace_caps.semantic_tokens.as_ref().and_then(|it| it.refresh_support) | 438 | } |
583 | { | 439 | pub fn files(&self) -> FilesConfig { |
584 | self.semantic_tokens_refresh = refresh_support; | 440 | FilesConfig { |
441 | watcher: match self.data.files_watcher.as_str() { | ||
442 | "notify" => FilesWatcher::Notify, | ||
443 | "client" | _ => FilesWatcher::Client, | ||
444 | }, | ||
445 | exclude: Vec::new(), | ||
446 | } | ||
447 | } | ||
448 | pub fn notifications(&self) -> NotificationsConfig { | ||
449 | NotificationsConfig { cargo_toml_not_found: self.data.notifications_cargoTomlNotFound } | ||
450 | } | ||
451 | pub fn cargo_autoreload(&self) -> bool { | ||
452 | self.data.cargo_autoreload | ||
453 | } | ||
454 | pub fn cargo(&self) -> CargoConfig { | ||
455 | let rustc_source = self.data.rustcSource.clone().and_then(|it| { | ||
456 | AbsPathBuf::try_from(it) | ||
457 | .map_err(|_| log::error!("rustc source directory must be an absolute path")) | ||
458 | .ok() | ||
459 | }); | ||
460 | |||
461 | CargoConfig { | ||
462 | no_default_features: self.data.cargo_noDefaultFeatures, | ||
463 | all_features: self.data.cargo_allFeatures, | ||
464 | features: self.data.cargo_features.clone(), | ||
465 | load_out_dirs_from_check: self.data.cargo_loadOutDirsFromCheck, | ||
466 | target: self.data.cargo_target.clone(), | ||
467 | rustc_source, | ||
468 | no_sysroot: self.data.cargo_noSysroot, | ||
469 | } | ||
470 | } | ||
471 | pub fn rustfmt(&self) -> RustfmtConfig { | ||
472 | match &self.data.rustfmt_overrideCommand { | ||
473 | Some(args) if !args.is_empty() => { | ||
474 | let mut args = args.clone(); | ||
475 | let command = args.remove(0); | ||
476 | RustfmtConfig::CustomCommand { command, args } | ||
585 | } | 477 | } |
586 | 478 | Some(_) | None => { | |
587 | if let Some(refresh_support) = | 479 | RustfmtConfig::Rustfmt { extra_args: self.data.rustfmt_extraArgs.clone() } |
588 | workspace_caps.code_lens.as_ref().and_then(|it| it.refresh_support) | ||
589 | { | ||
590 | self.code_lens_refresh = refresh_support; | ||
591 | } | 480 | } |
592 | } | 481 | } |
593 | } | 482 | } |
594 | 483 | pub fn flycheck(&self) -> Option<FlycheckConfig> { | |
595 | pub fn json_schema() -> serde_json::Value { | 484 | if !self.data.checkOnSave_enable { |
596 | ConfigData::json_schema() | 485 | return None; |
486 | } | ||
487 | let flycheck_config = match &self.data.checkOnSave_overrideCommand { | ||
488 | Some(args) if !args.is_empty() => { | ||
489 | let mut args = args.clone(); | ||
490 | let command = args.remove(0); | ||
491 | FlycheckConfig::CustomCommand { command, args } | ||
492 | } | ||
493 | Some(_) | None => FlycheckConfig::CargoCommand { | ||
494 | command: self.data.checkOnSave_command.clone(), | ||
495 | target_triple: self | ||
496 | .data | ||
497 | .checkOnSave_target | ||
498 | .clone() | ||
499 | .or(self.data.cargo_target.clone()), | ||
500 | all_targets: self.data.checkOnSave_allTargets, | ||
501 | no_default_features: self | ||
502 | .data | ||
503 | .checkOnSave_noDefaultFeatures | ||
504 | .unwrap_or(self.data.cargo_noDefaultFeatures), | ||
505 | all_features: self | ||
506 | .data | ||
507 | .checkOnSave_allFeatures | ||
508 | .unwrap_or(self.data.cargo_allFeatures), | ||
509 | features: self | ||
510 | .data | ||
511 | .checkOnSave_features | ||
512 | .clone() | ||
513 | .unwrap_or(self.data.cargo_features.clone()), | ||
514 | extra_args: self.data.checkOnSave_extraArgs.clone(), | ||
515 | }, | ||
516 | }; | ||
517 | Some(flycheck_config) | ||
518 | } | ||
519 | pub fn runnables(&self) -> RunnablesConfig { | ||
520 | RunnablesConfig { | ||
521 | override_cargo: self.data.runnables_overrideCargo.clone(), | ||
522 | cargo_extra_args: self.data.runnables_cargoExtraArgs.clone(), | ||
523 | } | ||
524 | } | ||
525 | pub fn inlay_hints(&self) -> InlayHintsConfig { | ||
526 | InlayHintsConfig { | ||
527 | type_hints: self.data.inlayHints_typeHints, | ||
528 | parameter_hints: self.data.inlayHints_parameterHints, | ||
529 | chaining_hints: self.data.inlayHints_chainingHints, | ||
530 | max_length: self.data.inlayHints_maxLength, | ||
531 | } | ||
532 | } | ||
533 | fn merge_behavior(&self) -> Option<MergeBehavior> { | ||
534 | match self.data.assist_importMergeBehavior { | ||
535 | MergeBehaviorDef::None => None, | ||
536 | MergeBehaviorDef::Full => Some(MergeBehavior::Full), | ||
537 | MergeBehaviorDef::Last => Some(MergeBehavior::Last), | ||
538 | } | ||
539 | } | ||
540 | pub fn completion(&self) -> CompletionConfig { | ||
541 | CompletionConfig { | ||
542 | enable_postfix_completions: self.data.completion_postfix_enable, | ||
543 | enable_autoimport_completions: self.data.completion_autoimport_enable | ||
544 | && completion_item_edit_resolve(&self.caps), | ||
545 | add_call_parenthesis: self.data.completion_addCallParenthesis, | ||
546 | add_call_argument_snippets: self.data.completion_addCallArgumentSnippets, | ||
547 | merge: self.merge_behavior(), | ||
548 | snippet_cap: SnippetCap::new(try_or!( | ||
549 | self.caps | ||
550 | .text_document | ||
551 | .as_ref()? | ||
552 | .completion | ||
553 | .as_ref()? | ||
554 | .completion_item | ||
555 | .as_ref()? | ||
556 | .snippet_support?, | ||
557 | false | ||
558 | )), | ||
559 | } | ||
560 | } | ||
561 | pub fn assist(&self) -> AssistConfig { | ||
562 | AssistConfig { | ||
563 | snippet_cap: SnippetCap::new(self.experimental("snippetTextEdit")), | ||
564 | allowed: None, | ||
565 | insert_use: InsertUseConfig { | ||
566 | merge: self.merge_behavior(), | ||
567 | prefix_kind: match self.data.assist_importPrefix { | ||
568 | ImportPrefixDef::Plain => PrefixKind::Plain, | ||
569 | ImportPrefixDef::ByCrate => PrefixKind::ByCrate, | ||
570 | ImportPrefixDef::BySelf => PrefixKind::BySelf, | ||
571 | }, | ||
572 | }, | ||
573 | } | ||
574 | } | ||
575 | pub fn call_info_full(&self) -> bool { | ||
576 | self.data.callInfo_full | ||
577 | } | ||
578 | pub fn lens(&self) -> LensConfig { | ||
579 | LensConfig { | ||
580 | run: self.data.lens_enable && self.data.lens_run, | ||
581 | debug: self.data.lens_enable && self.data.lens_debug, | ||
582 | implementations: self.data.lens_enable && self.data.lens_implementations, | ||
583 | method_refs: self.data.lens_enable && self.data.lens_methodReferences, | ||
584 | } | ||
585 | } | ||
586 | pub fn hover(&self) -> HoverConfig { | ||
587 | HoverConfig { | ||
588 | implementations: self.data.hoverActions_enable | ||
589 | && self.data.hoverActions_implementations, | ||
590 | run: self.data.hoverActions_enable && self.data.hoverActions_run, | ||
591 | debug: self.data.hoverActions_enable && self.data.hoverActions_debug, | ||
592 | goto_type_def: self.data.hoverActions_enable && self.data.hoverActions_gotoTypeDef, | ||
593 | links_in_hover: self.data.hoverActions_linksInHover, | ||
594 | markdown: try_or!( | ||
595 | self.caps | ||
596 | .text_document | ||
597 | .as_ref()? | ||
598 | .hover | ||
599 | .as_ref()? | ||
600 | .content_format | ||
601 | .as_ref()? | ||
602 | .as_slice(), | ||
603 | &[] | ||
604 | ) | ||
605 | .contains(&MarkupKind::Markdown), | ||
606 | } | ||
607 | } | ||
608 | pub fn semantic_tokens_refresh(&self) -> bool { | ||
609 | try_or!(self.caps.workspace.as_ref()?.semantic_tokens.as_ref()?.refresh_support?, false) | ||
610 | } | ||
611 | pub fn code_lens_refresh(&self) -> bool { | ||
612 | try_or!(self.caps.workspace.as_ref()?.code_lens.as_ref()?.refresh_support?, false) | ||
597 | } | 613 | } |
598 | } | 614 | } |
599 | 615 | ||
600 | #[derive(Deserialize)] | 616 | #[derive(Deserialize, Debug, Clone)] |
601 | #[serde(untagged)] | 617 | #[serde(untagged)] |
602 | enum ManifestOrProjectJson { | 618 | enum ManifestOrProjectJson { |
603 | Manifest(PathBuf), | 619 | Manifest(PathBuf), |
604 | ProjectJson(ProjectJsonData), | 620 | ProjectJson(ProjectJsonData), |
605 | } | 621 | } |
606 | 622 | ||
607 | #[derive(Deserialize)] | 623 | #[derive(Deserialize, Debug, Clone)] |
608 | #[serde(rename_all = "snake_case")] | 624 | #[serde(rename_all = "snake_case")] |
609 | enum MergeBehaviorDef { | 625 | enum MergeBehaviorDef { |
610 | None, | 626 | None, |
@@ -612,7 +628,7 @@ enum MergeBehaviorDef { | |||
612 | Last, | 628 | Last, |
613 | } | 629 | } |
614 | 630 | ||
615 | #[derive(Deserialize)] | 631 | #[derive(Deserialize, Debug, Clone)] |
616 | #[serde(rename_all = "snake_case")] | 632 | #[serde(rename_all = "snake_case")] |
617 | enum ImportPrefixDef { | 633 | enum ImportPrefixDef { |
618 | Plain, | 634 | Plain, |
@@ -624,15 +640,21 @@ macro_rules! _config_data { | |||
624 | (struct $name:ident { | 640 | (struct $name:ident { |
625 | $( | 641 | $( |
626 | $(#[doc=$doc:literal])* | 642 | $(#[doc=$doc:literal])* |
627 | $field:ident: $ty:ty = $default:expr, | 643 | $field:ident $(| $alias:ident)?: $ty:ty = $default:expr, |
628 | )* | 644 | )* |
629 | }) => { | 645 | }) => { |
630 | #[allow(non_snake_case)] | 646 | #[allow(non_snake_case)] |
647 | #[derive(Debug, Clone)] | ||
631 | struct $name { $($field: $ty,)* } | 648 | struct $name { $($field: $ty,)* } |
632 | impl $name { | 649 | impl $name { |
633 | fn from_json(mut json: serde_json::Value) -> $name { | 650 | fn from_json(mut json: serde_json::Value) -> $name { |
634 | $name {$( | 651 | $name {$( |
635 | $field: get_field(&mut json, stringify!($field), $default), | 652 | $field: get_field( |
653 | &mut json, | ||
654 | stringify!($field), | ||
655 | None$(.or(Some(stringify!($alias))))?, | ||
656 | $default, | ||
657 | ), | ||
636 | )*} | 658 | )*} |
637 | } | 659 | } |
638 | 660 | ||
@@ -664,14 +686,21 @@ use _config_data as config_data; | |||
664 | fn get_field<T: DeserializeOwned>( | 686 | fn get_field<T: DeserializeOwned>( |
665 | json: &mut serde_json::Value, | 687 | json: &mut serde_json::Value, |
666 | field: &'static str, | 688 | field: &'static str, |
689 | alias: Option<&'static str>, | ||
667 | default: &str, | 690 | default: &str, |
668 | ) -> T { | 691 | ) -> T { |
669 | let default = serde_json::from_str(default).unwrap(); | 692 | let default = serde_json::from_str(default).unwrap(); |
670 | 693 | ||
671 | let mut pointer = field.replace('_', "/"); | 694 | // XXX: check alias first, to work-around the VS Code where it pre-fills the |
672 | pointer.insert(0, '/'); | 695 | // defaults instead of sending an empty object. |
673 | json.pointer_mut(&pointer) | 696 | alias |
674 | .and_then(|it| serde_json::from_value(it.take()).ok()) | 697 | .into_iter() |
698 | .chain(iter::once(field)) | ||
699 | .find_map(move |field| { | ||
700 | let mut pointer = field.replace('_', "/"); | ||
701 | pointer.insert(0, '/'); | ||
702 | json.pointer_mut(&pointer).and_then(|it| serde_json::from_value(it.take()).ok()) | ||
703 | }) | ||
675 | .unwrap_or(default) | 704 | .unwrap_or(default) |
676 | } | 705 | } |
677 | 706 | ||
@@ -733,6 +762,9 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json | |||
733 | "Option<String>" => set! { | 762 | "Option<String>" => set! { |
734 | "type": ["null", "string"], | 763 | "type": ["null", "string"], |
735 | }, | 764 | }, |
765 | "Option<PathBuf>" => set! { | ||
766 | "type": ["null", "string"], | ||
767 | }, | ||
736 | "Option<bool>" => set! { | 768 | "Option<bool>" => set! { |
737 | "type": ["null", "boolean"], | 769 | "type": ["null", "boolean"], |
738 | }, | 770 | }, |
@@ -777,9 +809,8 @@ fn manual(fields: &[(&'static str, &'static str, &[&str], &str)]) -> String { | |||
777 | fields | 809 | fields |
778 | .iter() | 810 | .iter() |
779 | .map(|(field, _ty, doc, default)| { | 811 | .map(|(field, _ty, doc, default)| { |
780 | let name = field.replace("_", "."); | 812 | let name = format!("rust-analyzer.{}", field.replace("_", ".")); |
781 | let name = format!("rust-analyzer.{} (default: `{}`)", name, default); | 813 | format!("[[{}]]{} (default: `{}`)::\n{}\n", name, name, default, doc.join(" ")) |
782 | format!("{}::\n{}\n", name, doc.join(" ")) | ||
783 | }) | 814 | }) |
784 | .collect::<String>() | 815 | .collect::<String>() |
785 | } | 816 | } |
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 71dc56915..1f6bf1c8c 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -67,7 +67,7 @@ pub(crate) struct GlobalState { | |||
67 | pub(crate) flycheck: Vec<FlycheckHandle>, | 67 | pub(crate) flycheck: Vec<FlycheckHandle>, |
68 | pub(crate) flycheck_sender: Sender<flycheck::Message>, | 68 | pub(crate) flycheck_sender: Sender<flycheck::Message>, |
69 | pub(crate) flycheck_receiver: Receiver<flycheck::Message>, | 69 | pub(crate) flycheck_receiver: Receiver<flycheck::Message>, |
70 | pub(crate) config: Config, | 70 | pub(crate) config: Arc<Config>, |
71 | pub(crate) analysis_host: AnalysisHost, | 71 | pub(crate) analysis_host: AnalysisHost, |
72 | pub(crate) diagnostics: DiagnosticCollection, | 72 | pub(crate) diagnostics: DiagnosticCollection, |
73 | pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>, | 73 | pub(crate) mem_docs: FxHashMap<VfsPath, DocumentData>, |
@@ -83,7 +83,7 @@ pub(crate) struct GlobalState { | |||
83 | 83 | ||
84 | /// An immutable snapshot of the world's state at a point in time. | 84 | /// An immutable snapshot of the world's state at a point in time. |
85 | pub(crate) struct GlobalStateSnapshot { | 85 | pub(crate) struct GlobalStateSnapshot { |
86 | pub(crate) config: Config, | 86 | pub(crate) config: Arc<Config>, |
87 | pub(crate) analysis: Analysis, | 87 | pub(crate) analysis: Analysis, |
88 | pub(crate) check_fixes: CheckFixes, | 88 | pub(crate) check_fixes: CheckFixes, |
89 | pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, | 89 | pub(crate) latest_requests: Arc<RwLock<LatestRequests>>, |
@@ -109,7 +109,7 @@ impl GlobalState { | |||
109 | Handle { handle, receiver } | 109 | Handle { handle, receiver } |
110 | }; | 110 | }; |
111 | 111 | ||
112 | let analysis_host = AnalysisHost::new(config.lru_capacity); | 112 | let analysis_host = AnalysisHost::new(config.lru_capacity()); |
113 | let (flycheck_sender, flycheck_receiver) = unbounded(); | 113 | let (flycheck_sender, flycheck_receiver) = unbounded(); |
114 | GlobalState { | 114 | GlobalState { |
115 | sender, | 115 | sender, |
@@ -119,7 +119,7 @@ impl GlobalState { | |||
119 | flycheck: Vec::new(), | 119 | flycheck: Vec::new(), |
120 | flycheck_sender, | 120 | flycheck_sender, |
121 | flycheck_receiver, | 121 | flycheck_receiver, |
122 | config, | 122 | config: Arc::new(config), |
123 | analysis_host, | 123 | analysis_host, |
124 | diagnostics: Default::default(), | 124 | diagnostics: Default::default(), |
125 | mem_docs: FxHashMap::default(), | 125 | mem_docs: FxHashMap::default(), |
@@ -184,7 +184,7 @@ impl GlobalState { | |||
184 | 184 | ||
185 | pub(crate) fn snapshot(&self) -> GlobalStateSnapshot { | 185 | pub(crate) fn snapshot(&self) -> GlobalStateSnapshot { |
186 | GlobalStateSnapshot { | 186 | GlobalStateSnapshot { |
187 | config: self.config.clone(), | 187 | config: Arc::clone(&self.config), |
188 | workspaces: Arc::clone(&self.workspaces), | 188 | workspaces: Arc::clone(&self.workspaces), |
189 | analysis: self.analysis_host.analysis(), | 189 | analysis: self.analysis_host.analysis(), |
190 | vfs: Arc::clone(&self.vfs), | 190 | vfs: Arc::clone(&self.vfs), |
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index dd486070b..29cc9051e 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs | |||
@@ -9,9 +9,8 @@ use std::{ | |||
9 | }; | 9 | }; |
10 | 10 | ||
11 | use ide::{ | 11 | use ide::{ |
12 | AssistConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, | 12 | FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, LineIndex, NavigationTarget, |
13 | HoverGotoTypeData, LineIndex, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, | 13 | Query, RangeInfo, Runnable, RunnableKind, SearchScope, SourceChange, SymbolKind, TextEdit, |
14 | SearchScope, SourceChange, SymbolKind, TextEdit, | ||
15 | }; | 14 | }; |
16 | use itertools::Itertools; | 15 | use itertools::Itertools; |
17 | use lsp_server::ErrorCode; | 16 | use lsp_server::ErrorCode; |
@@ -19,8 +18,8 @@ use lsp_types::{ | |||
19 | CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, | 18 | CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, |
20 | CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, | 19 | CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams, |
21 | CodeActionKind, CodeLens, Command, CompletionItem, Diagnostic, DiagnosticTag, | 20 | CodeActionKind, CodeLens, Command, CompletionItem, Diagnostic, DiagnosticTag, |
22 | DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, | 21 | DocumentFormattingParams, DocumentHighlight, FoldingRange, FoldingRangeParams, HoverContents, |
23 | HoverContents, Location, NumberOrString, Position, PrepareRenameResponse, Range, RenameParams, | 22 | Location, NumberOrString, Position, PrepareRenameResponse, Range, RenameParams, |
24 | SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams, | 23 | SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams, |
25 | SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, | 24 | SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation, |
26 | SymbolTag, TextDocumentIdentifier, TextDocumentPositionParams, Url, WorkspaceEdit, | 25 | SymbolTag, TextDocumentIdentifier, TextDocumentPositionParams, Url, WorkspaceEdit, |
@@ -31,12 +30,13 @@ use serde_json::to_value; | |||
31 | use stdx::{format_to, split_once}; | 30 | use stdx::{format_to, split_once}; |
32 | use syntax::{algo, ast, AstNode, TextRange, TextSize}; | 31 | use syntax::{algo, ast, AstNode, TextRange, TextSize}; |
33 | 32 | ||
34 | use crate::diff::diff; | ||
35 | use crate::{ | 33 | use crate::{ |
36 | cargo_target_spec::CargoTargetSpec, | 34 | cargo_target_spec::CargoTargetSpec, |
37 | config::RustfmtConfig, | 35 | config::RustfmtConfig, |
36 | diff::diff, | ||
38 | from_json, from_proto, | 37 | from_json, from_proto, |
39 | global_state::{GlobalState, GlobalStateSnapshot}, | 38 | global_state::{GlobalState, GlobalStateSnapshot}, |
39 | line_endings::LineEndings, | ||
40 | lsp_ext::{self, InlayHint, InlayHintsParams}, | 40 | lsp_ext::{self, InlayHint, InlayHintsParams}, |
41 | lsp_utils::all_edits_are_disjoint, | 41 | lsp_utils::all_edits_are_disjoint, |
42 | to_proto, LspError, Result, | 42 | to_proto, LspError, Result, |
@@ -280,7 +280,7 @@ pub(crate) fn handle_document_symbol( | |||
280 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; | 280 | let file_id = from_proto::file_id(&snap, ¶ms.text_document.uri)?; |
281 | let line_index = snap.analysis.file_line_index(file_id)?; | 281 | let line_index = snap.analysis.file_line_index(file_id)?; |
282 | 282 | ||
283 | let mut parents: Vec<(DocumentSymbol, Option<usize>)> = Vec::new(); | 283 | let mut parents: Vec<(lsp_types::DocumentSymbol, Option<usize>)> = Vec::new(); |
284 | 284 | ||
285 | for symbol in snap.analysis.file_structure(file_id)? { | 285 | for symbol in snap.analysis.file_structure(file_id)? { |
286 | let mut tags = Vec::new(); | 286 | let mut tags = Vec::new(); |
@@ -289,7 +289,7 @@ pub(crate) fn handle_document_symbol( | |||
289 | }; | 289 | }; |
290 | 290 | ||
291 | #[allow(deprecated)] | 291 | #[allow(deprecated)] |
292 | let doc_symbol = DocumentSymbol { | 292 | let doc_symbol = lsp_types::DocumentSymbol { |
293 | name: symbol.label, | 293 | name: symbol.label, |
294 | detail: symbol.detail, | 294 | detail: symbol.detail, |
295 | kind: to_proto::symbol_kind(symbol.kind), | 295 | kind: to_proto::symbol_kind(symbol.kind), |
@@ -320,7 +320,7 @@ pub(crate) fn handle_document_symbol( | |||
320 | acc | 320 | acc |
321 | }; | 321 | }; |
322 | 322 | ||
323 | let res = if snap.config.client_caps.hierarchical_symbols { | 323 | let res = if snap.config.hierarchical_symbols() { |
324 | document_symbols.into() | 324 | document_symbols.into() |
325 | } else { | 325 | } else { |
326 | let url = to_proto::url(&snap, file_id); | 326 | let url = to_proto::url(&snap, file_id); |
@@ -333,7 +333,7 @@ pub(crate) fn handle_document_symbol( | |||
333 | return Ok(Some(res)); | 333 | return Ok(Some(res)); |
334 | 334 | ||
335 | fn flatten_document_symbol( | 335 | fn flatten_document_symbol( |
336 | symbol: &DocumentSymbol, | 336 | symbol: &lsp_types::DocumentSymbol, |
337 | container_name: Option<String>, | 337 | container_name: Option<String>, |
338 | url: &Url, | 338 | url: &Url, |
339 | res: &mut Vec<SymbolInformation>, | 339 | res: &mut Vec<SymbolInformation>, |
@@ -547,7 +547,7 @@ pub(crate) fn handle_runnables( | |||
547 | } | 547 | } |
548 | 548 | ||
549 | // Add `cargo check` and `cargo test` for all targets of the whole package | 549 | // Add `cargo check` and `cargo test` for all targets of the whole package |
550 | let config = &snap.config.runnables; | 550 | let config = snap.config.runnables(); |
551 | match cargo_spec { | 551 | match cargo_spec { |
552 | Some(spec) => { | 552 | Some(spec) => { |
553 | for &cmd in ["check", "test"].iter() { | 553 | for &cmd in ["check", "test"].iter() { |
@@ -578,9 +578,9 @@ pub(crate) fn handle_runnables( | |||
578 | kind: lsp_ext::RunnableKind::Cargo, | 578 | kind: lsp_ext::RunnableKind::Cargo, |
579 | args: lsp_ext::CargoRunnable { | 579 | args: lsp_ext::CargoRunnable { |
580 | workspace_root: None, | 580 | workspace_root: None, |
581 | override_cargo: config.override_cargo.clone(), | 581 | override_cargo: config.override_cargo, |
582 | cargo_args: vec!["check".to_string(), "--workspace".to_string()], | 582 | cargo_args: vec!["check".to_string(), "--workspace".to_string()], |
583 | cargo_extra_args: config.cargo_extra_args.clone(), | 583 | cargo_extra_args: config.cargo_extra_args, |
584 | executable_args: Vec::new(), | 584 | executable_args: Vec::new(), |
585 | expect_test: None, | 585 | expect_test: None, |
586 | }, | 586 | }, |
@@ -619,7 +619,8 @@ pub(crate) fn handle_completion( | |||
619 | return Ok(None); | 619 | return Ok(None); |
620 | } | 620 | } |
621 | 621 | ||
622 | let items = match snap.analysis.completions(&snap.config.completion, position)? { | 622 | let completion_config = &snap.config.completion(); |
623 | let items = match snap.analysis.completions(completion_config, position)? { | ||
623 | None => return Ok(None), | 624 | None => return Ok(None), |
624 | Some(items) => items, | 625 | Some(items) => items, |
625 | }; | 626 | }; |
@@ -632,10 +633,9 @@ pub(crate) fn handle_completion( | |||
632 | let mut new_completion_items = | 633 | let mut new_completion_items = |
633 | to_proto::completion_item(&line_index, line_endings, item.clone()); | 634 | to_proto::completion_item(&line_index, line_endings, item.clone()); |
634 | 635 | ||
635 | if snap.config.completion.resolve_additional_edits_lazily() { | 636 | if completion_config.enable_autoimport_completions { |
636 | for new_item in &mut new_completion_items { | 637 | for new_item in &mut new_completion_items { |
637 | let _ = fill_resolve_data(&mut new_item.data, &item, &text_document_position) | 638 | fill_resolve_data(&mut new_item.data, &item, &text_document_position); |
638 | .take(); | ||
639 | } | 639 | } |
640 | } | 640 | } |
641 | 641 | ||
@@ -661,16 +661,6 @@ pub(crate) fn handle_completion_resolve( | |||
661 | .into()); | 661 | .into()); |
662 | } | 662 | } |
663 | 663 | ||
664 | // FIXME resolve the other capabilities also? | ||
665 | if !snap | ||
666 | .config | ||
667 | .completion | ||
668 | .active_resolve_capabilities | ||
669 | .contains(&CompletionResolveCapability::AdditionalTextEdits) | ||
670 | { | ||
671 | return Ok(original_completion); | ||
672 | } | ||
673 | |||
674 | let resolve_data = match original_completion | 664 | let resolve_data = match original_completion |
675 | .data | 665 | .data |
676 | .take() | 666 | .take() |
@@ -689,7 +679,7 @@ pub(crate) fn handle_completion_resolve( | |||
689 | let additional_edits = snap | 679 | let additional_edits = snap |
690 | .analysis | 680 | .analysis |
691 | .resolve_completion_edits( | 681 | .resolve_completion_edits( |
692 | &snap.config.completion, | 682 | &snap.config.completion(), |
693 | FilePosition { file_id, offset }, | 683 | FilePosition { file_id, offset }, |
694 | &resolve_data.full_import_path, | 684 | &resolve_data.full_import_path, |
695 | resolve_data.imported_name, | 685 | resolve_data.imported_name, |
@@ -727,7 +717,7 @@ pub(crate) fn handle_folding_range( | |||
727 | let folds = snap.analysis.folding_ranges(file_id)?; | 717 | let folds = snap.analysis.folding_ranges(file_id)?; |
728 | let text = snap.analysis.file_text(file_id)?; | 718 | let text = snap.analysis.file_text(file_id)?; |
729 | let line_index = snap.analysis.file_line_index(file_id)?; | 719 | let line_index = snap.analysis.file_line_index(file_id)?; |
730 | let line_folding_only = snap.config.client_caps.line_folding_only; | 720 | let line_folding_only = snap.config.line_folding_only(); |
731 | let res = folds | 721 | let res = folds |
732 | .into_iter() | 722 | .into_iter() |
733 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) | 723 | .map(|it| to_proto::folding_range(&*text, &line_index, line_folding_only, it)) |
@@ -745,12 +735,9 @@ pub(crate) fn handle_signature_help( | |||
745 | Some(it) => it, | 735 | Some(it) => it, |
746 | None => return Ok(None), | 736 | None => return Ok(None), |
747 | }; | 737 | }; |
748 | let concise = !snap.config.call_info_full; | 738 | let concise = !snap.config.call_info_full(); |
749 | let res = to_proto::signature_help( | 739 | let res = |
750 | call_info, | 740 | to_proto::signature_help(call_info, concise, snap.config.signature_help_label_offsets()); |
751 | concise, | ||
752 | snap.config.client_caps.signature_help_label_offsets, | ||
753 | ); | ||
754 | Ok(Some(res)) | 741 | Ok(Some(res)) |
755 | } | 742 | } |
756 | 743 | ||
@@ -760,14 +747,12 @@ pub(crate) fn handle_hover( | |||
760 | ) -> Result<Option<lsp_ext::Hover>> { | 747 | ) -> Result<Option<lsp_ext::Hover>> { |
761 | let _p = profile::span("handle_hover"); | 748 | let _p = profile::span("handle_hover"); |
762 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; | 749 | let position = from_proto::file_position(&snap, params.text_document_position_params)?; |
763 | let info = match snap.analysis.hover( | 750 | let hover_config = snap.config.hover(); |
764 | position, | 751 | let info = |
765 | snap.config.hover.links_in_hover, | 752 | match snap.analysis.hover(position, hover_config.links_in_hover, hover_config.markdown)? { |
766 | snap.config.hover.markdown, | 753 | None => return Ok(None), |
767 | )? { | 754 | Some(info) => info, |
768 | None => return Ok(None), | 755 | }; |
769 | Some(info) => info, | ||
770 | }; | ||
771 | let line_index = snap.analysis.file_line_index(position.file_id)?; | 756 | let line_index = snap.analysis.file_line_index(position.file_id)?; |
772 | let range = to_proto::range(&line_index, info.range); | 757 | let range = to_proto::range(&line_index, info.range); |
773 | let hover = lsp_ext::Hover { | 758 | let hover = lsp_ext::Hover { |
@@ -853,7 +838,7 @@ pub(crate) fn handle_formatting( | |||
853 | let file_line_index = snap.analysis.file_line_index(file_id)?; | 838 | let file_line_index = snap.analysis.file_line_index(file_id)?; |
854 | let file_line_endings = snap.file_line_endings(file_id); | 839 | let file_line_endings = snap.file_line_endings(file_id); |
855 | 840 | ||
856 | let mut rustfmt = match &snap.config.rustfmt { | 841 | let mut rustfmt = match snap.config.rustfmt() { |
857 | RustfmtConfig::Rustfmt { extra_args } => { | 842 | RustfmtConfig::Rustfmt { extra_args } => { |
858 | let mut cmd = process::Command::new(toolchain::rustfmt()); | 843 | let mut cmd = process::Command::new(toolchain::rustfmt()); |
859 | cmd.args(extra_args); | 844 | cmd.args(extra_args); |
@@ -909,14 +894,25 @@ pub(crate) fn handle_formatting( | |||
909 | } | 894 | } |
910 | } | 895 | } |
911 | 896 | ||
912 | if *file == captured_stdout { | 897 | let (new_text, new_line_endings) = LineEndings::normalize(captured_stdout); |
898 | |||
899 | if file_line_endings != new_line_endings { | ||
900 | // If line endings are different, send the entire file. | ||
901 | // Diffing would not work here, as the line endings might be the only | ||
902 | // difference. | ||
903 | Ok(Some(to_proto::text_edit_vec( | ||
904 | &file_line_index, | ||
905 | new_line_endings, | ||
906 | TextEdit::replace(TextRange::up_to(TextSize::of(&*file)), new_text), | ||
907 | ))) | ||
908 | } else if *file == new_text { | ||
913 | // The document is already formatted correctly -- no edits needed. | 909 | // The document is already formatted correctly -- no edits needed. |
914 | Ok(None) | 910 | Ok(None) |
915 | } else { | 911 | } else { |
916 | Ok(Some(to_proto::text_edit_vec( | 912 | Ok(Some(to_proto::text_edit_vec( |
917 | &file_line_index, | 913 | &file_line_index, |
918 | file_line_endings, | 914 | file_line_endings, |
919 | diff(&file, &captured_stdout), | 915 | diff(&file, &new_text), |
920 | ))) | 916 | ))) |
921 | } | 917 | } |
922 | } | 918 | } |
@@ -929,7 +925,7 @@ pub(crate) fn handle_code_action( | |||
929 | // We intentionally don't support command-based actions, as those either | 925 | // We intentionally don't support command-based actions, as those either |
930 | // requires custom client-code anyway, or requires server-initiated edits. | 926 | // requires custom client-code anyway, or requires server-initiated edits. |
931 | // Server initiated edits break causality, so we avoid those as well. | 927 | // Server initiated edits break causality, so we avoid those as well. |
932 | if !snap.config.client_caps.code_action_literals { | 928 | if !snap.config.code_action_literals() { |
933 | return Ok(None); | 929 | return Ok(None); |
934 | } | 930 | } |
935 | 931 | ||
@@ -938,14 +934,12 @@ pub(crate) fn handle_code_action( | |||
938 | let range = from_proto::text_range(&line_index, params.range); | 934 | let range = from_proto::text_range(&line_index, params.range); |
939 | let frange = FileRange { file_id, range }; | 935 | let frange = FileRange { file_id, range }; |
940 | 936 | ||
941 | let assists_config = AssistConfig { | 937 | let mut assists_config = snap.config.assist(); |
942 | allowed: params | 938 | assists_config.allowed = params |
943 | .clone() | 939 | .clone() |
944 | .context | 940 | .context |
945 | .only | 941 | .only |
946 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()), | 942 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); |
947 | ..snap.config.assist | ||
948 | }; | ||
949 | 943 | ||
950 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); | 944 | let mut res: Vec<lsp_ext::CodeAction> = Vec::new(); |
951 | 945 | ||
@@ -959,7 +953,7 @@ pub(crate) fn handle_code_action( | |||
959 | add_quick_fixes(&snap, frange, &line_index, &mut res)?; | 953 | add_quick_fixes(&snap, frange, &line_index, &mut res)?; |
960 | } | 954 | } |
961 | 955 | ||
962 | if snap.config.client_caps.code_action_resolve { | 956 | if snap.config.code_action_resolve() { |
963 | for (index, assist) in | 957 | for (index, assist) in |
964 | snap.analysis.assists(&assists_config, false, frange)?.into_iter().enumerate() | 958 | snap.analysis.assists(&assists_config, false, frange)?.into_iter().enumerate() |
965 | { | 959 | { |
@@ -980,7 +974,7 @@ fn add_quick_fixes( | |||
980 | line_index: &Arc<LineIndex>, | 974 | line_index: &Arc<LineIndex>, |
981 | acc: &mut Vec<lsp_ext::CodeAction>, | 975 | acc: &mut Vec<lsp_ext::CodeAction>, |
982 | ) -> Result<()> { | 976 | ) -> Result<()> { |
983 | let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics, frange.file_id)?; | 977 | let diagnostics = snap.analysis.diagnostics(&snap.config.diagnostics(), frange.file_id)?; |
984 | 978 | ||
985 | for fix in diagnostics | 979 | for fix in diagnostics |
986 | .into_iter() | 980 | .into_iter() |
@@ -1009,7 +1003,7 @@ fn add_quick_fixes( | |||
1009 | } | 1003 | } |
1010 | 1004 | ||
1011 | pub(crate) fn handle_code_action_resolve( | 1005 | pub(crate) fn handle_code_action_resolve( |
1012 | mut snap: GlobalStateSnapshot, | 1006 | snap: GlobalStateSnapshot, |
1013 | mut code_action: lsp_ext::CodeAction, | 1007 | mut code_action: lsp_ext::CodeAction, |
1014 | ) -> Result<lsp_ext::CodeAction> { | 1008 | ) -> Result<lsp_ext::CodeAction> { |
1015 | let _p = profile::span("handle_code_action_resolve"); | 1009 | let _p = profile::span("handle_code_action_resolve"); |
@@ -1023,13 +1017,14 @@ pub(crate) fn handle_code_action_resolve( | |||
1023 | let range = from_proto::text_range(&line_index, params.code_action_params.range); | 1017 | let range = from_proto::text_range(&line_index, params.code_action_params.range); |
1024 | let frange = FileRange { file_id, range }; | 1018 | let frange = FileRange { file_id, range }; |
1025 | 1019 | ||
1026 | snap.config.assist.allowed = params | 1020 | let mut assists_config = snap.config.assist(); |
1021 | assists_config.allowed = params | ||
1027 | .code_action_params | 1022 | .code_action_params |
1028 | .context | 1023 | .context |
1029 | .only | 1024 | .only |
1030 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); | 1025 | .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); |
1031 | 1026 | ||
1032 | let assists = snap.analysis.assists(&snap.config.assist, true, frange)?; | 1027 | let assists = snap.analysis.assists(&assists_config, true, frange)?; |
1033 | let (id, index) = split_once(¶ms.id, ':').unwrap(); | 1028 | let (id, index) = split_once(¶ms.id, ':').unwrap(); |
1034 | let index = index.parse::<usize>().unwrap(); | 1029 | let index = index.parse::<usize>().unwrap(); |
1035 | let assist = &assists[index]; | 1030 | let assist = &assists[index]; |
@@ -1046,7 +1041,8 @@ pub(crate) fn handle_code_lens( | |||
1046 | let _p = profile::span("handle_code_lens"); | 1041 | let _p = profile::span("handle_code_lens"); |
1047 | let mut lenses: Vec<CodeLens> = Default::default(); | 1042 | let mut lenses: Vec<CodeLens> = Default::default(); |
1048 | 1043 | ||
1049 | if snap.config.lens.none() { | 1044 | let lens_config = snap.config.lens(); |
1045 | if lens_config.none() { | ||
1050 | // early return before any db query! | 1046 | // early return before any db query! |
1051 | return Ok(Some(lenses)); | 1047 | return Ok(Some(lenses)); |
1052 | } | 1048 | } |
@@ -1055,7 +1051,7 @@ pub(crate) fn handle_code_lens( | |||
1055 | let line_index = snap.analysis.file_line_index(file_id)?; | 1051 | let line_index = snap.analysis.file_line_index(file_id)?; |
1056 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; | 1052 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id)?; |
1057 | 1053 | ||
1058 | if snap.config.lens.runnable() { | 1054 | if lens_config.runnable() { |
1059 | // Gather runnables | 1055 | // Gather runnables |
1060 | for runnable in snap.analysis.runnables(file_id)? { | 1056 | for runnable in snap.analysis.runnables(file_id)? { |
1061 | if should_skip_target(&runnable, cargo_spec.as_ref()) { | 1057 | if should_skip_target(&runnable, cargo_spec.as_ref()) { |
@@ -1065,7 +1061,7 @@ pub(crate) fn handle_code_lens( | |||
1065 | let action = runnable.action(); | 1061 | let action = runnable.action(); |
1066 | let range = to_proto::range(&line_index, runnable.nav.full_range); | 1062 | let range = to_proto::range(&line_index, runnable.nav.full_range); |
1067 | let r = to_proto::runnable(&snap, file_id, runnable)?; | 1063 | let r = to_proto::runnable(&snap, file_id, runnable)?; |
1068 | if snap.config.lens.run { | 1064 | if lens_config.run { |
1069 | let lens = CodeLens { | 1065 | let lens = CodeLens { |
1070 | range, | 1066 | range, |
1071 | command: Some(run_single_command(&r, action.run_title)), | 1067 | command: Some(run_single_command(&r, action.run_title)), |
@@ -1074,7 +1070,7 @@ pub(crate) fn handle_code_lens( | |||
1074 | lenses.push(lens); | 1070 | lenses.push(lens); |
1075 | } | 1071 | } |
1076 | 1072 | ||
1077 | if action.debugee && snap.config.lens.debug { | 1073 | if action.debugee && lens_config.debug { |
1078 | let debug_lens = | 1074 | let debug_lens = |
1079 | CodeLens { range, command: Some(debug_single_command(&r)), data: None }; | 1075 | CodeLens { range, command: Some(debug_single_command(&r)), data: None }; |
1080 | lenses.push(debug_lens); | 1076 | lenses.push(debug_lens); |
@@ -1082,7 +1078,7 @@ pub(crate) fn handle_code_lens( | |||
1082 | } | 1078 | } |
1083 | } | 1079 | } |
1084 | 1080 | ||
1085 | if snap.config.lens.implementations { | 1081 | if lens_config.implementations { |
1086 | // Handle impls | 1082 | // Handle impls |
1087 | lenses.extend( | 1083 | lenses.extend( |
1088 | snap.analysis | 1084 | snap.analysis |
@@ -1117,7 +1113,7 @@ pub(crate) fn handle_code_lens( | |||
1117 | ); | 1113 | ); |
1118 | } | 1114 | } |
1119 | 1115 | ||
1120 | if snap.config.lens.references() { | 1116 | if lens_config.references() { |
1121 | lenses.extend(snap.analysis.find_all_methods(file_id)?.into_iter().map(|it| { | 1117 | lenses.extend(snap.analysis.find_all_methods(file_id)?.into_iter().map(|it| { |
1122 | let range = to_proto::range(&line_index, it.range); | 1118 | let range = to_proto::range(&line_index, it.range); |
1123 | let position = to_proto::position(&line_index, it.range.start()); | 1119 | let position = to_proto::position(&line_index, it.range.start()); |
@@ -1263,7 +1259,7 @@ pub(crate) fn publish_diagnostics( | |||
1263 | 1259 | ||
1264 | let diagnostics: Vec<Diagnostic> = snap | 1260 | let diagnostics: Vec<Diagnostic> = snap |
1265 | .analysis | 1261 | .analysis |
1266 | .diagnostics(&snap.config.diagnostics, file_id)? | 1262 | .diagnostics(&snap.config.diagnostics(), file_id)? |
1267 | .into_iter() | 1263 | .into_iter() |
1268 | .map(|d| Diagnostic { | 1264 | .map(|d| Diagnostic { |
1269 | range: to_proto::range(&line_index, d.range), | 1265 | range: to_proto::range(&line_index, d.range), |
@@ -1296,7 +1292,7 @@ pub(crate) fn handle_inlay_hints( | |||
1296 | let line_index = snap.analysis.file_line_index(file_id)?; | 1292 | let line_index = snap.analysis.file_line_index(file_id)?; |
1297 | Ok(snap | 1293 | Ok(snap |
1298 | .analysis | 1294 | .analysis |
1299 | .inlay_hints(file_id, &snap.config.inlay_hints)? | 1295 | .inlay_hints(file_id, &snap.config.inlay_hints())? |
1300 | .into_iter() | 1296 | .into_iter() |
1301 | .map(|it| to_proto::inlay_hint(&line_index, it)) | 1297 | .map(|it| to_proto::inlay_hint(&line_index, it)) |
1302 | .collect()) | 1298 | .collect()) |
@@ -1542,7 +1538,7 @@ fn debug_single_command(runnable: &lsp_ext::Runnable) -> Command { | |||
1542 | } | 1538 | } |
1543 | 1539 | ||
1544 | fn goto_location_command(snap: &GlobalStateSnapshot, nav: &NavigationTarget) -> Option<Command> { | 1540 | fn goto_location_command(snap: &GlobalStateSnapshot, nav: &NavigationTarget) -> Option<Command> { |
1545 | let value = if snap.config.client_caps.location_link { | 1541 | let value = if snap.config.location_link() { |
1546 | let link = to_proto::location_link(snap, None, nav.clone()).ok()?; | 1542 | let link = to_proto::location_link(snap, None, nav.clone()).ok()?; |
1547 | to_value(link).ok()? | 1543 | to_value(link).ok()? |
1548 | } else { | 1544 | } else { |
@@ -1566,7 +1562,7 @@ fn show_impl_command_link( | |||
1566 | snap: &GlobalStateSnapshot, | 1562 | snap: &GlobalStateSnapshot, |
1567 | position: &FilePosition, | 1563 | position: &FilePosition, |
1568 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1564 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1569 | if snap.config.hover.implementations { | 1565 | if snap.config.hover().implementations { |
1570 | if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) { | 1566 | if let Some(nav_data) = snap.analysis.goto_implementation(*position).unwrap_or(None) { |
1571 | let uri = to_proto::url(snap, position.file_id); | 1567 | let uri = to_proto::url(snap, position.file_id); |
1572 | let line_index = snap.analysis.file_line_index(position.file_id).ok()?; | 1568 | let line_index = snap.analysis.file_line_index(position.file_id).ok()?; |
@@ -1594,7 +1590,8 @@ fn runnable_action_links( | |||
1594 | runnable: Runnable, | 1590 | runnable: Runnable, |
1595 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1591 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1596 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id).ok()?; | 1592 | let cargo_spec = CargoTargetSpec::for_file(&snap, file_id).ok()?; |
1597 | if !snap.config.hover.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) { | 1593 | let hover_config = snap.config.hover(); |
1594 | if !hover_config.runnable() || should_skip_target(&runnable, cargo_spec.as_ref()) { | ||
1598 | return None; | 1595 | return None; |
1599 | } | 1596 | } |
1600 | 1597 | ||
@@ -1602,12 +1599,12 @@ fn runnable_action_links( | |||
1602 | to_proto::runnable(snap, file_id, runnable).ok().map(|r| { | 1599 | to_proto::runnable(snap, file_id, runnable).ok().map(|r| { |
1603 | let mut group = lsp_ext::CommandLinkGroup::default(); | 1600 | let mut group = lsp_ext::CommandLinkGroup::default(); |
1604 | 1601 | ||
1605 | if snap.config.hover.run { | 1602 | if hover_config.run { |
1606 | let run_command = run_single_command(&r, action.run_title); | 1603 | let run_command = run_single_command(&r, action.run_title); |
1607 | group.commands.push(to_command_link(run_command, r.label.clone())); | 1604 | group.commands.push(to_command_link(run_command, r.label.clone())); |
1608 | } | 1605 | } |
1609 | 1606 | ||
1610 | if snap.config.hover.debug { | 1607 | if hover_config.debug { |
1611 | let dbg_command = debug_single_command(&r); | 1608 | let dbg_command = debug_single_command(&r); |
1612 | group.commands.push(to_command_link(dbg_command, r.label)); | 1609 | group.commands.push(to_command_link(dbg_command, r.label)); |
1613 | } | 1610 | } |
@@ -1620,7 +1617,7 @@ fn goto_type_action_links( | |||
1620 | snap: &GlobalStateSnapshot, | 1617 | snap: &GlobalStateSnapshot, |
1621 | nav_targets: &[HoverGotoTypeData], | 1618 | nav_targets: &[HoverGotoTypeData], |
1622 | ) -> Option<lsp_ext::CommandLinkGroup> { | 1619 | ) -> Option<lsp_ext::CommandLinkGroup> { |
1623 | if !snap.config.hover.goto_type_def || nav_targets.is_empty() { | 1620 | if !snap.config.hover().goto_type_def || nav_targets.is_empty() { |
1624 | return None; | 1621 | return None; |
1625 | } | 1622 | } |
1626 | 1623 | ||
@@ -1641,14 +1638,14 @@ fn prepare_hover_actions( | |||
1641 | file_id: FileId, | 1638 | file_id: FileId, |
1642 | actions: &[HoverAction], | 1639 | actions: &[HoverAction], |
1643 | ) -> Vec<lsp_ext::CommandLinkGroup> { | 1640 | ) -> Vec<lsp_ext::CommandLinkGroup> { |
1644 | if snap.config.hover.none() || !snap.config.client_caps.hover_actions { | 1641 | if snap.config.hover().none() || !snap.config.hover_actions() { |
1645 | return Vec::new(); | 1642 | return Vec::new(); |
1646 | } | 1643 | } |
1647 | 1644 | ||
1648 | actions | 1645 | actions |
1649 | .iter() | 1646 | .iter() |
1650 | .filter_map(|it| match it { | 1647 | .filter_map(|it| match it { |
1651 | HoverAction::Implementaion(position) => show_impl_command_link(snap, position), | 1648 | HoverAction::Implementation(position) => show_impl_command_link(snap, position), |
1652 | HoverAction::Runnable(r) => runnable_action_links(snap, file_id, r.clone()), | 1649 | HoverAction::Runnable(r) => runnable_action_links(snap, file_id, r.clone()), |
1653 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), | 1650 | HoverAction::GoToType(targets) => goto_type_action_links(snap, targets), |
1654 | }) | 1651 | }) |
diff --git a/crates/rust-analyzer/src/lsp_utils.rs b/crates/rust-analyzer/src/lsp_utils.rs index 60c12e4e2..40de56dad 100644 --- a/crates/rust-analyzer/src/lsp_utils.rs +++ b/crates/rust-analyzer/src/lsp_utils.rs | |||
@@ -46,7 +46,7 @@ impl GlobalState { | |||
46 | message: Option<String>, | 46 | message: Option<String>, |
47 | fraction: Option<f64>, | 47 | fraction: Option<f64>, |
48 | ) { | 48 | ) { |
49 | if !self.config.client_caps.work_done_progress { | 49 | if !self.config.work_done_progress() { |
50 | return; | 50 | return; |
51 | } | 51 | } |
52 | let percentage = fraction.map(|f| { | 52 | let percentage = fraction.map(|f| { |
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 8eca79f7e..22ee96775 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -22,6 +22,7 @@ use crate::{ | |||
22 | global_state::{file_id_to_url, url_to_file_id, GlobalState, Status}, | 22 | global_state::{file_id_to_url, url_to_file_id, GlobalState, Status}, |
23 | handlers, lsp_ext, | 23 | handlers, lsp_ext, |
24 | lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, | 24 | lsp_utils::{apply_document_changes, is_canceled, notification_is, Progress}, |
25 | reload::ProjectWorkspaceProgress, | ||
25 | Result, | 26 | Result, |
26 | }; | 27 | }; |
27 | 28 | ||
@@ -63,6 +64,7 @@ pub(crate) enum Task { | |||
63 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), | 64 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), |
64 | Workspaces(Vec<anyhow::Result<ProjectWorkspace>>), | 65 | Workspaces(Vec<anyhow::Result<ProjectWorkspace>>), |
65 | PrimeCaches(PrimeCachesProgress), | 66 | PrimeCaches(PrimeCachesProgress), |
67 | FetchWorkspace(ProjectWorkspaceProgress), | ||
66 | } | 68 | } |
67 | 69 | ||
68 | impl fmt::Debug for Event { | 70 | impl fmt::Debug for Event { |
@@ -99,7 +101,8 @@ impl fmt::Debug for Event { | |||
99 | 101 | ||
100 | impl GlobalState { | 102 | impl GlobalState { |
101 | fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { | 103 | fn run(mut self, inbox: Receiver<lsp_server::Message>) -> Result<()> { |
102 | if self.config.linked_projects.is_empty() && self.config.notifications.cargo_toml_not_found | 104 | if self.config.linked_projects().is_empty() |
105 | && self.config.notifications().cargo_toml_not_found | ||
103 | { | 106 | { |
104 | self.show_message( | 107 | self.show_message( |
105 | lsp_types::MessageType::Error, | 108 | lsp_types::MessageType::Error, |
@@ -215,6 +218,16 @@ impl GlobalState { | |||
215 | } | 218 | } |
216 | PrimeCachesProgress::Finished => prime_caches_progress.push(progress), | 219 | PrimeCachesProgress::Finished => prime_caches_progress.push(progress), |
217 | }, | 220 | }, |
221 | Task::FetchWorkspace(progress) => { | ||
222 | let (state, msg) = match progress { | ||
223 | ProjectWorkspaceProgress::Begin => (Progress::Begin, None), | ||
224 | ProjectWorkspaceProgress::Report(msg) => { | ||
225 | (Progress::Report, Some(msg)) | ||
226 | } | ||
227 | ProjectWorkspaceProgress::End => (Progress::End, None), | ||
228 | }; | ||
229 | self.report_progress("fetching", state, msg, None); | ||
230 | } | ||
218 | } | 231 | } |
219 | // Coalesce multiple task events into one loop turn | 232 | // Coalesce multiple task events into one loop turn |
220 | task = match self.task_pool.receiver.try_recv() { | 233 | task = match self.task_pool.receiver.try_recv() { |
@@ -296,7 +309,7 @@ impl GlobalState { | |||
296 | flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => { | 309 | flycheck::Message::AddDiagnostic { workspace_root, diagnostic } => { |
297 | let diagnostics = | 310 | let diagnostics = |
298 | crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( | 311 | crate::diagnostics::to_proto::map_rust_diagnostic_to_lsp( |
299 | &self.config.diagnostics_map, | 312 | &self.config.diagnostics_map(), |
300 | &diagnostic, | 313 | &diagnostic, |
301 | &workspace_root, | 314 | &workspace_root, |
302 | ); | 315 | ); |
@@ -365,13 +378,13 @@ impl GlobalState { | |||
365 | self.update_file_notifications_on_threadpool(); | 378 | self.update_file_notifications_on_threadpool(); |
366 | 379 | ||
367 | // Refresh semantic tokens if the client supports it. | 380 | // Refresh semantic tokens if the client supports it. |
368 | if self.config.semantic_tokens_refresh { | 381 | if self.config.semantic_tokens_refresh() { |
369 | self.semantic_tokens_cache.lock().clear(); | 382 | self.semantic_tokens_cache.lock().clear(); |
370 | self.send_request::<lsp_types::request::SemanticTokensRefesh>((), |_, _| ()); | 383 | self.send_request::<lsp_types::request::SemanticTokensRefesh>((), |_, _| ()); |
371 | } | 384 | } |
372 | 385 | ||
373 | // Refresh code lens if the client supports it. | 386 | // Refresh code lens if the client supports it. |
374 | if self.config.code_lens_refresh { | 387 | if self.config.code_lens_refresh() { |
375 | self.send_request::<lsp_types::request::CodeLensRefresh>((), |_, _| ()); | 388 | self.send_request::<lsp_types::request::CodeLensRefresh>((), |_, _| ()); |
376 | } | 389 | } |
377 | } | 390 | } |
@@ -608,7 +621,7 @@ impl GlobalState { | |||
608 | if let Some(json) = configs.get_mut(0) { | 621 | if let Some(json) = configs.get_mut(0) { |
609 | // Note that json can be null according to the spec if the client can't | 622 | // Note that json can be null according to the spec if the client can't |
610 | // provide a configuration. This is handled in Config::update below. | 623 | // provide a configuration. This is handled in Config::update below. |
611 | let mut config = this.config.clone(); | 624 | let mut config = Config::clone(&*this.config); |
612 | config.update(json.take()); | 625 | config.update(json.take()); |
613 | this.update_configuration(config); | 626 | this.update_configuration(config); |
614 | } | 627 | } |
@@ -658,7 +671,7 @@ impl GlobalState { | |||
658 | .collect::<Vec<_>>(); | 671 | .collect::<Vec<_>>(); |
659 | 672 | ||
660 | log::trace!("updating notifications for {:?}", subscriptions); | 673 | log::trace!("updating notifications for {:?}", subscriptions); |
661 | if self.config.publish_diagnostics { | 674 | if self.config.publish_diagnostics() { |
662 | let snapshot = self.snapshot(); | 675 | let snapshot = self.snapshot(); |
663 | self.task_pool.handle.spawn(move || { | 676 | self.task_pool.handle.spawn(move || { |
664 | let diagnostics = subscriptions | 677 | let diagnostics = subscriptions |
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index 79e39e3a5..f4e084741 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -15,16 +15,23 @@ use crate::{ | |||
15 | }; | 15 | }; |
16 | use lsp_ext::StatusParams; | 16 | use lsp_ext::StatusParams; |
17 | 17 | ||
18 | #[derive(Debug)] | ||
19 | pub(crate) enum ProjectWorkspaceProgress { | ||
20 | Begin, | ||
21 | Report(String), | ||
22 | End, | ||
23 | } | ||
24 | |||
18 | impl GlobalState { | 25 | impl GlobalState { |
19 | pub(crate) fn update_configuration(&mut self, config: Config) { | 26 | pub(crate) fn update_configuration(&mut self, config: Config) { |
20 | let _p = profile::span("GlobalState::update_configuration"); | 27 | let _p = profile::span("GlobalState::update_configuration"); |
21 | let old_config = mem::replace(&mut self.config, config); | 28 | let old_config = mem::replace(&mut self.config, Arc::new(config)); |
22 | if self.config.lru_capacity != old_config.lru_capacity { | 29 | if self.config.lru_capacity() != old_config.lru_capacity() { |
23 | self.analysis_host.update_lru_capacity(old_config.lru_capacity); | 30 | self.analysis_host.update_lru_capacity(self.config.lru_capacity()); |
24 | } | 31 | } |
25 | if self.config.linked_projects != old_config.linked_projects { | 32 | if self.config.linked_projects() != old_config.linked_projects() { |
26 | self.fetch_workspaces() | 33 | self.fetch_workspaces() |
27 | } else if self.config.flycheck != old_config.flycheck { | 34 | } else if self.config.flycheck() != old_config.flycheck() { |
28 | self.reload_flycheck(); | 35 | self.reload_flycheck(); |
29 | } | 36 | } |
30 | } | 37 | } |
@@ -36,7 +43,7 @@ impl GlobalState { | |||
36 | Status::Loading | Status::NeedsReload => return, | 43 | Status::Loading | Status::NeedsReload => return, |
37 | Status::Ready | Status::Invalid => (), | 44 | Status::Ready | Status::Invalid => (), |
38 | } | 45 | } |
39 | if self.config.cargo_autoreload { | 46 | if self.config.cargo_autoreload() { |
40 | self.fetch_workspaces(); | 47 | self.fetch_workspaces(); |
41 | } else { | 48 | } else { |
42 | self.transition(Status::NeedsReload); | 49 | self.transition(Status::NeedsReload); |
@@ -79,7 +86,7 @@ impl GlobalState { | |||
79 | } | 86 | } |
80 | pub(crate) fn transition(&mut self, new_status: Status) { | 87 | pub(crate) fn transition(&mut self, new_status: Status) { |
81 | self.status = new_status; | 88 | self.status = new_status; |
82 | if self.config.client_caps.status_notification { | 89 | if self.config.status_notification() { |
83 | let lsp_status = match new_status { | 90 | let lsp_status = match new_status { |
84 | Status::Loading => lsp_ext::Status::Loading, | 91 | Status::Loading => lsp_ext::Status::Loading, |
85 | Status::Ready => lsp_ext::Status::Ready, | 92 | Status::Ready => lsp_ext::Status::Ready, |
@@ -93,23 +100,42 @@ impl GlobalState { | |||
93 | } | 100 | } |
94 | pub(crate) fn fetch_workspaces(&mut self) { | 101 | pub(crate) fn fetch_workspaces(&mut self) { |
95 | log::info!("will fetch workspaces"); | 102 | log::info!("will fetch workspaces"); |
96 | self.task_pool.handle.spawn({ | 103 | |
97 | let linked_projects = self.config.linked_projects.clone(); | 104 | self.task_pool.handle.spawn_with_sender({ |
98 | let cargo_config = self.config.cargo.clone(); | 105 | let linked_projects = self.config.linked_projects(); |
99 | move || { | 106 | let cargo_config = self.config.cargo(); |
107 | |||
108 | move |sender| { | ||
109 | let progress = { | ||
110 | let sender = sender.clone(); | ||
111 | move |msg| { | ||
112 | sender | ||
113 | .send(Task::FetchWorkspace(ProjectWorkspaceProgress::Report(msg))) | ||
114 | .unwrap() | ||
115 | } | ||
116 | }; | ||
117 | |||
118 | sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::Begin)).unwrap(); | ||
119 | |||
100 | let workspaces = linked_projects | 120 | let workspaces = linked_projects |
101 | .iter() | 121 | .iter() |
102 | .map(|project| match project { | 122 | .map(|project| match project { |
103 | LinkedProject::ProjectManifest(manifest) => { | 123 | LinkedProject::ProjectManifest(manifest) => { |
104 | project_model::ProjectWorkspace::load(manifest.clone(), &cargo_config) | 124 | project_model::ProjectWorkspace::load( |
125 | manifest.clone(), | ||
126 | &cargo_config, | ||
127 | &progress, | ||
128 | ) | ||
105 | } | 129 | } |
106 | LinkedProject::InlineJsonProject(it) => { | 130 | LinkedProject::InlineJsonProject(it) => { |
107 | project_model::ProjectWorkspace::load_inline(it.clone()) | 131 | project_model::ProjectWorkspace::load_inline(it.clone()) |
108 | } | 132 | } |
109 | }) | 133 | }) |
110 | .collect::<Vec<_>>(); | 134 | .collect::<Vec<_>>(); |
135 | |||
136 | sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End)).unwrap(); | ||
111 | log::info!("did fetch workspaces {:?}", workspaces); | 137 | log::info!("did fetch workspaces {:?}", workspaces); |
112 | Task::Workspaces(workspaces) | 138 | sender.send(Task::Workspaces(workspaces)).unwrap() |
113 | } | 139 | } |
114 | }); | 140 | }); |
115 | } | 141 | } |
@@ -143,7 +169,7 @@ impl GlobalState { | |||
143 | return; | 169 | return; |
144 | } | 170 | } |
145 | 171 | ||
146 | if let FilesWatcher::Client = self.config.files.watcher { | 172 | if let FilesWatcher::Client = self.config.files().watcher { |
147 | let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { | 173 | let registration_options = lsp_types::DidChangeWatchedFilesRegistrationOptions { |
148 | watchers: workspaces | 174 | watchers: workspaces |
149 | .iter() | 175 | .iter() |
@@ -170,9 +196,9 @@ impl GlobalState { | |||
170 | 196 | ||
171 | let project_folders = ProjectFolders::new(&workspaces); | 197 | let project_folders = ProjectFolders::new(&workspaces); |
172 | 198 | ||
173 | self.proc_macro_client = match &self.config.proc_macro_srv { | 199 | self.proc_macro_client = match self.config.proc_macro_srv() { |
174 | None => None, | 200 | None => None, |
175 | Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) { | 201 | Some((path, args)) => match ProcMacroClient::extern_process(path.clone(), args) { |
176 | Ok(it) => Some(it), | 202 | Ok(it) => Some(it), |
177 | Err(err) => { | 203 | Err(err) => { |
178 | log::error!( | 204 | log::error!( |
@@ -185,7 +211,7 @@ impl GlobalState { | |||
185 | }, | 211 | }, |
186 | }; | 212 | }; |
187 | 213 | ||
188 | let watch = match self.config.files.watcher { | 214 | let watch = match self.config.files().watcher { |
189 | FilesWatcher::Client => vec![], | 215 | FilesWatcher::Client => vec![], |
190 | FilesWatcher::Notify => project_folders.watch, | 216 | FilesWatcher::Notify => project_folders.watch, |
191 | }; | 217 | }; |
@@ -211,7 +237,7 @@ impl GlobalState { | |||
211 | }; | 237 | }; |
212 | for ws in workspaces.iter() { | 238 | for ws in workspaces.iter() { |
213 | crate_graph.extend(ws.to_crate_graph( | 239 | crate_graph.extend(ws.to_crate_graph( |
214 | self.config.cargo.target.as_deref(), | 240 | self.config.cargo().target.as_deref(), |
215 | self.proc_macro_client.as_ref(), | 241 | self.proc_macro_client.as_ref(), |
216 | &mut load, | 242 | &mut load, |
217 | )); | 243 | )); |
@@ -231,7 +257,7 @@ impl GlobalState { | |||
231 | } | 257 | } |
232 | 258 | ||
233 | fn reload_flycheck(&mut self) { | 259 | fn reload_flycheck(&mut self) { |
234 | let config = match self.config.flycheck.clone() { | 260 | let config = match self.config.flycheck() { |
235 | Some(it) => it, | 261 | Some(it) => it, |
236 | None => { | 262 | None => { |
237 | self.flycheck = Vec::new(); | 263 | self.flycheck = Vec::new(); |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 999b18351..bc9999ddc 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -605,7 +605,7 @@ pub(crate) fn goto_definition_response( | |||
605 | src: Option<FileRange>, | 605 | src: Option<FileRange>, |
606 | targets: Vec<NavigationTarget>, | 606 | targets: Vec<NavigationTarget>, |
607 | ) -> Result<lsp_types::GotoDefinitionResponse> { | 607 | ) -> Result<lsp_types::GotoDefinitionResponse> { |
608 | if snap.config.client_caps.location_link { | 608 | if snap.config.location_link() { |
609 | let links = targets | 609 | let links = targets |
610 | .into_iter() | 610 | .into_iter() |
611 | .map(|nav| location_link(snap, src, nav)) | 611 | .map(|nav| location_link(snap, src, nav)) |
@@ -785,7 +785,7 @@ pub(crate) fn unresolved_code_action( | |||
785 | assert!(assist.source_change.is_none()); | 785 | assert!(assist.source_change.is_none()); |
786 | let res = lsp_ext::CodeAction { | 786 | let res = lsp_ext::CodeAction { |
787 | title: assist.label.to_string(), | 787 | title: assist.label.to_string(), |
788 | group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), | 788 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), |
789 | kind: Some(code_action_kind(assist.id.1)), | 789 | kind: Some(code_action_kind(assist.id.1)), |
790 | edit: None, | 790 | edit: None, |
791 | is_preferred: None, | 791 | is_preferred: None, |
@@ -805,7 +805,7 @@ pub(crate) fn resolved_code_action( | |||
805 | let res = lsp_ext::CodeAction { | 805 | let res = lsp_ext::CodeAction { |
806 | edit: Some(snippet_workspace_edit(snap, change)?), | 806 | edit: Some(snippet_workspace_edit(snap, change)?), |
807 | title: assist.label.to_string(), | 807 | title: assist.label.to_string(), |
808 | group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), | 808 | group: assist.group.filter(|_| snap.config.code_action_group()).map(|gr| gr.0), |
809 | kind: Some(code_action_kind(assist.id.1)), | 809 | kind: Some(code_action_kind(assist.id.1)), |
810 | is_preferred: None, | 810 | is_preferred: None, |
811 | data: None, | 811 | data: None, |
@@ -818,7 +818,7 @@ pub(crate) fn runnable( | |||
818 | file_id: FileId, | 818 | file_id: FileId, |
819 | runnable: Runnable, | 819 | runnable: Runnable, |
820 | ) -> Result<lsp_ext::Runnable> { | 820 | ) -> Result<lsp_ext::Runnable> { |
821 | let config = &snap.config.runnables; | 821 | let config = snap.config.runnables(); |
822 | let spec = CargoTargetSpec::for_file(snap, file_id)?; | 822 | let spec = CargoTargetSpec::for_file(snap, file_id)?; |
823 | let workspace_root = spec.as_ref().map(|it| it.workspace_root.clone()); | 823 | let workspace_root = spec.as_ref().map(|it| it.workspace_root.clone()); |
824 | let target = spec.as_ref().map(|s| s.target.clone()); | 824 | let target = spec.as_ref().map(|s| s.target.clone()); |
@@ -833,9 +833,9 @@ pub(crate) fn runnable( | |||
833 | kind: lsp_ext::RunnableKind::Cargo, | 833 | kind: lsp_ext::RunnableKind::Cargo, |
834 | args: lsp_ext::CargoRunnable { | 834 | args: lsp_ext::CargoRunnable { |
835 | workspace_root: workspace_root.map(|it| it.into()), | 835 | workspace_root: workspace_root.map(|it| it.into()), |
836 | override_cargo: config.override_cargo.clone(), | 836 | override_cargo: config.override_cargo, |
837 | cargo_args, | 837 | cargo_args, |
838 | cargo_extra_args: config.cargo_extra_args.clone(), | 838 | cargo_extra_args: config.cargo_extra_args, |
839 | executable_args, | 839 | executable_args, |
840 | expect_test: None, | 840 | expect_test: None, |
841 | }, | 841 | }, |
@@ -850,6 +850,7 @@ pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent { | |||
850 | #[cfg(test)] | 850 | #[cfg(test)] |
851 | mod tests { | 851 | mod tests { |
852 | use ide::Analysis; | 852 | use ide::Analysis; |
853 | use ide_db::helpers::SnippetCap; | ||
853 | 854 | ||
854 | use super::*; | 855 | use super::*; |
855 | 856 | ||
@@ -860,7 +861,7 @@ mod tests { | |||
860 | fn foo(arg: &Foo) {} | 861 | fn foo(arg: &Foo) {} |
861 | fn main() { | 862 | fn main() { |
862 | let arg = Foo; | 863 | let arg = Foo; |
863 | foo(<|>) | 864 | foo($0) |
864 | }"#; | 865 | }"#; |
865 | 866 | ||
866 | let (offset, text) = test_utils::extract_offset(fixture); | 867 | let (offset, text) = test_utils::extract_offset(fixture); |
@@ -868,7 +869,14 @@ mod tests { | |||
868 | let (analysis, file_id) = Analysis::from_single_file(text); | 869 | let (analysis, file_id) = Analysis::from_single_file(text); |
869 | let completions: Vec<(String, Option<String>)> = analysis | 870 | let completions: Vec<(String, Option<String>)> = analysis |
870 | .completions( | 871 | .completions( |
871 | &ide::CompletionConfig::default(), | 872 | &ide::CompletionConfig { |
873 | enable_postfix_completions: true, | ||
874 | enable_autoimport_completions: true, | ||
875 | add_call_parenthesis: true, | ||
876 | add_call_argument_snippets: true, | ||
877 | snippet_cap: SnippetCap::new(true), | ||
878 | merge: None, | ||
879 | }, | ||
872 | ide_db::base_db::FilePosition { file_id, offset }, | 880 | ide_db::base_db::FilePosition { file_id, offset }, |
873 | ) | 881 | ) |
874 | .unwrap() | 882 | .unwrap() |
diff --git a/crates/rust-analyzer/tests/rust-analyzer/main.rs b/crates/rust-analyzer/tests/rust-analyzer/main.rs index 84db0856d..f5c5c63e5 100644 --- a/crates/rust-analyzer/tests/rust-analyzer/main.rs +++ b/crates/rust-analyzer/tests/rust-analyzer/main.rs | |||
@@ -13,6 +13,7 @@ mod support; | |||
13 | 13 | ||
14 | use std::{collections::HashMap, path::PathBuf, time::Instant}; | 14 | use std::{collections::HashMap, path::PathBuf, time::Instant}; |
15 | 15 | ||
16 | use expect_test::expect; | ||
16 | use lsp_types::{ | 17 | use lsp_types::{ |
17 | notification::DidOpenTextDocument, | 18 | notification::DidOpenTextDocument, |
18 | request::{CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest}, | 19 | request::{CodeActionRequest, Completion, Formatting, GotoTypeDefinition, HoverRequest}, |
@@ -569,9 +570,9 @@ fn main() { | |||
569 | } | 570 | } |
570 | "###, | 571 | "###, |
571 | ) | 572 | ) |
572 | .with_config(|config| { | 573 | .with_config(serde_json::json!({ |
573 | config.cargo.load_out_dirs_from_check = true; | 574 | "cargo": { "loadOutDirsFromCheck": true } |
574 | }) | 575 | })) |
575 | .server() | 576 | .server() |
576 | .wait_until_workspace_is_loaded(); | 577 | .wait_until_workspace_is_loaded(); |
577 | 578 | ||
@@ -712,12 +713,13 @@ pub fn foo(_input: TokenStream) -> TokenStream { | |||
712 | 713 | ||
713 | "###, | 714 | "###, |
714 | ) | 715 | ) |
715 | .with_config(|config| { | 716 | .with_config(serde_json::json!({ |
716 | let macro_srv_path = PathBuf::from(env!("CARGO_BIN_EXE_rust-analyzer")); | 717 | "cargo": { "loadOutDirsFromCheck": true }, |
717 | 718 | "procMacro": { | |
718 | config.cargo.load_out_dirs_from_check = true; | 719 | "enable": true, |
719 | config.proc_macro_srv = Some((macro_srv_path, vec!["proc-macro".into()])); | 720 | "server": PathBuf::from(env!("CARGO_BIN_EXE_rust-analyzer")), |
720 | }) | 721 | } |
722 | })) | ||
721 | .root("foo") | 723 | .root("foo") |
722 | .root("bar") | 724 | .root("bar") |
723 | .server() | 725 | .server() |
@@ -730,6 +732,16 @@ pub fn foo(_input: TokenStream) -> TokenStream { | |||
730 | ), | 732 | ), |
731 | work_done_progress_params: Default::default(), | 733 | work_done_progress_params: Default::default(), |
732 | }); | 734 | }); |
733 | let value = res.get("contents").unwrap().get("value").unwrap().to_string(); | 735 | let value = res.get("contents").unwrap().get("value").unwrap().as_str().unwrap(); |
734 | assert_eq!(value, r#""\n```rust\nfoo::Bar\n```\n\n```rust\nfn bar()\n```""#) | 736 | |
737 | expect![[r#" | ||
738 | |||
739 | ```rust | ||
740 | foo::Bar | ||
741 | ``` | ||
742 | |||
743 | ```rust | ||
744 | fn bar() | ||
745 | ```"#]] | ||
746 | .assert_eq(&value); | ||
735 | } | 747 | } |
diff --git a/crates/rust-analyzer/tests/rust-analyzer/support.rs b/crates/rust-analyzer/tests/rust-analyzer/support.rs index 456125789..2658ee185 100644 --- a/crates/rust-analyzer/tests/rust-analyzer/support.rs +++ b/crates/rust-analyzer/tests/rust-analyzer/support.rs | |||
@@ -12,11 +12,8 @@ use lsp_types::{ | |||
12 | notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress, | 12 | notification::Exit, request::Shutdown, TextDocumentIdentifier, Url, WorkDoneProgress, |
13 | }; | 13 | }; |
14 | use lsp_types::{ProgressParams, ProgressParamsValue}; | 14 | use lsp_types::{ProgressParams, ProgressParamsValue}; |
15 | use project_model::{CargoConfig, ProjectManifest}; | 15 | use project_model::ProjectManifest; |
16 | use rust_analyzer::{ | 16 | use rust_analyzer::{config::Config, main_loop}; |
17 | config::{ClientCapsConfig, Config, FilesConfig, FilesWatcher, LinkedProject}, | ||
18 | main_loop, | ||
19 | }; | ||
20 | use serde::Serialize; | 17 | use serde::Serialize; |
21 | use serde_json::{to_string_pretty, Value}; | 18 | use serde_json::{to_string_pretty, Value}; |
22 | use test_utils::{find_mismatch, Fixture}; | 19 | use test_utils::{find_mismatch, Fixture}; |
@@ -29,12 +26,18 @@ pub(crate) struct Project<'a> { | |||
29 | with_sysroot: bool, | 26 | with_sysroot: bool, |
30 | tmp_dir: Option<TestDir>, | 27 | tmp_dir: Option<TestDir>, |
31 | roots: Vec<PathBuf>, | 28 | roots: Vec<PathBuf>, |
32 | config: Option<Box<dyn Fn(&mut Config)>>, | 29 | config: serde_json::Value, |
33 | } | 30 | } |
34 | 31 | ||
35 | impl<'a> Project<'a> { | 32 | impl<'a> Project<'a> { |
36 | pub(crate) fn with_fixture(fixture: &str) -> Project { | 33 | pub(crate) fn with_fixture(fixture: &str) -> Project { |
37 | Project { fixture, tmp_dir: None, roots: vec![], with_sysroot: false, config: None } | 34 | Project { |
35 | fixture, | ||
36 | tmp_dir: None, | ||
37 | roots: vec![], | ||
38 | with_sysroot: false, | ||
39 | config: serde_json::Value::Null, | ||
40 | } | ||
38 | } | 41 | } |
39 | 42 | ||
40 | pub(crate) fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> { | 43 | pub(crate) fn tmp_dir(mut self, tmp_dir: TestDir) -> Project<'a> { |
@@ -52,8 +55,8 @@ impl<'a> Project<'a> { | |||
52 | self | 55 | self |
53 | } | 56 | } |
54 | 57 | ||
55 | pub(crate) fn with_config(mut self, config: impl Fn(&mut Config) + 'static) -> Project<'a> { | 58 | pub(crate) fn with_config(mut self, config: serde_json::Value) -> Project<'a> { |
56 | self.config = Some(Box::new(config)); | 59 | self.config = config; |
57 | self | 60 | self |
58 | } | 61 | } |
59 | 62 | ||
@@ -77,27 +80,40 @@ impl<'a> Project<'a> { | |||
77 | if roots.is_empty() { | 80 | if roots.is_empty() { |
78 | roots.push(tmp_dir_path.clone()); | 81 | roots.push(tmp_dir_path.clone()); |
79 | } | 82 | } |
80 | let linked_projects = roots | 83 | let discovered_projects = roots |
81 | .into_iter() | 84 | .into_iter() |
82 | .map(|it| ProjectManifest::discover_single(&it).unwrap()) | 85 | .map(|it| ProjectManifest::discover_single(&it).unwrap()) |
83 | .map(LinkedProject::from) | ||
84 | .collect::<Vec<_>>(); | 86 | .collect::<Vec<_>>(); |
85 | 87 | ||
86 | let mut config = Config { | 88 | let mut config = Config::new( |
87 | client_caps: ClientCapsConfig { | 89 | tmp_dir_path, |
88 | location_link: true, | 90 | lsp_types::ClientCapabilities { |
89 | code_action_literals: true, | 91 | text_document: Some(lsp_types::TextDocumentClientCapabilities { |
90 | work_done_progress: true, | 92 | definition: Some(lsp_types::GotoCapability { |
93 | link_support: Some(true), | ||
94 | ..Default::default() | ||
95 | }), | ||
96 | code_action: Some(lsp_types::CodeActionClientCapabilities { | ||
97 | code_action_literal_support: Some( | ||
98 | lsp_types::CodeActionLiteralSupport::default(), | ||
99 | ), | ||
100 | ..Default::default() | ||
101 | }), | ||
102 | hover: Some(lsp_types::HoverClientCapabilities { | ||
103 | content_format: Some(vec![lsp_types::MarkupKind::Markdown]), | ||
104 | ..Default::default() | ||
105 | }), | ||
106 | ..Default::default() | ||
107 | }), | ||
108 | window: Some(lsp_types::WindowClientCapabilities { | ||
109 | work_done_progress: Some(true), | ||
110 | ..Default::default() | ||
111 | }), | ||
91 | ..Default::default() | 112 | ..Default::default() |
92 | }, | 113 | }, |
93 | cargo: CargoConfig { no_sysroot: !self.with_sysroot, ..Default::default() }, | 114 | ); |
94 | linked_projects, | 115 | config.discovered_projects = Some(discovered_projects); |
95 | files: FilesConfig { watcher: FilesWatcher::Client, exclude: Vec::new() }, | 116 | config.update(self.config); |
96 | ..Config::new(tmp_dir_path) | ||
97 | }; | ||
98 | if let Some(f) = &self.config { | ||
99 | f(&mut config) | ||
100 | } | ||
101 | 117 | ||
102 | Server::new(tmp_dir, config) | 118 | Server::new(tmp_dir, config) |
103 | } | 119 | } |
diff --git a/crates/ssr/Cargo.toml b/crates/ssr/Cargo.toml index 339eda86a..cc8136d22 100644 --- a/crates/ssr/Cargo.toml +++ b/crates/ssr/Cargo.toml | |||
@@ -21,4 +21,4 @@ hir = { path = "../hir", version = "0.0.0" } | |||
21 | test_utils = { path = "../test_utils", version = "0.0.0" } | 21 | test_utils = { path = "../test_utils", version = "0.0.0" } |
22 | 22 | ||
23 | [dev-dependencies] | 23 | [dev-dependencies] |
24 | expect-test = "1.0" | 24 | expect-test = "1.1" |
diff --git a/crates/ssr/src/parsing.rs b/crates/ssr/src/parsing.rs index f3b084baf..3d5e4feb7 100644 --- a/crates/ssr/src/parsing.rs +++ b/crates/ssr/src/parsing.rs | |||
@@ -73,11 +73,18 @@ impl ParsedRule { | |||
73 | placeholders_by_stand_in: pattern.placeholders_by_stand_in(), | 73 | placeholders_by_stand_in: pattern.placeholders_by_stand_in(), |
74 | rules: Vec::new(), | 74 | rules: Vec::new(), |
75 | }; | 75 | }; |
76 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template.map(ast::Expr::parse)); | 76 | |
77 | let raw_template_stmt = raw_template.map(ast::Stmt::parse); | ||
78 | if let raw_template_expr @ Some(Ok(_)) = raw_template.map(ast::Expr::parse) { | ||
79 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_expr); | ||
80 | } else { | ||
81 | builder.try_add(ast::Expr::parse(&raw_pattern), raw_template_stmt.clone()); | ||
82 | } | ||
77 | builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); | 83 | builder.try_add(ast::Type::parse(&raw_pattern), raw_template.map(ast::Type::parse)); |
78 | builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); | 84 | builder.try_add(ast::Item::parse(&raw_pattern), raw_template.map(ast::Item::parse)); |
79 | builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); | 85 | builder.try_add(ast::Path::parse(&raw_pattern), raw_template.map(ast::Path::parse)); |
80 | builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); | 86 | builder.try_add(ast::Pat::parse(&raw_pattern), raw_template.map(ast::Pat::parse)); |
87 | builder.try_add(ast::Stmt::parse(&raw_pattern), raw_template_stmt); | ||
81 | builder.build() | 88 | builder.build() |
82 | } | 89 | } |
83 | } | 90 | } |
@@ -88,7 +95,11 @@ struct RuleBuilder { | |||
88 | } | 95 | } |
89 | 96 | ||
90 | impl RuleBuilder { | 97 | impl RuleBuilder { |
91 | fn try_add<T: AstNode>(&mut self, pattern: Result<T, ()>, template: Option<Result<T, ()>>) { | 98 | fn try_add<T: AstNode, T2: AstNode>( |
99 | &mut self, | ||
100 | pattern: Result<T, ()>, | ||
101 | template: Option<Result<T2, ()>>, | ||
102 | ) { | ||
92 | match (pattern, template) { | 103 | match (pattern, template) { |
93 | (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { | 104 | (Ok(pattern), Some(Ok(template))) => self.rules.push(ParsedRule { |
94 | placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), | 105 | placeholders_by_stand_in: self.placeholders_by_stand_in.clone(), |
diff --git a/crates/ssr/src/tests.rs b/crates/ssr/src/tests.rs index 63131f6ca..d6918c22d 100644 --- a/crates/ssr/src/tests.rs +++ b/crates/ssr/src/tests.rs | |||
@@ -59,7 +59,7 @@ fn parser_undefined_placeholder_in_replacement() { | |||
59 | ); | 59 | ); |
60 | } | 60 | } |
61 | 61 | ||
62 | /// `code` may optionally contain a cursor marker `<|>`. If it doesn't, then the position will be | 62 | /// `code` may optionally contain a cursor marker `$0`. If it doesn't, then the position will be |
63 | /// the start of the file. If there's a second cursor marker, then we'll return a single range. | 63 | /// the start of the file. If there's a second cursor marker, then we'll return a single range. |
64 | pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) { | 64 | pub(crate) fn single_file(code: &str) -> (ide_db::RootDatabase, FilePosition, Vec<FileRange>) { |
65 | use ide_db::base_db::fixture::WithFixture; | 65 | use ide_db::base_db::fixture::WithFixture; |
@@ -160,6 +160,97 @@ fn assert_match_failure_reason(pattern: &str, code: &str, snippet: &str, expecte | |||
160 | } | 160 | } |
161 | 161 | ||
162 | #[test] | 162 | #[test] |
163 | fn ssr_let_stmt_in_macro_match() { | ||
164 | assert_matches( | ||
165 | "let a = 0", | ||
166 | r#" | ||
167 | macro_rules! m1 { ($a:stmt) => {$a}; } | ||
168 | fn f() {m1!{ let a = 0 };}"#, | ||
169 | // FIXME: Whitespace is not part of the matched block | ||
170 | &["leta=0"], | ||
171 | ); | ||
172 | } | ||
173 | |||
174 | #[test] | ||
175 | fn ssr_let_stmt_in_fn_match() { | ||
176 | assert_matches("let $a = 10;", "fn main() { let x = 10; x }", &["let x = 10;"]); | ||
177 | assert_matches("let $a = $b;", "fn main() { let x = 10; x }", &["let x = 10;"]); | ||
178 | } | ||
179 | |||
180 | #[test] | ||
181 | fn ssr_block_expr_match() { | ||
182 | assert_matches("{ let $a = $b; }", "fn main() { let x = 10; }", &["{ let x = 10; }"]); | ||
183 | assert_matches("{ let $a = $b; $c }", "fn main() { let x = 10; x }", &["{ let x = 10; x }"]); | ||
184 | } | ||
185 | |||
186 | #[test] | ||
187 | fn ssr_let_stmt_replace() { | ||
188 | // Pattern and template with trailing semicolon | ||
189 | assert_ssr_transform( | ||
190 | "let $a = $b; ==>> let $a = 11;", | ||
191 | "fn main() { let x = 10; x }", | ||
192 | expect![["fn main() { let x = 11; x }"]], | ||
193 | ); | ||
194 | } | ||
195 | |||
196 | #[test] | ||
197 | fn ssr_let_stmt_replace_expr() { | ||
198 | // Trailing semicolon should be dropped from the new expression | ||
199 | assert_ssr_transform( | ||
200 | "let $a = $b; ==>> $b", | ||
201 | "fn main() { let x = 10; }", | ||
202 | expect![["fn main() { 10 }"]], | ||
203 | ); | ||
204 | } | ||
205 | |||
206 | #[test] | ||
207 | fn ssr_blockexpr_replace_stmt_with_stmt() { | ||
208 | assert_ssr_transform( | ||
209 | "if $a() {$b;} ==>> $b;", | ||
210 | "{ | ||
211 | if foo() { | ||
212 | bar(); | ||
213 | } | ||
214 | Ok(()) | ||
215 | }", | ||
216 | expect![[r#"{ | ||
217 | bar(); | ||
218 | Ok(()) | ||
219 | }"#]], | ||
220 | ); | ||
221 | } | ||
222 | |||
223 | #[test] | ||
224 | fn ssr_blockexpr_match_trailing_expr() { | ||
225 | assert_matches( | ||
226 | "if $a() {$b;}", | ||
227 | "{ | ||
228 | if foo() { | ||
229 | bar(); | ||
230 | } | ||
231 | }", | ||
232 | &["if foo() { | ||
233 | bar(); | ||
234 | }"], | ||
235 | ); | ||
236 | } | ||
237 | |||
238 | #[test] | ||
239 | fn ssr_blockexpr_replace_trailing_expr_with_stmt() { | ||
240 | assert_ssr_transform( | ||
241 | "if $a() {$b;} ==>> $b;", | ||
242 | "{ | ||
243 | if foo() { | ||
244 | bar(); | ||
245 | } | ||
246 | }", | ||
247 | expect![["{ | ||
248 | bar(); | ||
249 | }"]], | ||
250 | ); | ||
251 | } | ||
252 | |||
253 | #[test] | ||
163 | fn ssr_function_to_method() { | 254 | fn ssr_function_to_method() { |
164 | assert_ssr_transform( | 255 | assert_ssr_transform( |
165 | "my_function($a, $b) ==>> ($a).my_method($b)", | 256 | "my_function($a, $b) ==>> ($a).my_method($b)", |
@@ -505,7 +596,7 @@ fn replace_function_call() { | |||
505 | // This test also makes sure that we ignore empty-ranges. | 596 | // This test also makes sure that we ignore empty-ranges. |
506 | assert_ssr_transform( | 597 | assert_ssr_transform( |
507 | "foo() ==>> bar()", | 598 | "foo() ==>> bar()", |
508 | "fn foo() {<|><|>} fn bar() {} fn f1() {foo(); foo();}", | 599 | "fn foo() {$0$0} fn bar() {} fn f1() {foo(); foo();}", |
509 | expect![["fn foo() {} fn bar() {} fn f1() {bar(); bar();}"]], | 600 | expect![["fn foo() {} fn bar() {} fn f1() {bar(); bar();}"]], |
510 | ); | 601 | ); |
511 | } | 602 | } |
@@ -615,7 +706,7 @@ fn replace_associated_trait_constant() { | |||
615 | 706 | ||
616 | #[test] | 707 | #[test] |
617 | fn replace_path_in_different_contexts() { | 708 | fn replace_path_in_different_contexts() { |
618 | // Note the <|> inside module a::b which marks the point where the rule is interpreted. We | 709 | // Note the $0 inside module a::b which marks the point where the rule is interpreted. We |
619 | // replace foo with bar, but both need different path qualifiers in different contexts. In f4, | 710 | // replace foo with bar, but both need different path qualifiers in different contexts. In f4, |
620 | // foo is unqualified because of a use statement, however the replacement needs to be fully | 711 | // foo is unqualified because of a use statement, however the replacement needs to be fully |
621 | // qualified. | 712 | // qualified. |
@@ -623,7 +714,7 @@ fn replace_path_in_different_contexts() { | |||
623 | "c::foo() ==>> c::bar()", | 714 | "c::foo() ==>> c::bar()", |
624 | r#" | 715 | r#" |
625 | mod a { | 716 | mod a { |
626 | pub mod b {<|> | 717 | pub mod b {$0 |
627 | pub mod c { | 718 | pub mod c { |
628 | pub fn foo() {} | 719 | pub fn foo() {} |
629 | pub fn bar() {} | 720 | pub fn bar() {} |
@@ -1005,7 +1096,7 @@ fn pattern_is_a_single_segment_path() { | |||
1005 | fn f1() -> i32 { | 1096 | fn f1() -> i32 { |
1006 | let foo = 1; | 1097 | let foo = 1; |
1007 | let bar = 2; | 1098 | let bar = 2; |
1008 | foo<|> | 1099 | foo$0 |
1009 | } | 1100 | } |
1010 | "#, | 1101 | "#, |
1011 | expect![[r#" | 1102 | expect![[r#" |
@@ -1037,7 +1128,7 @@ fn replace_local_variable_reference() { | |||
1037 | let foo = 5; | 1128 | let foo = 5; |
1038 | res += foo + 1; | 1129 | res += foo + 1; |
1039 | let foo = 10; | 1130 | let foo = 10; |
1040 | res += foo + 2;<|> | 1131 | res += foo + 2;$0 |
1041 | res += foo + 3; | 1132 | res += foo + 3; |
1042 | let foo = 15; | 1133 | let foo = 15; |
1043 | res += foo + 4; | 1134 | res += foo + 4; |
@@ -1069,9 +1160,9 @@ fn replace_path_within_selection() { | |||
1069 | let foo = 41; | 1160 | let foo = 41; |
1070 | let bar = 42; | 1161 | let bar = 42; |
1071 | do_stuff(foo); | 1162 | do_stuff(foo); |
1072 | do_stuff(foo);<|> | 1163 | do_stuff(foo);$0 |
1073 | do_stuff(foo); | 1164 | do_stuff(foo); |
1074 | do_stuff(foo);<|> | 1165 | do_stuff(foo);$0 |
1075 | do_stuff(foo); | 1166 | do_stuff(foo); |
1076 | }"#, | 1167 | }"#, |
1077 | expect![[r#" | 1168 | expect![[r#" |
@@ -1094,9 +1185,9 @@ fn replace_nonpath_within_selection() { | |||
1094 | "$a + $b ==>> $b * $a", | 1185 | "$a + $b ==>> $b * $a", |
1095 | r#" | 1186 | r#" |
1096 | fn main() { | 1187 | fn main() { |
1097 | let v = 1 + 2;<|> | 1188 | let v = 1 + 2;$0 |
1098 | let v2 = 3 + 3; | 1189 | let v2 = 3 + 3; |
1099 | let v3 = 4 + 5;<|> | 1190 | let v3 = 4 + 5;$0 |
1100 | let v4 = 6 + 7; | 1191 | let v4 = 6 + 7; |
1101 | }"#, | 1192 | }"#, |
1102 | expect![[r#" | 1193 | expect![[r#" |
@@ -1121,7 +1212,7 @@ fn replace_self() { | |||
1121 | fn bar(_: &S1) {} | 1212 | fn bar(_: &S1) {} |
1122 | impl S1 { | 1213 | impl S1 { |
1123 | fn f1(&self) { | 1214 | fn f1(&self) { |
1124 | foo(self)<|> | 1215 | foo(self)$0 |
1125 | } | 1216 | } |
1126 | fn f2(&self) { | 1217 | fn f2(&self) { |
1127 | foo(self) | 1218 | foo(self) |
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 374ed5910..5332edb09 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -1,5 +1,5 @@ | |||
1 | //! Missing batteries for standard libraries. | 1 | //! Missing batteries for standard libraries. |
2 | use std::time::Instant; | 2 | use std::{ops, process, time::Instant}; |
3 | 3 | ||
4 | mod macros; | 4 | mod macros; |
5 | pub mod panic_context; | 5 | pub mod panic_context; |
@@ -147,6 +147,27 @@ where | |||
147 | left | 147 | left |
148 | } | 148 | } |
149 | 149 | ||
150 | pub struct JodChild(pub process::Child); | ||
151 | |||
152 | impl ops::Deref for JodChild { | ||
153 | type Target = process::Child; | ||
154 | fn deref(&self) -> &process::Child { | ||
155 | &self.0 | ||
156 | } | ||
157 | } | ||
158 | |||
159 | impl ops::DerefMut for JodChild { | ||
160 | fn deref_mut(&mut self) -> &mut process::Child { | ||
161 | &mut self.0 | ||
162 | } | ||
163 | } | ||
164 | |||
165 | impl Drop for JodChild { | ||
166 | fn drop(&mut self) { | ||
167 | let _ = self.0.kill(); | ||
168 | } | ||
169 | } | ||
170 | |||
150 | #[cfg(test)] | 171 | #[cfg(test)] |
151 | mod tests { | 172 | mod tests { |
152 | use super::*; | 173 | use super::*; |
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml index 5d8389ade..cfeaed9e6 100644 --- a/crates/syntax/Cargo.toml +++ b/crates/syntax/Cargo.toml | |||
@@ -13,7 +13,7 @@ doctest = false | |||
13 | [dependencies] | 13 | [dependencies] |
14 | itertools = "0.10.0" | 14 | itertools = "0.10.0" |
15 | rowan = "0.10.0" | 15 | rowan = "0.10.0" |
16 | rustc_lexer = { version = "695.0.0", package = "rustc-ap-rustc_lexer" } | 16 | rustc_lexer = { version = "697.0.0", package = "rustc-ap-rustc_lexer" } |
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
18 | arrayvec = "0.5.1" | 18 | arrayvec = "0.5.1" |
19 | once_cell = "1.3.1" | 19 | once_cell = "1.3.1" |
@@ -33,4 +33,4 @@ profile = { path = "../profile", version = "0.0.0" } | |||
33 | [dev-dependencies] | 33 | [dev-dependencies] |
34 | walkdir = "2.3.1" | 34 | walkdir = "2.3.1" |
35 | rayon = "1" | 35 | rayon = "1" |
36 | expect-test = "1.0" | 36 | expect-test = "1.1" |
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 5696c014f..22ab36cd2 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -19,7 +19,7 @@ use crate::{ | |||
19 | 19 | ||
20 | /// Returns ancestors of the node at the offset, sorted by length. This should | 20 | /// Returns ancestors of the node at the offset, sorted by length. This should |
21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ | 21 | /// do the right thing at an edge, e.g. when searching for expressions at `{ |
22 | /// <|>foo }` we will get the name reference instead of the whole block, which | 22 | /// $0foo }` we will get the name reference instead of the whole block, which |
23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| | 23 | /// we would get if we just did `find_token_at_offset(...).flat_map(|t| |
24 | /// t.parent().ancestors())`. | 24 | /// t.parent().ancestors())`. |
25 | pub fn ancestors_at_offset( | 25 | pub fn ancestors_at_offset( |
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index c5b80bffe..92ed2ee9d 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -484,7 +484,7 @@ impl ast::AttrsOwner for BlockExpr {} | |||
484 | impl BlockExpr { | 484 | impl BlockExpr { |
485 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } | 485 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['{']) } |
486 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } | 486 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } |
487 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } | 487 | pub fn tail_expr(&self) -> Option<Expr> { support::child(&self.syntax) } |
488 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } | 488 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['}']) } |
489 | } | 489 | } |
490 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 490 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
diff --git a/crates/syntax/src/lib.rs b/crates/syntax/src/lib.rs index 4d272f367..ea7482bb1 100644 --- a/crates/syntax/src/lib.rs +++ b/crates/syntax/src/lib.rs | |||
@@ -212,6 +212,13 @@ impl ast::Attr { | |||
212 | } | 212 | } |
213 | } | 213 | } |
214 | 214 | ||
215 | impl ast::Stmt { | ||
216 | /// Returns `text`, parsed as statement, but only if it has no errors. | ||
217 | pub fn parse(text: &str) -> Result<Self, ()> { | ||
218 | parsing::parse_text_fragment(text, parser::FragmentKind::StatementOptionalSemi) | ||
219 | } | ||
220 | } | ||
221 | |||
215 | /// Matches a `SyntaxNode` against an `ast` type. | 222 | /// Matches a `SyntaxNode` against an `ast` type. |
216 | /// | 223 | /// |
217 | /// # Example: | 224 | /// # Example: |
@@ -283,7 +290,7 @@ fn api_walkthrough() { | |||
283 | 290 | ||
284 | // Let's get the `1 + 1` expression! | 291 | // Let's get the `1 + 1` expression! |
285 | let body: ast::BlockExpr = func.body().unwrap(); | 292 | let body: ast::BlockExpr = func.body().unwrap(); |
286 | let expr: ast::Expr = body.expr().unwrap(); | 293 | let expr: ast::Expr = body.tail_expr().unwrap(); |
287 | 294 | ||
288 | // Enums are used to group related ast nodes together, and can be used for | 295 | // Enums are used to group related ast nodes together, and can be used for |
289 | // matching. However, because there are no public fields, it's possible to | 296 | // matching. However, because there are no public fields, it's possible to |
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 190f5f67a..78eaf3410 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs | |||
@@ -223,7 +223,7 @@ mod tests { | |||
223 | do_check( | 223 | do_check( |
224 | r" | 224 | r" |
225 | fn foo() { | 225 | fn foo() { |
226 | let x = foo + <|>bar<|> | 226 | let x = foo + $0bar$0 |
227 | } | 227 | } |
228 | ", | 228 | ", |
229 | "baz", | 229 | "baz", |
@@ -232,7 +232,7 @@ fn foo() { | |||
232 | do_check( | 232 | do_check( |
233 | r" | 233 | r" |
234 | fn foo() { | 234 | fn foo() { |
235 | let x = foo<|> + bar<|> | 235 | let x = foo$0 + bar$0 |
236 | } | 236 | } |
237 | ", | 237 | ", |
238 | "baz", | 238 | "baz", |
@@ -241,7 +241,7 @@ fn foo() { | |||
241 | do_check( | 241 | do_check( |
242 | r" | 242 | r" |
243 | struct Foo { | 243 | struct Foo { |
244 | f: foo<|><|> | 244 | f: foo$0$0 |
245 | } | 245 | } |
246 | ", | 246 | ", |
247 | ",\n g: (),", | 247 | ",\n g: (),", |
@@ -252,7 +252,7 @@ struct Foo { | |||
252 | fn foo { | 252 | fn foo { |
253 | let; | 253 | let; |
254 | 1 + 1; | 254 | 1 + 1; |
255 | <|>92<|>; | 255 | $092$0; |
256 | } | 256 | } |
257 | ", | 257 | ", |
258 | "62", | 258 | "62", |
@@ -261,7 +261,7 @@ fn foo { | |||
261 | do_check( | 261 | do_check( |
262 | r" | 262 | r" |
263 | mod foo { | 263 | mod foo { |
264 | fn <|><|> | 264 | fn $0$0 |
265 | } | 265 | } |
266 | ", | 266 | ", |
267 | "bar", | 267 | "bar", |
@@ -271,7 +271,7 @@ mod foo { | |||
271 | do_check( | 271 | do_check( |
272 | r" | 272 | r" |
273 | trait Foo { | 273 | trait Foo { |
274 | type <|>Foo<|>; | 274 | type $0Foo$0; |
275 | } | 275 | } |
276 | ", | 276 | ", |
277 | "Output", | 277 | "Output", |
@@ -280,17 +280,17 @@ trait Foo { | |||
280 | do_check( | 280 | do_check( |
281 | r" | 281 | r" |
282 | impl IntoIterator<Item=i32> for Foo { | 282 | impl IntoIterator<Item=i32> for Foo { |
283 | f<|><|> | 283 | f$0$0 |
284 | } | 284 | } |
285 | ", | 285 | ", |
286 | "n next(", | 286 | "n next(", |
287 | 9, | 287 | 9, |
288 | ); | 288 | ); |
289 | do_check(r"use a::b::{foo,<|>,bar<|>};", "baz", 10); | 289 | do_check(r"use a::b::{foo,$0,bar$0};", "baz", 10); |
290 | do_check( | 290 | do_check( |
291 | r" | 291 | r" |
292 | pub enum A { | 292 | pub enum A { |
293 | Foo<|><|> | 293 | Foo$0$0 |
294 | } | 294 | } |
295 | ", | 295 | ", |
296 | "\nBar;\n", | 296 | "\nBar;\n", |
@@ -298,7 +298,7 @@ pub enum A { | |||
298 | ); | 298 | ); |
299 | do_check( | 299 | do_check( |
300 | r" | 300 | r" |
301 | foo!{a, b<|><|> d} | 301 | foo!{a, b$0$0 d} |
302 | ", | 302 | ", |
303 | ", c[3]", | 303 | ", c[3]", |
304 | 8, | 304 | 8, |
@@ -306,7 +306,7 @@ foo!{a, b<|><|> d} | |||
306 | do_check( | 306 | do_check( |
307 | r" | 307 | r" |
308 | fn foo() { | 308 | fn foo() { |
309 | vec![<|><|>] | 309 | vec![$0$0] |
310 | } | 310 | } |
311 | ", | 311 | ", |
312 | "123", | 312 | "123", |
@@ -315,7 +315,7 @@ fn foo() { | |||
315 | do_check( | 315 | do_check( |
316 | r" | 316 | r" |
317 | extern { | 317 | extern { |
318 | fn<|>;<|> | 318 | fn$0;$0 |
319 | } | 319 | } |
320 | ", | 320 | ", |
321 | " exit(code: c_int)", | 321 | " exit(code: c_int)", |
@@ -326,7 +326,7 @@ extern { | |||
326 | #[test] | 326 | #[test] |
327 | fn reparse_token_tests() { | 327 | fn reparse_token_tests() { |
328 | do_check( | 328 | do_check( |
329 | r"<|><|> | 329 | r"$0$0 |
330 | fn foo() -> i32 { 1 } | 330 | fn foo() -> i32 { 1 } |
331 | ", | 331 | ", |
332 | "\n\n\n \n", | 332 | "\n\n\n \n", |
@@ -334,49 +334,49 @@ fn foo() -> i32 { 1 } | |||
334 | ); | 334 | ); |
335 | do_check( | 335 | do_check( |
336 | r" | 336 | r" |
337 | fn foo() -> <|><|> {} | 337 | fn foo() -> $0$0 {} |
338 | ", | 338 | ", |
339 | " \n", | 339 | " \n", |
340 | 2, | 340 | 2, |
341 | ); | 341 | ); |
342 | do_check( | 342 | do_check( |
343 | r" | 343 | r" |
344 | fn <|>foo<|>() -> i32 { 1 } | 344 | fn $0foo$0() -> i32 { 1 } |
345 | ", | 345 | ", |
346 | "bar", | 346 | "bar", |
347 | 3, | 347 | 3, |
348 | ); | 348 | ); |
349 | do_check( | 349 | do_check( |
350 | r" | 350 | r" |
351 | fn foo<|><|>foo() { } | 351 | fn foo$0$0foo() { } |
352 | ", | 352 | ", |
353 | "bar", | 353 | "bar", |
354 | 6, | 354 | 6, |
355 | ); | 355 | ); |
356 | do_check( | 356 | do_check( |
357 | r" | 357 | r" |
358 | fn foo /* <|><|> */ () {} | 358 | fn foo /* $0$0 */ () {} |
359 | ", | 359 | ", |
360 | "some comment", | 360 | "some comment", |
361 | 6, | 361 | 6, |
362 | ); | 362 | ); |
363 | do_check( | 363 | do_check( |
364 | r" | 364 | r" |
365 | fn baz <|><|> () {} | 365 | fn baz $0$0 () {} |
366 | ", | 366 | ", |
367 | " \t\t\n\n", | 367 | " \t\t\n\n", |
368 | 2, | 368 | 2, |
369 | ); | 369 | ); |
370 | do_check( | 370 | do_check( |
371 | r" | 371 | r" |
372 | fn baz <|><|> () {} | 372 | fn baz $0$0 () {} |
373 | ", | 373 | ", |
374 | " \t\t\n\n", | 374 | " \t\t\n\n", |
375 | 2, | 375 | 2, |
376 | ); | 376 | ); |
377 | do_check( | 377 | do_check( |
378 | r" | 378 | r" |
379 | /// foo <|><|>omment | 379 | /// foo $0$0omment |
380 | mod { } | 380 | mod { } |
381 | ", | 381 | ", |
382 | "c", | 382 | "c", |
@@ -384,28 +384,28 @@ mod { } | |||
384 | ); | 384 | ); |
385 | do_check( | 385 | do_check( |
386 | r#" | 386 | r#" |
387 | fn -> &str { "Hello<|><|>" } | 387 | fn -> &str { "Hello$0$0" } |
388 | "#, | 388 | "#, |
389 | ", world", | 389 | ", world", |
390 | 7, | 390 | 7, |
391 | ); | 391 | ); |
392 | do_check( | 392 | do_check( |
393 | r#" | 393 | r#" |
394 | fn -> &str { // "Hello<|><|>" | 394 | fn -> &str { // "Hello$0$0" |
395 | "#, | 395 | "#, |
396 | ", world", | 396 | ", world", |
397 | 10, | 397 | 10, |
398 | ); | 398 | ); |
399 | do_check( | 399 | do_check( |
400 | r##" | 400 | r##" |
401 | fn -> &str { r#"Hello<|><|>"# | 401 | fn -> &str { r#"Hello$0$0"# |
402 | "##, | 402 | "##, |
403 | ", world", | 403 | ", world", |
404 | 10, | 404 | 10, |
405 | ); | 405 | ); |
406 | do_check( | 406 | do_check( |
407 | r" | 407 | r" |
408 | #[derive(<|>Copy<|>)] | 408 | #[derive($0Copy$0)] |
409 | enum Foo { | 409 | enum Foo { |
410 | 410 | ||
411 | } | 411 | } |
@@ -417,12 +417,12 @@ enum Foo { | |||
417 | 417 | ||
418 | #[test] | 418 | #[test] |
419 | fn reparse_str_token_with_error_unchanged() { | 419 | fn reparse_str_token_with_error_unchanged() { |
420 | do_check(r#""<|>Unclosed<|> string literal"#, "Still unclosed", 24); | 420 | do_check(r#""$0Unclosed$0 string literal"#, "Still unclosed", 24); |
421 | } | 421 | } |
422 | 422 | ||
423 | #[test] | 423 | #[test] |
424 | fn reparse_str_token_with_error_fixed() { | 424 | fn reparse_str_token_with_error_fixed() { |
425 | do_check(r#""unterinated<|><|>"#, "\"", 12); | 425 | do_check(r#""unterinated$0$0"#, "\"", 12); |
426 | } | 426 | } |
427 | 427 | ||
428 | #[test] | 428 | #[test] |
@@ -430,7 +430,7 @@ enum Foo { | |||
430 | do_check( | 430 | do_check( |
431 | r#"fn main() { | 431 | r#"fn main() { |
432 | if {} | 432 | if {} |
433 | 32 + 4<|><|> | 433 | 32 + 4$0$0 |
434 | return | 434 | return |
435 | if {} | 435 | if {} |
436 | }"#, | 436 | }"#, |
@@ -444,7 +444,7 @@ enum Foo { | |||
444 | do_check( | 444 | do_check( |
445 | r#"fn main() { | 445 | r#"fn main() { |
446 | if {} | 446 | if {} |
447 | 32 + 4<|><|> | 447 | 32 + 4$0$0 |
448 | return | 448 | return |
449 | if {} | 449 | if {} |
450 | }"#, | 450 | }"#, |
diff --git a/crates/syntax/src/tests.rs b/crates/syntax/src/tests.rs index 8c217dfe0..9d3433c9d 100644 --- a/crates/syntax/src/tests.rs +++ b/crates/syntax/src/tests.rs | |||
@@ -103,6 +103,15 @@ fn type_parser_tests() { | |||
103 | } | 103 | } |
104 | 104 | ||
105 | #[test] | 105 | #[test] |
106 | fn stmt_parser_tests() { | ||
107 | fragment_parser_dir_test( | ||
108 | &["parser/fragments/stmt/ok"], | ||
109 | &["parser/fragments/stmt/err"], | ||
110 | crate::ast::Stmt::parse, | ||
111 | ); | ||
112 | } | ||
113 | |||
114 | #[test] | ||
106 | fn parser_fuzz_tests() { | 115 | fn parser_fuzz_tests() { |
107 | for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { | 116 | for (_, text) in collect_rust_files(&test_data_dir(), &["parser/fuzz-failures"]) { |
108 | fuzz::check_parser(&text) | 117 | fuzz::check_parser(&text) |
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rast | |||
@@ -0,0 +1 @@ | |||
ERROR | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs new file mode 100644 index 000000000..988df0705 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_attr.rs | |||
@@ -0,0 +1 @@ | |||
#[foo] | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rast | |||
@@ -0,0 +1 @@ | |||
ERROR | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs new file mode 100644 index 000000000..7e3b2fd49 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_multiple_stmts.rs | |||
@@ -0,0 +1 @@ | |||
a(); b(); c() | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rast | |||
@@ -0,0 +1 @@ | |||
ERROR | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs new file mode 100644 index 000000000..2d06f3766 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_open_parenthesis.rs | |||
@@ -0,0 +1 @@ | |||
( | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rast | |||
@@ -0,0 +1 @@ | |||
ERROR | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs new file mode 100644 index 000000000..092bc2b04 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_semicolon.rs | |||
@@ -0,0 +1 @@ | |||
; | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast new file mode 100644 index 000000000..5df7507e2 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rast | |||
@@ -0,0 +1 @@ | |||
ERROR | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs new file mode 100644 index 000000000..ca49acb07 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/err/0000_unterminated_expr.rs | |||
@@ -0,0 +1 @@ | |||
1 + | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast new file mode 100644 index 000000000..274fdf16d --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rast | |||
@@ -0,0 +1,9 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] "1" | ||
5 | [email protected] " " | ||
6 | [email protected] "+" | ||
7 | [email protected] " " | ||
8 | [email protected] | ||
9 | [email protected] "1" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs new file mode 100644 index 000000000..8d2f0971e --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr.rs | |||
@@ -0,0 +1 @@ | |||
1 + 1 | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast new file mode 100644 index 000000000..6c946091f --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rast | |||
@@ -0,0 +1,69 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "{" | ||
4 | [email protected] "\n " | ||
5 | [email protected] | ||
6 | [email protected] "let" | ||
7 | [email protected] " " | ||
8 | [email protected] | ||
9 | [email protected] | ||
10 | [email protected] "x" | ||
11 | [email protected] " " | ||
12 | [email protected] "=" | ||
13 | [email protected] " " | ||
14 | [email protected] | ||
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] "foo" | ||
20 | [email protected] | ||
21 | [email protected] "(" | ||
22 | [email protected] ")" | ||
23 | [email protected] ";" | ||
24 | [email protected] "\n " | ||
25 | [email protected] | ||
26 | [email protected] "let" | ||
27 | [email protected] " " | ||
28 | [email protected] | ||
29 | [email protected] | ||
30 | [email protected] "y" | ||
31 | [email protected] " " | ||
32 | [email protected] "=" | ||
33 | [email protected] " " | ||
34 | [email protected] | ||
35 | [email protected] | ||
36 | [email protected] | ||
37 | [email protected] | ||
38 | [email protected] | ||
39 | [email protected] "bar" | ||
40 | [email protected] | ||
41 | [email protected] "(" | ||
42 | [email protected] ")" | ||
43 | [email protected] ";" | ||
44 | [email protected] "\n " | ||
45 | [email protected] | ||
46 | [email protected] | ||
47 | [email protected] | ||
48 | [email protected] | ||
49 | [email protected] | ||
50 | [email protected] "Ok" | ||
51 | [email protected] | ||
52 | [email protected] "(" | ||
53 | [email protected] | ||
54 | [email protected] | ||
55 | [email protected] | ||
56 | [email protected] | ||
57 | [email protected] | ||
58 | [email protected] "x" | ||
59 | [email protected] " " | ||
60 | [email protected] "+" | ||
61 | [email protected] " " | ||
62 | [email protected] | ||
63 | [email protected] | ||
64 | [email protected] | ||
65 | [email protected] | ||
66 | [email protected] "y" | ||
67 | [email protected] ")" | ||
68 | [email protected] "\n" | ||
69 | [email protected] "}" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs new file mode 100644 index 000000000..ffa5c1e66 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_expr_block.rs | |||
@@ -0,0 +1,5 @@ | |||
1 | { | ||
2 | let x = foo(); | ||
3 | let y = bar(); | ||
4 | Ok(x + y) | ||
5 | } | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rast new file mode 100644 index 000000000..8c186da93 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rast | |||
@@ -0,0 +1,11 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] | ||
7 | [email protected] "foo" | ||
8 | [email protected] | ||
9 | [email protected] "(" | ||
10 | [email protected] ")" | ||
11 | [email protected] ";" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rs new file mode 100644 index 000000000..a280f9a5c --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_fn_call.rs | |||
@@ -0,0 +1 @@ | |||
foo(); | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rast new file mode 100644 index 000000000..8ab38da21 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rast | |||
@@ -0,0 +1,12 @@ | |||
1 | [email protected] | ||
2 | [email protected] "let" | ||
3 | [email protected] " " | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "x" | ||
7 | [email protected] " " | ||
8 | [email protected] "=" | ||
9 | [email protected] " " | ||
10 | [email protected] | ||
11 | [email protected] "10" | ||
12 | [email protected] ";" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rs new file mode 100644 index 000000000..de8a7f1fc --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_let_stmt.rs | |||
@@ -0,0 +1 @@ | |||
let x = 10; | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rast new file mode 100644 index 000000000..81d6df29a --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rast | |||
@@ -0,0 +1,21 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "m1" | ||
7 | [email protected] "!" | ||
8 | [email protected] | ||
9 | [email protected] "{" | ||
10 | [email protected] " " | ||
11 | [email protected] "let" | ||
12 | [email protected] " " | ||
13 | [email protected] "a" | ||
14 | [email protected] " " | ||
15 | [email protected] "=" | ||
16 | [email protected] " " | ||
17 | [email protected] "0" | ||
18 | [email protected] ";" | ||
19 | [email protected] " " | ||
20 | [email protected] "}" | ||
21 | [email protected] ";" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rs new file mode 100644 index 000000000..075f30159 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_let_stmt.rs | |||
@@ -0,0 +1 @@ | |||
m1!{ let a = 0; }; | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rast new file mode 100644 index 000000000..81d6df29a --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rast | |||
@@ -0,0 +1,21 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "m1" | ||
7 | [email protected] "!" | ||
8 | [email protected] | ||
9 | [email protected] "{" | ||
10 | [email protected] " " | ||
11 | [email protected] "let" | ||
12 | [email protected] " " | ||
13 | [email protected] "a" | ||
14 | [email protected] " " | ||
15 | [email protected] "=" | ||
16 | [email protected] " " | ||
17 | [email protected] "0" | ||
18 | [email protected] ";" | ||
19 | [email protected] " " | ||
20 | [email protected] "}" | ||
21 | [email protected] ";" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rs new file mode 100644 index 000000000..075f30159 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_macro_unterminated_let_stmt.rs | |||
@@ -0,0 +1 @@ | |||
m1!{ let a = 0; }; | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast new file mode 100644 index 000000000..64c5d2969 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rast | |||
@@ -0,0 +1,22 @@ | |||
1 | [email protected] | ||
2 | [email protected] "struct" | ||
3 | [email protected] " " | ||
4 | [email protected] | ||
5 | [email protected] "Foo" | ||
6 | [email protected] " " | ||
7 | [email protected] | ||
8 | [email protected] "{" | ||
9 | [email protected] "\n " | ||
10 | [email protected] | ||
11 | [email protected] | ||
12 | [email protected] "bar" | ||
13 | [email protected] ":" | ||
14 | [email protected] " " | ||
15 | [email protected] | ||
16 | [email protected] | ||
17 | [email protected] | ||
18 | [email protected] | ||
19 | [email protected] "u32" | ||
20 | [email protected] "," | ||
21 | [email protected] "\n" | ||
22 | [email protected] "}" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs new file mode 100644 index 000000000..e5473e3ac --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_struct_item.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | struct Foo { | ||
2 | bar: u32, | ||
3 | } | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast new file mode 100644 index 000000000..9089906bc --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rast | |||
@@ -0,0 +1,10 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] | ||
7 | [email protected] "foo" | ||
8 | [email protected] | ||
9 | [email protected] "(" | ||
10 | [email protected] ")" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs new file mode 100644 index 000000000..eb28ef440 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_fn_call.rs | |||
@@ -0,0 +1 @@ | |||
foo() | |||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast new file mode 100644 index 000000000..37663671f --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rast | |||
@@ -0,0 +1,11 @@ | |||
1 | [email protected] | ||
2 | [email protected] "let" | ||
3 | [email protected] " " | ||
4 | [email protected] | ||
5 | [email protected] | ||
6 | [email protected] "x" | ||
7 | [email protected] " " | ||
8 | [email protected] "=" | ||
9 | [email protected] " " | ||
10 | [email protected] | ||
11 | [email protected] "10" | ||
diff --git a/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs new file mode 100644 index 000000000..78364b2a9 --- /dev/null +++ b/crates/syntax/test_data/parser/fragments/stmt/ok/0000_unterminated_let_stmt.rs | |||
@@ -0,0 +1 @@ | |||
let x = 10 | |||
diff --git a/crates/test_utils/Cargo.toml b/crates/test_utils/Cargo.toml index 93eecc678..06341f003 100644 --- a/crates/test_utils/Cargo.toml +++ b/crates/test_utils/Cargo.toml | |||
@@ -11,7 +11,7 @@ doctest = false | |||
11 | 11 | ||
12 | [dependencies] | 12 | [dependencies] |
13 | # Avoid adding deps here, this crate is widely used in tests it should compile fast! | 13 | # Avoid adding deps here, this crate is widely used in tests it should compile fast! |
14 | difference = "2.0.0" | 14 | dissimilar = "1.0.2" |
15 | text-size = "1.0.0" | 15 | text-size = "1.0.0" |
16 | serde_json = "1.0.48" | 16 | serde_json = "1.0.48" |
17 | rustc-hash = "1.1.0" | 17 | rustc-hash = "1.1.0" |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 05940a546..84c1d7ebb 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | //! Most notable things are: | 3 | //! Most notable things are: |
4 | //! | 4 | //! |
5 | //! * Rich text comparison, which outputs a diff. | 5 | //! * Rich text comparison, which outputs a diff. |
6 | //! * Extracting markup (mainly, `<|>` markers) out of fixture strings. | 6 | //! * Extracting markup (mainly, `$0` markers) out of fixture strings. |
7 | //! * marks (see the eponymous module). | 7 | //! * marks (see the eponymous module). |
8 | 8 | ||
9 | #[macro_use] | 9 | #[macro_use] |
@@ -20,12 +20,13 @@ use serde_json::Value; | |||
20 | use stdx::lines_with_ends; | 20 | use stdx::lines_with_ends; |
21 | use text_size::{TextRange, TextSize}; | 21 | use text_size::{TextRange, TextSize}; |
22 | 22 | ||
23 | pub use difference::Changeset as __Changeset; | 23 | pub use dissimilar::diff as __diff; |
24 | pub use rustc_hash::FxHashMap; | 24 | pub use rustc_hash::FxHashMap; |
25 | 25 | ||
26 | pub use crate::fixture::Fixture; | 26 | pub use crate::fixture::Fixture; |
27 | 27 | ||
28 | pub const CURSOR_MARKER: &str = "<|>"; | 28 | pub const CURSOR_MARKER: &str = "$0"; |
29 | pub const ESCAPED_CURSOR_MARKER: &str = "\\$0"; | ||
29 | 30 | ||
30 | /// Asserts that two strings are equal, otherwise displays a rich diff between them. | 31 | /// Asserts that two strings are equal, otherwise displays a rich diff between them. |
31 | /// | 32 | /// |
@@ -45,8 +46,8 @@ macro_rules! assert_eq_text { | |||
45 | if left.trim() == right.trim() { | 46 | if left.trim() == right.trim() { |
46 | std::eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right); | 47 | std::eprintln!("Left:\n{:?}\n\nRight:\n{:?}\n\nWhitespace difference\n", left, right); |
47 | } else { | 48 | } else { |
48 | let changeset = $crate::__Changeset::new(left, right, "\n"); | 49 | let diff = $crate::__diff(left, right); |
49 | std::eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, changeset); | 50 | std::eprintln!("Left:\n{}\n\nRight:\n{}\n\nDiff:\n{}\n", left, right, $crate::format_diff(diff)); |
50 | } | 51 | } |
51 | std::eprintln!($($tt)*); | 52 | std::eprintln!($($tt)*); |
52 | panic!("text differs"); | 53 | panic!("text differs"); |
@@ -62,7 +63,7 @@ pub fn extract_offset(text: &str) -> (TextSize, String) { | |||
62 | } | 63 | } |
63 | } | 64 | } |
64 | 65 | ||
65 | /// Returns the offset of the first occurence of `<|>` marker and the copy of `text` | 66 | /// Returns the offset of the first occurence of `$0` marker and the copy of `text` |
66 | /// without the marker. | 67 | /// without the marker. |
67 | fn try_extract_offset(text: &str) -> Option<(TextSize, String)> { | 68 | fn try_extract_offset(text: &str) -> Option<(TextSize, String)> { |
68 | let cursor_pos = text.find(CURSOR_MARKER)?; | 69 | let cursor_pos = text.find(CURSOR_MARKER)?; |
@@ -81,7 +82,7 @@ pub fn extract_range(text: &str) -> (TextRange, String) { | |||
81 | } | 82 | } |
82 | } | 83 | } |
83 | 84 | ||
84 | /// Returns `TextRange` between the first two markers `<|>...<|>` and the copy | 85 | /// Returns `TextRange` between the first two markers `$0...$0` and the copy |
85 | /// of `text` without both of these markers. | 86 | /// of `text` without both of these markers. |
86 | fn try_extract_range(text: &str) -> Option<(TextRange, String)> { | 87 | fn try_extract_range(text: &str) -> Option<(TextRange, String)> { |
87 | let (start, text) = try_extract_offset(text)?; | 88 | let (start, text) = try_extract_offset(text)?; |
@@ -104,11 +105,11 @@ impl From<RangeOrOffset> for TextRange { | |||
104 | } | 105 | } |
105 | } | 106 | } |
106 | 107 | ||
107 | /// Extracts `TextRange` or `TextSize` depending on the amount of `<|>` markers | 108 | /// Extracts `TextRange` or `TextSize` depending on the amount of `$0` markers |
108 | /// found in `text`. | 109 | /// found in `text`. |
109 | /// | 110 | /// |
110 | /// # Panics | 111 | /// # Panics |
111 | /// Panics if no `<|>` marker is present in the `text`. | 112 | /// Panics if no `$0` marker is present in the `text`. |
112 | pub fn extract_range_or_offset(text: &str) -> (RangeOrOffset, String) { | 113 | pub fn extract_range_or_offset(text: &str) -> (RangeOrOffset, String) { |
113 | if let Some((range, text)) = try_extract_range(text) { | 114 | if let Some((range, text)) = try_extract_range(text) { |
114 | return (RangeOrOffset::Range(range), text); | 115 | return (RangeOrOffset::Range(range), text); |
@@ -164,12 +165,12 @@ fn test_extract_tags() { | |||
164 | assert_eq!(actual, vec![("fn main() {}", Some("fn".into())), ("main", None),]); | 165 | assert_eq!(actual, vec![("fn main() {}", Some("fn".into())), ("main", None),]); |
165 | } | 166 | } |
166 | 167 | ||
167 | /// Inserts `<|>` marker into the `text` at `offset`. | 168 | /// Inserts `$0` marker into the `text` at `offset`. |
168 | pub fn add_cursor(text: &str, offset: TextSize) -> String { | 169 | pub fn add_cursor(text: &str, offset: TextSize) -> String { |
169 | let offset: usize = offset.into(); | 170 | let offset: usize = offset.into(); |
170 | let mut res = String::new(); | 171 | let mut res = String::new(); |
171 | res.push_str(&text[..offset]); | 172 | res.push_str(&text[..offset]); |
172 | res.push_str("<|>"); | 173 | res.push_str("$0"); |
173 | res.push_str(&text[offset..]); | 174 | res.push_str(&text[offset..]); |
174 | res | 175 | res |
175 | } | 176 | } |
@@ -392,3 +393,16 @@ pub fn project_dir() -> PathBuf { | |||
392 | let dir = env!("CARGO_MANIFEST_DIR"); | 393 | let dir = env!("CARGO_MANIFEST_DIR"); |
393 | PathBuf::from(dir).parent().unwrap().parent().unwrap().to_owned() | 394 | PathBuf::from(dir).parent().unwrap().parent().unwrap().to_owned() |
394 | } | 395 | } |
396 | |||
397 | pub fn format_diff(chunks: Vec<dissimilar::Chunk>) -> String { | ||
398 | let mut buf = String::new(); | ||
399 | for chunk in chunks { | ||
400 | let formatted = match chunk { | ||
401 | dissimilar::Chunk::Equal(text) => text.into(), | ||
402 | dissimilar::Chunk::Delete(text) => format!("\x1b[41m{}\x1b[0m", text), | ||
403 | dissimilar::Chunk::Insert(text) => format!("\x1b[42m{}\x1b[0m", text), | ||
404 | }; | ||
405 | buf.push_str(&formatted); | ||
406 | } | ||
407 | buf | ||
408 | } | ||
diff --git a/crates/tt/src/buffer.rs b/crates/tt/src/buffer.rs index 02c771f70..3606c887d 100644 --- a/crates/tt/src/buffer.rs +++ b/crates/tt/src/buffer.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use crate::{Subtree, TokenTree}; | 3 | use crate::{Leaf, Subtree, TokenTree}; |
4 | 4 | ||
5 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] | 5 | #[derive(Copy, Clone, Debug, Eq, PartialEq)] |
6 | struct EntryId(usize); | 6 | struct EntryId(usize); |
@@ -13,7 +13,7 @@ struct EntryPtr(EntryId, usize); | |||
13 | #[derive(Debug)] | 13 | #[derive(Debug)] |
14 | enum Entry<'t> { | 14 | enum Entry<'t> { |
15 | // Mimicking types from proc-macro. | 15 | // Mimicking types from proc-macro. |
16 | Subtree(&'t TokenTree, EntryId), | 16 | Subtree(Option<&'t TokenTree>, &'t Subtree, EntryId), |
17 | Leaf(&'t TokenTree), | 17 | Leaf(&'t TokenTree), |
18 | // End entries contain a pointer to the entry from the containing | 18 | // End entries contain a pointer to the entry from the containing |
19 | // token tree, or None if this is the outermost level. | 19 | // token tree, or None if this is the outermost level. |
@@ -27,37 +27,64 @@ pub struct TokenBuffer<'t> { | |||
27 | buffers: Vec<Box<[Entry<'t>]>>, | 27 | buffers: Vec<Box<[Entry<'t>]>>, |
28 | } | 28 | } |
29 | 29 | ||
30 | impl<'t> TokenBuffer<'t> { | 30 | trait TokenList<'a> { |
31 | pub fn new(tokens: &'t [TokenTree]) -> TokenBuffer<'t> { | 31 | fn entries(&self) -> (Vec<(usize, (&'a Subtree, Option<&'a TokenTree>))>, Vec<Entry<'a>>); |
32 | let mut buffers = vec![]; | 32 | } |
33 | |||
34 | let idx = TokenBuffer::new_inner(tokens, &mut buffers, None); | ||
35 | assert_eq!(idx, 0); | ||
36 | |||
37 | TokenBuffer { buffers } | ||
38 | } | ||
39 | 33 | ||
40 | fn new_inner( | 34 | impl<'a> TokenList<'a> for &'a [TokenTree] { |
41 | tokens: &'t [TokenTree], | 35 | fn entries(&self) -> (Vec<(usize, (&'a Subtree, Option<&'a TokenTree>))>, Vec<Entry<'a>>) { |
42 | buffers: &mut Vec<Box<[Entry<'t>]>>, | ||
43 | next: Option<EntryPtr>, | ||
44 | ) -> usize { | ||
45 | // Must contain everything in tokens and then the Entry::End | 36 | // Must contain everything in tokens and then the Entry::End |
46 | let start_capacity = tokens.len() + 1; | 37 | let start_capacity = self.len() + 1; |
47 | let mut entries = Vec::with_capacity(start_capacity); | 38 | let mut entries = Vec::with_capacity(start_capacity); |
48 | let mut children = vec![]; | 39 | let mut children = vec![]; |
49 | 40 | for (idx, tt) in self.iter().enumerate() { | |
50 | for (idx, tt) in tokens.iter().enumerate() { | ||
51 | match tt { | 41 | match tt { |
52 | TokenTree::Leaf(_) => { | 42 | TokenTree::Leaf(_) => { |
53 | entries.push(Entry::Leaf(tt)); | 43 | entries.push(Entry::Leaf(tt)); |
54 | } | 44 | } |
55 | TokenTree::Subtree(subtree) => { | 45 | TokenTree::Subtree(subtree) => { |
56 | entries.push(Entry::End(None)); | 46 | entries.push(Entry::End(None)); |
57 | children.push((idx, (subtree, tt))); | 47 | children.push((idx, (subtree, Some(tt)))); |
58 | } | 48 | } |
59 | } | 49 | } |
60 | } | 50 | } |
51 | (children, entries) | ||
52 | } | ||
53 | } | ||
54 | |||
55 | impl<'a> TokenList<'a> for &'a Subtree { | ||
56 | fn entries(&self) -> (Vec<(usize, (&'a Subtree, Option<&'a TokenTree>))>, Vec<Entry<'a>>) { | ||
57 | // Must contain everything in tokens and then the Entry::End | ||
58 | let mut entries = vec![]; | ||
59 | let mut children = vec![]; | ||
60 | entries.push(Entry::End(None)); | ||
61 | children.push((0usize, (*self, None))); | ||
62 | (children, entries) | ||
63 | } | ||
64 | } | ||
65 | |||
66 | impl<'t> TokenBuffer<'t> { | ||
67 | pub fn from_tokens(tokens: &'t [TokenTree]) -> TokenBuffer<'t> { | ||
68 | Self::new(tokens) | ||
69 | } | ||
70 | |||
71 | pub fn from_subtree(subtree: &'t Subtree) -> TokenBuffer<'t> { | ||
72 | Self::new(subtree) | ||
73 | } | ||
74 | |||
75 | fn new<T: TokenList<'t>>(tokens: T) -> TokenBuffer<'t> { | ||
76 | let mut buffers = vec![]; | ||
77 | let idx = TokenBuffer::new_inner(tokens, &mut buffers, None); | ||
78 | assert_eq!(idx, 0); | ||
79 | TokenBuffer { buffers } | ||
80 | } | ||
81 | |||
82 | fn new_inner<T: TokenList<'t>>( | ||
83 | tokens: T, | ||
84 | buffers: &mut Vec<Box<[Entry<'t>]>>, | ||
85 | next: Option<EntryPtr>, | ||
86 | ) -> usize { | ||
87 | let (children, mut entries) = tokens.entries(); | ||
61 | 88 | ||
62 | entries.push(Entry::End(next)); | 89 | entries.push(Entry::End(next)); |
63 | let res = buffers.len(); | 90 | let res = buffers.len(); |
@@ -65,11 +92,11 @@ impl<'t> TokenBuffer<'t> { | |||
65 | 92 | ||
66 | for (child_idx, (subtree, tt)) in children { | 93 | for (child_idx, (subtree, tt)) in children { |
67 | let idx = TokenBuffer::new_inner( | 94 | let idx = TokenBuffer::new_inner( |
68 | &subtree.token_trees, | 95 | subtree.token_trees.as_slice(), |
69 | buffers, | 96 | buffers, |
70 | Some(EntryPtr(EntryId(res), child_idx + 1)), | 97 | Some(EntryPtr(EntryId(res), child_idx + 1)), |
71 | ); | 98 | ); |
72 | buffers[res].as_mut()[child_idx] = Entry::Subtree(tt, EntryId(idx)); | 99 | buffers[res].as_mut()[child_idx] = Entry::Subtree(tt, subtree, EntryId(idx)); |
73 | } | 100 | } |
74 | 101 | ||
75 | res | 102 | res |
@@ -87,6 +114,24 @@ impl<'t> TokenBuffer<'t> { | |||
87 | } | 114 | } |
88 | } | 115 | } |
89 | 116 | ||
117 | #[derive(Debug)] | ||
118 | pub enum TokenTreeRef<'a> { | ||
119 | Subtree(&'a Subtree, Option<&'a TokenTree>), | ||
120 | Leaf(&'a Leaf, &'a TokenTree), | ||
121 | } | ||
122 | |||
123 | impl<'a> TokenTreeRef<'a> { | ||
124 | pub fn cloned(&self) -> TokenTree { | ||
125 | match &self { | ||
126 | TokenTreeRef::Subtree(subtree, tt) => match tt { | ||
127 | Some(it) => (*it).clone(), | ||
128 | None => (*subtree).clone().into(), | ||
129 | }, | ||
130 | TokenTreeRef::Leaf(_, tt) => (*tt).clone(), | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
90 | /// A safe version of `Cursor` from `syn` crate https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L125 | 135 | /// A safe version of `Cursor` from `syn` crate https://github.com/dtolnay/syn/blob/6533607f91686545cb034d2838beea338d9d0742/src/buffer.rs#L125 |
91 | #[derive(Copy, Clone, Debug)] | 136 | #[derive(Copy, Clone, Debug)] |
92 | pub struct Cursor<'a> { | 137 | pub struct Cursor<'a> { |
@@ -114,12 +159,11 @@ impl<'a> Cursor<'a> { | |||
114 | match self.entry() { | 159 | match self.entry() { |
115 | Some(Entry::End(Some(ptr))) => { | 160 | Some(Entry::End(Some(ptr))) => { |
116 | let idx = ptr.1; | 161 | let idx = ptr.1; |
117 | if let Some(Entry::Subtree(TokenTree::Subtree(subtree), _)) = | 162 | if let Some(Entry::Subtree(_, subtree, _)) = |
118 | self.buffer.entry(&EntryPtr(ptr.0, idx - 1)) | 163 | self.buffer.entry(&EntryPtr(ptr.0, idx - 1)) |
119 | { | 164 | { |
120 | return Some(subtree); | 165 | return Some(subtree); |
121 | } | 166 | } |
122 | |||
123 | None | 167 | None |
124 | } | 168 | } |
125 | _ => None, | 169 | _ => None, |
@@ -134,7 +178,7 @@ impl<'a> Cursor<'a> { | |||
134 | /// a cursor into that subtree | 178 | /// a cursor into that subtree |
135 | pub fn subtree(self) -> Option<Cursor<'a>> { | 179 | pub fn subtree(self) -> Option<Cursor<'a>> { |
136 | match self.entry() { | 180 | match self.entry() { |
137 | Some(Entry::Subtree(_, entry_id)) => { | 181 | Some(Entry::Subtree(_, _, entry_id)) => { |
138 | Some(Cursor::create(self.buffer, EntryPtr(*entry_id, 0))) | 182 | Some(Cursor::create(self.buffer, EntryPtr(*entry_id, 0))) |
139 | } | 183 | } |
140 | _ => None, | 184 | _ => None, |
@@ -142,10 +186,13 @@ impl<'a> Cursor<'a> { | |||
142 | } | 186 | } |
143 | 187 | ||
144 | /// If the cursor is pointing at a `TokenTree`, returns it | 188 | /// If the cursor is pointing at a `TokenTree`, returns it |
145 | pub fn token_tree(self) -> Option<&'a TokenTree> { | 189 | pub fn token_tree(self) -> Option<TokenTreeRef<'a>> { |
146 | match self.entry() { | 190 | match self.entry() { |
147 | Some(Entry::Leaf(tt)) => Some(tt), | 191 | Some(Entry::Leaf(tt)) => match tt { |
148 | Some(Entry::Subtree(tt, _)) => Some(tt), | 192 | TokenTree::Leaf(leaf) => Some(TokenTreeRef::Leaf(leaf, *tt)), |
193 | TokenTree::Subtree(subtree) => Some(TokenTreeRef::Subtree(subtree, Some(tt))), | ||
194 | }, | ||
195 | Some(Entry::Subtree(tt, subtree, _)) => Some(TokenTreeRef::Subtree(subtree, *tt)), | ||
149 | Some(Entry::End(_)) => None, | 196 | Some(Entry::End(_)) => None, |
150 | None => None, | 197 | None => None, |
151 | } | 198 | } |
@@ -172,7 +219,7 @@ impl<'a> Cursor<'a> { | |||
172 | /// a cursor into that subtree | 219 | /// a cursor into that subtree |
173 | pub fn bump_subtree(self) -> Cursor<'a> { | 220 | pub fn bump_subtree(self) -> Cursor<'a> { |
174 | match self.entry() { | 221 | match self.entry() { |
175 | Some(Entry::Subtree(_, _)) => self.subtree().unwrap(), | 222 | Some(Entry::Subtree(_, _, _)) => self.subtree().unwrap(), |
176 | _ => self.bump(), | 223 | _ => self.bump(), |
177 | } | 224 | } |
178 | } | 225 | } |
diff --git a/crates/vfs/src/lib.rs b/crates/vfs/src/lib.rs index 9cf2afd33..2b7b14524 100644 --- a/crates/vfs/src/lib.rs +++ b/crates/vfs/src/lib.rs | |||
@@ -2,43 +2,46 @@ | |||
2 | //! | 2 | //! |
3 | //! VFS stores all files read by rust-analyzer. Reading file contents from VFS | 3 | //! VFS stores all files read by rust-analyzer. Reading file contents from VFS |
4 | //! always returns the same contents, unless VFS was explicitly modified with | 4 | //! always returns the same contents, unless VFS was explicitly modified with |
5 | //! `set_file_contents`. All changes to VFS are logged, and can be retrieved via | 5 | //! [`set_file_contents`]. All changes to VFS are logged, and can be retrieved via |
6 | //! `take_changes` method. The pack of changes is then pushed to `salsa` and | 6 | //! [`take_changes`] method. The pack of changes is then pushed to `salsa` and |
7 | //! triggers incremental recomputation. | 7 | //! triggers incremental recomputation. |
8 | //! | 8 | //! |
9 | //! Files in VFS are identified with `FileId`s -- interned paths. The notion of | 9 | //! Files in VFS are identified with [`FileId`]s -- interned paths. The notion of |
10 | //! the path, `VfsPath` is somewhat abstract: at the moment, it is represented | 10 | //! the path, [`VfsPath`] is somewhat abstract: at the moment, it is represented |
11 | //! as an `std::path::PathBuf` internally, but this is an implementation detail. | 11 | //! as an [`std::path::PathBuf`] internally, but this is an implementation detail. |
12 | //! | 12 | //! |
13 | //! VFS doesn't do IO or file watching itself. For that, see the `loader` | 13 | //! VFS doesn't do IO or file watching itself. For that, see the [`loader`] |
14 | //! module. `loader::Handle` is an object-safe trait which abstracts both file | 14 | //! module. [`loader::Handle`] is an object-safe trait which abstracts both file |
15 | //! loading and file watching. `Handle` is dynamically configured with a set of | 15 | //! loading and file watching. [`Handle`] is dynamically configured with a set of |
16 | //! directory entries which should be scanned and watched. `Handle` then | 16 | //! directory entries which should be scanned and watched. [`Handle`] then |
17 | //! asynchronously pushes file changes. Directory entries are configured in | 17 | //! asynchronously pushes file changes. Directory entries are configured in |
18 | //! free-form via list of globs, it's up to the `Handle` to interpret the globs | 18 | //! free-form via list of globs, it's up to the [`Handle`] to interpret the globs |
19 | //! in any specific way. | 19 | //! in any specific way. |
20 | //! | 20 | //! |
21 | //! A simple `WalkdirLoaderHandle` is provided, which doesn't implement watching | 21 | //! VFS stores a flat list of files. [`file_set::FileSet`] can partition this list |
22 | //! and just scans the directory using walkdir. | 22 | //! of files into disjoint sets of files. Traversal-like operations (including |
23 | //! | 23 | //! getting the neighbor file by the relative path) are handled by the [`FileSet`]. |
24 | //! VFS stores a flat list of files. `FileSet` can partition this list of files | 24 | //! [`FileSet`]s are also pushed to salsa and cause it to re-check `mod foo;` |
25 | //! into disjoint sets of files. Traversal-like operations (including getting | ||
26 | //! the neighbor file by the relative path) are handled by the `FileSet`. | ||
27 | //! `FileSet`s are also pushed to salsa and cause it to re-check `mod foo;` | ||
28 | //! declarations when files are created or deleted. | 25 | //! declarations when files are created or deleted. |
29 | //! | 26 | //! |
30 | //! `file_set::FileSet` and `loader::Entry` play similar, but different roles. | 27 | //! [`FileSet`] and [`loader::Entry`] play similar, but different roles. |
31 | //! Both specify the "set of paths/files", one is geared towards file watching, | 28 | //! Both specify the "set of paths/files", one is geared towards file watching, |
32 | //! the other towards salsa changes. In particular, single `file_set::FileSet` | 29 | //! the other towards salsa changes. In particular, single [`FileSet`] |
33 | //! may correspond to several `loader::Entry`. For example, a crate from | 30 | //! may correspond to several [`loader::Entry`]. For example, a crate from |
34 | //! crates.io which uses code generation would have two `Entries` -- for sources | 31 | //! crates.io which uses code generation would have two [`Entries`] -- for sources |
35 | //! in `~/.cargo`, and for generated code in `./target/debug/build`. It will | 32 | //! in `~/.cargo`, and for generated code in `./target/debug/build`. It will |
36 | //! have a single `FileSet` which unions the two sources. | 33 | //! have a single [`FileSet`] which unions the two sources. |
37 | mod vfs_path; | 34 | //! |
38 | mod path_interner; | 35 | //! [`set_file_contents`]: Vfs::set_file_contents |
36 | //! [`take_changes`]: Vfs::take_changes | ||
37 | //! [`FileSet`]: file_set::FileSet | ||
38 | //! [`Handle`]: loader::Handle | ||
39 | //! [`Entries`]: loader::Entry | ||
39 | mod anchored_path; | 40 | mod anchored_path; |
40 | pub mod file_set; | 41 | pub mod file_set; |
41 | pub mod loader; | 42 | pub mod loader; |
43 | mod path_interner; | ||
44 | mod vfs_path; | ||
42 | 45 | ||
43 | use std::{fmt, mem}; | 46 | use std::{fmt, mem}; |
44 | 47 | ||