@@ -10,8 +10,8 @@ use std::{
1010use anyhow:: Context ;
1111use ide:: {
1212 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 ,
1515} ;
1616use ide_db:: SymbolKind ;
1717use lsp_server:: ErrorCode ;
@@ -20,9 +20,9 @@ use lsp_types::{
2020 CallHierarchyOutgoingCall , CallHierarchyOutgoingCallsParams , CallHierarchyPrepareParams ,
2121 CodeLens , CompletionItem , FoldingRange , FoldingRangeParams , HoverContents , InlayHint ,
2222 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 ,
2626} ;
2727use project_model:: { ManifestPath , ProjectWorkspace , TargetKind } ;
2828use serde_json:: json;
@@ -548,6 +548,13 @@ pub(crate) fn handle_will_rename_files(
548548) -> anyhow:: Result < Option < lsp_types:: WorkspaceEdit > > {
549549 let _p = profile:: span ( "handle_will_rename_files" ) ;
550550
551+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) {
552+ return Err ( Box :: new ( LspError :: new (
553+ ErrorCode :: RequestFailed as i32 ,
554+ "Client does not support rename capability." . to_owned ( ) ,
555+ ) ) ) ;
556+ }
557+
551558 let source_changes: Vec < SourceChange > = params
552559 . files
553560 . into_iter ( )
@@ -1029,7 +1036,30 @@ pub(crate) fn handle_rename(
10291036 // See https://github.com/microsoft/vscode-languageserver-node/issues/752 for more info
10301037 if !change. file_system_edits . is_empty ( ) && snap. config . will_rename ( ) {
10311038 change. source_file_edits . clear ( ) ;
1039+ } else {
1040+ for edit in & change. file_system_edits {
1041+ match edit {
1042+ & FileSystemEdit :: CreateFile { .. }
1043+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1044+ {
1045+ return Err ( Box :: new ( LspError :: new (
1046+ ErrorCode :: RequestFailed as i32 ,
1047+ "Client does not support create capability." . to_owned ( ) ,
1048+ ) ) )
1049+ }
1050+ & FileSystemEdit :: MoveFile { .. } | & FileSystemEdit :: MoveDir { .. }
1051+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1052+ {
1053+ return Err ( Box :: new ( LspError :: new (
1054+ ErrorCode :: RequestFailed as i32 ,
1055+ "Client does not support move/rename capability." . to_owned ( ) ,
1056+ ) ) )
1057+ }
1058+ _ => ( ) ,
1059+ }
1060+ }
10321061 }
1062+
10331063 let workspace_edit = to_proto:: workspace_edit ( & snap, change) ?;
10341064 Ok ( Some ( workspace_edit) )
10351065}
@@ -1137,6 +1167,40 @@ pub(crate) fn handle_code_action(
11371167 let resolve_data =
11381168 if code_action_resolve_cap { Some ( ( index, params. clone ( ) ) ) } else { None } ;
11391169 let code_action = to_proto:: code_action ( & snap, assist, resolve_data) ?;
1170+
1171+ // Check if the client supports the necessary `ResourceOperation`s.
1172+ if let Some ( changes) = & code_action. edit . as_ref ( ) . unwrap ( ) . document_changes {
1173+ for change in changes {
1174+ match change {
1175+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Create ( _) )
1176+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1177+ {
1178+ return Err ( Box :: new ( LspError :: new (
1179+ ErrorCode :: RequestFailed as i32 ,
1180+ "Client does not support create capability." . to_owned ( ) ,
1181+ ) ) ) ;
1182+ }
1183+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Rename ( _) )
1184+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1185+ {
1186+ return Err ( Box :: new ( LspError :: new (
1187+ ErrorCode :: RequestFailed as i32 ,
1188+ "Client does not support rename capability." . to_owned ( ) ,
1189+ ) ) ) ;
1190+ }
1191+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Delete ( _) )
1192+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Delete ) =>
1193+ {
1194+ return Err ( Box :: new ( LspError :: new (
1195+ ErrorCode :: RequestFailed as i32 ,
1196+ "Client does not support delete capability." . to_owned ( ) ,
1197+ ) ) ) ;
1198+ }
1199+ _ => ( ) ,
1200+ }
1201+ }
1202+ }
1203+
11401204 res. push ( code_action)
11411205 }
11421206
@@ -1219,6 +1283,41 @@ pub(crate) fn handle_code_action_resolve(
12191283 let ca = to_proto:: code_action ( & snap, assist. clone ( ) , None ) ?;
12201284 code_action. edit = ca. edit ;
12211285 code_action. command = ca. command ;
1286+
1287+ if let Some ( edit) = code_action. edit . as_ref ( ) {
1288+ if let Some ( changes) = edit. document_changes . as_ref ( ) {
1289+ for change in changes {
1290+ match change {
1291+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Create ( _) )
1292+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Create ) =>
1293+ {
1294+ return Err ( Box :: new ( LspError :: new (
1295+ ErrorCode :: RequestFailed as i32 ,
1296+ "Client does not support create capability." . to_owned ( ) ,
1297+ ) ) ) ;
1298+ }
1299+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Rename ( _) )
1300+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Rename ) =>
1301+ {
1302+ return Err ( Box :: new ( LspError :: new (
1303+ ErrorCode :: RequestFailed as i32 ,
1304+ "Client does not support rename capability." . to_owned ( ) ,
1305+ ) ) ) ;
1306+ }
1307+ lsp_ext:: SnippetDocumentChangeOperation :: Op ( ResourceOp :: Delete ( _) )
1308+ if !resource_ops_supported ( & snap, & ResourceOperationKind :: Delete ) =>
1309+ {
1310+ return Err ( Box :: new ( LspError :: new (
1311+ ErrorCode :: RequestFailed as i32 ,
1312+ "Client does not support delete capability." . to_owned ( ) ,
1313+ ) ) ) ;
1314+ }
1315+ _ => ( ) ,
1316+ }
1317+ }
1318+ }
1319+ }
1320+
12221321 Ok ( code_action)
12231322}
12241323
@@ -1990,3 +2089,19 @@ fn to_url(path: VfsPath) -> Option<Url> {
19902089 let str_path = path. as_os_str ( ) . to_str ( ) ?;
19912090 Url :: from_file_path ( str_path) . ok ( )
19922091}
2092+
2093+ fn resource_ops_supported ( snap : & GlobalStateSnapshot , kind : & ResourceOperationKind ) -> bool {
2094+ snap. config
2095+ . as_ref ( )
2096+ . caps ( )
2097+ . workspace
2098+ . as_ref ( )
2099+ . unwrap ( )
2100+ . workspace_edit
2101+ . as_ref ( )
2102+ . unwrap ( )
2103+ . resource_operations
2104+ . as_ref ( )
2105+ . unwrap ( )
2106+ . contains ( kind)
2107+ }
0 commit comments