show function params in completion detail

This commit is contained in:
Josh Mcguigan 2021-03-06 16:56:07 -08:00
parent 437527b226
commit 53bb46fa85
8 changed files with 155 additions and 82 deletions

View File

@ -921,6 +921,14 @@ impl SelfParam {
}) })
.unwrap_or(Access::Owned) .unwrap_or(Access::Owned)
} }
pub fn display(self, db: &dyn HirDatabase) -> &'static str {
match self.access(db) {
Access::Shared => "&self",
Access::Exclusive => "&mut self",
Access::Owned => "self",
}
}
} }
impl HasVisibility for Function { impl HasVisibility for Function {

View File

@ -81,7 +81,7 @@ fn foo(s: S) { s.$0 }
"#, "#,
expect![[r#" expect![[r#"
fd foo u32 fd foo u32
me bar() -> () me bar() fn(&self)
"#]], "#]],
); );
} }
@ -97,7 +97,7 @@ impl S {
"#, "#,
expect![[r#" expect![[r#"
fd the_field (u32,) fd the_field (u32,)
me foo() -> () me foo() fn(self)
"#]], "#]],
) )
} }
@ -113,7 +113,7 @@ impl A {
"#, "#,
expect![[r#" expect![[r#"
fd the_field (u32, i32) fd the_field (u32, i32)
me foo() -> () me foo() fn(&self)
"#]], "#]],
) )
} }
@ -163,7 +163,7 @@ mod m {
fn foo(a: A) { a.$0 } fn foo(a: A) { a.$0 }
"#, "#,
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
); );
} }
@ -196,7 +196,7 @@ impl A<i32> {
fn foo(a: A<u32>) { a.$0 } fn foo(a: A<u32>) { a.$0 }
"#, "#,
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
) )
} }
@ -211,7 +211,7 @@ impl Trait for A {}
fn foo(a: A) { a.$0 } fn foo(a: A) { a.$0 }
"#, "#,
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
); );
} }
@ -226,7 +226,7 @@ impl<T> Trait for T {}
fn foo(a: &A) { a.$0 } fn foo(a: &A) { a.$0 }
", ",
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
); );
} }
@ -244,7 +244,7 @@ impl Trait for A {}
fn foo(a: A) { a.$0 } fn foo(a: A) { a.$0 }
", ",
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
); );
} }
@ -298,7 +298,7 @@ impl T {
} }
"#, "#,
expect![[r#" expect![[r#"
me blah() -> () me blah() fn(&self)
"#]], "#]],
); );
} }
@ -407,7 +407,7 @@ fn foo() {
} }
"#, "#,
expect![[r#" expect![[r#"
me the_method() -> () me the_method() fn(&self)
"#]], "#]],
); );
} }
@ -422,7 +422,7 @@ macro_rules! make_s { () => { S }; }
fn main() { make_s!().f$0; } fn main() { make_s!().f$0; }
"#, "#,
expect![[r#" expect![[r#"
me foo() -> () me foo() fn(&self)
"#]], "#]],
) )
} }
@ -450,7 +450,7 @@ mod foo {
} }
"#, "#,
expect![[r#" expect![[r#"
me private() -> () me private() fn(&self)
"#]], "#]],
); );
} }

View File

@ -402,7 +402,7 @@ fn main() {
check( check(
fixture, fixture,
expect![[r#" expect![[r#"
fn weird_function() (dep::test_mod::TestTrait) -> () fn weird_function() (dep::test_mod::TestTrait) fn()
"#]], "#]],
); );
@ -495,7 +495,7 @@ fn main() {
check( check(
fixture, fixture,
expect![[r#" expect![[r#"
me random_method() (dep::test_mod::TestTrait) -> () me random_method() (dep::test_mod::TestTrait) fn(&self)
"#]], "#]],
); );
@ -665,7 +665,7 @@ fn main() {
} }
"#, "#,
expect![[r#" expect![[r#"
me random_method() (dep::test_mod::TestTrait) -> () DEPRECATED me random_method() (dep::test_mod::TestTrait) fn(&self) DEPRECATED
"#]], "#]],
); );
@ -696,7 +696,7 @@ fn main() {
"#, "#,
expect![[r#" expect![[r#"
ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED ct SPECIAL_CONST (dep::test_mod::TestTrait) DEPRECATED
fn weird_function() (dep::test_mod::TestTrait) -> () DEPRECATED fn weird_function() (dep::test_mod::TestTrait) fn() DEPRECATED
"#]], "#]],
); );
} }

View File

@ -359,8 +359,8 @@ impl S {
fn foo() { let _ = S::$0 } fn foo() { let _ = S::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn a() -> () fn a() fn()
me b() -> () me b() fn(&self)
ct C const C: i32 = 42; ct C const C: i32 = 42;
ta T type T = i32; ta T type T = i32;
"#]], "#]],
@ -387,7 +387,7 @@ mod m {
fn foo() { let _ = S::$0 } fn foo() { let _ = S::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn public_method() -> () fn public_method() fn()
ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1; ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
ta PublicType pub(crate) type PublicType = u32; ta PublicType pub(crate) type PublicType = u32;
"#]], "#]],
@ -404,7 +404,7 @@ impl E { fn m() { } }
fn foo() { let _ = E::$0 } fn foo() { let _ = E::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn m() -> () fn m() fn()
"#]], "#]],
); );
} }
@ -419,7 +419,7 @@ impl U { fn m() { } }
fn foo() { let _ = U::$0 } fn foo() { let _ = U::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn m() -> () fn m() fn()
"#]], "#]],
); );
} }
@ -449,7 +449,7 @@ trait Trait { fn m(); }
fn foo() { let _ = Trait::$0 } fn foo() { let _ = Trait::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn m() -> () fn m() fn()
"#]], "#]],
); );
} }
@ -466,7 +466,7 @@ impl Trait for S {}
fn foo() { let _ = S::$0 } fn foo() { let _ = S::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn m() -> () fn m() fn()
"#]], "#]],
); );
} }
@ -483,7 +483,7 @@ impl Trait for S {}
fn foo() { let _ = <S as Trait>::$0 } fn foo() { let _ = <S as Trait>::$0 }
"#, "#,
expect![[r#" expect![[r#"
fn m() -> () fn m() fn()
"#]], "#]],
); );
} }
@ -512,11 +512,11 @@ fn foo<T: Sub>() { T::$0 }
ta SubTy type SubTy; ta SubTy type SubTy;
ta Ty type Ty; ta Ty type Ty;
ct C2 const C2: (); ct C2 const C2: ();
fn subfunc() -> () fn subfunc() fn()
me submethod() -> () me submethod() fn(&self)
ct CONST const CONST: u8; ct CONST const CONST: u8;
fn func() -> () fn func() fn()
me method() -> () me method() fn(&self)
"#]], "#]],
); );
} }
@ -552,11 +552,11 @@ impl<T> Sub for Wrap<T> {
ta SubTy type SubTy; ta SubTy type SubTy;
ta Ty type Ty; ta Ty type Ty;
ct CONST const CONST: u8 = 0; ct CONST const CONST: u8 = 0;
fn func() -> () fn func() fn()
me method() -> () me method() fn(&self)
ct C2 const C2: () = (); ct C2 const C2: () = ();
fn subfunc() -> () fn subfunc() fn()
me submethod() -> () me submethod() fn(&self)
"#]], "#]],
); );
} }
@ -573,8 +573,8 @@ impl T { fn bar() {} }
fn main() { T::$0; } fn main() { T::$0; }
"#, "#,
expect![[r#" expect![[r#"
fn foo() -> () fn foo() fn()
fn bar() -> () fn bar() fn()
"#]], "#]],
); );
} }
@ -589,7 +589,7 @@ macro_rules! foo { () => {} }
fn main() { let _ = crate::$0 } fn main() { let _ = crate::$0 }
"#, "#,
expect![[r##" expect![[r##"
fn main() -> () fn main() fn()
ma foo!() #[macro_export] macro_rules! foo ma foo!() #[macro_export] macro_rules! foo
"##]], "##]],
); );
@ -633,7 +633,7 @@ mod p {
"#, "#,
expect![[r#" expect![[r#"
ct RIGHT_CONST ct RIGHT_CONST
fn right_fn() -> () fn right_fn() fn()
st RightType st RightType
"#]], "#]],
); );
@ -680,8 +680,8 @@ fn main() { m!(self::f$0); }
fn foo() {} fn foo() {}
"#, "#,
expect![[r#" expect![[r#"
fn main() -> () fn main() fn()
fn foo() -> () fn foo() fn()
"#]], "#]],
); );
} }
@ -699,7 +699,7 @@ mod m {
"#, "#,
expect![[r#" expect![[r#"
md z md z
fn z() -> () fn z() fn()
"#]], "#]],
); );
} }
@ -719,7 +719,7 @@ fn foo() {
} }
"#, "#,
expect![[r#" expect![[r#"
fn new() -> HashMap<K, V, RandomState> fn new() fn() -> HashMap<K, V, RandomState>
"#]], "#]],
); );
} }
@ -752,8 +752,8 @@ fn main() {
} }
"#, "#,
expect![[r#" expect![[r#"
fn main() -> () fn main() fn()
fn foo() -> () fn foo() fn(i32, i32)
"#]], "#]],
); );
} }
@ -776,7 +776,7 @@ impl Foo {
expect![[r#" expect![[r#"
ev Bar () ev Bar ()
ev Baz () ev Baz ()
me foo() -> () me foo() fn(self)
"#]], "#]],
); );
} }
@ -800,7 +800,7 @@ impl u8 {
"#, "#,
expect![[r#" expect![[r#"
ct MAX pub const MAX: Self = 255; ct MAX pub const MAX: Self = 255;
me func() -> () me func() fn(self)
"#]], "#]],
); );
} }

View File

@ -139,7 +139,7 @@ fn quux(x: i32) {
expect![[r#" expect![[r#"
lc y i32 lc y i32
lc x i32 lc x i32
fn quux() -> () fn quux() fn(i32)
"#]], "#]],
); );
} }
@ -161,7 +161,7 @@ fn quux() {
expect![[r#" expect![[r#"
lc b i32 lc b i32
lc a lc a
fn quux() -> () fn quux() fn()
"#]], "#]],
); );
} }
@ -176,7 +176,7 @@ fn quux() {
"#, "#,
expect![[r#" expect![[r#"
lc x lc x
fn quux() -> () fn quux() fn()
"#]], "#]],
); );
} }
@ -207,14 +207,14 @@ fn main() {
r#"fn quux<T>() { $0 }"#, r#"fn quux<T>() { $0 }"#,
expect![[r#" expect![[r#"
tp T tp T
fn quux() -> () fn quux() fn()
"#]], "#]],
); );
check( check(
r#"fn quux<const C: usize>() { $0 }"#, r#"fn quux<const C: usize>() { $0 }"#,
expect![[r#" expect![[r#"
cp C cp C
fn quux() -> () fn quux() fn()
"#]], "#]],
); );
} }
@ -225,7 +225,7 @@ fn main() {
check( check(
r#"fn quux<'a>() { $0 }"#, r#"fn quux<'a>() { $0 }"#,
expect![[r#" expect![[r#"
fn quux() -> () fn quux() fn()
"#]], "#]],
); );
} }
@ -263,7 +263,7 @@ fn quux() { $0 }
"#, "#,
expect![[r#" expect![[r#"
st S st S
fn quux() -> () fn quux() fn()
en E en E
"#]], "#]],
); );
@ -316,7 +316,7 @@ mod m {
} }
"#, "#,
expect![[r#" expect![[r#"
fn quux() -> () fn quux() fn()
st Bar st Bar
"#]], "#]],
); );
@ -331,7 +331,7 @@ fn x() -> $0
"#, "#,
expect![[r#" expect![[r#"
st Foo st Foo
fn x() -> () fn x() fn()
"#]], "#]],
); );
} }
@ -352,7 +352,7 @@ fn foo() {
expect![[r#" expect![[r#"
lc bar i32 lc bar i32
lc bar i32 lc bar i32
fn foo() -> () fn foo() fn()
"#]], "#]],
); );
} }
@ -382,7 +382,7 @@ use prelude::*;
mod prelude { struct Option; } mod prelude { struct Option; }
"#, "#,
expect![[r#" expect![[r#"
fn foo() -> () fn foo() fn()
md std md std
st Option st Option
"#]], "#]],
@ -412,7 +412,7 @@ mod macros {
} }
"#, "#,
expect![[r##" expect![[r##"
fn f() -> () fn f() fn()
ma concat!() #[macro_export] macro_rules! concat ma concat!() #[macro_export] macro_rules! concat
md std md std
"##]], "##]],
@ -439,7 +439,7 @@ use prelude::*;
mod prelude { struct String; } mod prelude { struct String; }
"#, "#,
expect![[r#" expect![[r#"
fn foo() -> () fn foo() fn()
md std md std
md core md core
st String st String
@ -470,7 +470,7 @@ fn main() { let v = $0 }
expect![[r##" expect![[r##"
md m1 md m1
ma baz!() #[macro_export] macro_rules! baz ma baz!() #[macro_export] macro_rules! baz
fn main() -> () fn main() fn()
md m2 md m2
ma bar!() macro_rules! bar ma bar!() macro_rules! bar
ma foo!() macro_rules! foo ma foo!() macro_rules! foo
@ -486,7 +486,7 @@ macro_rules! foo { () => {} }
fn foo() { $0 } fn foo() { $0 }
"#, "#,
expect![[r#" expect![[r#"
fn foo() -> () fn foo() fn()
ma foo!() macro_rules! foo ma foo!() macro_rules! foo
"#]], "#]],
); );
@ -500,7 +500,7 @@ macro_rules! foo { () => {} }
fn main() { let x: $0 } fn main() { let x: $0 }
"#, "#,
expect![[r#" expect![[r#"
fn main() -> () fn main() fn()
ma foo!() macro_rules! foo ma foo!() macro_rules! foo
"#]], "#]],
); );
@ -514,7 +514,7 @@ macro_rules! foo { () => {} }
fn main() { $0 } fn main() { $0 }
"#, "#,
expect![[r#" expect![[r#"
fn main() -> () fn main() fn()
ma foo!() macro_rules! foo ma foo!() macro_rules! foo
"#]], "#]],
); );
@ -530,8 +530,8 @@ fn main() {
} }
"#, "#,
expect![[r#" expect![[r#"
fn frobnicate() -> () fn frobnicate() fn()
fn main() -> () fn main() fn()
"#]], "#]],
); );
} }
@ -549,7 +549,7 @@ fn quux(x: i32) {
expect![[r#" expect![[r#"
lc y i32 lc y i32
lc x i32 lc x i32
fn quux() -> () fn quux() fn(i32)
ma m!() macro_rules! m ma m!() macro_rules! m
"#]], "#]],
); );
@ -568,7 +568,7 @@ fn quux(x: i32) {
expect![[r#" expect![[r#"
lc y i32 lc y i32
lc x i32 lc x i32
fn quux() -> () fn quux() fn(i32)
ma m!() macro_rules! m ma m!() macro_rules! m
"#]], "#]],
); );
@ -587,7 +587,7 @@ fn quux(x: i32) {
expect![[r#" expect![[r#"
lc y i32 lc y i32
lc x i32 lc x i32
fn quux() -> () fn quux() fn(i32)
ma m!() macro_rules! m ma m!() macro_rules! m
"#]], "#]],
); );
@ -602,7 +602,7 @@ use spam::Quux;
fn main() { $0 } fn main() { $0 }
"#, "#,
expect![[r#" expect![[r#"
fn main() -> () fn main() fn()
?? Quux ?? Quux
"#]], "#]],
); );
@ -680,7 +680,7 @@ fn main() { let foo: Foo = Q$0 }
ev Foo::Baz () ev Foo::Baz ()
ev Foo::Quux () ev Foo::Quux ()
en Foo en Foo
fn main() -> () fn main() fn()
"#]], "#]],
) )
} }
@ -695,7 +695,7 @@ fn f() -> m::E { V$0 }
expect![[r#" expect![[r#"
ev m::E::V () ev m::E::V ()
md m md m
fn f() -> E fn f() fn() -> E
"#]], "#]],
) )
} }

View File

@ -230,7 +230,7 @@ fn foo() {
bar.fo$0; bar.fo$0;
} }
"#, "#,
DetailAndDocumentation { detail: "-> ()", documentation: "Do the foo" }, DetailAndDocumentation { detail: "fn(&self)", documentation: "Do the foo" },
); );
} }
@ -255,7 +255,7 @@ fn foo() {
bar.fo$0; bar.fo$0;
} }
"#, "#,
DetailAndDocumentation { detail: "-> ()", documentation: " Do the foo" }, DetailAndDocumentation { detail: "fn(&self)", documentation: " Do the foo" },
); );
} }
@ -273,7 +273,7 @@ fn bar() {
for c in fo$0 for c in fo$0
} }
"#, "#,
DetailAndDocumentation { detail: "-> &str", documentation: "Do the foo" }, DetailAndDocumentation { detail: "fn() -> &str", documentation: "Do the foo" },
); );
} }
} }

View File

@ -424,6 +424,44 @@ fn main() { Foo::Fo$0 }
); );
} }
#[test]
fn fn_detail_includes_args_and_return_type() {
check(
r#"
fn foo<T>(a: u32, b: u32, t: T) -> (u32, T) { (a, t) }
fn main() { fo$0 }
"#,
expect![[r#"
[
CompletionItem {
label: "foo(…)",
source_range: 68..70,
delete: 68..70,
insert: "foo(${1:a}, ${2:b}, ${3:t})$0",
kind: SymbolKind(
Function,
),
lookup: "foo",
detail: "fn(u32, u32, T) -> (u32, T)",
trigger_call_info: true,
},
CompletionItem {
label: "main()",
source_range: 68..70,
delete: 68..70,
insert: "main()$0",
kind: SymbolKind(
Function,
),
lookup: "main",
detail: "fn()",
},
]
"#]],
);
}
#[test] #[test]
fn enum_detail_just_parentheses_for_unit() { fn enum_detail_just_parentheses_for_unit() {
check( check(
@ -501,7 +539,7 @@ fn main() { let _: m::Spam = S$0 }
Function, Function,
), ),
lookup: "main", lookup: "main",
detail: "-> ()", detail: "fn()",
}, },
] ]
"#]], "#]],
@ -530,7 +568,7 @@ fn main() { som$0 }
Function, Function,
), ),
lookup: "main", lookup: "main",
detail: "-> ()", detail: "fn()",
}, },
CompletionItem { CompletionItem {
label: "something_deprecated()", label: "something_deprecated()",
@ -541,7 +579,7 @@ fn main() { som$0 }
Function, Function,
), ),
lookup: "something_deprecated", lookup: "something_deprecated",
detail: "-> ()", detail: "fn()",
deprecated: true, deprecated: true,
}, },
CompletionItem { CompletionItem {
@ -553,7 +591,7 @@ fn main() { som$0 }
Function, Function,
), ),
lookup: "something_else_deprecated", lookup: "something_else_deprecated",
detail: "-> ()", detail: "fn()",
deprecated: true, deprecated: true,
}, },
] ]
@ -604,7 +642,7 @@ impl S {
insert: "bar()$0", insert: "bar()$0",
kind: Method, kind: Method,
lookup: "bar", lookup: "bar",
detail: "-> ()", detail: "fn(self)",
documentation: Documentation( documentation: Documentation(
"Method docs", "Method docs",
), ),
@ -704,7 +742,7 @@ fn foo(s: S) { s.$0 }
insert: "the_method()$0", insert: "the_method()$0",
kind: Method, kind: Method,
lookup: "the_method", lookup: "the_method",
detail: "-> ()", detail: "fn(&self)",
}, },
] ]
"#]], "#]],
@ -954,7 +992,7 @@ fn main() {
Function, Function,
), ),
lookup: "foo", lookup: "foo",
detail: "-> ()", detail: "fn(&mut S)",
trigger_call_info: true, trigger_call_info: true,
}, },
CompletionItem { CompletionItem {
@ -966,7 +1004,7 @@ fn main() {
Function, Function,
), ),
lookup: "main", lookup: "main",
detail: "-> ()", detail: "fn()",
}, },
CompletionItem { CompletionItem {
label: "s", label: "s",

View File

@ -2,6 +2,7 @@
use hir::{HasSource, HirDisplay, Type}; use hir::{HasSource, HirDisplay, Type};
use ide_db::SymbolKind; use ide_db::SymbolKind;
use itertools::Itertools;
use syntax::ast::Fn; use syntax::ast::Fn;
use crate::{ use crate::{
@ -59,8 +60,34 @@ impl<'a> FunctionRender<'a> {
} }
fn detail(&self) -> String { fn detail(&self) -> String {
let ty = self.func.ret_type(self.ctx.db()); let params = if let Some(self_param) = self.func.self_param(self.ctx.db()) {
format!("-> {}", ty.display(self.ctx.db())) let params = self
.func
.assoc_fn_params(self.ctx.db())
.into_iter()
.skip(1) // skip the self param because we are manually handling that
.map(|p| p.ty().display(self.ctx.db()).to_string());
std::iter::once(self_param.display(self.ctx.db()).to_owned()).chain(params).join(", ")
} else {
let params = self
.func
.assoc_fn_params(self.ctx.db())
.into_iter()
.map(|p| p.ty().display(self.ctx.db()).to_string())
.join(", ");
params
};
let ret_ty = self.func.ret_type(self.ctx.db());
let ret = if ret_ty.is_unit() {
// Omit the `-> ()` for unit return types
String::new()
} else {
format!(" -> {}", ret_ty.display(self.ctx.db()))
};
format!("fn({}){}", params, ret)
} }
fn add_arg(&self, arg: &str, ty: &Type) -> String { fn add_arg(&self, arg: &str, ty: &Type) -> String {