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)
}
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 {

View file

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

View file

@ -402,7 +402,7 @@ fn main() {
check(
fixture,
expect![[r#"
fn weird_function() (dep::test_mod::TestTrait) -> ()
fn weird_function() (dep::test_mod::TestTrait) fn()
"#]],
);
@ -495,7 +495,7 @@ fn main() {
check(
fixture,
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#"
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#"
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 }
"#,
expect![[r#"
fn a() -> ()
me b() -> ()
fn a() fn()
me b() fn(&self)
ct C const C: i32 = 42;
ta T type T = i32;
"#]],
@ -387,7 +387,7 @@ mod m {
fn foo() { let _ = S::$0 }
"#,
expect![[r#"
fn public_method() -> ()
fn public_method() fn()
ct PUBLIC_CONST pub(crate) const PUBLIC_CONST: u32 = 1;
ta PublicType pub(crate) type PublicType = u32;
"#]],
@ -404,7 +404,7 @@ impl E { fn m() { } }
fn foo() { let _ = E::$0 }
"#,
expect![[r#"
fn m() -> ()
fn m() fn()
"#]],
);
}
@ -419,7 +419,7 @@ impl U { fn m() { } }
fn foo() { let _ = U::$0 }
"#,
expect![[r#"
fn m() -> ()
fn m() fn()
"#]],
);
}
@ -449,7 +449,7 @@ trait Trait { fn m(); }
fn foo() { let _ = Trait::$0 }
"#,
expect![[r#"
fn m() -> ()
fn m() fn()
"#]],
);
}
@ -466,7 +466,7 @@ impl Trait for S {}
fn foo() { let _ = S::$0 }
"#,
expect![[r#"
fn m() -> ()
fn m() fn()
"#]],
);
}
@ -483,7 +483,7 @@ impl Trait for S {}
fn foo() { let _ = <S as Trait>::$0 }
"#,
expect![[r#"
fn m() -> ()
fn m() fn()
"#]],
);
}
@ -512,11 +512,11 @@ fn foo<T: Sub>() { T::$0 }
ta SubTy type SubTy;
ta Ty type Ty;
ct C2 const C2: ();
fn subfunc() -> ()
me submethod() -> ()
fn subfunc() fn()
me submethod() fn(&self)
ct CONST const CONST: u8;
fn func() -> ()
me method() -> ()
fn func() fn()
me method() fn(&self)
"#]],
);
}
@ -552,11 +552,11 @@ impl<T> Sub for Wrap<T> {
ta SubTy type SubTy;
ta Ty type Ty;
ct CONST const CONST: u8 = 0;
fn func() -> ()
me method() -> ()
fn func() fn()
me method() fn(&self)
ct C2 const C2: () = ();
fn subfunc() -> ()
me submethod() -> ()
fn subfunc() fn()
me submethod() fn(&self)
"#]],
);
}
@ -573,8 +573,8 @@ impl T { fn bar() {} }
fn main() { T::$0; }
"#,
expect![[r#"
fn foo() -> ()
fn bar() -> ()
fn foo() fn()
fn bar() fn()
"#]],
);
}
@ -589,7 +589,7 @@ macro_rules! foo { () => {} }
fn main() { let _ = crate::$0 }
"#,
expect![[r##"
fn main() -> ()
fn main() fn()
ma foo!() #[macro_export] macro_rules! foo
"##]],
);
@ -633,7 +633,7 @@ mod p {
"#,
expect![[r#"
ct RIGHT_CONST
fn right_fn() -> ()
fn right_fn() fn()
st RightType
"#]],
);
@ -680,8 +680,8 @@ fn main() { m!(self::f$0); }
fn foo() {}
"#,
expect![[r#"
fn main() -> ()
fn foo() -> ()
fn main() fn()
fn foo() fn()
"#]],
);
}
@ -699,7 +699,7 @@ mod m {
"#,
expect![[r#"
md z
fn z() -> ()
fn z() fn()
"#]],
);
}
@ -719,7 +719,7 @@ fn foo() {
}
"#,
expect![[r#"
fn new() -> HashMap<K, V, RandomState>
fn new() fn() -> HashMap<K, V, RandomState>
"#]],
);
}
@ -752,8 +752,8 @@ fn main() {
}
"#,
expect![[r#"
fn main() -> ()
fn foo() -> ()
fn main() fn()
fn foo() fn(i32, i32)
"#]],
);
}
@ -776,7 +776,7 @@ impl Foo {
expect![[r#"
ev Bar ()
ev Baz ()
me foo() -> ()
me foo() fn(self)
"#]],
);
}
@ -800,7 +800,7 @@ impl u8 {
"#,
expect![[r#"
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#"
lc y i32
lc x i32
fn quux() -> ()
fn quux() fn(i32)
"#]],
);
}
@ -161,7 +161,7 @@ fn quux() {
expect![[r#"
lc b i32
lc a
fn quux() -> ()
fn quux() fn()
"#]],
);
}
@ -176,7 +176,7 @@ fn quux() {
"#,
expect![[r#"
lc x
fn quux() -> ()
fn quux() fn()
"#]],
);
}
@ -207,14 +207,14 @@ fn main() {
r#"fn quux<T>() { $0 }"#,
expect![[r#"
tp T
fn quux() -> ()
fn quux() fn()
"#]],
);
check(
r#"fn quux<const C: usize>() { $0 }"#,
expect![[r#"
cp C
fn quux() -> ()
fn quux() fn()
"#]],
);
}
@ -225,7 +225,7 @@ fn main() {
check(
r#"fn quux<'a>() { $0 }"#,
expect![[r#"
fn quux() -> ()
fn quux() fn()
"#]],
);
}
@ -263,7 +263,7 @@ fn quux() { $0 }
"#,
expect![[r#"
st S
fn quux() -> ()
fn quux() fn()
en E
"#]],
);
@ -316,7 +316,7 @@ mod m {
}
"#,
expect![[r#"
fn quux() -> ()
fn quux() fn()
st Bar
"#]],
);
@ -331,7 +331,7 @@ fn x() -> $0
"#,
expect![[r#"
st Foo
fn x() -> ()
fn x() fn()
"#]],
);
}
@ -352,7 +352,7 @@ fn foo() {
expect![[r#"
lc bar i32
lc bar i32
fn foo() -> ()
fn foo() fn()
"#]],
);
}
@ -382,7 +382,7 @@ use prelude::*;
mod prelude { struct Option; }
"#,
expect![[r#"
fn foo() -> ()
fn foo() fn()
md std
st Option
"#]],
@ -412,7 +412,7 @@ mod macros {
}
"#,
expect![[r##"
fn f() -> ()
fn f() fn()
ma concat!() #[macro_export] macro_rules! concat
md std
"##]],
@ -439,7 +439,7 @@ use prelude::*;
mod prelude { struct String; }
"#,
expect![[r#"
fn foo() -> ()
fn foo() fn()
md std
md core
st String
@ -470,7 +470,7 @@ fn main() { let v = $0 }
expect![[r##"
md m1
ma baz!() #[macro_export] macro_rules! baz
fn main() -> ()
fn main() fn()
md m2
ma bar!() macro_rules! bar
ma foo!() macro_rules! foo
@ -486,7 +486,7 @@ macro_rules! foo { () => {} }
fn foo() { $0 }
"#,
expect![[r#"
fn foo() -> ()
fn foo() fn()
ma foo!() macro_rules! foo
"#]],
);
@ -500,7 +500,7 @@ macro_rules! foo { () => {} }
fn main() { let x: $0 }
"#,
expect![[r#"
fn main() -> ()
fn main() fn()
ma foo!() macro_rules! foo
"#]],
);
@ -514,7 +514,7 @@ macro_rules! foo { () => {} }
fn main() { $0 }
"#,
expect![[r#"
fn main() -> ()
fn main() fn()
ma foo!() macro_rules! foo
"#]],
);
@ -530,8 +530,8 @@ fn main() {
}
"#,
expect![[r#"
fn frobnicate() -> ()
fn main() -> ()
fn frobnicate() fn()
fn main() fn()
"#]],
);
}
@ -549,7 +549,7 @@ fn quux(x: i32) {
expect![[r#"
lc y i32
lc x i32
fn quux() -> ()
fn quux() fn(i32)
ma m!() macro_rules! m
"#]],
);
@ -568,7 +568,7 @@ fn quux(x: i32) {
expect![[r#"
lc y i32
lc x i32
fn quux() -> ()
fn quux() fn(i32)
ma m!() macro_rules! m
"#]],
);
@ -587,7 +587,7 @@ fn quux(x: i32) {
expect![[r#"
lc y i32
lc x i32
fn quux() -> ()
fn quux() fn(i32)
ma m!() macro_rules! m
"#]],
);
@ -602,7 +602,7 @@ use spam::Quux;
fn main() { $0 }
"#,
expect![[r#"
fn main() -> ()
fn main() fn()
?? Quux
"#]],
);
@ -680,7 +680,7 @@ fn main() { let foo: Foo = Q$0 }
ev Foo::Baz ()
ev Foo::Quux ()
en Foo
fn main() -> ()
fn main() fn()
"#]],
)
}
@ -695,7 +695,7 @@ fn f() -> m::E { V$0 }
expect![[r#"
ev m::E::V ()
md m
fn f() -> E
fn f() fn() -> E
"#]],
)
}

View file

@ -230,7 +230,7 @@ fn foo() {
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;
}
"#,
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
}
"#,
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]
fn enum_detail_just_parentheses_for_unit() {
check(
@ -501,7 +539,7 @@ fn main() { let _: m::Spam = S$0 }
Function,
),
lookup: "main",
detail: "-> ()",
detail: "fn()",
},
]
"#]],
@ -530,7 +568,7 @@ fn main() { som$0 }
Function,
),
lookup: "main",
detail: "-> ()",
detail: "fn()",
},
CompletionItem {
label: "something_deprecated()",
@ -541,7 +579,7 @@ fn main() { som$0 }
Function,
),
lookup: "something_deprecated",
detail: "-> ()",
detail: "fn()",
deprecated: true,
},
CompletionItem {
@ -553,7 +591,7 @@ fn main() { som$0 }
Function,
),
lookup: "something_else_deprecated",
detail: "-> ()",
detail: "fn()",
deprecated: true,
},
]
@ -604,7 +642,7 @@ impl S {
insert: "bar()$0",
kind: Method,
lookup: "bar",
detail: "-> ()",
detail: "fn(self)",
documentation: Documentation(
"Method docs",
),
@ -704,7 +742,7 @@ fn foo(s: S) { s.$0 }
insert: "the_method()$0",
kind: Method,
lookup: "the_method",
detail: "-> ()",
detail: "fn(&self)",
},
]
"#]],
@ -954,7 +992,7 @@ fn main() {
Function,
),
lookup: "foo",
detail: "-> ()",
detail: "fn(&mut S)",
trigger_call_info: true,
},
CompletionItem {
@ -966,7 +1004,7 @@ fn main() {
Function,
),
lookup: "main",
detail: "-> ()",
detail: "fn()",
},
CompletionItem {
label: "s",

View file

@ -2,6 +2,7 @@
use hir::{HasSource, HirDisplay, Type};
use ide_db::SymbolKind;
use itertools::Itertools;
use syntax::ast::Fn;
use crate::{
@ -59,8 +60,34 @@ impl<'a> FunctionRender<'a> {
}
fn detail(&self) -> String {
let ty = self.func.ret_type(self.ctx.db());
format!("-> {}", ty.display(self.ctx.db()))
let params = if let Some(self_param) = self.func.self_param(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 {