@@ -10,8 +10,8 @@ use std::{
10
10
use anyhow:: Context ;
11
11
use ide:: {
12
12
AnnotationConfig , AssistKind , AssistResolveStrategy , Cancellable , FilePosition , FileRange ,
13
- HoverAction , HoverGotoTypeData , Query , RangeInfo , ReferenceCategory , Runnable , RunnableKind ,
14
- SingleResolve , SourceChange , TextEdit ,
13
+ FileSystemEdit , HoverAction , HoverGotoTypeData , Query , RangeInfo , ReferenceCategory , Runnable ,
14
+ RunnableKind , SingleResolve , SourceChange , TextEdit ,
15
15
} ;
16
16
use ide_db:: SymbolKind ;
17
17
use lsp_server:: ErrorCode ;
@@ -20,9 +20,9 @@ use lsp_types::{
20
20
CallHierarchyOutgoingCall , CallHierarchyOutgoingCallsParams , CallHierarchyPrepareParams ,
21
21
CodeLens , CompletionItem , FoldingRange , FoldingRangeParams , HoverContents , InlayHint ,
22
22
InlayHintParams , Location , LocationLink , Position , PrepareRenameResponse , Range , RenameParams ,
23
- SemanticTokensDeltaParams , SemanticTokensFullDeltaResult , SemanticTokensParams ,
24
- SemanticTokensRangeParams , SemanticTokensRangeResult , SemanticTokensResult , SymbolInformation ,
25
- SymbolTag , TextDocumentIdentifier , Url , WorkspaceEdit ,
23
+ ResourceOp , ResourceOperationKind , SemanticTokensDeltaParams , SemanticTokensFullDeltaResult ,
24
+ SemanticTokensParams , SemanticTokensRangeParams , SemanticTokensRangeResult ,
25
+ SemanticTokensResult , SymbolInformation , SymbolTag , TextDocumentIdentifier , Url , WorkspaceEdit ,
26
26
} ;
27
27
use project_model:: { ManifestPath , ProjectWorkspace , TargetKind } ;
28
28
use serde_json:: json;
@@ -548,6 +548,14 @@ pub(crate) fn handle_will_rename_files(
548
548
) -> anyhow:: Result < Option < lsp_types:: WorkspaceEdit > > {
549
549
let _p = profile:: span ( "handle_will_rename_files" ) ;
550
550
551
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) {
552
+ return Err ( LspError :: new (
553
+ ErrorCode :: RequestFailed as i32 ,
554
+ "Client does not support rename capability." . to_owned ( ) ,
555
+ )
556
+ . into ( ) ) ;
557
+ }
558
+
551
559
let source_changes: Vec < SourceChange > = params
552
560
. files
553
561
. into_iter ( )
@@ -1029,7 +1037,32 @@ pub(crate) fn handle_rename(
1029
1037
// See https://github.com/microsoft/vscode-languageserver-node/issues/752 for more info
1030
1038
if !change. file_system_edits . is_empty ( ) && snap. config . will_rename ( ) {
1031
1039
change. source_file_edits . clear ( ) ;
1040
+ } else {
1041
+ for edit in & change. file_system_edits {
1042
+ match edit {
1043
+ & FileSystemEdit :: CreateFile { .. }
1044
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1045
+ {
1046
+ return Err ( LspError :: new (
1047
+ ErrorCode :: RequestFailed as i32 ,
1048
+ "Client does not support create capability." . to_owned ( ) ,
1049
+ )
1050
+ . into ( ) )
1051
+ }
1052
+ & FileSystemEdit :: MoveFile { .. } | & FileSystemEdit :: MoveDir { .. }
1053
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1054
+ {
1055
+ return Err ( LspError :: new (
1056
+ ErrorCode :: RequestFailed as i32 ,
1057
+ "Client does not support move/rename capability." . to_owned ( ) ,
1058
+ )
1059
+ . into ( ) )
1060
+ }
1061
+ _ => ( ) ,
1062
+ }
1063
+ }
1032
1064
}
1065
+
1033
1066
let workspace_edit = to_proto:: workspace_edit ( & snap, change) ?;
1034
1067
Ok ( Some ( workspace_edit) )
1035
1068
}
@@ -1137,6 +1170,43 @@ pub(crate) fn handle_code_action(
1137
1170
let resolve_data =
1138
1171
if code_action_resolve_cap { Some ( ( index, params. clone ( ) ) ) } else { None } ;
1139
1172
let code_action = to_proto:: code_action ( & snap, assist, resolve_data) ?;
1173
+
1174
+ // Check if the client supports the necessary `ResourceOperation`s.
1175
+ if let Some ( changes) = & code_action. edit . as_ref ( ) . unwrap ( ) . document_changes {
1176
+ for change in changes {
1177
+ match change {
1178
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Create ( _) )
1179
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1180
+ {
1181
+ return Err ( LspError :: new (
1182
+ ErrorCode :: RequestFailed as i32 ,
1183
+ "Client does not support create capability." . to_owned ( ) ,
1184
+ )
1185
+ . into ( ) ) ;
1186
+ }
1187
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Rename ( _) )
1188
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1189
+ {
1190
+ return Err ( LspError :: new (
1191
+ ErrorCode :: RequestFailed as i32 ,
1192
+ "Client does not support rename capability." . to_owned ( ) ,
1193
+ )
1194
+ . into ( ) ) ;
1195
+ }
1196
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Delete ( _) )
1197
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Delete ) =>
1198
+ {
1199
+ return Err ( LspError :: new (
1200
+ ErrorCode :: RequestFailed as i32 ,
1201
+ "Client does not support delete capability." . to_owned ( ) ,
1202
+ )
1203
+ . into ( ) ) ;
1204
+ }
1205
+ _ => ( ) ,
1206
+ }
1207
+ }
1208
+ }
1209
+
1140
1210
res. push ( code_action)
1141
1211
}
1142
1212
@@ -1219,6 +1289,44 @@ pub(crate) fn handle_code_action_resolve(
1219
1289
let ca = to_proto:: code_action ( & snap, assist. clone ( ) , None ) ?;
1220
1290
code_action. edit = ca. edit ;
1221
1291
code_action. command = ca. command ;
1292
+
1293
+ if let Some ( edit) = code_action. edit . as_ref ( ) {
1294
+ if let Some ( changes) = edit. document_changes . as_ref ( ) {
1295
+ for change in changes {
1296
+ match change {
1297
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Create ( _) )
1298
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1299
+ {
1300
+ return Err ( LspError :: new (
1301
+ ErrorCode :: RequestFailed as i32 ,
1302
+ "Client does not support create capability." . to_owned ( ) ,
1303
+ )
1304
+ . into ( ) ) ;
1305
+ }
1306
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Rename ( _) )
1307
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1308
+ {
1309
+ return Err ( LspError :: new (
1310
+ ErrorCode :: RequestFailed as i32 ,
1311
+ "Client does not support rename capability." . to_owned ( ) ,
1312
+ )
1313
+ . into ( ) ) ;
1314
+ }
1315
+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Delete ( _) )
1316
+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Delete ) =>
1317
+ {
1318
+ return Err ( LspError :: new (
1319
+ ErrorCode :: RequestFailed as i32 ,
1320
+ "Client does not support delete capability." . to_owned ( ) ,
1321
+ )
1322
+ . into ( ) ) ;
1323
+ }
1324
+ _ => ( ) ,
1325
+ }
1326
+ }
1327
+ }
1328
+ }
1329
+
1222
1330
Ok ( code_action)
1223
1331
}
1224
1332
@@ -1990,3 +2098,19 @@ fn to_url(path: VfsPath) -> Option<Url> {
1990
2098
let str_path = path. as_os_str ( ) . to_str ( ) ?;
1991
2099
Url :: from_file_path ( str_path) . ok ( )
1992
2100
}
2101
+
2102
+ fn resource_ops_supported ( snap : & GlobalStateSnapshot , kind : & ResourceOperationKind ) -> bool {
2103
+ snap. config
2104
+ . as_ref ( )
2105
+ . caps ( )
2106
+ . workspace
2107
+ . as_ref ( )
2108
+ . unwrap ( )
2109
+ . workspace_edit
2110
+ . as_ref ( )
2111
+ . unwrap ( )
2112
+ . resource_operations
2113
+ . as_ref ( )
2114
+ . unwrap ( )
2115
+ . contains ( kind)
2116
+ }
0 commit comments