Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions crates/ide-completion/src/context/analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2094,12 +2094,12 @@ fn next_non_trivia_token(e: impl Into<SyntaxElement>) -> Option<SyntaxToken> {
}

fn next_non_trivia_sibling(ele: SyntaxElement) -> Option<SyntaxElement> {
let mut e = ele.next_sibling_or_token();
while let Some(inner) = e {
if !inner.kind().is_trivia() {
return Some(inner);
let mut e = ele;
while let Some(next) = e.next_sibling_or_token() {
if !next.kind().is_trivia() {
return Some(next);
} else {
e = inner.next_sibling_or_token();
e = next;
}
}
None
Expand Down
46 changes: 44 additions & 2 deletions crates/ide-completion/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ pub struct CompletionItem {
pub documentation: Option<Documentation<'static>>,

/// Whether this item is marked as deprecated
///
/// NOTE: this field is used in the LSP protocol. For the use of this information in completion
/// scoring, see [`CompletionRelevance::is_deprecated`].
pub deprecated: bool,

/// If completing a function call, ask the editor to show parameter popup
Expand Down Expand Up @@ -186,6 +189,11 @@ pub struct CompletionRelevance {
pub is_skipping_completion: bool,
/// if inherent impl already exists in current module, user may not want to implement it again.
pub has_local_inherent_impl: bool,
/// Set when the completion item is deprecated.
///
/// NOTE: This is duplicated from [`CompletionItem::deprecated`] in order to allow using this
/// information in the calculation of the relevance score.
pub is_deprecated: bool,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub struct CompletionRelevanceTraitInfo {
Expand Down Expand Up @@ -278,6 +286,7 @@ impl CompletionRelevance {
function,
is_skipping_completion,
has_local_inherent_impl,
is_deprecated,
} = self;

// only applicable for completions within use items
Expand Down Expand Up @@ -354,6 +363,11 @@ impl CompletionRelevance {
score -= 5;
}

// lower rank for deprecated items
if is_deprecated {
score -= 5;
}

score
}

Expand Down Expand Up @@ -582,6 +596,9 @@ impl Builder {
None => TextEdit::replace(self.source_range, insert_text),
};

// Copy `deprecated` to `self.relevance.is_deprecated`
let relevance = CompletionRelevance { is_deprecated: self.deprecated, ..self.relevance };

let import_to_add = self
.imports_to_add
.into_iter()
Expand All @@ -603,7 +620,7 @@ impl Builder {
kind: self.kind,
deprecated: self.deprecated,
trigger_call_info: self.trigger_call_info,
relevance: self.relevance,
relevance,
ref_match: self.ref_match,
import_to_add,
}
Expand Down Expand Up @@ -674,6 +691,15 @@ impl Builder {
self
}
pub(crate) fn set_relevance(&mut self, relevance: CompletionRelevance) -> &mut Builder {
// The default value of `CompletionRelevance.is_deprecated` is `false`, so it being `true`
// would mean it was set manually. Advise using the other function instead.
//
// This is technically not necessary, because `deprecated` will get reconciled in
// `Builder::build` anyway -- it just helps keep the callers consistent.
assert!(
!relevance.is_deprecated,
"`deprecated` should be set using `Builder::set_deprecated` instead"
);
self.relevance = relevance;
self
}
Expand Down Expand Up @@ -708,9 +734,25 @@ mod tests {
use test_utils::assert_eq_text;

use super::{
CompletionRelevance, CompletionRelevancePostfixMatch, CompletionRelevanceTypeMatch,
CompletionItem, CompletionItemKind, CompletionRelevance, CompletionRelevancePostfixMatch,
CompletionRelevanceTypeMatch,
};

#[test]
fn builder_deprecated_from_set_deprecated() {
// setting just `item.deprecated` also sets `item.relevance.is_deprecated`
let mut builder = CompletionItem::new(
CompletionItemKind::Expression,
Default::default(),
"",
syntax::Edition::DEFAULT,
);
builder.set_deprecated(true);
let item = builder.build(&Default::default());
assert!(item.deprecated);
assert!(item.relevance.is_deprecated);
}

/// Check that these are CompletionRelevance are sorted in ascending order
/// by their relevance score.
///
Expand Down
Loading