diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 80d0b166396..9b01eb0aba1 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs @@ -17,8 +17,9 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) -> Ca }; let receiver_ty = infer_result[expr].clone(); if !ctx.is_call { - complete_fields(acc, ctx, receiver_ty)?; + complete_fields(acc, ctx, receiver_ty.clone())?; } + complete_methods(acc, ctx, receiver_ty)?; Ok(()) } @@ -55,6 +56,24 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) Ok(()) } +fn complete_methods( + acc: &mut Completions, + ctx: &CompletionContext, + receiver: Ty, +) -> Cancelable<()> { + receiver.iterate_methods(ctx.db, |func| { + let sig = func.signature(ctx.db); + if sig.has_self_arg() { + CompletionItem::new(CompletionKind::Reference, sig.name().to_string()) + .from_function(ctx, func) + .kind(CompletionItemKind::Method) + .add_to(acc); + } + Ok(None::<()>) + })?; + Ok(()) +} + #[cfg(test)] mod tests { use crate::completion::*; @@ -87,7 +106,8 @@ mod tests { } } ", - r#"the_field "(u32,)""#, + r#"the_field "(u32,)" + foo "foo($0)""#, ); } @@ -102,7 +122,8 @@ mod tests { } } ", - r#"the_field "(u32, i32)""#, + r#"the_field "(u32, i32)" + foo "foo($0)""#, ); } @@ -118,4 +139,36 @@ mod tests { r#""#, ); } + + #[test] + fn test_method_completion() { + check_ref_completion( + r" + struct A {} + impl A { + fn the_method(&self) {} + } + fn foo(a: A) { + a.<|> + } + ", + r#"the_method "the_method($0)""#, + ); + } + + #[test] + fn test_no_non_self_method() { + check_ref_completion( + r" + struct A {} + impl A { + fn the_method() {} + } + fn foo(a: A) { + a.<|> + } + ", + r#""#, + ); + } } diff --git a/crates/ra_ide_api/src/completion/completion_item.rs b/crates/ra_ide_api/src/completion/completion_item.rs index e7fa967a03d..9ce7784875f 100644 --- a/crates/ra_ide_api/src/completion/completion_item.rs +++ b/crates/ra_ide_api/src/completion/completion_item.rs @@ -37,6 +37,7 @@ pub enum CompletionItemKind { Const, Trait, TypeAlias, + Method, } #[derive(Debug, PartialEq, Eq)] @@ -183,7 +184,11 @@ impl Builder { self } - fn from_function(mut self, ctx: &CompletionContext, function: hir::Function) -> Builder { + pub(super) fn from_function( + mut self, + ctx: &CompletionContext, + function: hir::Function, + ) -> Builder { // If not an import, add parenthesis automatically. if ctx.use_item_syntax.is_none() && !ctx.is_call { if function.signature(ctx.db).args().is_empty() { diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs index 7ca2f437dd9..22b8e9221bf 100644 --- a/crates/ra_lsp_server/src/conv.rs +++ b/crates/ra_lsp_server/src/conv.rs @@ -69,6 +69,7 @@ impl Conv for CompletionItemKind { CompletionItemKind::TypeAlias => Struct, CompletionItemKind::Const => Constant, CompletionItemKind::Static => Value, + CompletionItemKind::Method => Method, } } }