1
1
//! Conversion of rust-analyzer specific types to lsp_types equivalents.
2
2
use std:: {
3
+ iter:: once,
3
4
path:: { self , Path } ,
4
5
sync:: atomic:: { AtomicU32 , Ordering } ,
5
6
} ;
6
7
7
8
use ide:: {
8
- Annotation , AnnotationKind , Assist , AssistKind , CallInfo , CompletionItem , CompletionItemKind ,
9
- CompletionRelevance , Documentation , FileId , FileRange , FileSystemEdit , Fold , FoldKind ,
10
- Highlight , HlMod , HlOperator , HlPunct , HlRange , HlTag , Indel , InlayHint , InlayKind ,
11
- InsertTextFormat , Markup , NavigationTarget , ReferenceAccess , RenameError , Runnable , Severity ,
12
- SourceChange , StructureNodeKind , SymbolKind , TextEdit , TextRange , TextSize ,
9
+ Annotation , AnnotationKind , Assist , AssistKind , CallInfo , Cancelable , CompletionItem ,
10
+ CompletionItemKind , CompletionRelevance , Documentation , FileId , FileRange , FileSystemEdit ,
11
+ Fold , FoldKind , Highlight , HlMod , HlOperator , HlPunct , HlRange , HlTag , Indel , InlayHint ,
12
+ InlayKind , InsertTextFormat , Markup , NavigationTarget , ReferenceAccess , RenameError , Runnable ,
13
+ Severity , SourceChange , StructureNodeKind , SymbolKind , TextEdit , TextRange , TextSize ,
13
14
} ;
14
15
use itertools:: Itertools ;
15
16
use serde_json:: to_value;
@@ -174,6 +175,7 @@ pub(crate) fn snippet_text_edit(
174
175
range : text_edit. range ,
175
176
new_text : text_edit. new_text ,
176
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_id ( ) -> String {
694
+ String :: from ( "OutsideWorkspace" )
695
+ }
696
+
691
697
pub ( crate ) fn snippet_text_document_edit (
692
698
snap : & GlobalStateSnapshot ,
693
699
is_snippet : bool ,
@@ -696,14 +702,21 @@ pub(crate) fn snippet_text_document_edit(
696
702
) -> Result < lsp_ext:: SnippetTextDocumentEdit > {
697
703
let text_document = optional_versioned_text_document_identifier ( snap, file_id) ;
698
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 mut edits: Vec < _ > =
706
+ edit. into_iter ( ) . map ( |it| snippet_text_edit ( & line_index, is_snippet, it) ) . collect ( ) ;
707
+
708
+ if snap. analysis . is_library_file ( file_id) ? && snap. config . change_annotation_support ( ) {
709
+ for edit in & mut edits {
710
+ edit. annotation_id = Some ( outside_workspace_annotation_id ( ) )
711
+ }
712
+ }
700
713
Ok ( lsp_ext:: SnippetTextDocumentEdit { text_document, edits } )
701
714
}
702
715
703
716
pub ( crate ) fn snippet_text_document_ops (
704
717
snap : & GlobalStateSnapshot ,
705
718
file_system_edit : FileSystemEdit ,
706
- ) -> Vec < lsp_ext:: SnippetDocumentChangeOperation > {
719
+ ) -> Cancelable < Vec < lsp_ext:: SnippetDocumentChangeOperation > > {
707
720
let mut ops = Vec :: new ( ) ;
708
721
match file_system_edit {
709
722
FileSystemEdit :: CreateFile { dst, initial_contents } => {
@@ -721,6 +734,7 @@ pub(crate) fn snippet_text_document_ops(
721
734
range : lsp_types:: Range :: default ( ) ,
722
735
new_text : initial_contents,
723
736
insert_text_format : Some ( lsp_types:: InsertTextFormat :: PlainText ) ,
737
+ annotation_id : None ,
724
738
} ;
725
739
let edit_file =
726
740
lsp_ext:: SnippetTextDocumentEdit { text_document, edits : vec ! [ text_edit] } ;
@@ -730,33 +744,55 @@ pub(crate) fn snippet_text_document_ops(
730
744
FileSystemEdit :: MoveFile { src, dst } => {
731
745
let old_uri = snap. file_id_to_url ( src) ;
732
746
let new_uri = snap. anchored_path ( & dst) ;
733
- let rename_file = lsp_types:: ResourceOp :: Rename ( lsp_types:: RenameFile {
734
- old_uri,
735
- new_uri,
736
- options : None ,
737
- annotation_id : None ,
738
- } ) ;
739
- ops. push ( lsp_ext:: SnippetDocumentChangeOperation :: Op ( rename_file) )
747
+ let mut rename_file =
748
+ lsp_types:: RenameFile { old_uri, new_uri, options : None , annotation_id : None } ;
749
+ if snap. analysis . is_library_file ( src) == Ok ( true )
750
+ && snap. config . change_annotation_support ( )
751
+ {
752
+ rename_file. annotation_id = Some ( outside_workspace_annotation_id ( ) )
753
+ }
754
+ ops. push ( lsp_ext:: SnippetDocumentChangeOperation :: Op ( lsp_types:: ResourceOp :: Rename (
755
+ rename_file,
756
+ ) ) )
740
757
}
741
758
}
742
- ops
759
+ Ok ( ops)
743
760
}
744
761
745
762
pub ( crate ) fn snippet_workspace_edit (
746
763
snap : & GlobalStateSnapshot ,
747
764
source_change : SourceChange ,
748
765
) -> Result < lsp_ext:: SnippetWorkspaceEdit > {
749
766
let mut document_changes: Vec < lsp_ext:: SnippetDocumentChangeOperation > = Vec :: new ( ) ;
767
+
750
768
for op in source_change. file_system_edits {
751
- let ops = snippet_text_document_ops ( snap, op) ;
769
+ let ops = snippet_text_document_ops ( snap, op) ? ;
752
770
document_changes. extend_from_slice ( & ops) ;
753
771
}
754
772
for ( file_id, edit) in source_change. source_file_edits {
755
773
let edit = snippet_text_document_edit ( & snap, source_change. is_snippet , file_id, edit) ?;
756
774
document_changes. push ( lsp_ext:: SnippetDocumentChangeOperation :: Edit ( edit) ) ;
757
775
}
758
- let workspace_edit =
759
- lsp_ext:: SnippetWorkspaceEdit { changes : None , document_changes : Some ( document_changes) } ;
776
+ let mut workspace_edit = lsp_ext:: SnippetWorkspaceEdit {
777
+ changes : None ,
778
+ document_changes : Some ( document_changes) ,
779
+ change_annotations : None ,
780
+ } ;
781
+ if snap. config . change_annotation_support ( ) {
782
+ workspace_edit. change_annotations = Some (
783
+ once ( (
784
+ outside_workspace_annotation_id ( ) ,
785
+ lsp_types:: ChangeAnnotation {
786
+ label : String :: from ( "Edit outside of the workspace" ) ,
787
+ needs_confirmation : Some ( true ) ,
788
+ description : Some ( String :: from (
789
+ "This edit lies outside of the workspace and may affect dependencies" ,
790
+ ) ) ,
791
+ } ,
792
+ ) )
793
+ . collect ( ) ,
794
+ )
795
+ }
760
796
Ok ( workspace_edit)
761
797
}
762
798
@@ -784,24 +820,31 @@ impl From<lsp_ext::SnippetWorkspaceEdit> for lsp_types::WorkspaceEdit {
784
820
lsp_types:: DocumentChangeOperation :: Edit (
785
821
lsp_types:: TextDocumentEdit {
786
822
text_document : edit. text_document ,
787
- edits : edit
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 ( ) ,
823
+ edits : edit. edits . into_iter ( ) . map ( From :: from) . collect ( ) ,
797
824
} ,
798
825
)
799
826
}
800
827
} )
801
828
. collect ( ) ,
802
829
)
803
830
} ) ,
804
- change_annotations : None ,
831
+ change_annotations : snippet_workspace_edit. change_annotations ,
832
+ }
833
+ }
834
+ }
835
+
836
+ impl From < lsp_ext:: SnippetTextEdit >
837
+ for lsp_types:: OneOf < lsp_types:: TextEdit , lsp_types:: AnnotatedTextEdit >
838
+ {
839
+ fn from (
840
+ lsp_ext:: SnippetTextEdit { annotation_id, insert_text_format : _, new_text, range } : lsp_ext:: SnippetTextEdit ,
841
+ ) -> Self {
842
+ match annotation_id {
843
+ Some ( annotation_id) => lsp_types:: OneOf :: Right ( lsp_types:: AnnotatedTextEdit {
844
+ text_edit : lsp_types:: TextEdit { range, new_text } ,
845
+ annotation_id,
846
+ } ) ,
847
+ None => lsp_types:: OneOf :: Left ( lsp_types:: TextEdit { range, new_text } ) ,
805
848
}
806
849
}
807
850
}
0 commit comments