diff --git a/crates/ruff_server/src/server.rs b/crates/ruff_server/src/server.rs index dfdea1e252154..0374217fb95b3 100644 --- a/crates/ruff_server/src/server.rs +++ b/crates/ruff_server/src/server.rs @@ -224,7 +224,7 @@ impl Server { CodeActionOptions { code_action_kinds: Some( SupportedCodeAction::all() - .flat_map(|action| action.kinds().into_iter()) + .map(SupportedCodeAction::to_kind) .collect(), ), work_done_progress_options: WorkDoneProgressOptions { @@ -284,18 +284,21 @@ pub(crate) enum SupportedCodeAction { } impl SupportedCodeAction { - /// Returns the possible LSP code action kind(s) that map to this code action. - fn kinds(self) -> Vec { + /// Returns the LSP code action kind that map to this code action. + fn to_kind(self) -> CodeActionKind { match self { - Self::QuickFix => vec![CodeActionKind::QUICKFIX], - Self::SourceFixAll => vec![CodeActionKind::SOURCE_FIX_ALL, crate::SOURCE_FIX_ALL_RUFF], - Self::SourceOrganizeImports => vec![ - CodeActionKind::SOURCE_ORGANIZE_IMPORTS, - crate::SOURCE_ORGANIZE_IMPORTS_RUFF, - ], + Self::QuickFix => CodeActionKind::QUICKFIX, + Self::SourceFixAll => crate::SOURCE_FIX_ALL_RUFF, + Self::SourceOrganizeImports => crate::SOURCE_ORGANIZE_IMPORTS_RUFF, } } + fn from_kind(kind: CodeActionKind) -> impl Iterator { + Self::all().filter(move |supported_kind| { + supported_kind.to_kind().as_str().starts_with(kind.as_str()) + }) + } + /// Returns all code actions kinds that the server currently supports. fn all() -> impl Iterator { [ @@ -306,16 +309,3 @@ impl SupportedCodeAction { .into_iter() } } - -impl TryFrom for SupportedCodeAction { - type Error = (); - - fn try_from(kind: CodeActionKind) -> std::result::Result { - for supported_kind in Self::all() { - if supported_kind.kinds().contains(&kind) { - return Ok(supported_kind); - } - } - Err(()) - } -} diff --git a/crates/ruff_server/src/server/api/requests/code_action.rs b/crates/ruff_server/src/server/api/requests/code_action.rs index 0d697b0e59196..49f969918c541 100644 --- a/crates/ruff_server/src/server/api/requests/code_action.rs +++ b/crates/ruff_server/src/server/api/requests/code_action.rs @@ -112,14 +112,14 @@ fn fix_all(snapshot: &DocumentSnapshot) -> crate::Result { None, ) }; - let action = types::CodeAction { + + Ok(CodeActionOrCommand::CodeAction(types::CodeAction { title: format!("{DIAGNOSTIC_NAME}: Fix all auto-fixable problems"), - kind: Some(types::CodeActionKind::SOURCE_FIX_ALL), + kind: Some(crate::SOURCE_FIX_ALL_RUFF), edit, data, ..Default::default() - }; - Ok(types::CodeActionOrCommand::CodeAction(action)) + })) } fn organize_imports(snapshot: &DocumentSnapshot) -> crate::Result { @@ -147,14 +147,14 @@ fn organize_imports(snapshot: &DocumentSnapshot) -> crate::Result Result { let document = snapshot.document(); - let action_kind: SupportedCodeAction = action - .kind - .clone() - .ok_or(anyhow::anyhow!("No kind was given for code action")) - .with_failure_code(ErrorCode::InvalidParams)? - .try_into() - .map_err(|()| anyhow::anyhow!("Code action was of an invalid kind")) - .with_failure_code(ErrorCode::InvalidParams)?; + let code_actions = SupportedCodeAction::from_kind( + action + .kind + .clone() + .ok_or(anyhow::anyhow!("No kind was given for code action")) + .with_failure_code(ErrorCode::InvalidParams)?, + ) + .collect::>(); + + // Ensure that the code action maps to _exactly one_ supported code action + let [action_kind] = code_actions.as_slice() else { + return Err(anyhow::anyhow!( + "Code action resolver did not expect code action kind {:?}", + action.kind.as_ref().unwrap() + )) + .with_failure_code(ErrorCode::InvalidParams); + }; action.edit = match action_kind { SupportedCodeAction::SourceFixAll => Some(