aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/completion/completion_item.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_ide/src/completion/completion_item.rs')
-rw-r--r--crates/ra_ide/src/completion/completion_item.rs106
1 files changed, 48 insertions, 58 deletions
diff --git a/crates/ra_ide/src/completion/completion_item.rs b/crates/ra_ide/src/completion/completion_item.rs
index 84d51bafe..a3ae9c86b 100644
--- a/crates/ra_ide/src/completion/completion_item.rs
+++ b/crates/ra_ide/src/completion/completion_item.rs
@@ -1,11 +1,11 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3use std::{cmp::Ordering, fmt}; 3use std::fmt;
4 4
5use super::completion_context::CompletionContext; 5use super::completion_context::CompletionContext;
6use crate::CallInfo; 6use crate::call_info::call_info;
7use hir::{Documentation, HirDisplay}; 7use hir::{Documentation, HirDisplay};
8use ra_syntax::{ast::RecordField, TextRange}; 8use ra_syntax::TextRange;
9use ra_text_edit::TextEdit; 9use ra_text_edit::TextEdit;
10 10
11/// `CompletionItem` describes a single completion variant in the editor pop-up. 11/// `CompletionItem` describes a single completion variant in the editor pop-up.
@@ -199,6 +199,10 @@ impl CompletionItem {
199 self.score.clone() 199 self.score.clone()
200 } 200 }
201 201
202 pub fn set_score(&mut self, score: CompletionScore) {
203 self.score = Some(score);
204 }
205
202 pub fn trigger_call_info(&self) -> bool { 206 pub fn trigger_call_info(&self) -> bool {
203 self.trigger_call_info 207 self.trigger_call_info
204 } 208 }
@@ -300,6 +304,47 @@ impl Builder {
300 self.deprecated = Some(deprecated); 304 self.deprecated = Some(deprecated);
301 self 305 self
302 } 306 }
307 #[allow(unused)]
308 pub(crate) fn compute_score(mut self, ctx: &CompletionContext) -> Builder {
309 let (active_name, active_type) = if let Some(record_field) = &ctx.record_field_syntax {
310 if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) {
311 (
312 struct_field.name(ctx.db).to_string(),
313 struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
314 )
315 } else {
316 return self;
317 }
318 } else if let Some(call_info) = call_info(ctx.db, ctx.file_position) {
319 if call_info.active_parameter_type().is_some()
320 && call_info.active_parameter_name().is_some()
321 {
322 (
323 call_info.active_parameter_name().unwrap(),
324 call_info.active_parameter_type().unwrap(),
325 )
326 } else {
327 return self;
328 }
329 } else {
330 return self;
331 };
332
333 // Compute score
334 // For the same type
335 if let Some(a_parameter_type) = &self.detail {
336 if &active_type == a_parameter_type {
337 // If same type + same name then go top position
338 if active_name == self.label {
339 return self.set_score(CompletionScore::TypeAndNameMatch);
340 } else {
341 return self.set_score(CompletionScore::TypeMatch);
342 }
343 }
344 }
345
346 self
347 }
303 pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder { 348 pub(crate) fn set_score(mut self, score: CompletionScore) -> Builder {
304 self.score = Some(score); 349 self.score = Some(score);
305 self 350 self
@@ -316,12 +361,6 @@ impl<'a> Into<CompletionItem> for Builder {
316 } 361 }
317} 362}
318 363
319#[derive(Debug)]
320pub(crate) enum ScoreOption {
321 CallFn(CallInfo),
322 RecordField(RecordField),
323}
324
325#[derive(Debug, Clone)] 364#[derive(Debug, Clone)]
326pub enum CompletionScore { 365pub enum CompletionScore {
327 TypeMatch, 366 TypeMatch,
@@ -332,7 +371,6 @@ pub enum CompletionScore {
332#[derive(Debug, Default)] 371#[derive(Debug, Default)]
333pub(crate) struct Completions { 372pub(crate) struct Completions {
334 buf: Vec<CompletionItem>, 373 buf: Vec<CompletionItem>,
335 score_option: Option<ScoreOption>,
336} 374}
337 375
338impl Completions { 376impl Completions {
@@ -346,54 +384,6 @@ impl Completions {
346 { 384 {
347 items.into_iter().for_each(|item| self.add(item.into())) 385 items.into_iter().for_each(|item| self.add(item.into()))
348 } 386 }
349
350 pub(crate) fn with_score_option(&mut self, score_option: ScoreOption) {
351 self.score_option = Some(score_option);
352 }
353
354 pub(crate) fn compute_score(&mut self, ctx: &CompletionContext) {
355 if self.score_option.is_none() {
356 return;
357 }
358
359 let (active_name, active_type) = match self.score_option.as_ref().unwrap() {
360 ScoreOption::CallFn(call_info) => {
361 if call_info.active_parameter_type().is_none()
362 || call_info.active_parameter_name().is_none()
363 {
364 return;
365 }
366 (
367 call_info.active_parameter_name().unwrap(),
368 call_info.active_parameter_type().unwrap(),
369 )
370 }
371 ScoreOption::RecordField(record_field) => {
372 if let Some((struct_field, _)) = ctx.sema.resolve_record_field(record_field) {
373 (
374 struct_field.name(ctx.db).to_string(),
375 struct_field.signature_ty(ctx.db).display(ctx.db).to_string(),
376 )
377 } else {
378 return;
379 }
380 }
381 };
382
383 for completion_item in &mut self.buf {
384 // For the same type
385 if let Some(a_parameter_type) = &completion_item.detail {
386 if &active_type == a_parameter_type {
387 // If same type + same name then go top position
388 if active_name == completion_item.label {
389 completion_item.score = Some(CompletionScore::TypeAndNameMatch);
390 } else {
391 completion_item.score = Some(CompletionScore::TypeMatch);
392 }
393 }
394 }
395 }
396 }
397} 387}
398 388
399impl Into<Vec<CompletionItem>> for Completions { 389impl Into<Vec<CompletionItem>> for Completions {