Refactor the code

This commit is contained in:
Kirill Bulatov 2020-12-03 00:13:32 +02:00
parent d9bd1f171d
commit 50e06ee95a
11 changed files with 48 additions and 34 deletions

View File

@ -15,9 +15,15 @@ pub struct CompletionConfig {
pub add_call_argument_snippets: bool,
pub snippet_cap: Option<SnippetCap>,
pub merge: Option<MergeBehaviour>,
/// A set of capabilities, enabled on the cliend and supported on the server.
pub resolve_capabilities: FxHashSet<CompletionResolveCapability>,
}
/// A resolve capability, supported on a server.
/// If the client registers any of those in its completion resolve capabilities,
/// the server is able to render completion items' corresponding fields later,
/// not during an initial completion item request.
/// See https://github.com/rust-analyzer/rust-analyzer/issues/6366 for more details.
#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq)]
pub enum CompletionResolveCapability {
Documentation,
@ -30,7 +36,8 @@ impl CompletionConfig {
self.snippet_cap = if yes { Some(SnippetCap { _private: () }) } else { None }
}
pub fn should_resolve_immediately(&self) -> bool {
/// Whether the completions' additional edits are calculated later, during a resolve request or not.
pub fn should_resolve_additional_edits_immediately(&self) -> bool {
!self.resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits)
}
}

View File

@ -67,8 +67,7 @@ pub struct CompletionItem {
/// possible match.
ref_match: Option<(Mutability, CompletionScore)>,
/// The data later to be used in the `completionItem/resolve` response
/// to add the insert import edit.
/// The import data to add to completion's edits.
import_to_add: Option<ImportToAdd>,
}

View File

@ -194,7 +194,10 @@ impl<'a> Render<'a> {
local_name,
)
.kind(CompletionItemKind::UnresolvedReference)
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
.add_import(
import_to_add,
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
)
.build();
return Some(item);
}
@ -249,7 +252,10 @@ impl<'a> Render<'a> {
let item = item
.kind(kind)
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
.add_import(
import_to_add,
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
)
.set_documentation(docs)
.set_ref_match(ref_match)
.build();

View File

@ -71,7 +71,10 @@ impl<'a> EnumVariantRender<'a> {
.kind(CompletionItemKind::EnumVariant)
.set_documentation(self.variant.docs(self.ctx.db()))
.set_deprecated(self.ctx.is_deprecated(self.variant))
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
.add_import(
import_to_add,
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
)
.detail(self.detail());
if self.variant_kind == StructKind::Tuple {

View File

@ -47,7 +47,10 @@ impl<'a> FunctionRender<'a> {
.set_deprecated(self.ctx.is_deprecated(self.func))
.detail(self.detail())
.add_call_parens(self.ctx.completion, self.name, params)
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
.add_import(
import_to_add,
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
)
.build()
}

View File

@ -50,7 +50,10 @@ impl<'a> MacroRender<'a> {
.kind(CompletionItemKind::Macro)
.set_documentation(self.docs.clone())
.set_deprecated(self.ctx.is_deprecated(self.macro_))
.add_import(import_to_add, self.ctx.completion.config.should_resolve_immediately())
.add_import(
import_to_add,
self.ctx.completion.config.should_resolve_additional_edits_immediately(),
)
.detail(self.detail());
let needs_bang = self.needs_bang();

View File

@ -97,7 +97,6 @@ pub(crate) fn check_edit_with_config(
.unwrap_or_else(|| panic!("can't find {:?} completion in {:#?}", what, completions));
let mut actual = db.file_text(position.file_id).to_string();
completion.text_edit().apply(&mut actual);
// git how to apply imports now?
assert_eq_text!(&ra_fixture_after, &actual)
}

View File

@ -32,7 +32,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
})),
hover_provider: Some(HoverProviderCapability::Simple(true)),
completion_provider: Some(CompletionOptions {
resolve_provider: Some(true),
resolve_provider: completions_resolve_provider(client_caps),
trigger_characters: Some(vec![":".to_string(), ".".to_string()]),
work_done_progress_options: WorkDoneProgressOptions { work_done_progress: None },
}),
@ -50,9 +50,7 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
document_symbol_provider: Some(OneOf::Left(true)),
workspace_symbol_provider: Some(OneOf::Left(true)),
code_action_provider: Some(code_action_capabilities(client_caps)),
code_lens_provider: Some(CodeLensOptions {
resolve_provider: resolve_provider(client_caps),
}),
code_lens_provider: Some(CodeLensOptions { resolve_provider: Some(true) }),
document_formatting_provider: Some(OneOf::Left(true)),
document_range_formatting_provider: None,
document_on_type_formatting_provider: Some(DocumentOnTypeFormattingOptions {
@ -97,16 +95,16 @@ pub fn server_capabilities(client_caps: &ClientCapabilities) -> ServerCapabiliti
}
}
fn resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
if enabled_resolve_capabilities(client_caps)?.is_empty() {
fn completions_resolve_provider(client_caps: &ClientCapabilities) -> Option<bool> {
if enabled_completions_resolve_capabilities(client_caps)?.is_empty() {
None
} else {
Some(true)
}
}
/// Parses client capabilities and returns all that rust-analyzer supports.
pub fn enabled_resolve_capabilities(
/// Parses client capabilities and returns all completion resolve capabilities rust-analyzer supports.
pub fn enabled_completions_resolve_capabilities(
caps: &ClientCapabilities,
) -> Option<FxHashSet<CompletionResolveCapability>> {
Some(

View File

@ -19,7 +19,7 @@ use rustc_hash::FxHashSet;
use serde::Deserialize;
use vfs::AbsPathBuf;
use crate::{caps::enabled_resolve_capabilities, diagnostics::DiagnosticsMapConfig};
use crate::{caps::enabled_completions_resolve_capabilities, diagnostics::DiagnosticsMapConfig};
#[derive(Debug, Clone)]
pub struct Config {
@ -389,7 +389,7 @@ impl Config {
self.completion.allow_snippets(false);
self.completion.resolve_capabilities =
enabled_resolve_capabilities(caps).unwrap_or_default();
enabled_completions_resolve_capabilities(caps).unwrap_or_default();
if let Some(completion) = &doc_caps.completion {
if let Some(completion_item) = &completion.completion_item {
if let Some(value) = completion_item.snippet_support {

View File

@ -581,7 +581,7 @@ pub(crate) fn handle_completion(
&line_index,
line_endings,
item.clone(),
&snap.config.completion.resolve_capabilities,
snap.config.completion.should_resolve_additional_edits_immediately(),
);
let item_id = serde_json::to_value(&item_index)

View File

@ -5,10 +5,10 @@ use std::{
};
use ide::{
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, CompletionResolveCapability,
Documentation, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag,
HighlightedRange, ImportToAdd, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex,
Markup, NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
ImportToAdd, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup,
NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange,
SourceFileEdit, TextEdit,
};
use ide_db::{
@ -16,7 +16,6 @@ use ide_db::{
helpers::{insert_use, mod_path_to_ast},
};
use itertools::Itertools;
use rustc_hash::FxHashSet;
use syntax::{algo, SyntaxKind, TextRange, TextSize};
use crate::{
@ -163,7 +162,7 @@ pub(crate) fn completion_item(
line_index: &LineIndex,
line_endings: LineEndings,
completion_item: CompletionItem,
resolve_capabilities: &FxHashSet<CompletionResolveCapability>,
should_resolve_additional_edits_immediately: bool,
) -> Vec<lsp_types::CompletionItem> {
fn set_score(res: &mut lsp_types::CompletionItem, label: &str) {
res.preselect = Some(true);
@ -237,14 +236,12 @@ pub(crate) fn completion_item(
None => vec![res],
};
let unapplied_import_data = completion_item.import_to_add().filter(|_| {
!resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits)
});
for mut r in all_results.iter_mut() {
r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format()));
if let Some(unapplied_import_data) = unapplied_import_data {
append_import_edits(r, unapplied_import_data, line_index, line_endings);
if !should_resolve_additional_edits_immediately {
if let Some(unapplied_import_data) = completion_item.import_to_add() {
append_import_edits(r, unapplied_import_data, line_index, line_endings);
}
}
}
@ -891,7 +888,6 @@ mod tests {
let (offset, text) = test_utils::extract_offset(fixture);
let line_index = LineIndex::new(&text);
let (analysis, file_id) = Analysis::from_single_file(text);
let resolve_caps = FxHashSet::default();
let completions: Vec<(String, Option<String>)> = analysis
.completions(
&ide::CompletionConfig::default(),
@ -901,7 +897,7 @@ mod tests {
.unwrap()
.into_iter()
.filter(|c| c.label().ends_with("arg"))
.map(|c| completion_item(&line_index, LineEndings::Unix, c, &resolve_caps))
.map(|c| completion_item(&line_index, LineEndings::Unix, c, true))
.flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text)))
.collect();
expect_test::expect![[r#"