diff options
author | Lukas Wirth <[email protected]> | 2021-04-16 16:31:47 +0100 |
---|---|---|
committer | Lukas Wirth <[email protected]> | 2021-04-18 11:44:00 +0100 |
commit | c447a795abecbf9a4138778bab44197250b2dc4a (patch) | |
tree | c35a00f004f09c01f41714ca44e3a0a045a19ea1 /crates/rust-analyzer/src/to_proto.rs | |
parent | 75371eb0fa015ba8834ae2b66cda68eba5d83874 (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.rs | 78 |
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. |
2 | use std::{ | 2 | use 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 | ||
693 | fn outside_workspace_annotation(snap: &GlobalStateSnapshot) -> Option<String> { | ||
694 | snap.config.change_annotation_support().then(|| String::from("OutsideWorkspace")) | ||
695 | } | ||
696 | |||
691 | pub(crate) fn snippet_text_document_edit( | 697 | pub(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 | |||
841 | impl 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 | } |