From 49e89772f63e10ebeb3c8720bd0b0ef8244f6c4a Mon Sep 17 00:00:00 2001 From: Jeremy Kolb Date: Sun, 27 Oct 2019 21:26:12 -0400 Subject: Preliminary enum variant support --- crates/ra_ide_api/src/call_info.rs | 32 ++++++++++++++++++- .../ra_ide_api/src/display/function_signature.rs | 37 +++++++++++++++++++++- 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 29ae2f552..e6bdaae6a 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs @@ -29,7 +29,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option (CallInfo::with_struct(db, it), false), - hir::CallableDef::EnumVariant(_it) => return None, + hir::CallableDef::EnumVariant(it) => (CallInfo::with_enum_variant(db, it), false), } } FnCallNode::MethodCallExpr(expr) => { @@ -129,6 +129,12 @@ impl CallInfo { CallInfo { signature, active_parameter: None } } + fn with_enum_variant(db: &RootDatabase, variant: hir::EnumVariant) -> Self { + let signature = FunctionSignature::from_enum_variant(db, variant); + + CallInfo { signature, active_parameter: None } + } + fn parameters(&self) -> &[String] { &self.signature.parameters } @@ -485,4 +491,28 @@ fn main() { assert_eq!(info.doc().map(|it| it.into()), Some("A cool tuple struct".to_string())); assert_eq!(info.active_parameter, Some(1)); } + + #[test] + fn works_for_enum_variants() { + let info = call_info( + r#" +enum E { + /// A Variant + A(i32), + /// Another + B, + /// And C + C(a: i32, b: i32) +} + +fn main() { + let a = E::A(<|>); +} + "#, + ); + + assert_eq!(info.label(), "E::A(0: i32)"); + assert_eq!(info.doc().map(|it| it.into()), Some("A Variant".to_string())); + assert_eq!(info.active_parameter, Some(0)); + } } diff --git a/crates/ra_ide_api/src/display/function_signature.rs b/crates/ra_ide_api/src/display/function_signature.rs index 6555f8619..6b169b3ae 100644 --- a/crates/ra_ide_api/src/display/function_signature.rs +++ b/crates/ra_ide_api/src/display/function_signature.rs @@ -16,6 +16,7 @@ use crate::{ pub enum SigKind { Function, Struct, + EnumVariant, } /// Contains information about a function signature @@ -70,13 +71,46 @@ impl FunctionSignature { visibility: node.visibility().map(|n| n.syntax().text().to_string()), name: node.name().map(|n| n.text().to_string()), ret_type: node.name().map(|n| n.text().to_string()), - parameters: /*param_list(node)*/ params, + parameters: params, generic_parameters: generic_parameters(&node), where_predicates: where_predicates(&node), doc: None, } .with_doc_opt(doc) } + + pub(crate) fn from_enum_variant(db: &db::RootDatabase, variant: hir::EnumVariant) -> Self { + let doc = variant.docs(db); + + let parent_name = match variant.parent_enum(db).name(db) { + Some(name) => name.to_string(), + None => "missing".into(), + }; + + let name = format!("{}::{}", parent_name, variant.name(db).unwrap()); + + let params = variant + .fields(db) + .into_iter() + .map(|field: hir::StructField| { + let name = field.name(db); + let ty = field.ty(db); + format!("{}: {}", name, ty.display(db)) + }) + .collect(); + + FunctionSignature { + kind: SigKind::EnumVariant, + visibility: None, + name: Some(name), + ret_type: None, + parameters: params, + generic_parameters: vec![], + where_predicates: vec![], + doc: None, + } + .with_doc_opt(doc) + } } impl From<&'_ ast::FnDef> for FunctionSignature { @@ -120,6 +154,7 @@ impl Display for FunctionSignature { match self.kind { SigKind::Function => write!(f, "fn {}", name)?, SigKind::Struct => write!(f, "struct {}", name)?, + SigKind::EnumVariant => write!(f, "{}", name)?, } } -- cgit v1.2.3