diff options
Diffstat (limited to 'crates/ide_completion')
-rw-r--r-- | crates/ide_completion/src/context.rs | 38 | ||||
-rw-r--r-- | crates/ide_completion/src/render.rs | 5 |
2 files changed, 24 insertions, 19 deletions
diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 3c31de9ad..4c2b31084 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs | |||
@@ -4,8 +4,11 @@ use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; | |||
4 | use ide_db::base_db::{FilePosition, SourceDatabase}; | 4 | use ide_db::base_db::{FilePosition, SourceDatabase}; |
5 | use ide_db::{call_info::ActiveParameter, RootDatabase}; | 5 | use ide_db::{call_info::ActiveParameter, RootDatabase}; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | algo::find_node_at_offset, ast, match_ast, AstNode, NodeOrToken, SyntaxKind::*, SyntaxNode, | 7 | algo::find_node_at_offset, |
8 | SyntaxToken, TextRange, TextSize, | 8 | ast::{self, NameOrNameRef, NameOwner}, |
9 | match_ast, AstNode, NodeOrToken, | ||
10 | SyntaxKind::*, | ||
11 | SyntaxNode, SyntaxToken, TextRange, TextSize, | ||
9 | }; | 12 | }; |
10 | 13 | ||
11 | use text_edit::Indel; | 14 | use text_edit::Indel; |
@@ -35,7 +38,7 @@ pub(crate) struct CompletionContext<'a> { | |||
35 | /// The token before the cursor, in the macro-expanded file. | 38 | /// The token before the cursor, in the macro-expanded file. |
36 | pub(super) token: SyntaxToken, | 39 | pub(super) token: SyntaxToken, |
37 | pub(super) krate: Option<hir::Crate>, | 40 | pub(super) krate: Option<hir::Crate>, |
38 | pub(super) expected_name: Option<String>, | 41 | pub(super) expected_name: Option<NameOrNameRef>, |
39 | pub(super) expected_type: Option<Type>, | 42 | pub(super) expected_type: Option<Type>, |
40 | pub(super) name_ref_syntax: Option<ast::NameRef>, | 43 | pub(super) name_ref_syntax: Option<ast::NameRef>, |
41 | pub(super) lifetime_syntax: Option<ast::Lifetime>, | 44 | pub(super) lifetime_syntax: Option<ast::Lifetime>, |
@@ -298,13 +301,13 @@ impl<'a> CompletionContext<'a> { | |||
298 | file_with_fake_ident: SyntaxNode, | 301 | file_with_fake_ident: SyntaxNode, |
299 | offset: TextSize, | 302 | offset: TextSize, |
300 | ) { | 303 | ) { |
301 | let expected = { | 304 | let (expected_type, expected_name) = { |
302 | let mut node = match self.token.parent() { | 305 | let mut node = match self.token.parent() { |
303 | Some(it) => it, | 306 | Some(it) => it, |
304 | None => return, | 307 | None => return, |
305 | }; | 308 | }; |
306 | loop { | 309 | loop { |
307 | let ret = match_ast! { | 310 | break match_ast! { |
308 | match node { | 311 | match node { |
309 | ast::LetStmt(it) => { | 312 | ast::LetStmt(it) => { |
310 | cov_mark::hit!(expected_type_let_with_leading_char); | 313 | cov_mark::hit!(expected_type_let_with_leading_char); |
@@ -312,7 +315,7 @@ impl<'a> CompletionContext<'a> { | |||
312 | let ty = it.pat() | 315 | let ty = it.pat() |
313 | .and_then(|pat| self.sema.type_of_pat(&pat)); | 316 | .and_then(|pat| self.sema.type_of_pat(&pat)); |
314 | let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() { | 317 | let name = if let Some(ast::Pat::IdentPat(ident)) = it.pat() { |
315 | Some(ident.syntax().text().to_string()) | 318 | ident.name().map(NameOrNameRef::Name) |
316 | } else { | 319 | } else { |
317 | None | 320 | None |
318 | }; | 321 | }; |
@@ -325,7 +328,10 @@ impl<'a> CompletionContext<'a> { | |||
325 | ActiveParameter::at_token( | 328 | ActiveParameter::at_token( |
326 | &self.sema, | 329 | &self.sema, |
327 | self.token.clone(), | 330 | self.token.clone(), |
328 | ).map(|ap| (Some(ap.ty), Some(ap.name))) | 331 | ).map(|ap| { |
332 | let name = ap.ident().map(NameOrNameRef::Name); | ||
333 | (Some(ap.ty), name) | ||
334 | }) | ||
329 | .unwrap_or((None, None)) | 335 | .unwrap_or((None, None)) |
330 | }, | 336 | }, |
331 | ast::RecordExprFieldList(_it) => { | 337 | ast::RecordExprFieldList(_it) => { |
@@ -333,10 +339,10 @@ impl<'a> CompletionContext<'a> { | |||
333 | self.token.prev_sibling_or_token() | 339 | self.token.prev_sibling_or_token() |
334 | .and_then(|se| se.into_node()) | 340 | .and_then(|se| se.into_node()) |
335 | .and_then(|node| ast::RecordExprField::cast(node)) | 341 | .and_then(|node| ast::RecordExprField::cast(node)) |
336 | .and_then(|rf| self.sema.resolve_record_field(&rf)) | 342 | .and_then(|rf| self.sema.resolve_record_field(&rf).zip(Some(rf))) |
337 | .map(|f|( | 343 | .map(|(f, rf)|( |
338 | Some(f.0.signature_ty(self.db)), | 344 | Some(f.0.signature_ty(self.db)), |
339 | Some(f.0.name(self.db).to_string()), | 345 | rf.field_name().map(NameOrNameRef::NameRef), |
340 | )) | 346 | )) |
341 | .unwrap_or((None, None)) | 347 | .unwrap_or((None, None)) |
342 | }, | 348 | }, |
@@ -346,7 +352,7 @@ impl<'a> CompletionContext<'a> { | |||
346 | .resolve_record_field(&it) | 352 | .resolve_record_field(&it) |
347 | .map(|f|( | 353 | .map(|f|( |
348 | Some(f.0.signature_ty(self.db)), | 354 | Some(f.0.signature_ty(self.db)), |
349 | Some(f.0.name(self.db).to_string()), | 355 | it.field_name().map(NameOrNameRef::NameRef), |
350 | )) | 356 | )) |
351 | .unwrap_or((None, None)) | 357 | .unwrap_or((None, None)) |
352 | }, | 358 | }, |
@@ -384,12 +390,10 @@ impl<'a> CompletionContext<'a> { | |||
384 | }, | 390 | }, |
385 | } | 391 | } |
386 | }; | 392 | }; |
387 | |||
388 | break ret; | ||
389 | } | 393 | } |
390 | }; | 394 | }; |
391 | self.expected_type = expected.0; | 395 | self.expected_type = expected_type; |
392 | self.expected_name = expected.1; | 396 | self.expected_name = expected_name; |
393 | self.attribute_under_caret = find_node_at_offset(&file_with_fake_ident, offset); | 397 | self.attribute_under_caret = find_node_at_offset(&file_with_fake_ident, offset); |
394 | 398 | ||
395 | if let Some(lifetime) = find_node_at_offset::<ast::Lifetime>(&file_with_fake_ident, offset) | 399 | if let Some(lifetime) = find_node_at_offset::<ast::Lifetime>(&file_with_fake_ident, offset) |
@@ -659,7 +663,9 @@ mod tests { | |||
659 | .map(|t| t.display_test(&db).to_string()) | 663 | .map(|t| t.display_test(&db).to_string()) |
660 | .unwrap_or("?".to_owned()); | 664 | .unwrap_or("?".to_owned()); |
661 | 665 | ||
662 | let name = completion_context.expected_name.unwrap_or("?".to_owned()); | 666 | let name = completion_context |
667 | .expected_name | ||
668 | .map_or_else(|| "?".to_owned(), |name| name.to_string()); | ||
663 | 669 | ||
664 | expect.assert_eq(&format!("ty: {}, name: {}", ty, name)); | 670 | expect.assert_eq(&format!("ty: {}, name: {}", ty, name)); |
665 | } | 671 | } |
diff --git a/crates/ide_completion/src/render.rs b/crates/ide_completion/src/render.rs index 12921e12b..2b6e9ebd1 100644 --- a/crates/ide_completion/src/render.rs +++ b/crates/ide_completion/src/render.rs | |||
@@ -243,7 +243,7 @@ impl<'a> Render<'a> { | |||
243 | 243 | ||
244 | item.set_relevance(CompletionRelevance { | 244 | item.set_relevance(CompletionRelevance { |
245 | exact_type_match: compute_exact_type_match(self.ctx.completion, &ty), | 245 | exact_type_match: compute_exact_type_match(self.ctx.completion, &ty), |
246 | exact_name_match: compute_exact_name_match(self.ctx.completion, local_name.clone()), | 246 | exact_name_match: compute_exact_name_match(self.ctx.completion, &local_name), |
247 | is_local: true, | 247 | is_local: true, |
248 | ..CompletionRelevance::default() | 248 | ..CompletionRelevance::default() |
249 | }); | 249 | }); |
@@ -319,8 +319,7 @@ fn compute_exact_type_match(ctx: &CompletionContext, completion_ty: &hir::Type) | |||
319 | 319 | ||
320 | fn compute_exact_name_match(ctx: &CompletionContext, completion_name: impl Into<String>) -> bool { | 320 | fn compute_exact_name_match(ctx: &CompletionContext, completion_name: impl Into<String>) -> bool { |
321 | let completion_name = completion_name.into(); | 321 | let completion_name = completion_name.into(); |
322 | 322 | ctx.expected_name.as_ref().map_or(false, |name| name.text() == completion_name) | |
323 | Some(&completion_name) == ctx.expected_name.as_ref() | ||
324 | } | 323 | } |
325 | 324 | ||
326 | fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> { | 325 | fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> { |