Skip to content

Commit 891331c

Browse files
committed
Auto merge of #15101 - alibektas:14780, r=Veykril
Check Workspace Edit ResourceOps PR fixes #14780
2 parents c10c6b4 + f8518a6 commit 891331c

File tree

2 files changed

+98
-4
lines changed

2 files changed

+98
-4
lines changed

crates/rust-analyzer/src/handlers/request.rs

+90-4
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use std::{
88
};
99

1010
use anyhow::Context;
11+
1112
use ide::{
1213
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
1314
HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
@@ -20,9 +21,9 @@ use lsp_types::{
2021
CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
2122
CodeLens, CompletionItem, FoldingRange, FoldingRangeParams, HoverContents, InlayHint,
2223
InlayHintParams, Location, LocationLink, Position, PrepareRenameResponse, Range, RenameParams,
23-
SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams,
24-
SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation,
25-
SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
24+
ResourceOp, ResourceOperationKind, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult,
25+
SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult,
26+
SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
2627
};
2728
use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
2829
use serde_json::json;
@@ -33,7 +34,7 @@ use vfs::{AbsPath, AbsPathBuf, VfsPath};
3334

3435
use crate::{
3536
cargo_target_spec::CargoTargetSpec,
36-
config::{RustfmtConfig, WorkspaceSymbolConfig},
37+
config::{Config, RustfmtConfig, WorkspaceSymbolConfig},
3738
diff::diff,
3839
from_proto,
3940
global_state::{GlobalState, GlobalStateSnapshot},
@@ -1030,7 +1031,23 @@ pub(crate) fn handle_rename(
10301031
if !change.file_system_edits.is_empty() && snap.config.will_rename() {
10311032
change.source_file_edits.clear();
10321033
}
1034+
10331035
let workspace_edit = to_proto::workspace_edit(&snap, change)?;
1036+
1037+
if let Some(lsp_types::DocumentChanges::Operations(ops)) =
1038+
workspace_edit.document_changes.as_ref()
1039+
{
1040+
for op in ops {
1041+
if let lsp_types::DocumentChangeOperation::Op(doc_change_op) = op {
1042+
if let Err(err) =
1043+
resource_ops_supported(&snap.config, resolve_resource_op(doc_change_op))
1044+
{
1045+
return Err(err);
1046+
}
1047+
}
1048+
}
1049+
}
1050+
10341051
Ok(Some(workspace_edit))
10351052
}
10361053

@@ -1137,6 +1154,20 @@ pub(crate) fn handle_code_action(
11371154
let resolve_data =
11381155
if code_action_resolve_cap { Some((index, params.clone())) } else { None };
11391156
let code_action = to_proto::code_action(&snap, assist, resolve_data)?;
1157+
1158+
// Check if the client supports the necessary `ResourceOperation`s.
1159+
if let Some(changes) = &code_action.edit.as_ref().unwrap().document_changes {
1160+
for change in changes {
1161+
if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
1162+
if let Err(err) =
1163+
resource_ops_supported(&snap.config, resolve_resource_op(res_op))
1164+
{
1165+
return Err(err);
1166+
}
1167+
}
1168+
}
1169+
}
1170+
11401171
res.push(code_action)
11411172
}
11421173

@@ -1219,6 +1250,21 @@ pub(crate) fn handle_code_action_resolve(
12191250
let ca = to_proto::code_action(&snap, assist.clone(), None)?;
12201251
code_action.edit = ca.edit;
12211252
code_action.command = ca.command;
1253+
1254+
if let Some(edit) = code_action.edit.as_ref() {
1255+
if let Some(changes) = edit.document_changes.as_ref() {
1256+
for change in changes {
1257+
if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
1258+
if let Err(err) =
1259+
resource_ops_supported(&snap.config, resolve_resource_op(res_op))
1260+
{
1261+
return Err(err);
1262+
}
1263+
}
1264+
}
1265+
}
1266+
}
1267+
12221268
Ok(code_action)
12231269
}
12241270

@@ -1990,3 +2036,43 @@ fn to_url(path: VfsPath) -> Option<Url> {
19902036
let str_path = path.as_os_str().to_str()?;
19912037
Url::from_file_path(str_path).ok()
19922038
}
2039+
2040+
fn resource_ops_supported(config: &Config, kind: ResourceOperationKind) -> anyhow::Result<()> {
2041+
let ctn = config
2042+
.caps()
2043+
.workspace
2044+
.as_ref()
2045+
.unwrap()
2046+
.workspace_edit
2047+
.as_ref()
2048+
.unwrap()
2049+
.resource_operations
2050+
.as_ref()
2051+
.unwrap()
2052+
.contains(&kind);
2053+
2054+
if !ctn {
2055+
return Err(LspError::new(
2056+
ErrorCode::RequestFailed as i32,
2057+
format!(
2058+
"Client does not support {} capability.",
2059+
match kind {
2060+
ResourceOperationKind::Create => "create",
2061+
ResourceOperationKind::Rename => "rename",
2062+
ResourceOperationKind::Delete => "delete",
2063+
}
2064+
),
2065+
)
2066+
.into());
2067+
}
2068+
2069+
Ok(())
2070+
}
2071+
2072+
fn resolve_resource_op(op: &ResourceOp) -> ResourceOperationKind {
2073+
match op {
2074+
ResourceOp::Create(_) => ResourceOperationKind::Create,
2075+
ResourceOp::Rename(_) => ResourceOperationKind::Rename,
2076+
ResourceOp::Delete(_) => ResourceOperationKind::Delete,
2077+
}
2078+
}

crates/rust-analyzer/tests/slow-tests/support.rs

+8
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ impl<'a> Project<'a> {
113113
relative_pattern_support: None,
114114
},
115115
),
116+
workspace_edit: Some(lsp_types::WorkspaceEditClientCapabilities {
117+
resource_operations: Some(vec![
118+
lsp_types::ResourceOperationKind::Create,
119+
lsp_types::ResourceOperationKind::Delete,
120+
lsp_types::ResourceOperationKind::Rename,
121+
]),
122+
..Default::default()
123+
}),
116124
..Default::default()
117125
}),
118126
text_document: Some(lsp_types::TextDocumentClientCapabilities {

0 commit comments

Comments
 (0)