Handle a `codeAction/resolve` request. The editor sends back a `CodeAction` that was previously returned by [`handle_code_action`](Self::handle_code_action) with a `data` field but no `edit`. This method deserializes the data, computes the full workspace edit, and returns the completed action. For PHPStan quickfixes the matched diagnostic is also eagerly removed from the cache and updated diagn
(&self, mut action: CodeAction)
| 246 | /// removed from the cache and updated diagnostics are returned via |
| 247 | /// the `diagnostics_to_republish` output parameter. |
| 248 | pub fn resolve_code_action(&self, mut action: CodeAction) -> (CodeAction, Option<String>) { |
| 249 | let data_value = match &action.data { |
| 250 | Some(v) => v.clone(), |
| 251 | None => return (action, None), |
| 252 | }; |
| 253 | |
| 254 | let data: CodeActionData = match serde_json::from_value(data_value) { |
| 255 | Ok(d) => d, |
| 256 | Err(_) => return (action, None), |
| 257 | }; |
| 258 | |
| 259 | let content = match self.get_file_content(&data.uri) { |
| 260 | Some(c) => c, |
| 261 | None => return (action, None), |
| 262 | }; |
| 263 | |
| 264 | let result = match data.action_kind.as_str() { |
| 265 | // ── PHPStan quickfixes ────────────────────────────────── |
| 266 | "phpstan.addThrows" => { |
| 267 | let edit = self.resolve_add_throws(&data, &content); |
| 268 | |
| 269 | // Adding a @throws tag for an exception resolves the |
| 270 | // diagnostic for *every* throw of that exception in |
| 271 | // the same function/method body. Expand the action's |
| 272 | // diagnostic list so they all get cleared at once. |
| 273 | if edit.is_some() { |
| 274 | self.expand_sibling_checked_exception_diags(&data, &content, &mut action); |
| 275 | } |
| 276 | |
| 277 | edit |
| 278 | } |
| 279 | "phpstan.removeThrows" => self.resolve_remove_throws(&data, &content), |
| 280 | "phpstan.addOverride" => self.resolve_add_override(&data, &content), |
| 281 | "phpstan.addIgnore" => self.resolve_add_ignore(&data, &content), |
| 282 | "phpstan.removeIgnore" => self.resolve_remove_ignore(&data, &content), |
| 283 | "phpstan.removeOverride" => self.resolve_remove_override(&data, &content), |
| 284 | "phpstan.addReturnTypeWillChange" => { |
| 285 | self.resolve_add_return_type_will_change(&data, &content) |
| 286 | } |
| 287 | "phpstan.fixPhpDocType.update" | "phpstan.fixPhpDocType.remove" => { |
| 288 | self.resolve_fix_phpdoc_type(&data, &content) |
| 289 | } |
| 290 | "phpstan.newStatic.addTag" |
| 291 | | "phpstan.newStatic.finalClass" |
| 292 | | "phpstan.newStatic.finalConstructor" => self.resolve_new_static(&data, &content), |
| 293 | // ── Fix prefixed class name ───────────────────────────── |
| 294 | "phpstan.fixPrefixedClass" => self.resolve_fix_prefixed_class(&data, &content), |
| 295 | // ── Remove always-true assert() ───────────────────────── |
| 296 | "phpstan.removeAssert" => self.resolve_remove_assert(&data, &content), |
| 297 | // ── Fix return type ───────────────────────────────────── |
| 298 | "phpstan.fixReturnType.stripExpr" |
| 299 | | "phpstan.fixReturnType.changeTypeToActual" |
| 300 | | "phpstan.fixReturnType.changeType" |
| 301 | | "phpstan.fixReturnType.addType" |
| 302 | | "phpstan.fixReturnType.updateReturnType" => { |
| 303 | self.resolve_fix_return_type(&data, &content) |
| 304 | } |
| 305 | // ── Remove unused return type ──────────────────────────── |