aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
Diffstat (limited to 'crates')
-rw-r--r--crates/ide/src/syntax_highlighting/inject.rs2
-rw-r--r--crates/ide_completion/src/context.rs38
-rw-r--r--crates/ide_completion/src/render.rs5
-rw-r--r--crates/ide_db/src/call_info.rs14
-rw-r--r--crates/syntax/src/ast/node_ext.rs9
5 files changed, 44 insertions, 24 deletions
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 00493a6b5..8e0940184 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -23,7 +23,7 @@ pub(super) fn ra_fixture(
23 expanded: SyntaxToken, 23 expanded: SyntaxToken,
24) -> Option<()> { 24) -> Option<()> {
25 let active_parameter = ActiveParameter::at_token(&sema, expanded)?; 25 let active_parameter = ActiveParameter::at_token(&sema, expanded)?;
26 if !active_parameter.name.starts_with("ra_fixture") { 26 if !active_parameter.ident().map_or(false, |name| name.text().starts_with("ra_fixture")) {
27 return None; 27 return None;
28 } 28 }
29 let value = literal.value()?; 29 let value = literal.value()?;
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};
4use ide_db::base_db::{FilePosition, SourceDatabase}; 4use ide_db::base_db::{FilePosition, SourceDatabase};
5use ide_db::{call_info::ActiveParameter, RootDatabase}; 5use ide_db::{call_info::ActiveParameter, RootDatabase};
6use syntax::{ 6use 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
11use text_edit::Indel; 14use 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
320fn compute_exact_name_match(ctx: &CompletionContext, completion_name: impl Into<String>) -> bool { 320fn 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
326fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> { 325fn compute_ref_match(ctx: &CompletionContext, completion_ty: &hir::Type) -> Option<Mutability> {
diff --git a/crates/ide_db/src/call_info.rs b/crates/ide_db/src/call_info.rs
index 7e26c3ccf..e583a52f4 100644
--- a/crates/ide_db/src/call_info.rs
+++ b/crates/ide_db/src/call_info.rs
@@ -4,7 +4,7 @@ use either::Either;
4use hir::{HasAttrs, HirDisplay, Semantics, Type}; 4use hir::{HasAttrs, HirDisplay, Semantics, Type};
5use stdx::format_to; 5use stdx::format_to;
6use syntax::{ 6use syntax::{
7 ast::{self, ArgListOwner}, 7 ast::{self, ArgListOwner, NameOwner},
8 match_ast, AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize, 8 match_ast, AstNode, SyntaxNode, SyntaxToken, TextRange, TextSize,
9}; 9};
10 10
@@ -142,7 +142,7 @@ fn call_info_impl(
142#[derive(Debug)] 142#[derive(Debug)]
143pub struct ActiveParameter { 143pub struct ActiveParameter {
144 pub ty: Type, 144 pub ty: Type,
145 pub name: String, 145 pub pat: Either<ast::SelfParam, ast::Pat>,
146} 146}
147 147
148impl ActiveParameter { 148impl ActiveParameter {
@@ -165,8 +165,14 @@ impl ActiveParameter {
165 return None; 165 return None;
166 } 166 }
167 let (pat, ty) = params.swap_remove(idx); 167 let (pat, ty) = params.swap_remove(idx);
168 let name = pat?.to_string(); 168 pat.map(|pat| ActiveParameter { ty, pat })
169 Some(ActiveParameter { ty, name }) 169 }
170
171 pub fn ident(&self) -> Option<ast::Name> {
172 self.pat.as_ref().right().and_then(|param| match param {
173 ast::Pat::IdentPat(ident) => ident.name(),
174 _ => None,
175 })
170 } 176 }
171} 177}
172 178
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 01f580a40..42a7b9c2a 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -380,6 +380,15 @@ impl fmt::Display for NameOrNameRef {
380 } 380 }
381} 381}
382 382
383impl NameOrNameRef {
384 pub fn text(&self) -> &str {
385 match self {
386 NameOrNameRef::Name(name) => name.text(),
387 NameOrNameRef::NameRef(name_ref) => name_ref.text(),
388 }
389 }
390}
391
383impl ast::RecordPatField { 392impl ast::RecordPatField {
384 pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> { 393 pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> {
385 let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; 394 let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?;