Skip to content

Commit 584c8d9

Browse files
committed
Slightly refactor inlay hints
1 parent 2e0d894 commit 584c8d9

File tree

2 files changed

+59
-70
lines changed

2 files changed

+59
-70
lines changed

crates/ra_ide/src/inlay_hints.rs

Lines changed: 58 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use ra_ide_db::RootDatabase;
55
use ra_prof::profile;
66
use ra_syntax::{
77
ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner},
8-
match_ast, SmolStr, SyntaxNode, TextRange,
8+
match_ast, SmolStr, TextRange,
99
};
1010

1111
use crate::{FileId, FunctionSignature};
@@ -28,50 +28,76 @@ pub(crate) fn inlay_hints(
2828
file_id: FileId,
2929
max_inlay_hint_length: Option<usize>,
3030
) -> Vec<InlayHint> {
31+
let _p = profile("inlay_hints");
3132
let sema = Semantics::new(db);
3233
let file = sema.parse(file_id);
34+
3335
let mut res = Vec::new();
3436
for node in file.syntax().descendants() {
35-
get_inlay_hints(&mut res, &sema, &node, max_inlay_hint_length);
37+
match_ast! {
38+
match node {
39+
ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); },
40+
ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); },
41+
ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, max_inlay_hint_length, it); },
42+
_ => (),
43+
}
44+
}
3645
}
3746
res
3847
}
3948

40-
fn get_inlay_hints(
49+
fn get_param_name_hints(
50+
acc: &mut Vec<InlayHint>,
51+
sema: &Semantics<RootDatabase>,
52+
expr: ast::Expr,
53+
) -> Option<()> {
54+
let args = match &expr {
55+
ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
56+
ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
57+
_ => return None,
58+
};
59+
let args_count = args.clone().count();
60+
61+
let fn_signature = get_fn_signature(sema, &expr)?;
62+
let n_params_to_skip =
63+
if fn_signature.has_self_param && fn_signature.parameter_names.len() > args_count {
64+
1
65+
} else {
66+
0
67+
};
68+
let hints = fn_signature
69+
.parameter_names
70+
.iter()
71+
.skip(n_params_to_skip)
72+
.zip(args)
73+
.filter(|(param, arg)| should_show_param_hint(&fn_signature, param, &arg))
74+
.map(|(param_name, arg)| InlayHint {
75+
range: arg.syntax().text_range(),
76+
kind: InlayKind::ParameterHint,
77+
label: param_name.into(),
78+
});
79+
80+
acc.extend(hints);
81+
Some(())
82+
}
83+
84+
fn get_bind_pat_hints(
4185
acc: &mut Vec<InlayHint>,
4286
sema: &Semantics<RootDatabase>,
43-
node: &SyntaxNode,
4487
max_inlay_hint_length: Option<usize>,
88+
pat: ast::BindPat,
4589
) -> Option<()> {
46-
let _p = profile("get_inlay_hints");
47-
let db = sema.db;
48-
match_ast! {
49-
match node {
50-
ast::CallExpr(it) => {
51-
get_param_name_hints(acc, sema, ast::Expr::from(it));
52-
},
53-
ast::MethodCallExpr(it) => {
54-
get_param_name_hints(acc, sema, ast::Expr::from(it));
55-
},
56-
ast::BindPat(it) => {
57-
let pat = ast::Pat::from(it.clone());
58-
let ty = sema.type_of_pat(&pat)?;
59-
60-
if should_not_display_type_hint(db, &it, &ty) {
61-
return None;
62-
}
90+
let ty = sema.type_of_pat(&pat.clone().into())?;
6391

64-
acc.push(
65-
InlayHint {
66-
range: pat.syntax().text_range(),
67-
kind: InlayKind::TypeHint,
68-
label: ty.display_truncated(db, max_inlay_hint_length).to_string().into(),
69-
}
70-
);
71-
},
72-
_ => (),
73-
}
74-
};
92+
if should_not_display_type_hint(sema.db, &pat, &ty) {
93+
return None;
94+
}
95+
96+
acc.push(InlayHint {
97+
range: pat.syntax().text_range(),
98+
kind: InlayKind::TypeHint,
99+
label: ty.display_truncated(sema.db, max_inlay_hint_length).to_string().into(),
100+
});
75101
Some(())
76102
}
77103

@@ -120,43 +146,6 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_
120146
false
121147
}
122148

123-
fn get_param_name_hints(
124-
acc: &mut Vec<InlayHint>,
125-
sema: &Semantics<RootDatabase>,
126-
expr: ast::Expr,
127-
) -> Option<()> {
128-
let args = match &expr {
129-
ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
130-
ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
131-
_ => return None,
132-
}
133-
.into_iter()
134-
// we need args len to determine whether to skip or not the &self parameter
135-
.collect::<Vec<_>>();
136-
137-
let fn_signature = get_fn_signature(sema, &expr)?;
138-
let n_params_to_skip =
139-
if fn_signature.has_self_param && fn_signature.parameter_names.len() > args.len() {
140-
1
141-
} else {
142-
0
143-
};
144-
let hints = fn_signature
145-
.parameter_names
146-
.iter()
147-
.skip(n_params_to_skip)
148-
.zip(args)
149-
.filter(|(param, arg)| should_show_param_hint(&fn_signature, param, &arg))
150-
.map(|(param_name, arg)| InlayHint {
151-
range: arg.syntax().text_range(),
152-
kind: InlayKind::ParameterHint,
153-
label: param_name.into(),
154-
});
155-
156-
acc.extend(hints);
157-
Some(())
158-
}
159-
160149
fn should_show_param_hint(
161150
fn_signature: &FunctionSignature,
162151
param_name: &str,

crates/ra_syntax/src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub trait AstToken {
5959
}
6060

6161
/// An iterator over `SyntaxNode` children of a particular AST type.
62-
#[derive(Debug)]
62+
#[derive(Debug, Clone)]
6363
pub struct AstChildren<N> {
6464
inner: SyntaxNodeChildren,
6565
ph: PhantomData<N>,

0 commit comments

Comments
 (0)