diff options
Diffstat (limited to 'crates/ide/src')
-rw-r--r-- | crates/ide/src/completion/complete_postfix.rs | 17 | ||||
-rw-r--r-- | crates/ide/src/completion/completion_context.rs | 10 | ||||
-rw-r--r-- | crates/ide/src/completion/presentation.rs | 123 | ||||
-rw-r--r-- | crates/ide/src/diagnostics.rs | 62 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/test_data/highlighting.html | 6 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 6 |
6 files changed, 210 insertions, 14 deletions
diff --git a/crates/ide/src/completion/complete_postfix.rs b/crates/ide/src/completion/complete_postfix.rs index 84c4e129d..26a5af5b9 100644 --- a/crates/ide/src/completion/complete_postfix.rs +++ b/crates/ide/src/completion/complete_postfix.rs | |||
@@ -175,6 +175,9 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
175 | ) | 175 | ) |
176 | .add_to(acc); | 176 | .add_to(acc); |
177 | 177 | ||
178 | postfix_snippet(ctx, cap, &dot_receiver, "ok", "Ok(expr)", &format!("Ok({})", receiver_text)) | ||
179 | .add_to(acc); | ||
180 | |||
178 | postfix_snippet( | 181 | postfix_snippet( |
179 | ctx, | 182 | ctx, |
180 | cap, | 183 | cap, |
@@ -189,6 +192,16 @@ pub(super) fn complete_postfix(acc: &mut Completions, ctx: &CompletionContext) { | |||
189 | ctx, | 192 | ctx, |
190 | cap, | 193 | cap, |
191 | &dot_receiver, | 194 | &dot_receiver, |
195 | "dbgr", | ||
196 | "dbg!(&expr)", | ||
197 | &format!("dbg!(&{})", receiver_text), | ||
198 | ) | ||
199 | .add_to(acc); | ||
200 | |||
201 | postfix_snippet( | ||
202 | ctx, | ||
203 | cap, | ||
204 | &dot_receiver, | ||
192 | "call", | 205 | "call", |
193 | "function(expr)", | 206 | "function(expr)", |
194 | &format!("${{1}}({})", receiver_text), | 207 | &format!("${{1}}({})", receiver_text), |
@@ -263,9 +276,11 @@ fn main() { | |||
263 | sn box Box::new(expr) | 276 | sn box Box::new(expr) |
264 | sn call function(expr) | 277 | sn call function(expr) |
265 | sn dbg dbg!(expr) | 278 | sn dbg dbg!(expr) |
279 | sn dbgr dbg!(&expr) | ||
266 | sn if if expr {} | 280 | sn if if expr {} |
267 | sn match match expr {} | 281 | sn match match expr {} |
268 | sn not !expr | 282 | sn not !expr |
283 | sn ok Ok(expr) | ||
269 | sn ref &expr | 284 | sn ref &expr |
270 | sn refm &mut expr | 285 | sn refm &mut expr |
271 | sn while while expr {} | 286 | sn while while expr {} |
@@ -286,7 +301,9 @@ fn main() { | |||
286 | sn box Box::new(expr) | 301 | sn box Box::new(expr) |
287 | sn call function(expr) | 302 | sn call function(expr) |
288 | sn dbg dbg!(expr) | 303 | sn dbg dbg!(expr) |
304 | sn dbgr dbg!(&expr) | ||
289 | sn match match expr {} | 305 | sn match match expr {} |
306 | sn ok Ok(expr) | ||
290 | sn ref &expr | 307 | sn ref &expr |
291 | sn refm &mut expr | 308 | sn refm &mut expr |
292 | "#]], | 309 | "#]], |
diff --git a/crates/ide/src/completion/completion_context.rs b/crates/ide/src/completion/completion_context.rs index 161f59c1e..671b13328 100644 --- a/crates/ide/src/completion/completion_context.rs +++ b/crates/ide/src/completion/completion_context.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use base_db::SourceDatabase; | 3 | use base_db::SourceDatabase; |
4 | use hir::{Semantics, SemanticsScope, Type}; | 4 | use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; |
5 | use ide_db::RootDatabase; | 5 | use ide_db::RootDatabase; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | algo::{find_covering_element, find_node_at_offset}, | 7 | algo::{find_covering_element, find_node_at_offset}, |
@@ -91,6 +91,7 @@ pub(crate) struct CompletionContext<'a> { | |||
91 | pub(super) impl_as_prev_sibling: bool, | 91 | pub(super) impl_as_prev_sibling: bool, |
92 | pub(super) is_match_arm: bool, | 92 | pub(super) is_match_arm: bool, |
93 | pub(super) has_item_list_or_source_file_parent: bool, | 93 | pub(super) has_item_list_or_source_file_parent: bool, |
94 | pub(super) locals: Vec<(String, Local)>, | ||
94 | } | 95 | } |
95 | 96 | ||
96 | impl<'a> CompletionContext<'a> { | 97 | impl<'a> CompletionContext<'a> { |
@@ -119,6 +120,12 @@ impl<'a> CompletionContext<'a> { | |||
119 | original_file.syntax().token_at_offset(position.offset).left_biased()?; | 120 | original_file.syntax().token_at_offset(position.offset).left_biased()?; |
120 | let token = sema.descend_into_macros(original_token.clone()); | 121 | let token = sema.descend_into_macros(original_token.clone()); |
121 | let scope = sema.scope_at_offset(&token.parent(), position.offset); | 122 | let scope = sema.scope_at_offset(&token.parent(), position.offset); |
123 | let mut locals = vec![]; | ||
124 | scope.process_all_names(&mut |name, scope| { | ||
125 | if let ScopeDef::Local(local) = scope { | ||
126 | locals.push((name.to_string(), local)); | ||
127 | } | ||
128 | }); | ||
122 | let mut ctx = CompletionContext { | 129 | let mut ctx = CompletionContext { |
123 | sema, | 130 | sema, |
124 | scope, | 131 | scope, |
@@ -167,6 +174,7 @@ impl<'a> CompletionContext<'a> { | |||
167 | if_is_prev: false, | 174 | if_is_prev: false, |
168 | is_match_arm: false, | 175 | is_match_arm: false, |
169 | has_item_list_or_source_file_parent: false, | 176 | has_item_list_or_source_file_parent: false, |
177 | locals, | ||
170 | }; | 178 | }; |
171 | 179 | ||
172 | let mut original_file = original_file.syntax().clone(); | 180 | let mut original_file = original_file.syntax().clone(); |
diff --git a/crates/ide/src/completion/presentation.rs b/crates/ide/src/completion/presentation.rs index 24c507f9b..987cbfa7a 100644 --- a/crates/ide/src/completion/presentation.rs +++ b/crates/ide/src/completion/presentation.rs | |||
@@ -191,6 +191,17 @@ impl Completions { | |||
191 | func: hir::Function, | 191 | func: hir::Function, |
192 | local_name: Option<String>, | 192 | local_name: Option<String>, |
193 | ) { | 193 | ) { |
194 | fn add_arg(arg: &str, ty: &Type, ctx: &CompletionContext) -> String { | ||
195 | if let Some(derefed_ty) = ty.remove_ref() { | ||
196 | for (name, local) in ctx.locals.iter() { | ||
197 | if name == arg && local.ty(ctx.db) == derefed_ty { | ||
198 | return (if ty.is_mutable_reference() { "&mut " } else { "&" }).to_string() | ||
199 | + &arg.to_string(); | ||
200 | } | ||
201 | } | ||
202 | } | ||
203 | arg.to_string() | ||
204 | }; | ||
194 | let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); | 205 | let name = local_name.unwrap_or_else(|| func.name(ctx.db).to_string()); |
195 | let ast_node = func.source(ctx.db).value; | 206 | let ast_node = func.source(ctx.db).value; |
196 | 207 | ||
@@ -205,12 +216,20 @@ impl Completions { | |||
205 | .set_deprecated(is_deprecated(func, ctx.db)) | 216 | .set_deprecated(is_deprecated(func, ctx.db)) |
206 | .detail(function_declaration(&ast_node)); | 217 | .detail(function_declaration(&ast_node)); |
207 | 218 | ||
219 | let params_ty = func.params(ctx.db); | ||
208 | let params = ast_node | 220 | let params = ast_node |
209 | .param_list() | 221 | .param_list() |
210 | .into_iter() | 222 | .into_iter() |
211 | .flat_map(|it| it.params()) | 223 | .flat_map(|it| it.params()) |
212 | .flat_map(|it| it.pat()) | 224 | .zip(params_ty) |
213 | .map(|pat| pat.to_string().trim_start_matches('_').into()) | 225 | .flat_map(|(it, param_ty)| { |
226 | if let Some(pat) = it.pat() { | ||
227 | let name = pat.to_string(); | ||
228 | let arg = name.trim_start_matches("mut ").trim_start_matches('_'); | ||
229 | return Some(add_arg(arg, param_ty.ty(), ctx)); | ||
230 | } | ||
231 | None | ||
232 | }) | ||
214 | .collect(); | 233 | .collect(); |
215 | 234 | ||
216 | builder = builder.add_call_parens(ctx, name, Params::Named(params)); | 235 | builder = builder.add_call_parens(ctx, name, Params::Named(params)); |
@@ -864,6 +883,106 @@ fn main() { foo(${1:foo}, ${2:bar}, ${3:ho_ge_})$0 } | |||
864 | } | 883 | } |
865 | 884 | ||
866 | #[test] | 885 | #[test] |
886 | fn insert_ref_when_matching_local_in_scope() { | ||
887 | check_edit( | ||
888 | "ref_arg", | ||
889 | r#" | ||
890 | struct Foo {} | ||
891 | fn ref_arg(x: &Foo) {} | ||
892 | fn main() { | ||
893 | let x = Foo {}; | ||
894 | ref_ar<|> | ||
895 | } | ||
896 | "#, | ||
897 | r#" | ||
898 | struct Foo {} | ||
899 | fn ref_arg(x: &Foo) {} | ||
900 | fn main() { | ||
901 | let x = Foo {}; | ||
902 | ref_arg(${1:&x})$0 | ||
903 | } | ||
904 | "#, | ||
905 | ); | ||
906 | } | ||
907 | |||
908 | #[test] | ||
909 | fn insert_mut_ref_when_matching_local_in_scope() { | ||
910 | check_edit( | ||
911 | "ref_arg", | ||
912 | r#" | ||
913 | struct Foo {} | ||
914 | fn ref_arg(x: &mut Foo) {} | ||
915 | fn main() { | ||
916 | let x = Foo {}; | ||
917 | ref_ar<|> | ||
918 | } | ||
919 | "#, | ||
920 | r#" | ||
921 | struct Foo {} | ||
922 | fn ref_arg(x: &mut Foo) {} | ||
923 | fn main() { | ||
924 | let x = Foo {}; | ||
925 | ref_arg(${1:&mut x})$0 | ||
926 | } | ||
927 | "#, | ||
928 | ); | ||
929 | } | ||
930 | |||
931 | #[test] | ||
932 | fn insert_ref_when_matching_local_in_scope_for_method() { | ||
933 | check_edit( | ||
934 | "apply_foo", | ||
935 | r#" | ||
936 | struct Foo {} | ||
937 | struct Bar {} | ||
938 | impl Bar { | ||
939 | fn apply_foo(&self, x: &Foo) {} | ||
940 | } | ||
941 | |||
942 | fn main() { | ||
943 | let x = Foo {}; | ||
944 | let y = Bar {}; | ||
945 | y.<|> | ||
946 | } | ||
947 | "#, | ||
948 | r#" | ||
949 | struct Foo {} | ||
950 | struct Bar {} | ||
951 | impl Bar { | ||
952 | fn apply_foo(&self, x: &Foo) {} | ||
953 | } | ||
954 | |||
955 | fn main() { | ||
956 | let x = Foo {}; | ||
957 | let y = Bar {}; | ||
958 | y.apply_foo(${1:&x})$0 | ||
959 | } | ||
960 | "#, | ||
961 | ); | ||
962 | } | ||
963 | |||
964 | #[test] | ||
965 | fn trim_mut_keyword_in_func_completion() { | ||
966 | check_edit( | ||
967 | "take_mutably", | ||
968 | r#" | ||
969 | fn take_mutably(mut x: &i32) {} | ||
970 | |||
971 | fn main() { | ||
972 | take_m<|> | ||
973 | } | ||
974 | "#, | ||
975 | r#" | ||
976 | fn take_mutably(mut x: &i32) {} | ||
977 | |||
978 | fn main() { | ||
979 | take_mutably(${1:x})$0 | ||
980 | } | ||
981 | "#, | ||
982 | ); | ||
983 | } | ||
984 | |||
985 | #[test] | ||
867 | fn inserts_parens_for_tuple_enums() { | 986 | fn inserts_parens_for_tuple_enums() { |
868 | mark::check!(inserts_parens_for_tuple_enums); | 987 | mark::check!(inserts_parens_for_tuple_enums); |
869 | check_edit( | 988 | check_edit( |
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs index b2b972b02..dc815a483 100644 --- a/crates/ide/src/diagnostics.rs +++ b/crates/ide/src/diagnostics.rs | |||
@@ -622,13 +622,65 @@ pub struct Foo { pub a: i32, pub b: i32 } | |||
622 | r#" | 622 | r#" |
623 | use a; | 623 | use a; |
624 | use a::{c, d::e}; | 624 | use a::{c, d::e}; |
625 | |||
626 | mod a { | ||
627 | mod c {} | ||
628 | mod d { | ||
629 | mod e {} | ||
630 | } | ||
631 | } | ||
625 | "#, | 632 | "#, |
626 | ); | 633 | ); |
627 | check_fix(r#"use {<|>b};"#, r#"use b;"#); | 634 | check_fix( |
628 | check_fix(r#"use {b<|>};"#, r#"use b;"#); | 635 | r" |
629 | check_fix(r#"use a::{c<|>};"#, r#"use a::c;"#); | 636 | mod b {} |
630 | check_fix(r#"use a::{self<|>};"#, r#"use a;"#); | 637 | use {<|>b}; |
631 | check_fix(r#"use a::{c, d::{e<|>}};"#, r#"use a::{c, d::e};"#); | 638 | ", |
639 | r" | ||
640 | mod b {} | ||
641 | use b; | ||
642 | ", | ||
643 | ); | ||
644 | check_fix( | ||
645 | r" | ||
646 | mod b {} | ||
647 | use {b<|>}; | ||
648 | ", | ||
649 | r" | ||
650 | mod b {} | ||
651 | use b; | ||
652 | ", | ||
653 | ); | ||
654 | check_fix( | ||
655 | r" | ||
656 | mod a { mod c {} } | ||
657 | use a::{c<|>}; | ||
658 | ", | ||
659 | r" | ||
660 | mod a { mod c {} } | ||
661 | use a::c; | ||
662 | ", | ||
663 | ); | ||
664 | check_fix( | ||
665 | r" | ||
666 | mod a {} | ||
667 | use a::{self<|>}; | ||
668 | ", | ||
669 | r" | ||
670 | mod a {} | ||
671 | use a; | ||
672 | ", | ||
673 | ); | ||
674 | check_fix( | ||
675 | r" | ||
676 | mod a { mod c {} mod d { mod e {} } } | ||
677 | use a::{c, d::{e<|>}}; | ||
678 | ", | ||
679 | r" | ||
680 | mod a { mod c {} mod d { mod e {} } } | ||
681 | use a::{c, d::e}; | ||
682 | ", | ||
683 | ); | ||
632 | } | 684 | } |
633 | 685 | ||
634 | #[test] | 686 | #[test] |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index cde42024c..1d8a3c404 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -44,7 +44,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
44 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 44 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
45 | <span class="punctuation">}</span> | 45 | <span class="punctuation">}</span> |
46 | 46 | ||
47 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> | 47 | |
48 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> | 48 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> |
49 | <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> | 49 | <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> |
50 | <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> | 50 | <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> |
@@ -74,7 +74,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
74 | <span class="punctuation">}</span> | 74 | <span class="punctuation">}</span> |
75 | <span class="punctuation">}</span> | 75 | <span class="punctuation">}</span> |
76 | 76 | ||
77 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Copy</span><span class="punctuation">,</span><span class="attribute"> Clone</span><span class="punctuation">)</span><span class="attribute">]</span> | 77 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Copy</span><span class="punctuation">)</span><span class="attribute">]</span> |
78 | <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="punctuation">{</span> | 78 | <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="punctuation">{</span> |
79 | <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span> | 79 | <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span> |
80 | <span class="punctuation">}</span> | 80 | <span class="punctuation">}</span> |
@@ -144,7 +144,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
144 | <span class="variable">y</span><span class="punctuation">;</span> | 144 | <span class="variable">y</span><span class="punctuation">;</span> |
145 | 145 | ||
146 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 146 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> |
147 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="unresolved_reference">clone</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 147 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> |
148 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 148 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
149 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 149 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> |
150 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> | 150 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 57d4e1252..211e62ea1 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -18,7 +18,7 @@ pub mod marker { | |||
18 | pub trait Copy {} | 18 | pub trait Copy {} |
19 | } | 19 | } |
20 | 20 | ||
21 | #[derive(Clone, Debug)] | 21 | |
22 | struct Foo { | 22 | struct Foo { |
23 | pub x: i32, | 23 | pub x: i32, |
24 | pub y: i32, | 24 | pub y: i32, |
@@ -48,7 +48,7 @@ impl Foo { | |||
48 | } | 48 | } |
49 | } | 49 | } |
50 | 50 | ||
51 | #[derive(Copy, Clone)] | 51 | #[derive(Copy)] |
52 | struct FooCopy { | 52 | struct FooCopy { |
53 | x: u32, | 53 | x: u32, |
54 | } | 54 | } |
@@ -118,7 +118,7 @@ fn main() { | |||
118 | y; | 118 | y; |
119 | 119 | ||
120 | let mut foo = Foo { x, y: x }; | 120 | let mut foo = Foo { x, y: x }; |
121 | let foo2 = foo.clone(); | 121 | let foo2 = Foo { x, y: x }; |
122 | foo.quop(); | 122 | foo.quop(); |
123 | foo.qux(); | 123 | foo.qux(); |
124 | foo.baz(foo2); | 124 | foo.baz(foo2); |