aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_ide_api/src/completion/complete_record_literal.rs28
-rw-r--r--crates/ra_ide_api/src/completion/completion_item.rs17
-rw-r--r--crates/ra_ide_api/src/completion/presentation.rs68
-rw-r--r--crates/ra_lsp_server/src/conv.rs1
4 files changed, 113 insertions, 1 deletions
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
186impl Builder { 198impl 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
259impl<'a> Into<CompletionItem> for Builder { 276impl<'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
3use hir::{db::HirDatabase, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk}; 3use hir::{db::HirDatabase, Docs, HasSource, HirDisplay, ScopeDef, Ty, TypeWalk};
4use join_to_string::join; 4use join_to_string::join;
5use ra_syntax::ast::NameOwner; 5use ra_syntax::ast::{AttrsOwner, NameOwner};
6use test_utils::tested_by; 6use test_utils::tested_by;
7 7
8use crate::completion::{ 8use 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(), &macro_declaration) 185 CompletionItem::new(CompletionKind::Reference, ctx.source_range(), &macro_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
294fn is_deprecated(node: impl AttrsOwner) -> bool {
295 node.attrs().filter_map(|x| x.simple_name()).any(|x| x == "deprecated")
296}
297
282fn has_non_default_type_params(def: hir::GenericDef, db: &db::RootDatabase) -> bool { 298fn 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_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index ee503633d..94ed619fa 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -127,6 +127,7 @@ impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem {
127 text_edit: Some(text_edit), 127 text_edit: Some(text_edit),
128 additional_text_edits: Some(additional_text_edits), 128 additional_text_edits: Some(additional_text_edits),
129 documentation: self.documentation().map(|it| it.conv()), 129 documentation: self.documentation().map(|it| it.conv()),
130 deprecated: Some(self.deprecated()),
130 ..Default::default() 131 ..Default::default()
131 }; 132 };
132 res.insert_text_format = Some(match self.insert_text_format() { 133 res.insert_text_format = Some(match self.insert_text_format() {