Skip to content

Commit

Permalink
Auto merge of #15101 - alibektas:14780, r=Veykril
Browse files Browse the repository at this point in the history
Check Workspace Edit ResourceOps

PR fixes #14780
  • Loading branch information
bors committed Jun 28, 2023
2 parents c10c6b4 + f8518a6 commit 891331c
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 4 deletions.
94 changes: 90 additions & 4 deletions crates/rust-analyzer/src/handlers/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use std::{
};

use anyhow::Context;

use ide::{
AnnotationConfig, AssistKind, AssistResolveStrategy, Cancellable, FilePosition, FileRange,
HoverAction, HoverGotoTypeData, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
Expand All @@ -20,9 +21,9 @@ use lsp_types::{
CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
CodeLens, CompletionItem, FoldingRange, FoldingRangeParams, HoverContents, InlayHint,
InlayHintParams, Location, LocationLink, Position, PrepareRenameResponse, Range, RenameParams,
SemanticTokensDeltaParams, SemanticTokensFullDeltaResult, SemanticTokensParams,
SemanticTokensRangeParams, SemanticTokensRangeResult, SemanticTokensResult, SymbolInformation,
SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
ResourceOp, ResourceOperationKind, SemanticTokensDeltaParams, SemanticTokensFullDeltaResult,
SemanticTokensParams, SemanticTokensRangeParams, SemanticTokensRangeResult,
SemanticTokensResult, SymbolInformation, SymbolTag, TextDocumentIdentifier, Url, WorkspaceEdit,
};
use project_model::{ManifestPath, ProjectWorkspace, TargetKind};
use serde_json::json;
Expand All @@ -33,7 +34,7 @@ use vfs::{AbsPath, AbsPathBuf, VfsPath};

use crate::{
cargo_target_spec::CargoTargetSpec,
config::{RustfmtConfig, WorkspaceSymbolConfig},
config::{Config, RustfmtConfig, WorkspaceSymbolConfig},
diff::diff,
from_proto,
global_state::{GlobalState, GlobalStateSnapshot},
Expand Down Expand Up @@ -1030,7 +1031,23 @@ pub(crate) fn handle_rename(
if !change.file_system_edits.is_empty() && snap.config.will_rename() {
change.source_file_edits.clear();
}

let workspace_edit = to_proto::workspace_edit(&snap, change)?;

if let Some(lsp_types::DocumentChanges::Operations(ops)) =
workspace_edit.document_changes.as_ref()
{
for op in ops {
if let lsp_types::DocumentChangeOperation::Op(doc_change_op) = op {
if let Err(err) =
resource_ops_supported(&snap.config, resolve_resource_op(doc_change_op))
{
return Err(err);
}
}
}
}

Ok(Some(workspace_edit))
}

Expand Down Expand Up @@ -1137,6 +1154,20 @@ pub(crate) fn handle_code_action(
let resolve_data =
if code_action_resolve_cap { Some((index, params.clone())) } else { None };
let code_action = to_proto::code_action(&snap, assist, resolve_data)?;

// Check if the client supports the necessary `ResourceOperation`s.
if let Some(changes) = &code_action.edit.as_ref().unwrap().document_changes {
for change in changes {
if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
if let Err(err) =
resource_ops_supported(&snap.config, resolve_resource_op(res_op))
{
return Err(err);
}
}
}
}

res.push(code_action)
}

Expand Down Expand Up @@ -1219,6 +1250,21 @@ pub(crate) fn handle_code_action_resolve(
let ca = to_proto::code_action(&snap, assist.clone(), None)?;
code_action.edit = ca.edit;
code_action.command = ca.command;

if let Some(edit) = code_action.edit.as_ref() {
if let Some(changes) = edit.document_changes.as_ref() {
for change in changes {
if let lsp_ext::SnippetDocumentChangeOperation::Op(res_op) = change {
if let Err(err) =
resource_ops_supported(&snap.config, resolve_resource_op(res_op))
{
return Err(err);
}
}
}
}
}

Ok(code_action)
}

Expand Down Expand Up @@ -1990,3 +2036,43 @@ fn to_url(path: VfsPath) -> Option<Url> {
let str_path = path.as_os_str().to_str()?;
Url::from_file_path(str_path).ok()
}

fn resource_ops_supported(config: &Config, kind: ResourceOperationKind) -> anyhow::Result<()> {
let ctn = config
.caps()
.workspace
.as_ref()
.unwrap()
.workspace_edit
.as_ref()
.unwrap()
.resource_operations
.as_ref()
.unwrap()
.contains(&kind);

if !ctn {
return Err(LspError::new(
ErrorCode::RequestFailed as i32,
format!(
"Client does not support {} capability.",
match kind {
ResourceOperationKind::Create => "create",
ResourceOperationKind::Rename => "rename",
ResourceOperationKind::Delete => "delete",
}
),
)
.into());
}

Ok(())
}

fn resolve_resource_op(op: &ResourceOp) -> ResourceOperationKind {
match op {
ResourceOp::Create(_) => ResourceOperationKind::Create,
ResourceOp::Rename(_) => ResourceOperationKind::Rename,
ResourceOp::Delete(_) => ResourceOperationKind::Delete,
}
}
8 changes: 8 additions & 0 deletions crates/rust-analyzer/tests/slow-tests/support.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,14 @@ impl<'a> Project<'a> {
relative_pattern_support: None,
},
),
workspace_edit: Some(lsp_types::WorkspaceEditClientCapabilities {
resource_operations: Some(vec![
lsp_types::ResourceOperationKind::Create,
lsp_types::ResourceOperationKind::Delete,
lsp_types::ResourceOperationKind::Rename,
]),
..Default::default()
}),
..Default::default()
}),
text_document: Some(lsp_types::TextDocumentClientCapabilities {
Expand Down

0 comments on commit 891331c

Please sign in to comment.