aboutsummaryrefslogtreecommitdiff
path: root/crates/rust-analyzer/src/to_proto.rs
diff options
context:
space:
mode:
authorLukas Wirth <[email protected]>2021-04-16 16:31:47 +0100
committerLukas Wirth <[email protected]>2021-04-18 11:44:00 +0100
commitc447a795abecbf9a4138778bab44197250b2dc4a (patch)
treec35a00f004f09c01f41714ca44e3a0a045a19ea1 /crates/rust-analyzer/src/to_proto.rs
parent75371eb0fa015ba8834ae2b66cda68eba5d83874 (diff)
Prevent being able to rename items that are not part of the workspace
Diffstat (limited to 'crates/rust-analyzer/src/to_proto.rs')
-rw-r--r--crates/rust-analyzer/src/to_proto.rs78
1 files changed, 63 insertions, 15 deletions
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 1a1f65f3b..13de11df1 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -1,5 +1,6 @@
1//! Conversion of rust-analyzer specific types to lsp_types equivalents. 1//! Conversion of rust-analyzer specific types to lsp_types equivalents.
2use std::{ 2use std::{
3 collections::HashMap,
3 path::{self, Path}, 4 path::{self, Path},
4 sync::atomic::{AtomicU32, Ordering}, 5 sync::atomic::{AtomicU32, Ordering},
5}; 6};
@@ -174,6 +175,7 @@ pub(crate) fn snippet_text_edit(
174 range: text_edit.range, 175 range: text_edit.range,
175 new_text: text_edit.new_text, 176 new_text: text_edit.new_text,
176 insert_text_format, 177 insert_text_format,
178 annotation_id: None,
177 } 179 }
178} 180}
179 181
@@ -688,6 +690,10 @@ pub(crate) fn goto_definition_response(
688 } 690 }
689} 691}
690 692
693fn outside_workspace_annotation(snap: &GlobalStateSnapshot) -> Option<String> {
694 snap.config.change_annotation_support().then(|| String::from("OutsideWorkspace"))
695}
696
691pub(crate) fn snippet_text_document_edit( 697pub(crate) fn snippet_text_document_edit(
692 snap: &GlobalStateSnapshot, 698 snap: &GlobalStateSnapshot,
693 is_snippet: bool, 699 is_snippet: bool,
@@ -696,7 +702,19 @@ pub(crate) fn snippet_text_document_edit(
696) -> Result<lsp_ext::SnippetTextDocumentEdit> { 702) -> Result<lsp_ext::SnippetTextDocumentEdit> {
697 let text_document = optional_versioned_text_document_identifier(snap, file_id); 703 let text_document = optional_versioned_text_document_identifier(snap, file_id);
698 let line_index = snap.file_line_index(file_id)?; 704 let line_index = snap.file_line_index(file_id)?;
699 let edits = edit.into_iter().map(|it| snippet_text_edit(&line_index, is_snippet, it)).collect(); 705 let outside_workspace_annotation = snap
706 .analysis
707 .is_library_file(file_id)?
708 .then(|| outside_workspace_annotation(snap))
709 .flatten();
710 let edits = edit
711 .into_iter()
712 .map(|it| {
713 let mut edit = snippet_text_edit(&line_index, is_snippet, it);
714 edit.annotation_id = outside_workspace_annotation.clone();
715 edit
716 })
717 .collect();
700 Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits }) 718 Ok(lsp_ext::SnippetTextDocumentEdit { text_document, edits })
701} 719}
702 720
@@ -721,6 +739,7 @@ pub(crate) fn snippet_text_document_ops(
721 range: lsp_types::Range::default(), 739 range: lsp_types::Range::default(),
722 new_text: initial_contents, 740 new_text: initial_contents,
723 insert_text_format: Some(lsp_types::InsertTextFormat::PlainText), 741 insert_text_format: Some(lsp_types::InsertTextFormat::PlainText),
742 annotation_id: None,
724 }; 743 };
725 let edit_file = 744 let edit_file =
726 lsp_ext::SnippetTextDocumentEdit { text_document, edits: vec![text_edit] }; 745 lsp_ext::SnippetTextDocumentEdit { text_document, edits: vec![text_edit] };
@@ -734,7 +753,12 @@ pub(crate) fn snippet_text_document_ops(
734 old_uri, 753 old_uri,
735 new_uri, 754 new_uri,
736 options: None, 755 options: None,
737 annotation_id: None, 756 annotation_id: snap
757 .analysis
758 .is_library_file(src)
759 .unwrap()
760 .then(|| outside_workspace_annotation(snap))
761 .flatten(),
738 }); 762 });
739 ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(rename_file)) 763 ops.push(lsp_ext::SnippetDocumentChangeOperation::Op(rename_file))
740 } 764 }
@@ -747,6 +771,7 @@ pub(crate) fn snippet_workspace_edit(
747 source_change: SourceChange, 771 source_change: SourceChange,
748) -> Result<lsp_ext::SnippetWorkspaceEdit> { 772) -> Result<lsp_ext::SnippetWorkspaceEdit> {
749 let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new(); 773 let mut document_changes: Vec<lsp_ext::SnippetDocumentChangeOperation> = Vec::new();
774
750 for op in source_change.file_system_edits { 775 for op in source_change.file_system_edits {
751 let ops = snippet_text_document_ops(snap, op); 776 let ops = snippet_text_document_ops(snap, op);
752 document_changes.extend_from_slice(&ops); 777 document_changes.extend_from_slice(&ops);
@@ -755,8 +780,24 @@ pub(crate) fn snippet_workspace_edit(
755 let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?; 780 let edit = snippet_text_document_edit(&snap, source_change.is_snippet, file_id, edit)?;
756 document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit)); 781 document_changes.push(lsp_ext::SnippetDocumentChangeOperation::Edit(edit));
757 } 782 }
758 let workspace_edit = 783 let change_annotations = outside_workspace_annotation(snap).map(|annotation| {
759 lsp_ext::SnippetWorkspaceEdit { changes: None, document_changes: Some(document_changes) }; 784 use std::iter::FromIterator;
785 HashMap::from_iter(Some((
786 annotation,
787 lsp_types::ChangeAnnotation {
788 label: String::from("Edit outside of the workspace"),
789 needs_confirmation: Some(true),
790 description: Some(String::from(
791 "This edit lies outside of the workspace and may affect dependencies",
792 )),
793 },
794 )))
795 });
796 let workspace_edit = lsp_ext::SnippetWorkspaceEdit {
797 changes: None,
798 document_changes: Some(document_changes),
799 change_annotations,
800 };
760 Ok(workspace_edit) 801 Ok(workspace_edit)
761} 802}
762 803
@@ -784,16 +825,7 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit {
784 lsp_types::DocumentChangeOperation::Edit( 825 lsp_types::DocumentChangeOperation::Edit(
785 lsp_types::TextDocumentEdit { 826 lsp_types::TextDocumentEdit {
786 text_document: edit.text_document, 827 text_document: edit.text_document,
787 edits: edit 828 edits: edit.edits.into_iter().map(From::from).collect(),
788 .edits
789 .into_iter()
790 .map(|edit| {
791 lsp_types::OneOf::Left(lsp_types::TextEdit {
792 range: edit.range,
793 new_text: edit.new_text,
794 })
795 })
796 .collect(),
797 }, 829 },
798 ) 830 )
799 } 831 }
@@ -801,7 +833,23 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit {
801 .collect(), 833 .collect(),
802 ) 834 )
803 }), 835 }),
804 change_annotations: None, 836 change_annotations: snippet_workspace_edit.change_annotations,
837 }
838 }
839}
840
841impl From<lsp_ext::SnippetTextEdit>
842 for lsp_types::OneOf<lsp_types::TextEdit, lsp_types::AnnotatedTextEdit>
843{
844 fn from(
845 lsp_ext::SnippetTextEdit { annotation_id, insert_text_format:_, new_text, range }: lsp_ext::SnippetTextEdit,
846 ) -> Self {
847 match annotation_id {
848 Some(annotation_id) => lsp_types::OneOf::Right(lsp_types::AnnotatedTextEdit {
849 text_edit: lsp_types::TextEdit { range, new_text },
850 annotation_id,
851 }),
852 None => lsp_types::OneOf::Left(lsp_types::TextEdit { range, new_text }),
805 } 853 }
806 } 854 }
807} 855}