@@ -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,14 @@ 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 ( LspError :: new (
553+ ErrorCode :: RequestFailed as i32 ,
554+ "Client does not support rename capability." . to_owned ( ) ,
555+ )
556+ . into ( ) ) ;
557+ }
558+
551559 let source_changes: Vec < SourceChange > = params
552560 . files
553561 . into_iter ( )
@@ -1029,7 +1037,32 @@ pub(crate) fn handle_rename(
10291037 // See https://github.com/microsoft/vscode-languageserver-node/issues/752 for more info
10301038 if !change. file_system_edits . is_empty ( ) && snap. config . will_rename ( ) {
10311039 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+ }
10321064 }
1065+
10331066 let workspace_edit = to_proto:: workspace_edit ( & snap, change) ?;
10341067 Ok ( Some ( workspace_edit) )
10351068}
@@ -1137,6 +1170,43 @@ pub(crate) fn handle_code_action(
11371170 let resolve_data =
11381171 if code_action_resolve_cap { Some ( ( index, params. clone ( ) ) ) } else { None } ;
11391172 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+
11401210 res. push ( code_action)
11411211 }
11421212
@@ -1219,6 +1289,44 @@ pub(crate) fn handle_code_action_resolve(
12191289 let ca = to_proto:: code_action ( & snap, assist. clone ( ) , None ) ?;
12201290 code_action. edit = ca. edit ;
12211291 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+
12221330 Ok ( code_action)
12231331}
12241332
@@ -1990,3 +2098,19 @@ fn to_url(path: VfsPath) -> Option<Url> {
19902098 let str_path = path. as_os_str ( ) . to_str ( ) ?;
19912099 Url :: from_file_path ( str_path) . ok ( )
19922100}
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