aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/inlay_hints.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/inlay_hints.rs')
-rw-r--r--crates/ra_ide/src/inlay_hints.rs113
1 files changed, 95 insertions, 18 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs
index cf0cbdbd0..ecd615cf4 100644
--- a/crates/ra_ide/src/inlay_hints.rs
+++ b/crates/ra_ide/src/inlay_hints.rs
@@ -10,7 +10,20 @@ use ra_syntax::{
10 10
11use crate::{FileId, FunctionSignature}; 11use crate::{FileId, FunctionSignature};
12 12
13#[derive(Debug, PartialEq, Eq)] 13#[derive(Clone, Debug, PartialEq, Eq)]
14pub struct InlayHintsOptions {
15 pub type_hints: bool,
16 pub parameter_hints: bool,
17 pub max_length: Option<usize>,
18}
19
20impl Default for InlayHintsOptions {
21 fn default() -> Self {
22 Self { type_hints: true, parameter_hints: true, max_length: None }
23 }
24}
25
26#[derive(Clone, Debug, PartialEq, Eq)]
14pub enum InlayKind { 27pub enum InlayKind {
15 TypeHint, 28 TypeHint,
16 ParameterHint, 29 ParameterHint,
@@ -26,7 +39,7 @@ pub struct InlayHint {
26pub(crate) fn inlay_hints( 39pub(crate) fn inlay_hints(
27 db: &RootDatabase, 40 db: &RootDatabase,
28 file_id: FileId, 41 file_id: FileId,
29 max_inlay_hint_length: Option<usize>, 42 options: &InlayHintsOptions,
30) -> Vec<InlayHint> { 43) -> Vec<InlayHint> {
31 let _p = profile("inlay_hints"); 44 let _p = profile("inlay_hints");
32 let sema = Semantics::new(db); 45 let sema = Semantics::new(db);
@@ -36,9 +49,9 @@ pub(crate) fn inlay_hints(
36 for node in file.syntax().descendants() { 49 for node in file.syntax().descendants() {
37 match_ast! { 50 match_ast! {
38 match node { 51 match node {
39 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 52 ast::CallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
40 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, ast::Expr::from(it)); }, 53 ast::MethodCallExpr(it) => { get_param_name_hints(&mut res, &sema, options, ast::Expr::from(it)); },
41 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, max_inlay_hint_length, it); }, 54 ast::BindPat(it) => { get_bind_pat_hints(&mut res, &sema, options, it); },
42 _ => (), 55 _ => (),
43 } 56 }
44 } 57 }
@@ -49,8 +62,13 @@ pub(crate) fn inlay_hints(
49fn get_param_name_hints( 62fn get_param_name_hints(
50 acc: &mut Vec<InlayHint>, 63 acc: &mut Vec<InlayHint>,
51 sema: &Semantics<RootDatabase>, 64 sema: &Semantics<RootDatabase>,
65 options: &InlayHintsOptions,
52 expr: ast::Expr, 66 expr: ast::Expr,
53) -> Option<()> { 67) -> Option<()> {
68 if !options.parameter_hints {
69 return None;
70 }
71
54 let args = match &expr { 72 let args = match &expr {
55 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), 73 ast::Expr::CallExpr(expr) => expr.arg_list()?.args(),
56 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), 74 ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(),
@@ -84,9 +102,13 @@ fn get_param_name_hints(
84fn get_bind_pat_hints( 102fn get_bind_pat_hints(
85 acc: &mut Vec<InlayHint>, 103 acc: &mut Vec<InlayHint>,
86 sema: &Semantics<RootDatabase>, 104 sema: &Semantics<RootDatabase>,
87 max_inlay_hint_length: Option<usize>, 105 options: &InlayHintsOptions,
88 pat: ast::BindPat, 106 pat: ast::BindPat,
89) -> Option<()> { 107) -> Option<()> {
108 if !options.type_hints {
109 return None;
110 }
111
90 let ty = sema.type_of_pat(&pat.clone().into())?; 112 let ty = sema.type_of_pat(&pat.clone().into())?;
91 113
92 if should_not_display_type_hint(sema.db, &pat, &ty) { 114 if should_not_display_type_hint(sema.db, &pat, &ty) {
@@ -96,7 +118,7 @@ fn get_bind_pat_hints(
96 acc.push(InlayHint { 118 acc.push(InlayHint {
97 range: pat.syntax().text_range(), 119 range: pat.syntax().text_range(),
98 kind: InlayKind::TypeHint, 120 kind: InlayKind::TypeHint,
99 label: ty.display_truncated(sema.db, max_inlay_hint_length).to_string().into(), 121 label: ty.display_truncated(sema.db, options.max_length).to_string().into(),
100 }); 122 });
101 Some(()) 123 Some(())
102} 124}
@@ -202,11 +224,66 @@ fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<
202 224
203#[cfg(test)] 225#[cfg(test)]
204mod tests { 226mod tests {
227 use crate::inlay_hints::InlayHintsOptions;
205 use insta::assert_debug_snapshot; 228 use insta::assert_debug_snapshot;
206 229
207 use crate::mock_analysis::single_file; 230 use crate::mock_analysis::single_file;
208 231
209 #[test] 232 #[test]
233 fn param_hints_only() {
234 let (analysis, file_id) = single_file(
235 r#"
236 fn foo(a: i32, b: i32) -> i32 { a + b }
237 fn main() {
238 let _x = foo(4, 4);
239 }"#,
240 );
241 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ parameter_hints: true, type_hints: false, max_length: None}).unwrap(), @r###"
242 [
243 InlayHint {
244 range: [106; 107),
245 kind: ParameterHint,
246 label: "a",
247 },
248 InlayHint {
249 range: [109; 110),
250 kind: ParameterHint,
251 label: "b",
252 },
253 ]"###);
254 }
255
256 #[test]
257 fn hints_disabled() {
258 let (analysis, file_id) = single_file(
259 r#"
260 fn foo(a: i32, b: i32) -> i32 { a + b }
261 fn main() {
262 let _x = foo(4, 4);
263 }"#,
264 );
265 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: false, parameter_hints: false, max_length: None}).unwrap(), @r###"[]"###);
266 }
267
268 #[test]
269 fn type_hints_only() {
270 let (analysis, file_id) = single_file(
271 r#"
272 fn foo(a: i32, b: i32) -> i32 { a + b }
273 fn main() {
274 let _x = foo(4, 4);
275 }"#,
276 );
277 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions{ type_hints: true, parameter_hints: false, max_length: None}).unwrap(), @r###"
278 [
279 InlayHint {
280 range: [97; 99),
281 kind: TypeHint,
282 label: "i32",
283 },
284 ]"###);
285 }
286 #[test]
210 fn default_generic_types_should_not_be_displayed() { 287 fn default_generic_types_should_not_be_displayed() {
211 let (analysis, file_id) = single_file( 288 let (analysis, file_id) = single_file(
212 r#" 289 r#"
@@ -221,7 +298,7 @@ fn main() {
221}"#, 298}"#,
222 ); 299 );
223 300
224 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 301 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
225 [ 302 [
226 InlayHint { 303 InlayHint {
227 range: [69; 71), 304 range: [69; 71),
@@ -278,7 +355,7 @@ fn main() {
278}"#, 355}"#,
279 ); 356 );
280 357
281 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 358 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
282 [ 359 [
283 InlayHint { 360 InlayHint {
284 range: [193; 197), 361 range: [193; 197),
@@ -358,7 +435,7 @@ fn main() {
358}"#, 435}"#,
359 ); 436 );
360 437
361 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 438 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
362 [ 439 [
363 InlayHint { 440 InlayHint {
364 range: [21; 30), 441 range: [21; 30),
@@ -422,7 +499,7 @@ fn main() {
422}"#, 499}"#,
423 ); 500 );
424 501
425 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 502 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
426 [ 503 [
427 InlayHint { 504 InlayHint {
428 range: [21; 30), 505 range: [21; 30),
@@ -472,7 +549,7 @@ fn main() {
472}"#, 549}"#,
473 ); 550 );
474 551
475 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 552 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
476 [ 553 [
477 InlayHint { 554 InlayHint {
478 range: [188; 192), 555 range: [188; 192),
@@ -567,7 +644,7 @@ fn main() {
567}"#, 644}"#,
568 ); 645 );
569 646
570 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 647 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
571 [ 648 [
572 InlayHint { 649 InlayHint {
573 range: [188; 192), 650 range: [188; 192),
@@ -662,7 +739,7 @@ fn main() {
662}"#, 739}"#,
663 ); 740 );
664 741
665 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 742 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
666 [ 743 [
667 InlayHint { 744 InlayHint {
668 range: [252; 256), 745 range: [252; 256),
@@ -734,7 +811,7 @@ fn main() {
734}"#, 811}"#,
735 ); 812 );
736 813
737 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 814 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
738 [ 815 [
739 InlayHint { 816 InlayHint {
740 range: [74; 75), 817 range: [74; 75),
@@ -822,7 +899,7 @@ fn main() {
822}"#, 899}"#,
823 ); 900 );
824 901
825 assert_debug_snapshot!(analysis.inlay_hints(file_id, None).unwrap(), @r###" 902 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions::default()).unwrap(), @r###"
826 [ 903 [
827 InlayHint { 904 InlayHint {
828 range: [798; 809), 905 range: [798; 809),
@@ -944,7 +1021,7 @@ fn main() {
944}"#, 1021}"#,
945 ); 1022 );
946 1023
947 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1024 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
948 [] 1025 []
949 "### 1026 "###
950 ); 1027 );
@@ -970,7 +1047,7 @@ fn main() {
970}"#, 1047}"#,
971 ); 1048 );
972 1049
973 assert_debug_snapshot!(analysis.inlay_hints(file_id, Some(8)).unwrap(), @r###" 1050 assert_debug_snapshot!(analysis.inlay_hints(file_id, &InlayHintsOptions { max_length: Some(8), ..Default::default() }).unwrap(), @r###"
974 [] 1051 []
975 "### 1052 "###
976 ); 1053 );