Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 244a48d

Browse files
committed
Cleanup signature help a bit
1 parent 9738f97 commit 244a48d

File tree

2 files changed

+79
-65
lines changed

2 files changed

+79
-65
lines changed

crates/ide-db/src/active_parameter.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use hir::{Semantics, Type};
55
use parser::T;
66
use syntax::{
77
ast::{self, HasArgList, HasName},
8-
AstNode, NodeOrToken, SyntaxToken,
8+
match_ast, AstNode, NodeOrToken, SyntaxToken,
99
};
1010

1111
use crate::RootDatabase;
@@ -81,3 +81,64 @@ pub fn callable_for_node(
8181
};
8282
Some((callable, active_param))
8383
}
84+
85+
pub fn generic_def_for_node(
86+
sema: &Semantics<'_, RootDatabase>,
87+
generic_arg_list: &ast::GenericArgList,
88+
token: &SyntaxToken,
89+
) -> Option<(hir::GenericDef, usize, bool)> {
90+
let parent = generic_arg_list.syntax().parent()?;
91+
let def = match_ast! {
92+
match parent {
93+
ast::PathSegment(ps) => {
94+
let res = sema.resolve_path(&ps.parent_path())?;
95+
let generic_def: hir::GenericDef = match res {
96+
hir::PathResolution::Def(hir::ModuleDef::Adt(it)) => it.into(),
97+
hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(),
98+
hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
99+
hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
100+
hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => it.into(),
101+
hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))
102+
| hir::PathResolution::Def(hir::ModuleDef::Const(_))
103+
| hir::PathResolution::Def(hir::ModuleDef::Macro(_))
104+
| hir::PathResolution::Def(hir::ModuleDef::Module(_))
105+
| hir::PathResolution::Def(hir::ModuleDef::Static(_)) => return None,
106+
hir::PathResolution::BuiltinAttr(_)
107+
| hir::PathResolution::ToolModule(_)
108+
| hir::PathResolution::Local(_)
109+
| hir::PathResolution::TypeParam(_)
110+
| hir::PathResolution::ConstParam(_)
111+
| hir::PathResolution::SelfType(_)
112+
| hir::PathResolution::DeriveHelper(_) => return None,
113+
};
114+
115+
generic_def
116+
},
117+
ast::AssocTypeArg(_) => {
118+
// FIXME: We don't record the resolutions for this anywhere atm
119+
return None;
120+
},
121+
ast::MethodCallExpr(mcall) => {
122+
// recv.method::<$0>()
123+
let method = sema.resolve_method_call(&mcall)?;
124+
method.into()
125+
},
126+
_ => return None,
127+
}
128+
};
129+
130+
let active_param = generic_arg_list
131+
.syntax()
132+
.children_with_tokens()
133+
.filter_map(NodeOrToken::into_token)
134+
.filter(|t| t.kind() == T![,])
135+
.take_while(|t| t.text_range().start() <= token.text_range().start())
136+
.count();
137+
138+
let first_arg_is_non_lifetime = generic_arg_list
139+
.generic_args()
140+
.next()
141+
.map_or(false, |arg| !matches!(arg, ast::GenericArg::LifetimeArg(_)));
142+
143+
Some((def, active_param, first_arg_is_non_lifetime))
144+
}

crates/ide/src/signature_help.rs

Lines changed: 17 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,11 @@ use either::Either;
77
use hir::{
88
AssocItem, GenericParam, HasAttrs, HirDisplay, ModuleDef, PathResolution, Semantics, Trait,
99
};
10-
use ide_db::{active_parameter::callable_for_node, base_db::FilePosition, FxIndexMap};
10+
use ide_db::{
11+
active_parameter::{callable_for_node, generic_def_for_node},
12+
base_db::FilePosition,
13+
FxIndexMap,
14+
};
1115
use stdx::format_to;
1216
use syntax::{
1317
algo,
@@ -214,59 +218,11 @@ fn signature_help_for_call(
214218

215219
fn signature_help_for_generics(
216220
sema: &Semantics<'_, RootDatabase>,
217-
garg_list: ast::GenericArgList,
221+
arg_list: ast::GenericArgList,
218222
token: SyntaxToken,
219223
) -> Option<SignatureHelp> {
220-
let arg_list = garg_list
221-
.syntax()
222-
.ancestors()
223-
.filter_map(ast::GenericArgList::cast)
224-
.find(|list| list.syntax().text_range().contains(token.text_range().start()))?;
225-
226-
let mut active_parameter = arg_list
227-
.generic_args()
228-
.take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
229-
.count();
230-
231-
let first_arg_is_non_lifetime = arg_list
232-
.generic_args()
233-
.next()
234-
.map_or(false, |arg| !matches!(arg, ast::GenericArg::LifetimeArg(_)));
235-
236-
let mut generics_def = if let Some(path) =
237-
arg_list.syntax().ancestors().find_map(ast::Path::cast)
238-
{
239-
let res = sema.resolve_path(&path)?;
240-
let generic_def: hir::GenericDef = match res {
241-
hir::PathResolution::Def(hir::ModuleDef::Adt(it)) => it.into(),
242-
hir::PathResolution::Def(hir::ModuleDef::Function(it)) => it.into(),
243-
hir::PathResolution::Def(hir::ModuleDef::Trait(it)) => it.into(),
244-
hir::PathResolution::Def(hir::ModuleDef::TypeAlias(it)) => it.into(),
245-
hir::PathResolution::Def(hir::ModuleDef::Variant(it)) => it.into(),
246-
hir::PathResolution::Def(hir::ModuleDef::BuiltinType(_))
247-
| hir::PathResolution::Def(hir::ModuleDef::Const(_))
248-
| hir::PathResolution::Def(hir::ModuleDef::Macro(_))
249-
| hir::PathResolution::Def(hir::ModuleDef::Module(_))
250-
| hir::PathResolution::Def(hir::ModuleDef::Static(_)) => return None,
251-
hir::PathResolution::BuiltinAttr(_)
252-
| hir::PathResolution::ToolModule(_)
253-
| hir::PathResolution::Local(_)
254-
| hir::PathResolution::TypeParam(_)
255-
| hir::PathResolution::ConstParam(_)
256-
| hir::PathResolution::SelfType(_)
257-
| hir::PathResolution::DeriveHelper(_) => return None,
258-
};
259-
260-
generic_def
261-
} else if let Some(method_call) = arg_list.syntax().parent().and_then(ast::MethodCallExpr::cast)
262-
{
263-
// recv.method::<$0>()
264-
let method = sema.resolve_method_call(&method_call)?;
265-
method.into()
266-
} else {
267-
return None;
268-
};
269-
224+
let (mut generics_def, mut active_parameter, first_arg_is_non_lifetime) =
225+
generic_def_for_node(sema, &arg_list, &token)?;
270226
let mut res = SignatureHelp {
271227
doc: None,
272228
signature: String::new(),
@@ -305,9 +261,9 @@ fn signature_help_for_generics(
305261
// eg. `None::<u8>`
306262
// We'll use the signature of the enum, but include the docs of the variant.
307263
res.doc = it.docs(db).map(|it| it.into());
308-
let it = it.parent_enum(db);
309-
format_to!(res.signature, "enum {}", it.name(db));
310-
generics_def = it.into();
264+
let enum_ = it.parent_enum(db);
265+
format_to!(res.signature, "enum {}", enum_.name(db));
266+
generics_def = enum_.into();
311267
}
312268
// These don't have generic args that can be specified
313269
hir::GenericDef::Impl(_) | hir::GenericDef::Const(_) => return None,
@@ -386,16 +342,13 @@ fn signature_help_for_record_lit(
386342
record: ast::RecordExpr,
387343
token: SyntaxToken,
388344
) -> Option<SignatureHelp> {
389-
let arg_list = record
390-
.syntax()
391-
.ancestors()
392-
.filter_map(ast::RecordExpr::cast)
393-
.find(|list| list.syntax().text_range().contains(token.text_range().start()))?;
394-
395-
let active_parameter = arg_list
345+
let active_parameter = record
396346
.record_expr_field_list()?
397-
.fields()
398-
.take_while(|arg| arg.syntax().text_range().end() <= token.text_range().start())
347+
.syntax()
348+
.children_with_tokens()
349+
.filter_map(syntax::NodeOrToken::into_token)
350+
.filter(|t| t.kind() == syntax::T![,])
351+
.take_while(|t| t.text_range().start() <= token.text_range().start())
399352
.count();
400353

401354
let mut res = SignatureHelp {

0 commit comments

Comments
 (0)