diff options
Diffstat (limited to 'crates/ra_ide_api/src')
-rw-r--r-- | crates/ra_ide_api/src/change.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_path.rs | 150 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/complete_record_literal.rs | 28 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/completion_item.rs | 17 | ||||
-rw-r--r-- | crates/ra_ide_api/src/completion/presentation.rs | 68 | ||||
-rw-r--r-- | crates/ra_ide_api/src/db.rs | 5 | ||||
-rw-r--r-- | crates/ra_ide_api/src/diagnostics.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/goto_definition.rs | 74 | ||||
-rw-r--r-- | crates/ra_ide_api/src/mock_analysis.rs | 2 | ||||
-rw-r--r-- | crates/ra_ide_api/src/references/rename.rs | 3 | ||||
-rw-r--r-- | crates/ra_ide_api/src/runnables.rs | 14 | ||||
-rw-r--r-- | crates/ra_ide_api/src/source_change.rs | 2 |
12 files changed, 340 insertions, 30 deletions
diff --git a/crates/ra_ide_api/src/change.rs b/crates/ra_ide_api/src/change.rs index 39c5946c7..4416421ae 100644 --- a/crates/ra_ide_api/src/change.rs +++ b/crates/ra_ide_api/src/change.rs | |||
@@ -4,13 +4,13 @@ use std::{fmt, sync::Arc, time}; | |||
4 | 4 | ||
5 | use ra_db::{ | 5 | use ra_db::{ |
6 | salsa::{Database, Durability, SweepStrategy}, | 6 | salsa::{Database, Durability, SweepStrategy}, |
7 | CrateGraph, CrateId, FileId, SourceDatabase, SourceDatabaseExt, SourceRoot, SourceRootId, | 7 | CrateGraph, CrateId, FileId, RelativePathBuf, SourceDatabase, SourceDatabaseExt, SourceRoot, |
8 | SourceRootId, | ||
8 | }; | 9 | }; |
9 | use ra_prof::{memory_usage, profile, Bytes}; | 10 | use ra_prof::{memory_usage, profile, Bytes}; |
10 | use ra_syntax::SourceFile; | 11 | use ra_syntax::SourceFile; |
11 | #[cfg(not(feature = "wasm"))] | 12 | #[cfg(not(feature = "wasm"))] |
12 | use rayon::prelude::*; | 13 | use rayon::prelude::*; |
13 | use relative_path::RelativePathBuf; | ||
14 | use rustc_hash::FxHashMap; | 14 | use rustc_hash::FxHashMap; |
15 | 15 | ||
16 | use crate::{ | 16 | use crate::{ |
diff --git a/crates/ra_ide_api/src/completion/complete_path.rs b/crates/ra_ide_api/src/completion/complete_path.rs index a58fdc036..09ca40179 100644 --- a/crates/ra_ide_api/src/completion/complete_path.rs +++ b/crates/ra_ide_api/src/completion/complete_path.rs | |||
@@ -18,15 +18,15 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
18 | match def { | 18 | match def { |
19 | hir::ModuleDef::Module(module) => { | 19 | hir::ModuleDef::Module(module) => { |
20 | let module_scope = module.scope(ctx.db); | 20 | let module_scope = module.scope(ctx.db); |
21 | for (name, res) in module_scope.entries() { | 21 | for (name, def, import) in module_scope { |
22 | if let Some(hir::ModuleDef::BuiltinType(..)) = res.def.take_types() { | 22 | if let hir::ScopeDef::ModuleDef(hir::ModuleDef::BuiltinType(..)) = def { |
23 | if ctx.use_item_syntax.is_some() { | 23 | if ctx.use_item_syntax.is_some() { |
24 | tested_by!(dont_complete_primitive_in_use); | 24 | tested_by!(dont_complete_primitive_in_use); |
25 | continue; | 25 | continue; |
26 | } | 26 | } |
27 | } | 27 | } |
28 | if Some(module) == ctx.module { | 28 | if Some(module) == ctx.module { |
29 | if let Some(import) = res.import { | 29 | if let Some(import) = import { |
30 | if let Either::A(use_tree) = module.import_source(ctx.db, import) { | 30 | if let Either::A(use_tree) = module.import_source(ctx.db, import) { |
31 | if use_tree.syntax().text_range().contains_inclusive(ctx.offset) { | 31 | if use_tree.syntax().text_range().contains_inclusive(ctx.offset) { |
32 | // for `use self::foo<|>`, don't suggest `foo` as a completion | 32 | // for `use self::foo<|>`, don't suggest `foo` as a completion |
@@ -36,7 +36,7 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
36 | } | 36 | } |
37 | } | 37 | } |
38 | } | 38 | } |
39 | acc.add_resolution(ctx, name.to_string(), &res.def.into()); | 39 | acc.add_resolution(ctx, name.to_string(), &def); |
40 | } | 40 | } |
41 | } | 41 | } |
42 | hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { | 42 | hir::ModuleDef::Adt(_) | hir::ModuleDef::TypeAlias(_) => { |
@@ -50,23 +50,46 @@ pub(super) fn complete_path(acc: &mut Completions, ctx: &CompletionContext) { | |||
50 | hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), | 50 | hir::ModuleDef::TypeAlias(a) => a.ty(ctx.db), |
51 | _ => unreachable!(), | 51 | _ => unreachable!(), |
52 | }; | 52 | }; |
53 | ctx.analyzer.iterate_path_candidates(ctx.db, ty.clone(), None, |_ty, item| { | ||
54 | match item { | ||
55 | hir::AssocItem::Function(func) => { | ||
56 | let data = func.data(ctx.db); | ||
57 | if !data.has_self_param() { | ||
58 | acc.add_function(ctx, func); | ||
59 | } | ||
60 | } | ||
61 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
62 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
63 | } | ||
64 | None::<()> | ||
65 | }); | ||
66 | // Iterate assoc types separately | ||
67 | // FIXME: complete T::AssocType | ||
53 | let krate = ctx.module.map(|m| m.krate()); | 68 | let krate = ctx.module.map(|m| m.krate()); |
54 | if let Some(krate) = krate { | 69 | if let Some(krate) = krate { |
55 | ty.iterate_impl_items(ctx.db, krate, |item| { | 70 | ty.iterate_impl_items(ctx.db, krate, |item| { |
56 | match item { | 71 | match item { |
57 | hir::AssocItem::Function(func) => { | 72 | hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => {} |
58 | let data = func.data(ctx.db); | ||
59 | if !data.has_self_param() { | ||
60 | acc.add_function(ctx, func); | ||
61 | } | ||
62 | } | ||
63 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
64 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | 73 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), |
65 | } | 74 | } |
66 | None::<()> | 75 | None::<()> |
67 | }); | 76 | }); |
68 | } | 77 | } |
69 | } | 78 | } |
79 | hir::ModuleDef::Trait(t) => { | ||
80 | for item in t.items(ctx.db) { | ||
81 | match item { | ||
82 | hir::AssocItem::Function(func) => { | ||
83 | let data = func.data(ctx.db); | ||
84 | if !data.has_self_param() { | ||
85 | acc.add_function(ctx, func); | ||
86 | } | ||
87 | } | ||
88 | hir::AssocItem::Const(ct) => acc.add_const(ctx, ct), | ||
89 | hir::AssocItem::TypeAlias(ty) => acc.add_type_alias(ctx, ty), | ||
90 | } | ||
91 | } | ||
92 | } | ||
70 | _ => {} | 93 | _ => {} |
71 | }; | 94 | }; |
72 | } | 95 | } |
@@ -559,6 +582,111 @@ mod tests { | |||
559 | } | 582 | } |
560 | 583 | ||
561 | #[test] | 584 | #[test] |
585 | fn completes_trait_associated_method_1() { | ||
586 | assert_debug_snapshot!( | ||
587 | do_reference_completion( | ||
588 | " | ||
589 | //- /lib.rs | ||
590 | trait Trait { | ||
591 | /// A trait method | ||
592 | fn m(); | ||
593 | } | ||
594 | |||
595 | fn foo() { let _ = Trait::<|> } | ||
596 | " | ||
597 | ), | ||
598 | @r###" | ||
599 | [ | ||
600 | CompletionItem { | ||
601 | label: "m()", | ||
602 | source_range: [73; 73), | ||
603 | delete: [73; 73), | ||
604 | insert: "m()$0", | ||
605 | kind: Function, | ||
606 | lookup: "m", | ||
607 | detail: "fn m()", | ||
608 | documentation: Documentation( | ||
609 | "A trait method", | ||
610 | ), | ||
611 | }, | ||
612 | ] | ||
613 | "### | ||
614 | ); | ||
615 | } | ||
616 | |||
617 | #[test] | ||
618 | fn completes_trait_associated_method_2() { | ||
619 | assert_debug_snapshot!( | ||
620 | do_reference_completion( | ||
621 | " | ||
622 | //- /lib.rs | ||
623 | trait Trait { | ||
624 | /// A trait method | ||
625 | fn m(); | ||
626 | } | ||
627 | |||
628 | struct S; | ||
629 | impl Trait for S {} | ||
630 | |||
631 | fn foo() { let _ = S::<|> } | ||
632 | " | ||
633 | ), | ||
634 | @r###" | ||
635 | [ | ||
636 | CompletionItem { | ||
637 | label: "m()", | ||
638 | source_range: [99; 99), | ||
639 | delete: [99; 99), | ||
640 | insert: "m()$0", | ||
641 | kind: Function, | ||
642 | lookup: "m", | ||
643 | detail: "fn m()", | ||
644 | documentation: Documentation( | ||
645 | "A trait method", | ||
646 | ), | ||
647 | }, | ||
648 | ] | ||
649 | "### | ||
650 | ); | ||
651 | } | ||
652 | |||
653 | #[test] | ||
654 | fn completes_trait_associated_method_3() { | ||
655 | assert_debug_snapshot!( | ||
656 | do_reference_completion( | ||
657 | " | ||
658 | //- /lib.rs | ||
659 | trait Trait { | ||
660 | /// A trait method | ||
661 | fn m(); | ||
662 | } | ||
663 | |||
664 | struct S; | ||
665 | impl Trait for S {} | ||
666 | |||
667 | fn foo() { let _ = <S as Trait>::<|> } | ||
668 | " | ||
669 | ), | ||
670 | @r###" | ||
671 | [ | ||
672 | CompletionItem { | ||
673 | label: "m()", | ||
674 | source_range: [110; 110), | ||
675 | delete: [110; 110), | ||
676 | insert: "m()$0", | ||
677 | kind: Function, | ||
678 | lookup: "m", | ||
679 | detail: "fn m()", | ||
680 | documentation: Documentation( | ||
681 | "A trait method", | ||
682 | ), | ||
683 | }, | ||
684 | ] | ||
685 | "### | ||
686 | ); | ||
687 | } | ||
688 | |||
689 | #[test] | ||
562 | fn completes_type_alias() { | 690 | fn completes_type_alias() { |
563 | assert_debug_snapshot!( | 691 | assert_debug_snapshot!( |
564 | do_reference_completion( | 692 | do_reference_completion( |
diff --git a/crates/ra_ide_api/src/completion/complete_record_literal.rs b/crates/ra_ide_api/src/completion/complete_record_literal.rs index 4406695d5..0295b8101 100644 --- a/crates/ra_ide_api/src/completion/complete_record_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_record_literal.rs | |||
@@ -32,6 +32,34 @@ mod tests { | |||
32 | } | 32 | } |
33 | 33 | ||
34 | #[test] | 34 | #[test] |
35 | fn test_record_literal_deprecated_field() { | ||
36 | let completions = complete( | ||
37 | r" | ||
38 | struct A { | ||
39 | #[deprecated] | ||
40 | the_field: u32, | ||
41 | } | ||
42 | fn foo() { | ||
43 | A { the<|> } | ||
44 | } | ||
45 | ", | ||
46 | ); | ||
47 | assert_debug_snapshot!(completions, @r###" | ||
48 | â‹®[ | ||
49 | â‹® CompletionItem { | ||
50 | â‹® label: "the_field", | ||
51 | â‹® source_range: [142; 145), | ||
52 | â‹® delete: [142; 145), | ||
53 | â‹® insert: "the_field", | ||
54 | â‹® kind: Field, | ||
55 | â‹® detail: "u32", | ||
56 | â‹® deprecated: true, | ||
57 | â‹® }, | ||
58 | â‹®] | ||
59 | "###); | ||
60 | } | ||
61 | |||
62 | #[test] | ||
35 | fn test_record_literal_field() { | 63 | fn test_record_literal_field() { |
36 | let completions = complete( | 64 | let completions = complete( |
37 | r" | 65 | r" |
diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index 5c9c44704..93f336370 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs | |||
@@ -44,6 +44,9 @@ pub struct CompletionItem { | |||
44 | /// Additional info to show in the UI pop up. | 44 | /// Additional info to show in the UI pop up. |
45 | detail: Option<String>, | 45 | detail: Option<String>, |
46 | documentation: Option<Documentation>, | 46 | documentation: Option<Documentation>, |
47 | |||
48 | /// Whether this item is marked as deprecated | ||
49 | deprecated: bool, | ||
47 | } | 50 | } |
48 | 51 | ||
49 | // We use custom debug for CompletionItem to make `insta`'s diffs more readable. | 52 | // We use custom debug for CompletionItem to make `insta`'s diffs more readable. |
@@ -70,6 +73,9 @@ impl fmt::Debug for CompletionItem { | |||
70 | if let Some(documentation) = self.documentation() { | 73 | if let Some(documentation) = self.documentation() { |
71 | s.field("documentation", &documentation); | 74 | s.field("documentation", &documentation); |
72 | } | 75 | } |
76 | if self.deprecated { | ||
77 | s.field("deprecated", &true); | ||
78 | } | ||
73 | s.finish() | 79 | s.finish() |
74 | } | 80 | } |
75 | } | 81 | } |
@@ -132,6 +138,7 @@ impl CompletionItem { | |||
132 | lookup: None, | 138 | lookup: None, |
133 | kind: None, | 139 | kind: None, |
134 | text_edit: None, | 140 | text_edit: None, |
141 | deprecated: None, | ||
135 | } | 142 | } |
136 | } | 143 | } |
137 | /// What user sees in pop-up in the UI. | 144 | /// What user sees in pop-up in the UI. |
@@ -166,6 +173,10 @@ impl CompletionItem { | |||
166 | pub fn kind(&self) -> Option<CompletionItemKind> { | 173 | pub fn kind(&self) -> Option<CompletionItemKind> { |
167 | self.kind | 174 | self.kind |
168 | } | 175 | } |
176 | |||
177 | pub fn deprecated(&self) -> bool { | ||
178 | self.deprecated | ||
179 | } | ||
169 | } | 180 | } |
170 | 181 | ||
171 | /// A helper to make `CompletionItem`s. | 182 | /// A helper to make `CompletionItem`s. |
@@ -181,6 +192,7 @@ pub(crate) struct Builder { | |||
181 | lookup: Option<String>, | 192 | lookup: Option<String>, |
182 | kind: Option<CompletionItemKind>, | 193 | kind: Option<CompletionItemKind>, |
183 | text_edit: Option<TextEdit>, | 194 | text_edit: Option<TextEdit>, |
195 | deprecated: Option<bool>, | ||
184 | } | 196 | } |
185 | 197 | ||
186 | impl Builder { | 198 | impl Builder { |
@@ -208,6 +220,7 @@ impl Builder { | |||
208 | lookup: self.lookup, | 220 | lookup: self.lookup, |
209 | kind: self.kind, | 221 | kind: self.kind, |
210 | completion_kind: self.completion_kind, | 222 | completion_kind: self.completion_kind, |
223 | deprecated: self.deprecated.unwrap_or(false), | ||
211 | } | 224 | } |
212 | } | 225 | } |
213 | pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { | 226 | pub(crate) fn lookup_by(mut self, lookup: impl Into<String>) -> Builder { |
@@ -254,6 +267,10 @@ impl Builder { | |||
254 | self.documentation = docs.map(Into::into); | 267 | self.documentation = docs.map(Into::into); |
255 | self | 268 | self |
256 | } | 269 | } |
270 | pub(crate) fn set_deprecated(mut self, deprecated: bool) -> Builder { | ||
271 | self.deprecated = Some(deprecated); | ||
272 | self | ||
273 | } | ||
257 | } | 274 | } |
258 | 275 | ||
259 | impl<'a> Into<CompletionItem> for Builder { | 276 | impl<'a> Into<CompletionItem> for Builder { |
diff --git a/crates/ra_ide_api/src/completion/presentation.rs b/crates/ra_ide_api/src/completion/presentation.rs index 65bb639ed..cb55d1875 100644 --- a/crates/ra_ide_api/src/completion/presentation.rs +++ b/crates/ra_ide_api/src/completion/presentation.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use hir::{db::HirDatabase, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; | 3 | use hir::{db::HirDatabase, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; |
4 | use join_to_string::join; | 4 | use join_to_string::join; |
5 | use ra_syntax::ast::NameOwner; | 5 | use ra_syntax::ast::{AttrsOwner, NameOwner}; |
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use crate::completion::{ | 8 | use crate::completion::{ |
@@ -18,6 +18,11 @@ impl Completions { | |||
18 | field: hir::StructField, | 18 | field: hir::StructField, |
19 | substs: &hir::Substs, | 19 | substs: &hir::Substs, |
20 | ) { | 20 | ) { |
21 | let ast_node = field.source(ctx.db).ast; | ||
22 | let is_deprecated = match ast_node { | ||
23 | hir::FieldSource::Named(m) => is_deprecated(m), | ||
24 | hir::FieldSource::Pos(m) => is_deprecated(m), | ||
25 | }; | ||
21 | CompletionItem::new( | 26 | CompletionItem::new( |
22 | CompletionKind::Reference, | 27 | CompletionKind::Reference, |
23 | ctx.source_range(), | 28 | ctx.source_range(), |
@@ -26,6 +31,7 @@ impl Completions { | |||
26 | .kind(CompletionItemKind::Field) | 31 | .kind(CompletionItemKind::Field) |
27 | .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) | 32 | .detail(field.ty(ctx.db).subst(substs).display(ctx.db).to_string()) |
28 | .set_documentation(field.docs(ctx.db)) | 33 | .set_documentation(field.docs(ctx.db)) |
34 | .set_deprecated(is_deprecated) | ||
29 | .add_to(self); | 35 | .add_to(self); |
30 | } | 36 | } |
31 | 37 | ||
@@ -179,6 +185,7 @@ impl Completions { | |||
179 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), ¯o_declaration) | 185 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), ¯o_declaration) |
180 | .kind(CompletionItemKind::Macro) | 186 | .kind(CompletionItemKind::Macro) |
181 | .set_documentation(docs.clone()) | 187 | .set_documentation(docs.clone()) |
188 | .set_deprecated(is_deprecated(ast_node)) | ||
182 | .detail(detail); | 189 | .detail(detail); |
183 | 190 | ||
184 | builder = if ctx.use_item_syntax.is_some() { | 191 | builder = if ctx.use_item_syntax.is_some() { |
@@ -211,6 +218,7 @@ impl Completions { | |||
211 | CompletionItemKind::Function | 218 | CompletionItemKind::Function |
212 | }) | 219 | }) |
213 | .set_documentation(func.docs(ctx.db)) | 220 | .set_documentation(func.docs(ctx.db)) |
221 | .set_deprecated(is_deprecated(ast_node)) | ||
214 | .detail(detail); | 222 | .detail(detail); |
215 | 223 | ||
216 | // Add `<>` for generic types | 224 | // Add `<>` for generic types |
@@ -242,6 +250,7 @@ impl Completions { | |||
242 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) | 250 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) |
243 | .kind(CompletionItemKind::Const) | 251 | .kind(CompletionItemKind::Const) |
244 | .set_documentation(constant.docs(ctx.db)) | 252 | .set_documentation(constant.docs(ctx.db)) |
253 | .set_deprecated(is_deprecated(ast_node)) | ||
245 | .detail(detail) | 254 | .detail(detail) |
246 | .add_to(self); | 255 | .add_to(self); |
247 | } | 256 | } |
@@ -257,11 +266,13 @@ impl Completions { | |||
257 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) | 266 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.text().to_string()) |
258 | .kind(CompletionItemKind::TypeAlias) | 267 | .kind(CompletionItemKind::TypeAlias) |
259 | .set_documentation(type_alias.docs(ctx.db)) | 268 | .set_documentation(type_alias.docs(ctx.db)) |
269 | .set_deprecated(is_deprecated(type_def)) | ||
260 | .detail(detail) | 270 | .detail(detail) |
261 | .add_to(self); | 271 | .add_to(self); |
262 | } | 272 | } |
263 | 273 | ||
264 | pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { | 274 | pub(crate) fn add_enum_variant(&mut self, ctx: &CompletionContext, variant: hir::EnumVariant) { |
275 | let is_deprecated = is_deprecated(variant.source(ctx.db).ast); | ||
265 | let name = match variant.name(ctx.db) { | 276 | let name = match variant.name(ctx.db) { |
266 | Some(it) => it, | 277 | Some(it) => it, |
267 | None => return, | 278 | None => return, |
@@ -274,11 +285,16 @@ impl Completions { | |||
274 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) | 285 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) |
275 | .kind(CompletionItemKind::EnumVariant) | 286 | .kind(CompletionItemKind::EnumVariant) |
276 | .set_documentation(variant.docs(ctx.db)) | 287 | .set_documentation(variant.docs(ctx.db)) |
288 | .set_deprecated(is_deprecated) | ||
277 | .detail(detail) | 289 | .detail(detail) |
278 | .add_to(self); | 290 | .add_to(self); |
279 | } | 291 | } |
280 | } | 292 | } |
281 | 293 | ||
294 | fn is_deprecated(node: impl AttrsOwner) -> bool { | ||
295 | node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated") | ||
296 | } | ||
297 | |||
282 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { | 298 | fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { |
283 | let subst = db.generic_defaults(def); | 299 | let subst = db.generic_defaults(def); |
284 | subst.iter().any(|ty| ty == &Ty::Unknown) | 300 | subst.iter().any(|ty| ty == &Ty::Unknown) |
@@ -296,6 +312,56 @@ mod tests { | |||
296 | } | 312 | } |
297 | 313 | ||
298 | #[test] | 314 | #[test] |
315 | fn sets_deprecated_flag_in_completion_items() { | ||
316 | assert_debug_snapshot!( | ||
317 | do_reference_completion( | ||
318 | r#" | ||
319 | #[deprecated] | ||
320 | fn something_deprecated() {} | ||
321 | |||
322 | #[deprecated(since = "1.0.0")] | ||
323 | fn something_else_deprecated() {} | ||
324 | |||
325 | fn main() { som<|> } | ||
326 | "#, | ||
327 | ), | ||
328 | @r###" | ||
329 | [ | ||
330 | CompletionItem { | ||
331 | label: "main()", | ||
332 | source_range: [203; 206), | ||
333 | delete: [203; 206), | ||
334 | insert: "main()$0", | ||
335 | kind: Function, | ||
336 | lookup: "main", | ||
337 | detail: "fn main()", | ||
338 | }, | ||
339 | CompletionItem { | ||
340 | label: "something_deprecated()", | ||
341 | source_range: [203; 206), | ||
342 | delete: [203; 206), | ||
343 | insert: "something_deprecated()$0", | ||
344 | kind: Function, | ||
345 | lookup: "something_deprecated", | ||
346 | detail: "fn something_deprecated()", | ||
347 | deprecated: true, | ||
348 | }, | ||
349 | CompletionItem { | ||
350 | label: "something_else_deprecated()", | ||
351 | source_range: [203; 206), | ||
352 | delete: [203; 206), | ||
353 | insert: "something_else_deprecated()$0", | ||
354 | kind: Function, | ||
355 | lookup: "something_else_deprecated", | ||
356 | detail: "fn something_else_deprecated()", | ||
357 | deprecated: true, | ||
358 | }, | ||
359 | ] | ||
360 | "### | ||
361 | ); | ||
362 | } | ||
363 | |||
364 | #[test] | ||
299 | fn inserts_parens_for_function_calls() { | 365 | fn inserts_parens_for_function_calls() { |
300 | covers!(inserts_parens_for_function_calls); | 366 | covers!(inserts_parens_for_function_calls); |
301 | assert_debug_snapshot!( | 367 | assert_debug_snapshot!( |
diff --git a/crates/ra_ide_api/src/db.rs b/crates/ra_ide_api/src/db.rs index 785e71808..c96465b6a 100644 --- a/crates/ra_ide_api/src/db.rs +++ b/crates/ra_ide_api/src/db.rs | |||
@@ -4,10 +4,9 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use ra_db::{ | 5 | use ra_db::{ |
6 | salsa::{self, Database, Durability}, | 6 | salsa::{self, Database, Durability}, |
7 | Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, SourceDatabase, | 7 | Canceled, CheckCanceled, CrateId, FileId, FileLoader, FileLoaderDelegate, RelativePath, |
8 | SourceDatabaseExt, SourceRootId, | 8 | SourceDatabase, SourceDatabaseExt, SourceRootId, |
9 | }; | 9 | }; |
10 | use relative_path::RelativePath; | ||
11 | use rustc_hash::FxHashMap; | 10 | use rustc_hash::FxHashMap; |
12 | 11 | ||
13 | use crate::{ | 12 | use crate::{ |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index 1f1f5cd74..2890a3d2b 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -4,7 +4,7 @@ use std::cell::RefCell; | |||
4 | 4 | ||
5 | use hir::diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSink}; | 5 | use hir::diagnostics::{AstDiagnostic, Diagnostic as _, DiagnosticSink}; |
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use ra_db::{SourceDatabase, SourceDatabaseExt}; | 7 | use ra_db::{RelativePath, SourceDatabase, SourceDatabaseExt}; |
8 | use ra_prof::profile; | 8 | use ra_prof::profile; |
9 | use ra_syntax::{ | 9 | use ra_syntax::{ |
10 | algo, | 10 | algo, |
@@ -12,7 +12,6 @@ use ra_syntax::{ | |||
12 | Location, SyntaxNode, TextRange, T, | 12 | Location, SyntaxNode, TextRange, T, |
13 | }; | 13 | }; |
14 | use ra_text_edit::{TextEdit, TextEditBuilder}; | 14 | use ra_text_edit::{TextEdit, TextEditBuilder}; |
15 | use relative_path::RelativePath; | ||
16 | 15 | ||
17 | use crate::{db::RootDatabase, Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit}; | 16 | use crate::{db::RootDatabase, Diagnostic, FileId, FileSystemEdit, SourceChange, SourceFileEdit}; |
18 | 17 | ||
diff --git a/crates/ra_ide_api/src/goto_definition.rs b/crates/ra_ide_api/src/goto_definition.rs index 1f3fa6c57..c1ce54bea 100644 --- a/crates/ra_ide_api/src/goto_definition.rs +++ b/crates/ra_ide_api/src/goto_definition.rs | |||
@@ -316,6 +316,25 @@ mod tests { | |||
316 | } | 316 | } |
317 | 317 | ||
318 | #[test] | 318 | #[test] |
319 | fn goto_definition_works_for_macros_in_use_tree() { | ||
320 | check_goto( | ||
321 | " | ||
322 | //- /lib.rs | ||
323 | use foo::foo<|>; | ||
324 | |||
325 | //- /foo/lib.rs | ||
326 | #[macro_export] | ||
327 | macro_rules! foo { | ||
328 | () => { | ||
329 | {} | ||
330 | }; | ||
331 | } | ||
332 | ", | ||
333 | "foo MACRO_CALL FileId(2) [0; 66) [29; 32)", | ||
334 | ); | ||
335 | } | ||
336 | |||
337 | #[test] | ||
319 | fn goto_definition_works_for_methods() { | 338 | fn goto_definition_works_for_methods() { |
320 | covers!(goto_definition_works_for_methods); | 339 | covers!(goto_definition_works_for_methods); |
321 | check_goto( | 340 | check_goto( |
@@ -371,6 +390,61 @@ mod tests { | |||
371 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", | 390 | "spam RECORD_FIELD_DEF FileId(1) [17; 26) [17; 21)", |
372 | ); | 391 | ); |
373 | } | 392 | } |
393 | |||
394 | #[test] | ||
395 | fn goto_definition_works_for_ufcs_inherent_methods() { | ||
396 | check_goto( | ||
397 | " | ||
398 | //- /lib.rs | ||
399 | struct Foo; | ||
400 | impl Foo { | ||
401 | fn frobnicate() { } | ||
402 | } | ||
403 | |||
404 | fn bar(foo: &Foo) { | ||
405 | Foo::frobnicate<|>(); | ||
406 | } | ||
407 | ", | ||
408 | "frobnicate FN_DEF FileId(1) [27; 47) [30; 40)", | ||
409 | ); | ||
410 | } | ||
411 | |||
412 | #[test] | ||
413 | fn goto_definition_works_for_ufcs_trait_methods_through_traits() { | ||
414 | check_goto( | ||
415 | " | ||
416 | //- /lib.rs | ||
417 | trait Foo { | ||
418 | fn frobnicate(); | ||
419 | } | ||
420 | |||
421 | fn bar() { | ||
422 | Foo::frobnicate<|>(); | ||
423 | } | ||
424 | ", | ||
425 | "frobnicate FN_DEF FileId(1) [16; 32) [19; 29)", | ||
426 | ); | ||
427 | } | ||
428 | |||
429 | #[test] | ||
430 | fn goto_definition_works_for_ufcs_trait_methods_through_self() { | ||
431 | check_goto( | ||
432 | " | ||
433 | //- /lib.rs | ||
434 | struct Foo; | ||
435 | trait Trait { | ||
436 | fn frobnicate(); | ||
437 | } | ||
438 | impl Trait for Foo {} | ||
439 | |||
440 | fn bar() { | ||
441 | Foo::frobnicate<|>(); | ||
442 | } | ||
443 | ", | ||
444 | "frobnicate FN_DEF FileId(1) [30; 46) [33; 43)", | ||
445 | ); | ||
446 | } | ||
447 | |||
374 | #[test] | 448 | #[test] |
375 | fn goto_definition_on_self() { | 449 | fn goto_definition_on_self() { |
376 | check_goto( | 450 | check_goto( |
diff --git a/crates/ra_ide_api/src/mock_analysis.rs b/crates/ra_ide_api/src/mock_analysis.rs index 80b71894c..2b1c96dbf 100644 --- a/crates/ra_ide_api/src/mock_analysis.rs +++ b/crates/ra_ide_api/src/mock_analysis.rs | |||
@@ -3,7 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_cfg::CfgOptions; | 5 | use ra_cfg::CfgOptions; |
6 | use relative_path::RelativePathBuf; | 6 | use ra_db::RelativePathBuf; |
7 | use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; | 7 | use test_utils::{extract_offset, extract_range, parse_fixture, CURSOR_MARKER}; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
diff --git a/crates/ra_ide_api/src/references/rename.rs b/crates/ra_ide_api/src/references/rename.rs index a8783d7a0..11f81cbb3 100644 --- a/crates/ra_ide_api/src/references/rename.rs +++ b/crates/ra_ide_api/src/references/rename.rs | |||
@@ -1,10 +1,9 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::ModuleSource; | 3 | use hir::ModuleSource; |
4 | use ra_db::{SourceDatabase, SourceDatabaseExt}; | 4 | use ra_db::{RelativePath, RelativePathBuf, SourceDatabase, SourceDatabaseExt}; |
5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode}; | 5 | use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SyntaxNode}; |
6 | use ra_text_edit::TextEdit; | 6 | use ra_text_edit::TextEdit; |
7 | use relative_path::{RelativePath, RelativePathBuf}; | ||
8 | 7 | ||
9 | use crate::{ | 8 | use crate::{ |
10 | db::RootDatabase, FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, | 9 | db::RootDatabase, FileId, FilePosition, FileSystemEdit, RangeInfo, SourceChange, |
diff --git a/crates/ra_ide_api/src/runnables.rs b/crates/ra_ide_api/src/runnables.rs index 910883da7..1b5c8deea 100644 --- a/crates/ra_ide_api/src/runnables.rs +++ b/crates/ra_ide_api/src/runnables.rs | |||
@@ -4,7 +4,7 @@ use itertools::Itertools; | |||
4 | use ra_db::SourceDatabase; | 4 | use ra_db::SourceDatabase; |
5 | use ra_syntax::{ | 5 | use ra_syntax::{ |
6 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, | 6 | ast::{self, AstNode, AttrsOwner, ModuleItemOwner, NameOwner}, |
7 | SyntaxNode, TextRange, | 7 | match_ast, SyntaxNode, TextRange, |
8 | }; | 8 | }; |
9 | 9 | ||
10 | use crate::{db::RootDatabase, FileId}; | 10 | use crate::{db::RootDatabase, FileId}; |
@@ -29,12 +29,12 @@ pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | |||
29 | } | 29 | } |
30 | 30 | ||
31 | fn runnable(db: &RootDatabase, file_id: FileId, item: SyntaxNode) -> Option<Runnable> { | 31 | fn runnable(db: &RootDatabase, file_id: FileId, item: SyntaxNode) -> Option<Runnable> { |
32 | if let Some(fn_def) = ast::FnDef::cast(item.clone()) { | 32 | match_ast! { |
33 | runnable_fn(fn_def) | 33 | match item { |
34 | } else if let Some(m) = ast::Module::cast(item) { | 34 | ast::FnDef(it) => { runnable_fn(it) }, |
35 | runnable_mod(db, file_id, m) | 35 | ast::Module(it) => { runnable_mod(db, file_id, it) }, |
36 | } else { | 36 | _ => { None }, |
37 | None | 37 | } |
38 | } | 38 | } |
39 | } | 39 | } |
40 | 40 | ||
diff --git a/crates/ra_ide_api/src/source_change.rs b/crates/ra_ide_api/src/source_change.rs index 4e63bbf6f..f5f7f8807 100644 --- a/crates/ra_ide_api/src/source_change.rs +++ b/crates/ra_ide_api/src/source_change.rs | |||
@@ -3,8 +3,8 @@ | |||
3 | //! | 3 | //! |
4 | //! It can be viewed as a dual for `AnalysisChange`. | 4 | //! It can be viewed as a dual for `AnalysisChange`. |
5 | 5 | ||
6 | use ra_db::RelativePathBuf; | ||
6 | use ra_text_edit::TextEdit; | 7 | use ra_text_edit::TextEdit; |
7 | use relative_path::RelativePathBuf; | ||
8 | 8 | ||
9 | use crate::{FileId, FilePosition, SourceRootId, TextUnit}; | 9 | use crate::{FileId, FilePosition, SourceRootId, TextUnit}; |
10 | 10 | ||