This commit is contained in:
Kirill Bulatov 2020-12-06 23:58:15 +02:00
parent 6badf705b3
commit 19cfa5802e
4 changed files with 34 additions and 35 deletions

View file

@ -141,7 +141,7 @@ pub fn resolve_completion_edits(
position: FilePosition,
full_import_path: &str,
imported_name: &str,
) -> Option<TextEdit> {
) -> Option<Vec<TextEdit>> {
let ctx = CompletionContext::new(db, position, config)?;
let anchor = ctx.name_ref_syntax.as_ref()?;
let import_scope = ImportScope::find_insert_use_container(anchor.syntax(), &ctx.sema)?;
@ -156,7 +156,9 @@ pub fn resolve_completion_edits(
})
.find(|mod_path| mod_path.to_string() == full_import_path)?;
ImportEdit { import_path, import_scope, merge_behaviour: config.merge }.to_text_edit()
ImportEdit { import_path, import_scope, merge_behaviour: config.merge }
.to_text_edit()
.map(|edit| vec![edit])
}
#[cfg(test)]

View file

@ -487,7 +487,6 @@ impl Analysis {
imported_name,
)
})?
.map(|edit| vec![edit])
.unwrap_or_default())
}

View file

@ -8,9 +8,8 @@ use std::{
};
use ide::{
CompletionConfig, CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction,
HoverGotoTypeData, NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope,
TextEdit,
CompletionResolveCapability, FileId, FilePosition, FileRange, HoverAction, HoverGotoTypeData,
NavigationTarget, Query, RangeInfo, Runnable, RunnableKind, SearchScope, TextEdit,
};
use itertools::Itertools;
use lsp_server::ErrorCode;
@ -578,14 +577,11 @@ pub(crate) fn handle_completion(
let mut new_completion_items =
to_proto::completion_item(&line_index, line_endings, item.clone());
for new_item in &mut new_completion_items {
let _ = fill_resolve_data(
&mut new_item.data,
&item,
&snap.config.completion,
&text_document_position,
)
.take();
if snap.config.completion.resolve_additional_edits_lazily() {
for new_item in &mut new_completion_items {
let _ = fill_resolve_data(&mut new_item.data, &item, &text_document_position)
.take();
}
}
new_completion_items
@ -600,12 +596,12 @@ pub(crate) fn handle_completion_resolve(
snap: GlobalStateSnapshot,
mut original_completion: CompletionItem,
) -> Result<CompletionItem> {
let _p = profile::span("handle_resolve_completion");
let _p = profile::span("handle_completion_resolve");
if !all_edits_are_disjoint(&original_completion, &[]) {
return Err(LspError::new(
ErrorCode::InvalidParams as i32,
"Received a completion with disjoint edits".into(),
"Received a completion with overlapping edits, this is not LSP-compliant".into(),
)
.into());
}
@ -635,7 +631,7 @@ pub(crate) fn handle_completion_resolve(
let line_endings = snap.file_line_endings(file_id);
let offset = from_proto::offset(&line_index, resolve_data.position.position);
let mut additional_edits = snap
let additional_edits = snap
.analysis
.resolve_completion_edits(
&snap.config.completion,
@ -652,13 +648,14 @@ pub(crate) fn handle_completion_resolve(
if !all_edits_are_disjoint(&original_completion, &additional_edits) {
return Err(LspError::new(
ErrorCode::InternalError as i32,
"Import edit is not disjoint with the original completion edits".into(),
"Import edit overlaps with the original completion edits, this is not LSP-compliant"
.into(),
)
.into());
}
if let Some(original_additional_edits) = original_completion.additional_text_edits.as_mut() {
original_additional_edits.extend(additional_edits.drain(..))
original_additional_edits.extend(additional_edits.into_iter())
} else {
original_completion.additional_text_edits = Some(additional_edits);
}
@ -1634,22 +1631,19 @@ struct CompletionResolveData {
fn fill_resolve_data(
resolve_data: &mut Option<serde_json::Value>,
item: &ide::CompletionItem,
completion_config: &CompletionConfig,
position: &TextDocumentPositionParams,
) -> Option<()> {
if completion_config.resolve_additional_edits_lazily() {
let import_edit = item.import_to_add()?;
let full_import_path = import_edit.import_path.to_string();
let imported_name = import_edit.import_path.segments.clone().pop()?.to_string();
let import_edit = item.import_to_add()?;
let full_import_path = import_edit.import_path.to_string();
let imported_name = import_edit.import_path.segments.clone().pop()?.to_string();
*resolve_data = Some(
to_value(CompletionResolveData {
position: position.to_owned(),
full_import_path,
imported_name,
})
.unwrap(),
)
}
*resolve_data = Some(
to_value(CompletionResolveData {
position: position.to_owned(),
full_import_path,
imported_name,
})
.unwrap(),
);
Some(())
}

View file

@ -129,7 +129,8 @@ pub(crate) fn apply_document_changes(
}
}
/// Checks that the edits inside the completion and the additional edits are disjoint.
/// Checks that the edits inside the completion and the additional edits do not overlap.
/// LSP explicitly forbits the additional edits to overlap both with the main edit and themselves.
pub(crate) fn all_edits_are_disjoint(
completion: &lsp_types::CompletionItem,
additional_edits: &[lsp_types::TextEdit],
@ -150,7 +151,10 @@ pub(crate) fn all_edits_are_disjoint(
};
edit_ranges.extend(additional_edits.iter().map(|edit| edit.range));
edit_ranges.sort_by_key(|range| (range.start, range.end));
edit_ranges.iter().zip(edit_ranges.iter().skip(1)).all(|(l, r)| l.end <= r.start)
edit_ranges
.iter()
.zip(edit_ranges.iter().skip(1))
.all(|(previous, next)| previous.end <= next.start)
}
#[cfg(test)]