Preliminary enum variant support

This commit is contained in:
Jeremy Kolb 2019-10-27 21:26:12 -04:00
parent 55d4b06a53
commit 49e89772f6
2 changed files with 67 additions and 2 deletions

View File

@ -29,7 +29,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
(CallInfo::with_fn(db, it), it.data(db).has_self_param())
}
hir::CallableDef::Struct(it) => (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));
}
}

View File

@ -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)?,
}
}