diff options
Diffstat (limited to 'crates/ra_ide/src/inlay_hints.rs')
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 77 |
1 files changed, 38 insertions, 39 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index e2da96129..1b631c7cd 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -30,19 +30,20 @@ pub(crate) fn inlay_hints( | |||
30 | max_inlay_hint_length: Option<usize>, | 30 | max_inlay_hint_length: Option<usize>, |
31 | ) -> Vec<InlayHint> { | 31 | ) -> Vec<InlayHint> { |
32 | let mut sb = SourceBinder::new(db); | 32 | let mut sb = SourceBinder::new(db); |
33 | file.syntax() | 33 | let mut res = Vec::new(); |
34 | .descendants() | 34 | for node in file.syntax().descendants() { |
35 | .flat_map(|node| get_inlay_hints(&mut sb, file_id, &node, max_inlay_hint_length)) | 35 | get_inlay_hints(&mut res, &mut sb, file_id, &node, max_inlay_hint_length); |
36 | .flatten() | 36 | } |
37 | .collect() | 37 | res |
38 | } | 38 | } |
39 | 39 | ||
40 | fn get_inlay_hints( | 40 | fn get_inlay_hints( |
41 | acc: &mut Vec<InlayHint>, | ||
41 | sb: &mut SourceBinder<RootDatabase>, | 42 | sb: &mut SourceBinder<RootDatabase>, |
42 | file_id: FileId, | 43 | file_id: FileId, |
43 | node: &SyntaxNode, | 44 | node: &SyntaxNode, |
44 | max_inlay_hint_length: Option<usize>, | 45 | max_inlay_hint_length: Option<usize>, |
45 | ) -> Option<Vec<InlayHint>> { | 46 | ) -> Option<()> { |
46 | let _p = profile("get_inlay_hints"); | 47 | let _p = profile("get_inlay_hints"); |
47 | let db = sb.db; | 48 | let db = sb.db; |
48 | let analyzer = Lazy::new(move || sb.analyze(hir::InFile::new(file_id.into(), node), None)); | 49 | let analyzer = Lazy::new(move || sb.analyze(hir::InFile::new(file_id.into(), node), None)); |
@@ -53,7 +54,7 @@ fn get_inlay_hints( | |||
53 | return None; | 54 | return None; |
54 | } | 55 | } |
55 | let pat = it.pat()?; | 56 | let pat = it.pat()?; |
56 | Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) | 57 | get_pat_type_hints(acc, db, &analyzer, pat, false, max_inlay_hint_length); |
57 | }, | 58 | }, |
58 | ast::LambdaExpr(it) => { | 59 | ast::LambdaExpr(it) => { |
59 | it.param_list().map(|param_list| { | 60 | it.param_list().map(|param_list| { |
@@ -61,54 +62,50 @@ fn get_inlay_hints( | |||
61 | .params() | 62 | .params() |
62 | .filter(|closure_param| closure_param.ascribed_type().is_none()) | 63 | .filter(|closure_param| closure_param.ascribed_type().is_none()) |
63 | .filter_map(|closure_param| closure_param.pat()) | 64 | .filter_map(|closure_param| closure_param.pat()) |
64 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, false, max_inlay_hint_length)) | 65 | .for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, false, max_inlay_hint_length)) |
65 | .flatten() | 66 | }); |
66 | .collect() | ||
67 | }) | ||
68 | }, | 67 | }, |
69 | ast::ForExpr(it) => { | 68 | ast::ForExpr(it) => { |
70 | let pat = it.pat()?; | 69 | let pat = it.pat()?; |
71 | Some(get_pat_type_hints(db, &analyzer, pat, false, max_inlay_hint_length)) | 70 | get_pat_type_hints(acc, db, &analyzer, pat, false, max_inlay_hint_length); |
72 | }, | 71 | }, |
73 | ast::IfExpr(it) => { | 72 | ast::IfExpr(it) => { |
74 | let pat = it.condition()?.pat()?; | 73 | let pat = it.condition()?.pat()?; |
75 | Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) | 74 | get_pat_type_hints(acc, db, &analyzer, pat, true, max_inlay_hint_length); |
76 | }, | 75 | }, |
77 | ast::WhileExpr(it) => { | 76 | ast::WhileExpr(it) => { |
78 | let pat = it.condition()?.pat()?; | 77 | let pat = it.condition()?.pat()?; |
79 | Some(get_pat_type_hints(db, &analyzer, pat, true, max_inlay_hint_length)) | 78 | get_pat_type_hints(acc, db, &analyzer, pat, true, max_inlay_hint_length); |
80 | }, | 79 | }, |
81 | ast::MatchArmList(it) => { | 80 | ast::MatchArmList(it) => { |
82 | Some( | 81 | it.arms() |
83 | it | 82 | .map(|match_arm| match_arm.pats()) |
84 | .arms() | 83 | .flatten() |
85 | .map(|match_arm| match_arm.pats()) | 84 | .for_each(|root_pat| get_pat_type_hints(acc, db, &analyzer, root_pat, true, max_inlay_hint_length)); |
86 | .flatten() | ||
87 | .map(|root_pat| get_pat_type_hints(db, &analyzer, root_pat, true, max_inlay_hint_length)) | ||
88 | .flatten() | ||
89 | .collect(), | ||
90 | ) | ||
91 | }, | 85 | }, |
92 | ast::CallExpr(it) => { | 86 | ast::CallExpr(it) => { |
93 | get_param_name_hints(db, &analyzer, ast::Expr::from(it)) | 87 | get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it)); |
94 | }, | 88 | }, |
95 | ast::MethodCallExpr(it) => { | 89 | ast::MethodCallExpr(it) => { |
96 | get_param_name_hints(db, &analyzer, ast::Expr::from(it)) | 90 | get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it)); |
97 | }, | 91 | }, |
98 | _ => None, | 92 | _ => (), |
99 | } | 93 | } |
100 | } | 94 | }; |
95 | Some(()) | ||
101 | } | 96 | } |
97 | |||
102 | fn get_param_name_hints( | 98 | fn get_param_name_hints( |
99 | acc: &mut Vec<InlayHint>, | ||
103 | db: &RootDatabase, | 100 | db: &RootDatabase, |
104 | analyzer: &SourceAnalyzer, | 101 | analyzer: &SourceAnalyzer, |
105 | expr: ast::Expr, | 102 | expr: ast::Expr, |
106 | ) -> Option<Vec<InlayHint>> { | 103 | ) -> Option<()> { |
107 | let args = match &expr { | 104 | let args = match &expr { |
108 | ast::Expr::CallExpr(expr) => Some(expr.arg_list()?.args()), | 105 | ast::Expr::CallExpr(expr) => expr.arg_list()?.args(), |
109 | ast::Expr::MethodCallExpr(expr) => Some(expr.arg_list()?.args()), | 106 | ast::Expr::MethodCallExpr(expr) => expr.arg_list()?.args(), |
110 | _ => None, | 107 | _ => return None, |
111 | }?; | 108 | }; |
112 | 109 | ||
113 | let mut parameters = get_fn_signature(db, analyzer, &expr)?.parameter_names.into_iter(); | 110 | let mut parameters = get_fn_signature(db, analyzer, &expr)?.parameter_names.into_iter(); |
114 | 111 | ||
@@ -129,10 +126,10 @@ fn get_param_name_hints( | |||
129 | range, | 126 | range, |
130 | kind: InlayKind::ParameterHint, | 127 | kind: InlayKind::ParameterHint, |
131 | label: param_name.into(), | 128 | label: param_name.into(), |
132 | }) | 129 | }); |
133 | .collect(); | ||
134 | 130 | ||
135 | Some(hints) | 131 | acc.extend(hints); |
132 | Some(()) | ||
136 | } | 133 | } |
137 | 134 | ||
138 | fn get_fn_signature( | 135 | fn get_fn_signature( |
@@ -164,15 +161,16 @@ fn get_fn_signature( | |||
164 | } | 161 | } |
165 | 162 | ||
166 | fn get_pat_type_hints( | 163 | fn get_pat_type_hints( |
164 | acc: &mut Vec<InlayHint>, | ||
167 | db: &RootDatabase, | 165 | db: &RootDatabase, |
168 | analyzer: &SourceAnalyzer, | 166 | analyzer: &SourceAnalyzer, |
169 | root_pat: ast::Pat, | 167 | root_pat: ast::Pat, |
170 | skip_root_pat_hint: bool, | 168 | skip_root_pat_hint: bool, |
171 | max_inlay_hint_length: Option<usize>, | 169 | max_inlay_hint_length: Option<usize>, |
172 | ) -> Vec<InlayHint> { | 170 | ) { |
173 | let original_pat = &root_pat.clone(); | 171 | let original_pat = &root_pat.clone(); |
174 | 172 | ||
175 | get_leaf_pats(root_pat) | 173 | let hints = get_leaf_pats(root_pat) |
176 | .into_iter() | 174 | .into_iter() |
177 | .filter(|pat| !skip_root_pat_hint || pat != original_pat) | 175 | .filter(|pat| !skip_root_pat_hint || pat != original_pat) |
178 | .filter_map(|pat| { | 176 | .filter_map(|pat| { |
@@ -186,8 +184,9 @@ fn get_pat_type_hints( | |||
186 | range, | 184 | range, |
187 | kind: InlayKind::TypeHint, | 185 | kind: InlayKind::TypeHint, |
188 | label: pat_type.display_truncated(db, max_inlay_hint_length).to_string().into(), | 186 | label: pat_type.display_truncated(db, max_inlay_hint_length).to_string().into(), |
189 | }) | 187 | }); |
190 | .collect() | 188 | |
189 | acc.extend(hints); | ||
191 | } | 190 | } |
192 | 191 | ||
193 | fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> { | 192 | fn get_leaf_pats(root_pat: ast::Pat) -> Vec<ast::Pat> { |