Remove redundant code

This commit is contained in:
Kirill Bulatov 2020-12-03 00:27:26 +02:00
parent 50e06ee95a
commit 68a747efe0
8 changed files with 79 additions and 102 deletions

View file

@ -15,12 +15,12 @@ pub struct CompletionConfig {
pub add_call_argument_snippets: bool, pub add_call_argument_snippets: bool,
pub snippet_cap: Option<SnippetCap>, pub snippet_cap: Option<SnippetCap>,
pub merge: Option<MergeBehaviour>, pub merge: Option<MergeBehaviour>,
/// A set of capabilities, enabled on the cliend and supported on the server. /// A set of capabilities, enabled on the client and supported on the server.
pub resolve_capabilities: FxHashSet<CompletionResolveCapability>, pub active_resolve_capabilities: FxHashSet<CompletionResolveCapability>,
} }
/// A resolve capability, supported on a server. /// A resolve capability, supported on the server.
/// If the client registers any of those in its completion resolve capabilities, /// If the client registers any completion resolve capabilities,
/// the server is able to render completion items' corresponding fields later, /// the server is able to render completion items' corresponding fields later,
/// not during an initial completion item request. /// not during an initial completion item request.
/// See https://github.com/rust-analyzer/rust-analyzer/issues/6366 for more details. /// See https://github.com/rust-analyzer/rust-analyzer/issues/6366 for more details.
@ -37,8 +37,11 @@ impl CompletionConfig {
} }
/// Whether the completions' additional edits are calculated later, during a resolve request or not. /// Whether the completions' additional edits are calculated later, during a resolve request or not.
pub fn should_resolve_additional_edits_immediately(&self) -> bool { /// See `CompletionResolveCapability` for the details.
!self.resolve_capabilities.contains(&CompletionResolveCapability::AdditionalTextEdits) pub fn resolve_edits_immediately(&self) -> bool {
!self
.active_resolve_capabilities
.contains(&CompletionResolveCapability::AdditionalTextEdits)
} }
} }
@ -56,7 +59,7 @@ impl Default for CompletionConfig {
add_call_argument_snippets: true, add_call_argument_snippets: true,
snippet_cap: Some(SnippetCap { _private: () }), snippet_cap: Some(SnippetCap { _private: () }),
merge: Some(MergeBehaviour::Full), merge: Some(MergeBehaviour::Full),
resolve_capabilities: FxHashSet::default(), active_resolve_capabilities: FxHashSet::default(),
} }
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

@ -388,7 +388,7 @@ impl Config {
} }
self.completion.allow_snippets(false); self.completion.allow_snippets(false);
self.completion.resolve_capabilities = self.completion.active_resolve_capabilities =
enabled_completions_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) = &doc_caps.completion {
if let Some(completion_item) = &completion.completion_item { if let Some(completion_item) = &completion.completion_item {

View file

@ -8,9 +8,10 @@ use std::{
}; };
use ide::{ use ide::{
FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, NavigationTarget, Query, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData, ImportToAdd, LineIndex,
RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
}; };
use ide_db::helpers::{insert_use, mod_path_to_ast};
use itertools::Itertools; use itertools::Itertools;
use lsp_server::ErrorCode; use lsp_server::ErrorCode;
use lsp_types::{ use lsp_types::{
@ -35,9 +36,9 @@ use crate::{
config::RustfmtConfig, config::RustfmtConfig,
from_json, from_proto, from_json, from_proto,
global_state::{CompletionResolveData, GlobalState, GlobalStateSnapshot}, global_state::{CompletionResolveData, GlobalState, GlobalStateSnapshot},
line_endings::LineEndings,
lsp_ext::{self, InlayHint, InlayHintsParams}, lsp_ext::{self, InlayHint, InlayHintsParams},
to_proto::{self, append_import_edits}, to_proto, LspError, Result,
LspError, Result,
}; };
pub(crate) fn handle_analyzer_status( pub(crate) fn handle_analyzer_status(
@ -577,13 +578,10 @@ pub(crate) fn handle_completion(
.into_iter() .into_iter()
.enumerate() .enumerate()
.flat_map(|(item_index, item)| { .flat_map(|(item_index, item)| {
let mut new_completion_items = to_proto::completion_item( let mut new_completion_items =
&line_index, to_proto::completion_item(&line_index, line_endings, item.clone());
line_endings,
item.clone(),
snap.config.completion.should_resolve_additional_edits_immediately(),
);
if !snap.config.completion.active_resolve_capabilities.is_empty() {
let item_id = serde_json::to_value(&item_index) let item_id = serde_json::to_value(&item_index)
.expect(&format!("Should be able to serialize usize value {}", item_index)); .expect(&format!("Should be able to serialize usize value {}", item_index));
completion_resolve_data completion_resolve_data
@ -591,6 +589,8 @@ pub(crate) fn handle_completion(
for new_item in &mut new_completion_items { for new_item in &mut new_completion_items {
new_item.data = Some(item_id.clone()); new_item.data = Some(item_id.clone());
} }
}
new_completion_items new_completion_items
}) })
.collect(); .collect();
@ -620,7 +620,7 @@ pub(crate) fn handle_resolve_completion(
}; };
let snap = &global_state.snapshot(); let snap = &global_state.snapshot();
for supported_completion_resolve_cap in &snap.config.completion.resolve_capabilities { for supported_completion_resolve_cap in &snap.config.completion.active_resolve_capabilities {
match supported_completion_resolve_cap { match supported_completion_resolve_cap {
ide::CompletionResolveCapability::AdditionalTextEdits => { ide::CompletionResolveCapability::AdditionalTextEdits => {
// FIXME actually add all additional edits here? // FIXME actually add all additional edits here?
@ -1598,3 +1598,44 @@ fn should_skip_target(runnable: &Runnable, cargo_spec: Option<&CargoTargetSpec>)
_ => false, _ => false,
} }
} }
fn append_import_edits(
completion: &mut lsp_types::CompletionItem,
import_to_add: &ImportToAdd,
line_index: &LineIndex,
line_endings: LineEndings,
) {
let new_edits = import_into_edits(import_to_add, line_index, line_endings);
if let Some(original_additional_edits) = completion.additional_text_edits.as_mut() {
if let Some(mut new_edits) = new_edits {
original_additional_edits.extend(new_edits.drain(..))
}
} else {
completion.additional_text_edits = new_edits;
}
}
fn import_into_edits(
import_to_add: &ImportToAdd,
line_index: &LineIndex,
line_endings: LineEndings,
) -> Option<Vec<lsp_types::TextEdit>> {
let _p = profile::span("add_import_edits");
let rewriter = insert_use::insert_use(
&import_to_add.import_scope,
mod_path_to_ast(&import_to_add.import_path),
import_to_add.merge_behaviour,
);
let old_ast = rewriter.rewrite_root()?;
let mut import_insert = TextEdit::builder();
algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert);
let import_edit = import_insert.finish();
Some(
import_edit
.into_iter()
.map(|indel| to_proto::text_edit(line_index, line_endings, indel))
.collect_vec(),
)
}

View file

@ -7,16 +7,12 @@ use std::{
use ide::{ use ide::{
Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation,
FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange, FileSystemEdit, Fold, FoldKind, Highlight, HighlightModifier, HighlightTag, HighlightedRange,
ImportToAdd, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, Indel, InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget,
NavigationTarget, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, ReferenceAccess, ResolvedAssist, Runnable, Severity, SourceChange, SourceFileEdit, TextEdit,
SourceFileEdit, TextEdit,
};
use ide_db::{
base_db::{FileId, FileRange},
helpers::{insert_use, mod_path_to_ast},
}; };
use ide_db::base_db::{FileId, FileRange};
use itertools::Itertools; use itertools::Itertools;
use syntax::{algo, SyntaxKind, TextRange, TextSize}; use syntax::{SyntaxKind, TextRange, TextSize};
use crate::{ use crate::{
cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot, cargo_target_spec::CargoTargetSpec, global_state::GlobalStateSnapshot,
@ -162,7 +158,6 @@ pub(crate) fn completion_item(
line_index: &LineIndex, line_index: &LineIndex,
line_endings: LineEndings, line_endings: LineEndings,
completion_item: CompletionItem, completion_item: CompletionItem,
should_resolve_additional_edits_immediately: bool,
) -> Vec<lsp_types::CompletionItem> { ) -> Vec<lsp_types::CompletionItem> {
fn set_score(res: &mut lsp_types::CompletionItem, label: &str) { fn set_score(res: &mut lsp_types::CompletionItem, label: &str) {
res.preselect = Some(true); res.preselect = Some(true);
@ -238,13 +233,7 @@ pub(crate) fn completion_item(
for mut r in all_results.iter_mut() { for mut r in all_results.iter_mut() {
r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format())); r.insert_text_format = Some(insert_text_format(completion_item.insert_text_format()));
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);
} }
}
}
all_results all_results
} }
@ -828,47 +817,6 @@ pub(crate) fn markup_content(markup: Markup) -> lsp_types::MarkupContent {
lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value } lsp_types::MarkupContent { kind: lsp_types::MarkupKind::Markdown, value }
} }
pub(crate) fn import_into_edits(
import_to_add: &ImportToAdd,
line_index: &LineIndex,
line_endings: LineEndings,
) -> Option<Vec<lsp_types::TextEdit>> {
let _p = profile::span("add_import_edits");
let rewriter = insert_use::insert_use(
&import_to_add.import_scope,
mod_path_to_ast(&import_to_add.import_path),
import_to_add.merge_behaviour,
);
let old_ast = rewriter.rewrite_root()?;
let mut import_insert = TextEdit::builder();
algo::diff(&old_ast, &rewriter.rewrite(&old_ast)).into_text_edit(&mut import_insert);
let import_edit = import_insert.finish();
Some(
import_edit
.into_iter()
.map(|indel| text_edit(line_index, line_endings, indel))
.collect_vec(),
)
}
pub(crate) fn append_import_edits(
completion: &mut lsp_types::CompletionItem,
import_to_add: &ImportToAdd,
line_index: &LineIndex,
line_endings: LineEndings,
) {
let new_edits = import_into_edits(import_to_add, line_index, line_endings);
if let Some(original_additional_edits) = completion.additional_text_edits.as_mut() {
if let Some(mut new_edits) = new_edits {
original_additional_edits.extend(new_edits.drain(..))
}
} else {
completion.additional_text_edits = new_edits;
}
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use ide::Analysis; use ide::Analysis;
@ -897,7 +845,7 @@ mod tests {
.unwrap() .unwrap()
.into_iter() .into_iter()
.filter(|c| c.label().ends_with("arg")) .filter(|c| c.label().ends_with("arg"))
.map(|c| completion_item(&line_index, LineEndings::Unix, c, true)) .map(|c| completion_item(&line_index, LineEndings::Unix, c))
.flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text))) .flat_map(|comps| comps.into_iter().map(|c| (c.label, c.sort_text)))
.collect(); .collect();
expect_test::expect![[r#" expect_test::expect![[r#"