diff options
author | kjeremy <[email protected]> | 2019-10-28 14:48:40 +0000 |
---|---|---|
committer | kjeremy <[email protected]> | 2019-10-28 14:48:40 +0000 |
commit | 01238a6fd7d89f97ea05d90b95d3244f1596dc93 (patch) | |
tree | c56902871c42cf5a9875fa56c69932e7c4dca931 | |
parent | ddf25e9481d79abb6b583a195fd26b8ca1b9f060 (diff) |
Filter out non callable versions of Struct/EnumVariant
-rw-r--r-- | crates/ra_ide_api/src/call_info.rs | 52 | ||||
-rw-r--r-- | crates/ra_ide_api/src/display/function_signature.rs | 70 |
2 files changed, 84 insertions, 38 deletions
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 25363a1d9..d947ac50c 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -28,8 +28,8 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
28 | hir::CallableDef::Function(it) => { | 28 | hir::CallableDef::Function(it) => { |
29 | (CallInfo::with_fn(db, it), it.data(db).has_self_param()) | 29 | (CallInfo::with_fn(db, it), it.data(db).has_self_param()) |
30 | } | 30 | } |
31 | hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it), false), | 31 | hir::CallableDef::Struct(it) => (CallInfo::with_struct(db, it)?, false), |
32 | hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it), false), | 32 | hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it)?, false), |
33 | } | 33 | } |
34 | } | 34 | } |
35 | FnCallNode::MethodCallExpr(expr) => { | 35 | FnCallNode::MethodCallExpr(expr) => { |
@@ -123,16 +123,16 @@ impl CallInfo { | |||
123 | CallInfo { signature, active_parameter: None } | 123 | CallInfo { signature, active_parameter: None } |
124 | } | 124 | } |
125 | 125 | ||
126 | fn with_struct(db: &RootDatabase, st: hir::Struct) -> Self { | 126 | fn with_struct(db: &RootDatabase, st: hir::Struct) -> Option<Self> { |
127 | let signature = FunctionSignature::from_struct(db, st); | 127 | let signature = FunctionSignature::from_struct(db, st)?; |
128 | 128 | ||
129 | CallInfo { signature, active_parameter: None } | 129 | Some(CallInfo { signature, active_parameter: None }) |
130 | } | 130 | } |
131 | 131 | ||
132 | fn with_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Self { | 132 | fn with_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Option<Self> { |
133 | let signature = FunctionSignature::from_enum_variant(db, variant); | 133 | let signature = FunctionSignature::from_enum_variant(db, variant)?; |
134 | 134 | ||
135 | CallInfo { signature, active_parameter: None } | 135 | Some(CallInfo { signature, active_parameter: None }) |
136 | } | 136 | } |
137 | 137 | ||
138 | fn parameters(&self) -> &[String] { | 138 | fn parameters(&self) -> &[String] { |
@@ -477,6 +477,7 @@ fn main() { | |||
477 | assert_eq!(info.label(), "fn bar(&self, _: u32)"); | 477 | assert_eq!(info.label(), "fn bar(&self, _: u32)"); |
478 | } | 478 | } |
479 | 479 | ||
480 | #[test] | ||
480 | fn works_for_tuple_structs() { | 481 | fn works_for_tuple_structs() { |
481 | let info = call_info( | 482 | let info = call_info( |
482 | r#" | 483 | r#" |
@@ -487,12 +488,24 @@ fn main() { | |||
487 | }"#, | 488 | }"#, |
488 | ); | 489 | ); |
489 | 490 | ||
490 | assert_eq!(info.label(), "struct TS(0: u32, 1: i32) -> TS"); | 491 | assert_eq!(info.label(), "struct TS(u32, i32) -> TS"); |
491 | assert_eq!(info.doc().map(|it| it.into()), Some("A cool tuple struct".to_string())); | 492 | assert_eq!(info.doc().map(|it| it.into()), Some("A cool tuple struct".to_string())); |
492 | assert_eq!(info.active_parameter, Some(1)); | 493 | assert_eq!(info.active_parameter, Some(1)); |
493 | } | 494 | } |
494 | 495 | ||
495 | #[test] | 496 | #[test] |
497 | #[should_panic] | ||
498 | fn cant_call_named_structs() { | ||
499 | let _ = call_info( | ||
500 | r#" | ||
501 | struct TS { x: u32, y: i32 } | ||
502 | fn main() { | ||
503 | let s = TS(<|>); | ||
504 | }"#, | ||
505 | ); | ||
506 | } | ||
507 | |||
508 | #[test] | ||
496 | fn works_for_enum_variants() { | 509 | fn works_for_enum_variants() { |
497 | let info = call_info( | 510 | let info = call_info( |
498 | r#" | 511 | r#" |
@@ -515,4 +528,25 @@ fn main() { | |||
515 | assert_eq!(info.doc().map(|it| it.into()), Some("A Variant".to_string())); | 528 | assert_eq!(info.doc().map(|it| it.into()), Some("A Variant".to_string())); |
516 | assert_eq!(info.active_parameter, Some(0)); | 529 | assert_eq!(info.active_parameter, Some(0)); |
517 | } | 530 | } |
531 | |||
532 | #[test] | ||
533 | #[should_panic] | ||
534 | fn cant_call_enum_records() { | ||
535 | let _ = call_info( | ||
536 | r#" | ||
537 | enum E { | ||
538 | /// A Variant | ||
539 | A(i32), | ||
540 | /// Another | ||
541 | B, | ||
542 | /// And C | ||
543 | C { a: i32, b: i32 } | ||
544 | } | ||
545 | |||
546 | fn main() { | ||
547 | let a = E::C(<|>); | ||
548 | } | ||
549 | "#, | ||
550 | ); | ||
551 | } | ||
518 | } | 552 | } |
diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index 6b169b3ae..736b5d3db 100644 --- a/crates/ra_ide_api/src/display/function_signature.rs +++ b/crates/ra_ide_api/src/display/function_signature.rs | |||
@@ -51,36 +51,46 @@ impl FunctionSignature { | |||
51 | FunctionSignature::from(&ast_node).with_doc_opt(doc) | 51 | FunctionSignature::from(&ast_node).with_doc_opt(doc) |
52 | } | 52 | } |
53 | 53 | ||
54 | pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Self { | 54 | pub(crate) fn from_struct(db: &db::RootDatabase, st: hir::Struct) -> Option<Self> { |
55 | let doc = st.docs(db); | ||
56 | |||
57 | let node: ast::StructDef = st.source(db).ast; | 55 | let node: ast::StructDef = st.source(db).ast; |
56 | match node.kind() { | ||
57 | ast::StructKind::Named(_) => return None, | ||
58 | _ => (), | ||
59 | }; | ||
58 | 60 | ||
59 | let params = st | 61 | let params = st |
60 | .fields(db) | 62 | .fields(db) |
61 | .into_iter() | 63 | .into_iter() |
62 | .map(|field: hir::StructField| { | 64 | .map(|field: hir::StructField| { |
63 | let name = field.name(db); | ||
64 | let ty = field.ty(db); | 65 | let ty = field.ty(db); |
65 | format!("{}: {}", name, ty.display(db)) | 66 | format!("{}", ty.display(db)) |
66 | }) | 67 | }) |
67 | .collect(); | 68 | .collect(); |
68 | 69 | ||
69 | FunctionSignature { | 70 | Some( |
70 | kind: SigKind::Struct, | 71 | FunctionSignature { |
71 | visibility: node.visibility().map(|n| n.syntax().text().to_string()), | 72 | kind: SigKind::Struct, |
72 | name: node.name().map(|n| n.text().to_string()), | 73 | visibility: node.visibility().map(|n| n.syntax().text().to_string()), |
73 | ret_type: node.name().map(|n| n.text().to_string()), | 74 | name: node.name().map(|n| n.text().to_string()), |
74 | parameters: params, | 75 | ret_type: node.name().map(|n| n.text().to_string()), |
75 | generic_parameters: generic_parameters(&node), | 76 | parameters: params, |
76 | where_predicates: where_predicates(&node), | 77 | generic_parameters: generic_parameters(&node), |
77 | doc: None, | 78 | where_predicates: where_predicates(&node), |
78 | } | 79 | doc: None, |
79 | .with_doc_opt(doc) | 80 | } |
81 | .with_doc_opt(st.docs(db)), | ||
82 | ) | ||
80 | } | 83 | } |
81 | 84 | ||
82 | pub(crate) fn from_enum_variant(db: &db::RootDatabase, variant: hir::EnumVariant) -> Self { | 85 | pub(crate) fn from_enum_variant( |
83 | let doc = variant.docs(db); | 86 | db: &db::RootDatabase, |
87 | variant: hir::EnumVariant, | ||
88 | ) -> Option<Self> { | ||
89 | let node: ast::EnumVariant = variant.source(db).ast; | ||
90 | match node.kind() { | ||
91 | ast::StructKind::Named(_) | ast::StructKind::Unit => return None, | ||
92 | _ => (), | ||
93 | }; | ||
84 | 94 | ||
85 | let parent_name = match variant.parent_enum(db).name(db) { | 95 | let parent_name = match variant.parent_enum(db).name(db) { |
86 | Some(name) => name.to_string(), | 96 | Some(name) => name.to_string(), |
@@ -99,17 +109,19 @@ impl FunctionSignature { | |||
99 | }) | 109 | }) |
100 | .collect(); | 110 | .collect(); |
101 | 111 | ||
102 | FunctionSignature { | 112 | Some( |
103 | kind: SigKind::EnumVariant, | 113 | FunctionSignature { |
104 | visibility: None, | 114 | kind: SigKind::EnumVariant, |
105 | name: Some(name), | 115 | visibility: None, |
106 | ret_type: None, | 116 | name: Some(name), |
107 | parameters: params, | 117 | ret_type: None, |
108 | generic_parameters: vec![], | 118 | parameters: params, |
109 | where_predicates: vec![], | 119 | generic_parameters: vec![], |
110 | doc: None, | 120 | where_predicates: vec![], |
111 | } | 121 | doc: None, |
112 | .with_doc_opt(doc) | 122 | } |
123 | .with_doc_opt(variant.docs(db)), | ||
124 | ) | ||
113 | } | 125 | } |
114 | } | 126 | } |
115 | 127 | ||