From 75cb1c1806b2fd21b7b3f9ca7ed0ef9111bc1a35 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 00:11:33 +0200 Subject: Move --- crates/ra_ide/src/completion/completion_item.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index e17586aa5..ea1e0433c 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs @@ -52,7 +52,7 @@ pub struct CompletionItem { /// after completion. trigger_call_info: bool, - /// Score is usefull to pre select or display in better order completion items + /// Score is useful to pre select or display in better order completion items score: Option, } @@ -93,6 +93,14 @@ impl fmt::Debug for CompletionItem { } } +#[derive(Debug, Clone)] +pub enum CompletionScore { + /// If only type match + TypeMatch, + /// If type and name match + TypeAndNameMatch, +} + #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum CompletionItemKind { Snippet, @@ -319,14 +327,6 @@ impl<'a> Into for Builder { } } -#[derive(Debug, Clone)] -pub enum CompletionScore { - /// If only type match - TypeMatch, - /// If type and name match - TypeAndNameMatch, -} - /// Represents an in-progress set of completions being built. #[derive(Debug, Default)] pub(crate) struct Completions { -- cgit v1.2.3 From 6654b9aff31dccdbc2284598deacc95c67b3672c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:08:27 +0200 Subject: More functional --- crates/ra_ide/src/completion/completion_item.rs | 4 ++-- crates/ra_ide/src/completion/presentation.rs | 25 ++++++++++++++++--------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index ea1e0433c..687b380bb 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs @@ -93,7 +93,7 @@ impl fmt::Debug for CompletionItem { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub enum CompletionScore { /// If only type match TypeMatch, @@ -202,7 +202,7 @@ impl CompletionItem { } pub fn score(&self) -> Option { - self.score.clone() + self.score } pub fn set_score(&mut self, score: CompletionScore) { diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index f8dac1d54..5aedfc47f 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -34,7 +34,9 @@ impl Completions { .set_deprecated(is_deprecated) .build(); - compute_score(&mut completion_item, ctx); + if let Some(score) = compute_score(&completion_item, ctx) { + completion_item.set_score(score); + } self.add(completion_item); } @@ -305,7 +307,10 @@ impl Completions { } } -pub(crate) fn compute_score(completion_item: &mut CompletionItem, ctx: &CompletionContext) { +pub(crate) fn compute_score( + completion_item: &CompletionItem, + ctx: &CompletionContext, +) -> Option { let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) { ( @@ -313,7 +318,7 @@ pub(crate) fn compute_score(completion_item: &mut CompletionItem, ctx: &Completi struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), ) } else { - return; + return None; } } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { if call_info.active_parameter_type().is_some() @@ -321,10 +326,10 @@ pub(crate) fn compute_score(completion_item: &mut CompletionItem, ctx: &Completi { (call_info.active_parameter_name().unwrap(), call_info.active_parameter_type().unwrap()) } else { - return; + return None; } } else { - return; + return None; }; // Compute score @@ -332,13 +337,15 @@ pub(crate) fn compute_score(completion_item: &mut CompletionItem, ctx: &Completi if let Some(a_parameter_type) = completion_item.detail() { if &active_type == a_parameter_type { // If same type + same name then go top position - if active_name == completion_item.label() { - completion_item.set_score(CompletionScore::TypeAndNameMatch); + let res = if active_name == completion_item.label() { + CompletionScore::TypeAndNameMatch } else { - completion_item.set_score(CompletionScore::TypeMatch); - } + CompletionScore::TypeMatch + }; + return Some(res); } } + None } enum Params { -- cgit v1.2.3 From 953b5f23cc493d75288cec1347ab65dd3ed38fd7 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:17:33 +0200 Subject: Restore CompletionItem immutability --- crates/ra_ide/src/completion/completion_item.rs | 7 +--- crates/ra_ide/src/completion/presentation.rs | 47 ++++++++++++------------- 2 files changed, 23 insertions(+), 31 deletions(-) diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs index 687b380bb..edbf4a5b7 100644 --- a/crates/ra_ide/src/completion/completion_item.rs +++ b/crates/ra_ide/src/completion/completion_item.rs @@ -190,7 +190,7 @@ impl CompletionItem { } /// What string is used for filtering. pub fn lookup(&self) -> &str { - self.lookup.as_deref().unwrap_or_else(|| self.label()) + self.lookup.as_deref().unwrap_or(&self.label) } pub fn kind(&self) -> Option { @@ -205,10 +205,6 @@ impl CompletionItem { self.score } - pub fn set_score(&mut self, score: CompletionScore) { - self.score = Some(score); - } - pub fn trigger_call_info(&self) -> bool { self.trigger_call_info } @@ -310,7 +306,6 @@ impl Builder { self.deprecated = Some(deprecated); self } - #[allow(unused)] pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder { self.score = Some(score); self diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 5aedfc47f..6d8a5dc08 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -23,22 +23,20 @@ impl Completions { ty: &Type, ) { let is_deprecated = is_deprecated(field, ctx.db); - let mut completion_item = CompletionItem::new( - CompletionKind::Reference, - ctx.source_range(), - field.name(ctx.db).to_string(), - ) - .kind(CompletionItemKind::Field) - .detail(ty.display(ctx.db).to_string()) - .set_documentation(field.docs(ctx.db)) - .set_deprecated(is_deprecated) - .build(); - - if let Some(score) = compute_score(&completion_item, ctx) { - completion_item.set_score(score); + let ty = ty.display(ctx.db).to_string(); + let name = field.name(ctx.db); + let mut completion_item = + CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) + .kind(CompletionItemKind::Field) + .detail(ty.clone()) + .set_documentation(field.docs(ctx.db)) + .set_deprecated(is_deprecated); + + if let Some(score) = compute_score(ctx, &ty, &name.to_string()) { + completion_item = completion_item.set_score(score); } - self.add(completion_item); + completion_item.add_to(self); } pub(crate) fn add_tuple_field(&mut self, ctx: &CompletionContext, field: usize, ty: &Type) { @@ -308,8 +306,9 @@ impl Completions { } pub(crate) fn compute_score( - completion_item: &CompletionItem, ctx: &CompletionContext, + ty: &str, + name: &str, ) -> Option { let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) { @@ -334,16 +333,14 @@ pub(crate) fn compute_score( // Compute score // For the same type - if let Some(a_parameter_type) = completion_item.detail() { - if &active_type == a_parameter_type { - // If same type + same name then go top position - let res = if active_name == completion_item.label() { - CompletionScore::TypeAndNameMatch - } else { - CompletionScore::TypeMatch - }; - return Some(res); - } + if &active_type == ty { + // If same type + same name then go top position + let res = if active_name == name { + CompletionScore::TypeAndNameMatch + } else { + CompletionScore::TypeMatch + }; + return Some(res); } None } -- cgit v1.2.3 From 174952e89b891b20ea580f37e34389467fb9e23c Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:24:08 +0200 Subject: Refactor --- crates/ra_ide/src/completion/presentation.rs | 42 ++++++++++++---------------- 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 6d8a5dc08..ab43d2a0a 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -307,42 +307,36 @@ impl Completions { pub(crate) fn compute_score( ctx: &CompletionContext, + // FIXME: this definitely should be a `Type` ty: &str, name: &str, ) -> Option { let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { - if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) { - ( - struct_field.name(ctx.db).to_string(), - struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), - ) - } else { - return None; - } + let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; + ( + struct_field.name(ctx.db).to_string(), + struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), + ) } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { - if call_info.active_parameter_type().is_some() - && call_info.active_parameter_name().is_some() - { - (call_info.active_parameter_name().unwrap(), call_info.active_parameter_type().unwrap()) - } else { - return None; - } + (call_info.active_parameter_name()?, call_info.active_parameter_type()?) } else { return None; }; // Compute score // For the same type - if &active_type == ty { - // If same type + same name then go top position - let res = if active_name == name { - CompletionScore::TypeAndNameMatch - } else { - CompletionScore::TypeMatch - }; - return Some(res); + if &active_type != ty { + return None; + } + + let mut res = CompletionScore::TypeMatch; + + // If same type + same name then go top position + if active_name == name { + res = CompletionScore::TypeAndNameMatch } - None + + Some(res) } enum Params { -- cgit v1.2.3 From 4b8e9d5483005844e711e2f6191274c3c6ae1c4a Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:25:54 +0200 Subject: Move tests to where they belong --- crates/ra_ide/src/completion/complete_dot.rs | 231 --------------------------- crates/ra_ide/src/completion/presentation.rs | 231 +++++++++++++++++++++++++++ 2 files changed, 231 insertions(+), 231 deletions(-) diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs index 44288f92e..b93153b48 100644 --- a/crates/ra_ide/src/completion/complete_dot.rs +++ b/crates/ra_ide/src/completion/complete_dot.rs @@ -105,237 +105,6 @@ mod tests { ); } - #[test] - fn test_struct_field_completion_in_func_call() { - assert_debug_snapshot!( - do_ref_completion( - r" - struct A { another_field: i64, the_field: u32, my_string: String } - fn test(my_param: u32) -> u32 { my_param } - fn foo(a: A) { - test(a.<|>) - } - ", - ), - @r###" - [ - CompletionItem { - label: "another_field", - source_range: [201; 201), - delete: [201; 201), - insert: "another_field", - kind: Field, - detail: "i64", - }, - CompletionItem { - label: "my_string", - source_range: [201; 201), - delete: [201; 201), - insert: "my_string", - kind: Field, - detail: "{unknown}", - }, - CompletionItem { - label: "the_field", - source_range: [201; 201), - delete: [201; 201), - insert: "the_field", - kind: Field, - detail: "u32", - score: TypeMatch, - }, - ] - "### - ); - } - - #[test] - fn test_struct_field_completion_in_func_call_with_type_and_name() { - assert_debug_snapshot!( - do_ref_completion( - r" - struct A { another_field: i64, another_good_type: u32, the_field: u32 } - fn test(the_field: u32) -> u32 { the_field } - fn foo(a: A) { - test(a.<|>) - } - ", - ), - @r###" - [ - CompletionItem { - label: "another_field", - source_range: [208; 208), - delete: [208; 208), - insert: "another_field", - kind: Field, - detail: "i64", - }, - CompletionItem { - label: "another_good_type", - source_range: [208; 208), - delete: [208; 208), - insert: "another_good_type", - kind: Field, - detail: "u32", - score: TypeMatch, - }, - CompletionItem { - label: "the_field", - source_range: [208; 208), - delete: [208; 208), - insert: "the_field", - kind: Field, - detail: "u32", - score: TypeAndNameMatch, - }, - ] - "### - ); - } - - #[test] - fn test_struct_field_completion_in_record_lit() { - assert_debug_snapshot!( - do_ref_completion( - r" - struct A { another_field: i64, another_good_type: u32, the_field: u32 } - struct B { my_string: String, my_vec: Vec, the_field: u32 } - fn foo(a: A) { - let b = B { - the_field: a.<|> - }; - } - ", - ), - @r###" - [ - CompletionItem { - label: "another_field", - source_range: [270; 270), - delete: [270; 270), - insert: "another_field", - kind: Field, - detail: "i64", - }, - CompletionItem { - label: "another_good_type", - source_range: [270; 270), - delete: [270; 270), - insert: "another_good_type", - kind: Field, - detail: "u32", - score: TypeMatch, - }, - CompletionItem { - label: "the_field", - source_range: [270; 270), - delete: [270; 270), - insert: "the_field", - kind: Field, - detail: "u32", - score: TypeAndNameMatch, - }, - ] - "### - ); - } - - #[test] - fn test_struct_field_completion_in_record_lit_and_fn_call() { - assert_debug_snapshot!( - do_ref_completion( - r" - struct A { another_field: i64, another_good_type: u32, the_field: u32 } - struct B { my_string: String, my_vec: Vec, the_field: u32 } - fn test(the_field: i64) -> i64 { the_field } - fn foo(a: A) { - let b = B { - the_field: test(a.<|>) - }; - } - ", - ), - @r###" - [ - CompletionItem { - label: "another_field", - source_range: [336; 336), - delete: [336; 336), - insert: "another_field", - kind: Field, - detail: "i64", - score: TypeMatch, - }, - CompletionItem { - label: "another_good_type", - source_range: [336; 336), - delete: [336; 336), - insert: "another_good_type", - kind: Field, - detail: "u32", - }, - CompletionItem { - label: "the_field", - source_range: [336; 336), - delete: [336; 336), - insert: "the_field", - kind: Field, - detail: "u32", - }, - ] - "### - ); - } - - #[test] - fn test_struct_field_completion_in_fn_call_and_record_lit() { - assert_debug_snapshot!( - do_ref_completion( - r" - struct A { another_field: i64, another_good_type: u32, the_field: u32 } - struct B { my_string: String, my_vec: Vec, the_field: u32 } - fn test(the_field: i64) -> i64 { the_field } - fn foo(a: A) { - test(B { - the_field: a.<|> - }); - } - ", - ), - @r###" - [ - CompletionItem { - label: "another_field", - source_range: [328; 328), - delete: [328; 328), - insert: "another_field", - kind: Field, - detail: "i64", - }, - CompletionItem { - label: "another_good_type", - source_range: [328; 328), - delete: [328; 328), - insert: "another_good_type", - kind: Field, - detail: "u32", - score: TypeMatch, - }, - CompletionItem { - label: "the_field", - source_range: [328; 328), - delete: [328; 328), - insert: "the_field", - kind: Field, - detail: "u32", - score: TypeAndNameMatch, - }, - ] - "### - ); - } - #[test] fn test_struct_field_completion_self() { assert_debug_snapshot!( diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index ab43d2a0a..ae15f91de 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -1070,4 +1070,235 @@ mod tests { "### ); } + + #[test] + fn test_struct_field_completion_in_func_call() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct A { another_field: i64, the_field: u32, my_string: String } + fn test(my_param: u32) -> u32 { my_param } + fn foo(a: A) { + test(a.<|>) + } + ", + ), + @r###" + [ + CompletionItem { + label: "another_field", + source_range: [201; 201), + delete: [201; 201), + insert: "another_field", + kind: Field, + detail: "i64", + }, + CompletionItem { + label: "my_string", + source_range: [201; 201), + delete: [201; 201), + insert: "my_string", + kind: Field, + detail: "{unknown}", + }, + CompletionItem { + label: "the_field", + source_range: [201; 201), + delete: [201; 201), + insert: "the_field", + kind: Field, + detail: "u32", + score: TypeMatch, + }, + ] + "### + ); + } + + #[test] + fn test_struct_field_completion_in_func_call_with_type_and_name() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct A { another_field: i64, another_good_type: u32, the_field: u32 } + fn test(the_field: u32) -> u32 { the_field } + fn foo(a: A) { + test(a.<|>) + } + ", + ), + @r###" + [ + CompletionItem { + label: "another_field", + source_range: [208; 208), + delete: [208; 208), + insert: "another_field", + kind: Field, + detail: "i64", + }, + CompletionItem { + label: "another_good_type", + source_range: [208; 208), + delete: [208; 208), + insert: "another_good_type", + kind: Field, + detail: "u32", + score: TypeMatch, + }, + CompletionItem { + label: "the_field", + source_range: [208; 208), + delete: [208; 208), + insert: "the_field", + kind: Field, + detail: "u32", + score: TypeAndNameMatch, + }, + ] + "### + ); + } + + #[test] + fn test_struct_field_completion_in_record_lit() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct A { another_field: i64, another_good_type: u32, the_field: u32 } + struct B { my_string: String, my_vec: Vec, the_field: u32 } + fn foo(a: A) { + let b = B { + the_field: a.<|> + }; + } + ", + ), + @r###" + [ + CompletionItem { + label: "another_field", + source_range: [270; 270), + delete: [270; 270), + insert: "another_field", + kind: Field, + detail: "i64", + }, + CompletionItem { + label: "another_good_type", + source_range: [270; 270), + delete: [270; 270), + insert: "another_good_type", + kind: Field, + detail: "u32", + score: TypeMatch, + }, + CompletionItem { + label: "the_field", + source_range: [270; 270), + delete: [270; 270), + insert: "the_field", + kind: Field, + detail: "u32", + score: TypeAndNameMatch, + }, + ] + "### + ); + } + + #[test] + fn test_struct_field_completion_in_record_lit_and_fn_call() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct A { another_field: i64, another_good_type: u32, the_field: u32 } + struct B { my_string: String, my_vec: Vec, the_field: u32 } + fn test(the_field: i64) -> i64 { the_field } + fn foo(a: A) { + let b = B { + the_field: test(a.<|>) + }; + } + ", + ), + @r###" + [ + CompletionItem { + label: "another_field", + source_range: [336; 336), + delete: [336; 336), + insert: "another_field", + kind: Field, + detail: "i64", + score: TypeMatch, + }, + CompletionItem { + label: "another_good_type", + source_range: [336; 336), + delete: [336; 336), + insert: "another_good_type", + kind: Field, + detail: "u32", + }, + CompletionItem { + label: "the_field", + source_range: [336; 336), + delete: [336; 336), + insert: "the_field", + kind: Field, + detail: "u32", + }, + ] + "### + ); + } + + #[test] + fn test_struct_field_completion_in_fn_call_and_record_lit() { + assert_debug_snapshot!( + do_reference_completion( + r" + struct A { another_field: i64, another_good_type: u32, the_field: u32 } + struct B { my_string: String, my_vec: Vec, the_field: u32 } + fn test(the_field: i64) -> i64 { the_field } + fn foo(a: A) { + test(B { + the_field: a.<|> + }); + } + ", + ), + @r###" + [ + CompletionItem { + label: "another_field", + source_range: [328; 328), + delete: [328; 328), + insert: "another_field", + kind: Field, + detail: "i64", + }, + CompletionItem { + label: "another_good_type", + source_range: [328; 328), + delete: [328; 328), + insert: "another_good_type", + kind: Field, + detail: "u32", + score: TypeMatch, + }, + CompletionItem { + label: "the_field", + source_range: [328; 328), + delete: [328; 328), + insert: "the_field", + kind: Field, + detail: "u32", + score: TypeAndNameMatch, + }, + ] + "### + ); + } } -- cgit v1.2.3 From 09a4b78775809677473b39505796785242bcee2f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:46:00 +0200 Subject: Introduce ActiveParameter --- crates/ra_ide/src/call_info.rs | 30 +++++++++++++++++++--- crates/ra_ide/src/completion/completion_context.rs | 7 ++--- crates/ra_ide/src/completion/presentation.rs | 5 ++-- crates/ra_ide/src/lib.rs | 15 ----------- crates/ra_ide/src/syntax_highlighting.rs | 8 +++--- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs index f95b6baf3..5da254a6e 100644 --- a/crates/ra_ide/src/call_info.rs +++ b/crates/ra_ide/src/call_info.rs @@ -19,10 +19,24 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option, - token: SyntaxToken, -) -> Option { +#[derive(Debug)] +pub(crate) struct ActiveParameter { + /// FIXME: should be `Type` and `Name + pub(crate) ty: String, + pub(crate) name: String, +} + +impl ActiveParameter { + pub(crate) fn at(db: &RootDatabase, position: FilePosition) -> Option { + call_info(db, position)?.into_active_parameter() + } + + pub(crate) fn at_token(sema: &Semantics, token: SyntaxToken) -> Option { + call_info_for_token(sema, token)?.into_active_parameter() + } +} + +fn call_info_for_token(sema: &Semantics, token: SyntaxToken) -> Option { // Find the calling expression and it's NameRef let calling_node = FnCallNode::with_node(&token.parent())?; @@ -160,6 +174,14 @@ impl FnCallNode { } impl CallInfo { + fn into_active_parameter(self) -> Option { + let idx = self.active_parameter?; + let ty = self.signature.parameter_types.get(idx)?.clone(); + let name = self.signature.parameter_names.get(idx)?.clone(); + let res = ActiveParameter { ty, name }; + Some(res) + } + fn with_fn(db: &RootDatabase, function: hir::Function) -> Self { let signature = FunctionSignature::from_hir(db, function); diff --git a/crates/ra_ide/src/completion/completion_context.rs b/crates/ra_ide/src/completion/completion_context.rs index dd7c8a873..a76d1ce45 100644 --- a/crates/ra_ide/src/completion/completion_context.rs +++ b/crates/ra_ide/src/completion/completion_context.rs @@ -11,7 +11,7 @@ use ra_syntax::{ }; use ra_text_edit::AtomTextEdit; -use crate::{completion::CompletionConfig, FilePosition}; +use crate::{call_info::ActiveParameter, completion::CompletionConfig, FilePosition}; /// `CompletionContext` is created early during completion to figure out, where /// exactly is the cursor, syntax-wise. @@ -21,7 +21,6 @@ pub(crate) struct CompletionContext<'a> { pub(super) db: &'a RootDatabase, pub(super) config: &'a CompletionConfig, pub(super) offset: TextUnit, - pub(super) file_position: FilePosition, /// The token before the cursor, in the original file. pub(super) original_token: SyntaxToken, /// The token before the cursor, in the macro-expanded file. @@ -34,6 +33,8 @@ pub(crate) struct CompletionContext<'a> { pub(super) record_pat_syntax: Option, pub(super) record_field_syntax: Option, pub(super) impl_def: Option, + /// FIXME: `ActiveParameter` is string-based, which is very wrong + pub(super) active_parameter: Option, pub(super) is_param: bool, /// If a name-binding or reference to a const in a pattern. /// Irrefutable patterns (like let) are excluded. @@ -90,7 +91,6 @@ impl<'a> CompletionContext<'a> { original_token, token, offset: position.offset, - file_position: position, krate, name_ref_syntax: None, function_syntax: None, @@ -99,6 +99,7 @@ impl<'a> CompletionContext<'a> { record_pat_syntax: None, record_field_syntax: None, impl_def: None, + active_parameter: ActiveParameter::at(db, position), is_param: false, is_pat_binding_or_const: false, is_trivial_path: false, diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index ae15f91de..6c0e32408 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -6,7 +6,6 @@ use stdx::SepBy; use test_utils::tested_by; use crate::{ - call_info::call_info, completion::{ completion_item::Builder, CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, @@ -317,8 +316,8 @@ pub(crate) fn compute_score( struct_field.name(ctx.db).to_string(), struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), ) - } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) { - (call_info.active_parameter_name()?, call_info.active_parameter_type()?) + } else if let Some(active_parameter) = &ctx.active_parameter { + (active_parameter.name.clone(), active_parameter.ty.clone()) } else { return None; }; diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs index ddaa30a16..f692fbaa2 100644 --- a/crates/ra_ide/src/lib.rs +++ b/crates/ra_ide/src/lib.rs @@ -129,21 +129,6 @@ pub struct CallInfo { pub active_parameter: Option, } -impl CallInfo { - pub fn active_parameter_type(&self) -> Option { - if let Some(id) = self.active_parameter { - return self.signature.parameter_types.get(id).map(|param_ty| param_ty.clone()); - } - None - } - pub fn active_parameter_name(&self) -> Option { - if let Some(id) = self.active_parameter { - return self.signature.parameter_names.get(id).map(|param_ty| param_ty.clone()); - } - None - } -} - /// `AnalysisHost` stores the current state of the world. #[derive(Debug)] pub struct AnalysisHost { diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs index 93d502875..d9912155b 100644 --- a/crates/ra_ide/src/syntax_highlighting.rs +++ b/crates/ra_ide/src/syntax_highlighting.rs @@ -19,7 +19,7 @@ use ra_syntax::{ }; use rustc_hash::FxHashMap; -use crate::{call_info::call_info_for_token, Analysis, FileId}; +use crate::{call_info::ActiveParameter, Analysis, FileId}; pub(crate) use html::highlight_as_html; pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag}; @@ -364,10 +364,8 @@ fn highlight_injection( literal: ast::RawString, expanded: SyntaxToken, ) -> Option<()> { - let call_info = call_info_for_token(&sema, expanded)?; - let idx = call_info.active_parameter?; - let name = call_info.signature.parameter_names.get(idx)?; - if !name.starts_with("ra_fixture") { + let active_parameter = ActiveParameter::at_token(&sema, expanded)?; + if !active_parameter.name.starts_with("ra_fixture") { return None; } let value = literal.value()?; -- cgit v1.2.3 From 647683b9bbbbac209b7cb1d2d1c2e1d50ffdfd11 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:48:32 +0200 Subject: Add test marks --- crates/ra_ide/src/completion/presentation.rs | 4 ++++ crates/ra_ide/src/marks.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 6c0e32408..78df9cbdb 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs @@ -311,12 +311,14 @@ pub(crate) fn compute_score( name: &str, ) -> Option { let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax { + tested_by!(test_struct_field_completion_in_record_lit); let (struct_field, _local) = ctx.sema.resolve_record_field(record_field)?; ( struct_field.name(ctx.db).to_string(), struct_field.signature_ty(ctx.db).display(ctx.db).to_string(), ) } else if let Some(active_parameter) = &ctx.active_parameter { + tested_by!(test_struct_field_completion_in_func_call); (active_parameter.name.clone(), active_parameter.ty.clone()) } else { return None; @@ -1072,6 +1074,7 @@ mod tests { #[test] fn test_struct_field_completion_in_func_call() { + covers!(test_struct_field_completion_in_func_call); assert_debug_snapshot!( do_reference_completion( r" @@ -1161,6 +1164,7 @@ mod tests { #[test] fn test_struct_field_completion_in_record_lit() { + covers!(test_struct_field_completion_in_func_call); assert_debug_snapshot!( do_reference_completion( r" diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs index eee44e886..bea30fe2a 100644 --- a/crates/ra_ide/src/marks.rs +++ b/crates/ra_ide/src/marks.rs @@ -9,4 +9,6 @@ test_utils::marks!( search_filters_by_range dont_insert_macro_call_parens_unncessary self_fulfilling_completion + test_struct_field_completion_in_func_call + test_struct_field_completion_in_record_lit ); -- cgit v1.2.3 From 88d243c742ecd724372c4293b6b6ea293bae2d17 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 24 Apr 2020 01:52:26 +0200 Subject: Don't set sortText I might be reading this wrong, but it looks like we are setting it to essentially arbitrary string at the moment, as there are no defined order on the items in the *set* of completions. --- crates/rust-analyzer/src/conv.rs | 21 ++++++++------------- crates/rust-analyzer/src/main_loop/handlers.rs | 7 ++----- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/crates/rust-analyzer/src/conv.rs b/crates/rust-analyzer/src/conv.rs index 7e30956cc..098ee369c 100644 --- a/crates/rust-analyzer/src/conv.rs +++ b/crates/rust-analyzer/src/conv.rs @@ -9,10 +9,10 @@ use lsp_types::{ TextDocumentPositionParams, Url, VersionedTextDocumentIdentifier, WorkspaceEdit, }; use ra_ide::{ - translate_offset_with_edit, CompletionItem, CompletionItemKind, CompletionScore, FileId, - FilePosition, FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, - HighlightTag, InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, - RangeInfo, ReferenceAccess, Severity, SourceChange, SourceFileEdit, + translate_offset_with_edit, CompletionItem, CompletionItemKind, FileId, FilePosition, + FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, + InlayHint, InlayKind, InsertTextFormat, LineCol, LineIndex, NavigationTarget, RangeInfo, + ReferenceAccess, Severity, SourceChange, SourceFileEdit, }; use ra_syntax::{SyntaxKind, TextRange, TextUnit}; use ra_text_edit::{AtomTextEdit, TextEdit}; @@ -114,10 +114,10 @@ impl Conv for Severity { } } -impl ConvWith<(&LineIndex, LineEndings, &mut usize)> for CompletionItem { +impl ConvWith<(&LineIndex, LineEndings)> for CompletionItem { type Output = ::lsp_types::CompletionItem; - fn conv_with(self, ctx: (&LineIndex, LineEndings, &mut usize)) -> ::lsp_types::CompletionItem { + fn conv_with(self, ctx: (&LineIndex, LineEndings)) -> ::lsp_types::CompletionItem { let mut additional_text_edits = Vec::new(); let mut text_edit = None; // LSP does not allow arbitrary edits in completion, so we have to do a @@ -165,13 +165,8 @@ impl ConvWith<(&LineIndex, LineEndings, &mut usize)> for CompletionItem { ..Default::default() }; - if let Some(score) = self.score() { - match score { - CompletionScore::TypeAndNameMatch => res.preselect = Some(true), - CompletionScore::TypeMatch => {} - } - res.sort_text = Some(format!("{:02}", *ctx.2)); - *ctx.2 += 1; + if self.score().is_some() { + res.preselect = Some(true) } if self.deprecated() { diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs index ee669f383..41d9fe344 100644 --- a/crates/rust-analyzer/src/main_loop/handlers.rs +++ b/crates/rust-analyzer/src/main_loop/handlers.rs @@ -423,11 +423,8 @@ pub fn handle_completion( }; let line_index = world.analysis().file_line_index(position.file_id)?; let line_endings = world.file_line_endings(position.file_id); - let mut count_sort_text_item = 0usize; - let items: Vec = items - .into_iter() - .map(|item| item.conv_with((&line_index, line_endings, &mut count_sort_text_item))) - .collect(); + let items: Vec = + items.into_iter().map(|item| item.conv_with((&line_index, line_endings))).collect(); Ok(Some(items.into())) } -- cgit v1.2.3