diff options
Diffstat (limited to 'crates/ra_ide/src/inlay_hints.rs')
-rw-r--r-- | crates/ra_ide/src/inlay_hints.rs | 48 |
1 files changed, 21 insertions, 27 deletions
diff --git a/crates/ra_ide/src/inlay_hints.rs b/crates/ra_ide/src/inlay_hints.rs index b42aa1523..35e3f782d 100644 --- a/crates/ra_ide/src/inlay_hints.rs +++ b/crates/ra_ide/src/inlay_hints.rs | |||
@@ -1,12 +1,11 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use hir::{Adt, HirDisplay, SourceAnalyzer, SourceBinder, Type}; | 3 | use hir::{Adt, HirDisplay, Semantics, Type}; |
4 | use once_cell::unsync::Lazy; | ||
5 | use ra_ide_db::RootDatabase; | 4 | use ra_ide_db::RootDatabase; |
6 | use ra_prof::profile; | 5 | use ra_prof::profile; |
7 | use ra_syntax::{ | 6 | use ra_syntax::{ |
8 | ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, | 7 | ast::{self, ArgListOwner, AstNode, TypeAscriptionOwner}, |
9 | match_ast, SmolStr, SourceFile, SyntaxNode, TextRange, | 8 | match_ast, SmolStr, SyntaxNode, TextRange, |
10 | }; | 9 | }; |
11 | 10 | ||
12 | use crate::{FileId, FunctionSignature}; | 11 | use crate::{FileId, FunctionSignature}; |
@@ -27,38 +26,36 @@ pub struct InlayHint { | |||
27 | pub(crate) fn inlay_hints( | 26 | pub(crate) fn inlay_hints( |
28 | db: &RootDatabase, | 27 | db: &RootDatabase, |
29 | file_id: FileId, | 28 | file_id: FileId, |
30 | file: &SourceFile, | ||
31 | max_inlay_hint_length: Option<usize>, | 29 | max_inlay_hint_length: Option<usize>, |
32 | ) -> Vec<InlayHint> { | 30 | ) -> Vec<InlayHint> { |
33 | let mut sb = SourceBinder::new(db); | 31 | let sema = Semantics::new(db); |
32 | let file = sema.parse(file_id); | ||
34 | let mut res = Vec::new(); | 33 | let mut res = Vec::new(); |
35 | for node in file.syntax().descendants() { | 34 | for node in file.syntax().descendants() { |
36 | get_inlay_hints(&mut res, &mut sb, file_id, &node, max_inlay_hint_length); | 35 | get_inlay_hints(&mut res, &sema, &node, max_inlay_hint_length); |
37 | } | 36 | } |
38 | res | 37 | res |
39 | } | 38 | } |
40 | 39 | ||
41 | fn get_inlay_hints( | 40 | fn get_inlay_hints( |
42 | acc: &mut Vec<InlayHint>, | 41 | acc: &mut Vec<InlayHint>, |
43 | sb: &mut SourceBinder<RootDatabase>, | 42 | sema: &Semantics<RootDatabase>, |
44 | file_id: FileId, | ||
45 | node: &SyntaxNode, | 43 | node: &SyntaxNode, |
46 | max_inlay_hint_length: Option<usize>, | 44 | max_inlay_hint_length: Option<usize>, |
47 | ) -> Option<()> { | 45 | ) -> Option<()> { |
48 | let _p = profile("get_inlay_hints"); | 46 | let _p = profile("get_inlay_hints"); |
49 | let db = sb.db; | 47 | let db = sema.db; |
50 | let analyzer = Lazy::new(move || sb.analyze(hir::InFile::new(file_id.into(), node), None)); | ||
51 | match_ast! { | 48 | match_ast! { |
52 | match node { | 49 | match node { |
53 | ast::CallExpr(it) => { | 50 | ast::CallExpr(it) => { |
54 | get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it)); | 51 | get_param_name_hints(acc, sema, ast::Expr::from(it)); |
55 | }, | 52 | }, |
56 | ast::MethodCallExpr(it) => { | 53 | ast::MethodCallExpr(it) => { |
57 | get_param_name_hints(acc, db, &analyzer, ast::Expr::from(it)); | 54 | get_param_name_hints(acc, sema, ast::Expr::from(it)); |
58 | }, | 55 | }, |
59 | ast::BindPat(it) => { | 56 | ast::BindPat(it) => { |
60 | let pat = ast::Pat::from(it.clone()); | 57 | let pat = ast::Pat::from(it.clone()); |
61 | let ty = analyzer.type_of_pat(db, &pat)?; | 58 | let ty = sema.type_of_pat(&pat)?; |
62 | 59 | ||
63 | if should_not_display_type_hint(db, &it, &ty) { | 60 | if should_not_display_type_hint(db, &it, &ty) { |
64 | return None; | 61 | return None; |
@@ -125,8 +122,7 @@ fn should_not_display_type_hint(db: &RootDatabase, bind_pat: &ast::BindPat, pat_ | |||
125 | 122 | ||
126 | fn get_param_name_hints( | 123 | fn get_param_name_hints( |
127 | acc: &mut Vec<InlayHint>, | 124 | acc: &mut Vec<InlayHint>, |
128 | db: &RootDatabase, | 125 | sema: &Semantics<RootDatabase>, |
129 | analyzer: &SourceAnalyzer, | ||
130 | expr: ast::Expr, | 126 | expr: ast::Expr, |
131 | ) -> Option<()> { | 127 | ) -> Option<()> { |
132 | let args = match &expr { | 128 | let args = match &expr { |
@@ -138,7 +134,7 @@ fn get_param_name_hints( | |||
138 | // we need args len to determine whether to skip or not the &self parameter | 134 | // we need args len to determine whether to skip or not the &self parameter |
139 | .collect::<Vec<_>>(); | 135 | .collect::<Vec<_>>(); |
140 | 136 | ||
141 | let fn_signature = get_fn_signature(db, analyzer, &expr)?; | 137 | let fn_signature = get_fn_signature(sema, &expr)?; |
142 | let n_params_to_skip = | 138 | let n_params_to_skip = |
143 | if fn_signature.has_self_param && fn_signature.parameter_names.len() > args.len() { | 139 | if fn_signature.has_self_param && fn_signature.parameter_names.len() > args.len() { |
144 | 1 | 140 | 1 |
@@ -184,28 +180,26 @@ fn should_show_param_hint( | |||
184 | true | 180 | true |
185 | } | 181 | } |
186 | 182 | ||
187 | fn get_fn_signature( | 183 | fn get_fn_signature(sema: &Semantics<RootDatabase>, expr: &ast::Expr) -> Option<FunctionSignature> { |
188 | db: &RootDatabase, | ||
189 | analyzer: &SourceAnalyzer, | ||
190 | expr: &ast::Expr, | ||
191 | ) -> Option<FunctionSignature> { | ||
192 | match expr { | 184 | match expr { |
193 | ast::Expr::CallExpr(expr) => { | 185 | ast::Expr::CallExpr(expr) => { |
194 | // FIXME: Type::as_callable is broken for closures | 186 | // FIXME: Type::as_callable is broken for closures |
195 | let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?; | 187 | let callable_def = sema.type_of_expr(&expr.expr()?)?.as_callable()?; |
196 | match callable_def { | 188 | match callable_def { |
197 | hir::CallableDef::FunctionId(it) => { | 189 | hir::CallableDef::FunctionId(it) => { |
198 | Some(FunctionSignature::from_hir(db, it.into())) | 190 | Some(FunctionSignature::from_hir(sema.db, it.into())) |
191 | } | ||
192 | hir::CallableDef::StructId(it) => { | ||
193 | FunctionSignature::from_struct(sema.db, it.into()) | ||
199 | } | 194 | } |
200 | hir::CallableDef::StructId(it) => FunctionSignature::from_struct(db, it.into()), | ||
201 | hir::CallableDef::EnumVariantId(it) => { | 195 | hir::CallableDef::EnumVariantId(it) => { |
202 | FunctionSignature::from_enum_variant(db, it.into()) | 196 | FunctionSignature::from_enum_variant(sema.db, it.into()) |
203 | } | 197 | } |
204 | } | 198 | } |
205 | } | 199 | } |
206 | ast::Expr::MethodCallExpr(expr) => { | 200 | ast::Expr::MethodCallExpr(expr) => { |
207 | let fn_def = analyzer.resolve_method_call(&expr)?; | 201 | let fn_def = sema.resolve_method_call(&expr)?; |
208 | Some(FunctionSignature::from_hir(db, fn_def)) | 202 | Some(FunctionSignature::from_hir(sema.db, fn_def)) |
209 | } | 203 | } |
210 | _ => None, | 204 | _ => None, |
211 | } | 205 | } |