Better visualise control flow for change_annotation_support"

This commit is contained in:
Lukas Wirth 2021-04-19 00:14:21 +02:00
parent b501b59eda
commit 493aaa1403

View file

@ -1,16 +1,16 @@
//! Conversion of rust-analyzer specific types to lsp_types equivalents. //! Conversion of rust-analyzer specific types to lsp_types equivalents.
use std::{ use std::{
collections::HashMap, iter::once,
path::{self, Path}, path::{self, Path},
sync::atomic::{AtomicU32, Ordering}, sync::atomic::{AtomicU32, Ordering},
}; };
use ide::{ use ide::{
Annotation, AnnotationKind, Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Annotation, AnnotationKind, Assist, AssistKind, CallInfo, Cancelable, CompletionItem,
CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit, Fold, FoldKind, CompletionItemKind, CompletionRelevance, Documentation, FileId, FileRange, FileSystemEdit,
Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint, InlayKind, Fold, FoldKind, Highlight, HlMod, HlOperator, HlPunct, HlRange, HlTag, Indel, InlayHint,
InsertTextFormat, Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable, Severity, InlayKind, InsertTextFormat, Markup, NavigationTarget, ReferenceAccess, RenameError, Runnable,
SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize, Severity, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
}; };
use itertools::Itertools; use itertools::Itertools;
use serde_json::to_value; use serde_json::to_value;
@ -690,8 +690,8 @@ pub(crate) fn goto_definition_response(
} }
} }
fn outside_workspace_annotation(snap: &GlobalStateSnapshot) -> Option<String> { fn outside_workspace_annotation_id() -> String {
snap.config.change_annotation_support().then(|| String::from("OutsideWorkspace")) String::from("OutsideWorkspace")
} }
pub(crate) fn snippet_text_document_edit( pub(crate) fn snippet_text_document_edit(
@ -702,26 +702,21 @@ pub(crate) fn snippet_text_document_edit(
) -> Result<lsp_ext::SnippetTextDocumentEdit> { ) -> Result<lsp_ext::SnippetTextDocumentEdit> {
let text_document = optional_versioned_text_document_identifier(snap, file_id); let text_document = optional_versioned_text_document_identifier(snap, file_id);
let line_index = snap.file_line_index(file_id)?; let line_index = snap.file_line_index(file_id)?;
let outside_workspace_annotation = snap let mut edits: Vec<_> =
.analysis edit.into_iter().map(|it| snippet_text_edit(&line_index, is_snippet, it)).collect();
.is_library_file(file_id)?
.then(|| outside_workspace_annotation(snap)) if snap.analysis.is_library_file(file_id)? && snap.config.change_annotation_support() {
.flatten(); for edit in &mut edits {
let edits = edit edit.annotation_id = Some(outside_workspace_annotation_id())
.into_iter() }
.map(|it| { }
let mut edit = snippet_text_edit(&line_index, is_snippet, it);
edit.annotation_id = outside_workspace_annotation.clone();
edit
})
.collect();
Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits }) Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits })
} }
pub(crate) fn snippet_text_document_ops( pub(crate) fn snippet_text_document_ops(
snap: &GlobalStateSnapshot, snap: &GlobalStateSnapshot,
file_system_edit: FileSystemEdit, file_system_edit: FileSystemEdit,
) -> Vec<lsp_ext::SnippetDocumentChangeOperation> { ) -> Cancelable<Vec<lsp_ext::SnippetDocumentChangeOperation>> {
let mut ops = Vec::new(); let mut ops = Vec::new();
match file_system_edit { match file_system_edit {
FileSystemEdit::CreateFile { dst, initial_contents } => { FileSystemEdit::CreateFile { dst, initial_contents } => {
@ -749,21 +744,19 @@ pub(crate) fn snippet_text_document_ops(
FileSystemEdit::MoveFile { src, dst } => { FileSystemEdit::MoveFile { src, dst } => {
let old_uri = snap.file_id_to_url(src); let old_uri = snap.file_id_to_url(src);
let new_uri = snap.anchored_path(&dst); let new_uri = snap.anchored_path(&dst);
let rename_file = lsp_types::ResourceOp::Rename(lsp_types::RenameFile { let mut rename_file =
old_uri, lsp_types::RenameFile { old_uri, new_uri, options: None, annotation_id: None };
new_uri, if snap.analysis.is_library_file(src) == Ok(true)
options: None, && snap.config.change_annotation_support()
annotation_id: snap {
.analysis rename_file.annotation_id = Some(outside_workspace_annotation_id())
.is_library_file(src) }
.unwrap() ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(lsp_types::ResourceOp::Rename(
.then(|| outside_workspace_annotation(snap)) rename_file,
.flatten(), )))
});
ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(rename_file))
} }
} }
ops Ok(ops)
} }
pub(crate) fn snippet_workspace_edit( pub(crate) fn snippet_workspace_edit(
@ -773,31 +766,33 @@ pub(crate) fn snippet_workspace_edit(
let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new();
for op in source_change.file_system_edits { for op in source_change.file_system_edits {
let ops = snippet_text_document_ops(snap, op); let ops = snippet_text_document_ops(snap, op)?;
document_changes.extend_from_slice(&ops); document_changes.extend_from_slice(&ops);
} }
for (file_id, edit) in source_change.source_file_edits { for (file_id, edit) in source_change.source_file_edits {
let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?; let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?;
document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit));
} }
let change_annotations = outside_workspace_annotation(snap).map(|annotation| { let mut workspace_edit = lsp_ext::SnippetWorkspaceEdit {
use std::iter::FromIterator;
HashMap::from_iter(Some((
annotation,
lsp_types::ChangeAnnotation {
label: String::from("Edit outside of the workspace"),
needs_confirmation: Some(true),
description: Some(String::from(
"This edit lies outside of the workspace and may affect dependencies",
)),
},
)))
});
let workspace_edit = lsp_ext::SnippetWorkspaceEdit {
changes: None, changes: None,
document_changes: Some(document_changes), document_changes: Some(document_changes),
change_annotations, change_annotations: None,
}; };
if snap.config.change_annotation_support() {
workspace_edit.change_annotations = Some(
once((
outside_workspace_annotation_id(),
lsp_types::ChangeAnnotation {
label: String::from("Edit outside of the workspace"),
needs_confirmation: Some(true),
description: Some(String::from(
"This edit lies outside of the workspace and may affect dependencies",
)),
},
))
.collect(),
)
}
Ok(workspace_edit) Ok(workspace_edit)
} }