From 666303faf3c8b4215fde884451688084e298d6a8 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Feb 2019 16:57:05 +0300 Subject: support upcastig in AST enum --- crates/ra_syntax/src/ast/generated.rs | 398 +++++++++++++++++++++++++++++ crates/ra_syntax/src/ast/generated.rs.tera | 9 + 2 files changed, 407 insertions(+) (limited to 'crates') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 47107a58b..aa88b1e28 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -834,6 +834,142 @@ pub enum ExprKind<'a> { BinExpr(&'a BinExpr), Literal(&'a Literal), } +impl<'a> From<&'a TupleExpr> for &'a Expr { + fn from(n: &'a TupleExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ArrayExpr> for &'a Expr { + fn from(n: &'a ArrayExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ParenExpr> for &'a Expr { + fn from(n: &'a ParenExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PathExpr> for &'a Expr { + fn from(n: &'a PathExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a LambdaExpr> for &'a Expr { + fn from(n: &'a LambdaExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a IfExpr> for &'a Expr { + fn from(n: &'a IfExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a LoopExpr> for &'a Expr { + fn from(n: &'a LoopExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ForExpr> for &'a Expr { + fn from(n: &'a ForExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a WhileExpr> for &'a Expr { + fn from(n: &'a WhileExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ContinueExpr> for &'a Expr { + fn from(n: &'a ContinueExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a BreakExpr> for &'a Expr { + fn from(n: &'a BreakExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a Label> for &'a Expr { + fn from(n: &'a Label) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a BlockExpr> for &'a Expr { + fn from(n: &'a BlockExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ReturnExpr> for &'a Expr { + fn from(n: &'a ReturnExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a MatchExpr> for &'a Expr { + fn from(n: &'a MatchExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a StructLit> for &'a Expr { + fn from(n: &'a StructLit) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a CallExpr> for &'a Expr { + fn from(n: &'a CallExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a IndexExpr> for &'a Expr { + fn from(n: &'a IndexExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a MethodCallExpr> for &'a Expr { + fn from(n: &'a MethodCallExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a FieldExpr> for &'a Expr { + fn from(n: &'a FieldExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TryExpr> for &'a Expr { + fn from(n: &'a TryExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a CastExpr> for &'a Expr { + fn from(n: &'a CastExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a RefExpr> for &'a Expr { + fn from(n: &'a RefExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PrefixExpr> for &'a Expr { + fn from(n: &'a PrefixExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a RangeExpr> for &'a Expr { + fn from(n: &'a RangeExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a BinExpr> for &'a Expr { + fn from(n: &'a BinExpr) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a Literal> for &'a Expr { + fn from(n: &'a Literal) -> &'a Expr { + Expr::cast(&n.syntax).unwrap() + } +} + impl AstNode for Expr { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -1375,6 +1511,22 @@ pub enum ImplItemKind<'a> { TypeDef(&'a TypeDef), ConstDef(&'a ConstDef), } +impl<'a> From<&'a FnDef> for &'a ImplItem { + fn from(n: &'a FnDef) -> &'a ImplItem { + ImplItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TypeDef> for &'a ImplItem { + fn from(n: &'a TypeDef) -> &'a ImplItem { + ImplItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ConstDef> for &'a ImplItem { + fn from(n: &'a ConstDef) -> &'a ImplItem { + ImplItem::cast(&n.syntax).unwrap() + } +} + impl AstNode for ImplItem { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -1778,6 +1930,57 @@ pub enum LiteralExprKind<'a> { TrueKw(&'a TrueKw), FalseKw(&'a FalseKw), } +impl<'a> From<&'a String> for &'a LiteralExpr { + fn from(n: &'a String) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ByteString> for &'a LiteralExpr { + fn from(n: &'a ByteString) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a RawString> for &'a LiteralExpr { + fn from(n: &'a RawString) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a RawByteString> for &'a LiteralExpr { + fn from(n: &'a RawByteString) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a Char> for &'a LiteralExpr { + fn from(n: &'a Char) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a Byte> for &'a LiteralExpr { + fn from(n: &'a Byte) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a IntNumber> for &'a LiteralExpr { + fn from(n: &'a IntNumber) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a FloatNumber> for &'a LiteralExpr { + fn from(n: &'a FloatNumber) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TrueKw> for &'a LiteralExpr { + fn from(n: &'a TrueKw) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a FalseKw> for &'a LiteralExpr { + fn from(n: &'a FalseKw) -> &'a LiteralExpr { + LiteralExpr::cast(&n.syntax).unwrap() + } +} + impl AstNode for LiteralExpr { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -2164,6 +2367,62 @@ pub enum ModuleItemKind<'a> { StaticDef(&'a StaticDef), Module(&'a Module), } +impl<'a> From<&'a StructDef> for &'a ModuleItem { + fn from(n: &'a StructDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a EnumDef> for &'a ModuleItem { + fn from(n: &'a EnumDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a FnDef> for &'a ModuleItem { + fn from(n: &'a FnDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TraitDef> for &'a ModuleItem { + fn from(n: &'a TraitDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TypeDef> for &'a ModuleItem { + fn from(n: &'a TypeDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ImplBlock> for &'a ModuleItem { + fn from(n: &'a ImplBlock) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a UseItem> for &'a ModuleItem { + fn from(n: &'a UseItem) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ExternCrateItem> for &'a ModuleItem { + fn from(n: &'a ExternCrateItem) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ConstDef> for &'a ModuleItem { + fn from(n: &'a ConstDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a StaticDef> for &'a ModuleItem { + fn from(n: &'a StaticDef) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a Module> for &'a ModuleItem { + fn from(n: &'a Module) -> &'a ModuleItem { + ModuleItem::cast(&n.syntax).unwrap() + } +} + impl AstNode for ModuleItem { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -2446,6 +2705,17 @@ pub enum NominalDefKind<'a> { StructDef(&'a StructDef), EnumDef(&'a EnumDef), } +impl<'a> From<&'a StructDef> for &'a NominalDef { + fn from(n: &'a StructDef) -> &'a NominalDef { + NominalDef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a EnumDef> for &'a NominalDef { + fn from(n: &'a EnumDef) -> &'a NominalDef { + NominalDef::cast(&n.syntax).unwrap() + } +} + impl AstNode for NominalDef { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -2637,6 +2907,57 @@ pub enum PatKind<'a> { RangePat(&'a RangePat), LiteralPat(&'a LiteralPat), } +impl<'a> From<&'a RefPat> for &'a Pat { + fn from(n: &'a RefPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a BindPat> for &'a Pat { + fn from(n: &'a BindPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PlaceholderPat> for &'a Pat { + fn from(n: &'a PlaceholderPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PathPat> for &'a Pat { + fn from(n: &'a PathPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a StructPat> for &'a Pat { + fn from(n: &'a StructPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TupleStructPat> for &'a Pat { + fn from(n: &'a TupleStructPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TuplePat> for &'a Pat { + fn from(n: &'a TuplePat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a SlicePat> for &'a Pat { + fn from(n: &'a SlicePat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a RangePat> for &'a Pat { + fn from(n: &'a RangePat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a LiteralPat> for &'a Pat { + fn from(n: &'a LiteralPat) -> &'a Pat { + Pat::cast(&n.syntax).unwrap() + } +} + impl AstNode for Pat { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -3520,6 +3841,17 @@ pub enum StmtKind<'a> { ExprStmt(&'a ExprStmt), LetStmt(&'a LetStmt), } +impl<'a> From<&'a ExprStmt> for &'a Stmt { + fn from(n: &'a ExprStmt) -> &'a Stmt { + Stmt::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a LetStmt> for &'a Stmt { + fn from(n: &'a LetStmt) -> &'a Stmt { + Stmt::cast(&n.syntax).unwrap() + } +} + impl AstNode for Stmt { fn cast(syntax: &SyntaxNode) -> Option<&Self> { @@ -4142,6 +4474,72 @@ pub enum TypeRefKind<'a> { ImplTraitType(&'a ImplTraitType), DynTraitType(&'a DynTraitType), } +impl<'a> From<&'a ParenType> for &'a TypeRef { + fn from(n: &'a ParenType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a TupleType> for &'a TypeRef { + fn from(n: &'a TupleType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a NeverType> for &'a TypeRef { + fn from(n: &'a NeverType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PathType> for &'a TypeRef { + fn from(n: &'a PathType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PointerType> for &'a TypeRef { + fn from(n: &'a PointerType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ArrayType> for &'a TypeRef { + fn from(n: &'a ArrayType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a SliceType> for &'a TypeRef { + fn from(n: &'a SliceType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ReferenceType> for &'a TypeRef { + fn from(n: &'a ReferenceType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a PlaceholderType> for &'a TypeRef { + fn from(n: &'a PlaceholderType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a FnPointerType> for &'a TypeRef { + fn from(n: &'a FnPointerType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ForType> for &'a TypeRef { + fn from(n: &'a ForType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a ImplTraitType> for &'a TypeRef { + fn from(n: &'a ImplTraitType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} +impl<'a> From<&'a DynTraitType> for &'a TypeRef { + fn from(n: &'a DynTraitType) -> &'a TypeRef { + TypeRef::cast(&n.syntax).unwrap() + } +} + impl AstNode for TypeRef { fn cast(syntax: &SyntaxNode) -> Option<&Self> { diff --git a/crates/ra_syntax/src/ast/generated.rs.tera b/crates/ra_syntax/src/ast/generated.rs.tera index ca7a28581..e2d4856cf 100644 --- a/crates/ra_syntax/src/ast/generated.rs.tera +++ b/crates/ra_syntax/src/ast/generated.rs.tera @@ -38,6 +38,15 @@ pub enum {{ node }}Kind<'a> { {%- endfor %} } +{%- for kind in methods.enum %} +impl<'a> From<&'a {{ kind }}> for &'a {{ node }} { + fn from(n: &'a {{ kind }}) -> &'a {{ node }} { + {{ node }}::cast(&n.syntax).unwrap() + } +} +{%- endfor %} + + impl AstNode for {{ node }} { fn cast(syntax: &SyntaxNode) -> Option<&Self> { match syntax.kind() { -- cgit v1.2.3 From 65a2be49539375502ca95c8da455f50f580df2e3 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Feb 2019 17:01:56 +0300 Subject: complete struct literals --- crates/ra_ide_api/src/completion.rs | 2 + .../src/completion/complete_struct_literal.rs | 64 ++++++++++++++++++++++ .../src/completion/completion_context.rs | 6 ++ crates/ra_syntax/src/ast.rs | 6 ++ 4 files changed, 78 insertions(+) create mode 100644 crates/ra_ide_api/src/completion/complete_struct_literal.rs (limited to 'crates') diff --git a/crates/ra_ide_api/src/completion.rs b/crates/ra_ide_api/src/completion.rs index 4a38d62bb..d92e01bfb 100644 --- a/crates/ra_ide_api/src/completion.rs +++ b/crates/ra_ide_api/src/completion.rs @@ -2,6 +2,7 @@ mod completion_item; mod completion_context; mod complete_dot; +mod complete_struct_literal; mod complete_fn_param; mod complete_keyword; mod complete_snippet; @@ -59,6 +60,7 @@ pub(crate) fn completions(db: &db::RootDatabase, position: FilePosition) -> Opti complete_path::complete_path(&mut acc, &ctx); complete_scope::complete_scope(&mut acc, &ctx); complete_dot::complete_dot(&mut acc, &ctx); + complete_struct_literal::complete_struct_literal(&mut acc, &ctx); complete_postfix::complete_postfix(&mut acc, &ctx); Some(acc) } diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs new file mode 100644 index 000000000..893056c2b --- /dev/null +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs @@ -0,0 +1,64 @@ +use hir::{Ty, AdtDef, Docs}; + +use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind}; +use crate::completion::completion_item::CompletionKind; + +/// Complete dot accesses, i.e. fields or methods (currently only fields). +pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { + let (function, struct_lit) = match (&ctx.function, ctx.struct_lit_syntax) { + (Some(function), Some(struct_lit)) => (function, struct_lit), + _ => return, + }; + let infer_result = function.infer(ctx.db); + let syntax_mapping = function.body_syntax_mapping(ctx.db); + let expr = match syntax_mapping.node_expr(struct_lit.into()) { + Some(expr) => expr, + None => return, + }; + let ty = infer_result[expr].clone(); + let (adt, substs) = match ty { + Ty::Adt { def_id, ref substs, .. } => (def_id, substs), + _ => return, + }; + match adt { + AdtDef::Struct(s) => { + for field in s.fields(ctx.db) { + CompletionItem::new( + CompletionKind::Reference, + ctx.source_range(), + field.name(ctx.db).to_string(), + ) + .kind(CompletionItemKind::Field) + .detail(field.ty(ctx.db).subst(substs).to_string()) + .set_documentation(field.docs(ctx.db)) + .add_to(acc); + } + } + + // TODO unions + AdtDef::Enum(_) => (), + }; +} + +#[cfg(test)] +mod tests { + use crate::completion::*; + use crate::completion::completion_item::check_completion; + + fn check_ref_completion(name: &str, code: &str) { + check_completion(name, code, CompletionKind::Reference); + } + + #[test] + fn test_struct_literal_field() { + check_ref_completion( + "test_struct_literal_field", + r" + struct A { the_field: u32 } + fn foo() { + A { the<|> } + } + ", + ); + } +} diff --git a/crates/ra_ide_api/src/completion/completion_context.rs b/crates/ra_ide_api/src/completion/completion_context.rs index b9f0abe19..d351be054 100644 --- a/crates/ra_ide_api/src/completion/completion_context.rs +++ b/crates/ra_ide_api/src/completion/completion_context.rs @@ -21,6 +21,7 @@ pub(crate) struct CompletionContext<'a> { pub(super) function: Option, pub(super) function_syntax: Option<&'a ast::FnDef>, pub(super) use_item_syntax: Option<&'a ast::UseItem>, + pub(super) struct_lit_syntax: Option<&'a ast::StructLit>, pub(super) is_param: bool, /// A single-indent path, like `foo`. `::foo` should not be considered a trivial path. pub(super) is_trivial_path: bool, @@ -55,6 +56,7 @@ impl<'a> CompletionContext<'a> { function: None, function_syntax: None, use_item_syntax: None, + struct_lit_syntax: None, is_param: false, is_trivial_path: false, path_prefix: None, @@ -108,6 +110,10 @@ impl<'a> CompletionContext<'a> { } fn classify_name_ref(&mut self, original_file: &'a SourceFile, name_ref: &ast::NameRef) { let name_range = name_ref.syntax().range(); + if name_ref.syntax().parent().and_then(ast::NamedField::cast).is_some() { + self.struct_lit_syntax = find_node_at_offset(original_file.syntax(), self.offset); + } + let top_node = name_ref.syntax().ancestors().take_while(|it| it.range() == name_range).last().unwrap(); diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 20e0a6856..56fb7c20c 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -724,6 +724,12 @@ impl LiteralExpr { } } +impl NamedField { + pub fn parent_struct_lit(&self) -> &StructLit { + self.syntax().ancestors().find_map(StructLit::cast).unwrap() + } +} + impl BindPat { pub fn is_mutable(&self) -> bool { self.syntax().children().any(|n| n.kind() == MUT_KW) -- cgit v1.2.3 From 6285fcc39b70bc92de5188a5eb64ee8d73fa8970 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 24 Feb 2019 17:23:54 +0300 Subject: complete fields in struct literals --- .../src/completion/complete_struct_literal.rs | 23 +++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'crates') diff --git a/crates/ra_ide_api/src/completion/complete_struct_literal.rs b/crates/ra_ide_api/src/completion/complete_struct_literal.rs index 893056c2b..f8dd2baad 100644 --- a/crates/ra_ide_api/src/completion/complete_struct_literal.rs +++ b/crates/ra_ide_api/src/completion/complete_struct_literal.rs @@ -3,7 +3,7 @@ use hir::{Ty, AdtDef, Docs}; use crate::completion::{CompletionContext, Completions, CompletionItem, CompletionItemKind}; use crate::completion::completion_item::CompletionKind; -/// Complete dot accesses, i.e. fields or methods (currently only fields). +/// Complete fields in fields literals. pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionContext) { let (function, struct_lit) = match (&ctx.function, ctx.struct_lit_syntax) { (Some(function), Some(struct_lit)) => (function, struct_lit), @@ -42,17 +42,16 @@ pub(super) fn complete_struct_literal(acc: &mut Completions, ctx: &CompletionCon #[cfg(test)] mod tests { - use crate::completion::*; - use crate::completion::completion_item::check_completion; + use insta::assert_debug_snapshot_matches; + use crate::completion::{CompletionItem, CompletionKind}; - fn check_ref_completion(name: &str, code: &str) { - check_completion(name, code, CompletionKind::Reference); + fn complete(code: &str) -> Vec { + crate::completion::completion_item::do_completion(code, CompletionKind::Reference) } #[test] fn test_struct_literal_field() { - check_ref_completion( - "test_struct_literal_field", + let completions = complete( r" struct A { the_field: u32 } fn foo() { @@ -60,5 +59,15 @@ mod tests { } ", ); + assert_debug_snapshot_matches!(completions, @r###"[ + CompletionItem { + label: "the_field", + source_range: [83; 86), + delete: [83; 86), + insert: "the_field", + kind: Field, + detail: "u32" + } +]"###); } } -- cgit v1.2.3