From 72525e94e6021d9995a4c22df19c78e602a8405b Mon Sep 17 00:00:00 2001 From: Pig Fang Date: Tue, 24 Dec 2024 18:37:09 +0800 Subject: [PATCH] refactor(service): respect diagnostics in code action --- crates/service/src/features/code_action.rs | 23 ++++++---- .../src/refactorings/fix_invalid_mem_arg.rs | 19 +++++++- .../tests/code_action/fix_invalid_mem_arg.rs | 25 +++++++++- ...x_invalid_mem_arg__around_whitespaces.snap | 1 + ...ion__fix_invalid_mem_arg__diagnostics.snap | 46 +++++++++++++++++++ ...x_invalid_mem_arg__leading_whitespace.snap | 1 + ..._invalid_mem_arg__trailing_whitespace.snap | 1 + 7 files changed, 106 insertions(+), 10 deletions(-) create mode 100644 crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__diagnostics.snap diff --git a/crates/service/src/features/code_action.rs b/crates/service/src/features/code_action.rs index 8dab998..f6593de 100644 --- a/crates/service/src/features/code_action.rs +++ b/crates/service/src/features/code_action.rs @@ -10,13 +10,19 @@ impl LanguageService { let mut quickfix = params.context.only.is_none(); let mut rewrite = params.context.only.is_none(); - params.context.only.into_iter().flatten().for_each(|kind| { - if kind == CodeActionKind::QUICKFIX { - quickfix = true; - } else if kind == CodeActionKind::REFACTOR_REWRITE { - rewrite = true; - } - }); + params + .context + .only + .iter() + .flatten() + .cloned() + .for_each(|kind| { + if kind == CodeActionKind::QUICKFIX { + quickfix = true; + } else if kind == CodeActionKind::REFACTOR_REWRITE { + rewrite = true; + } + }); let mut actions = vec![]; let range = helpers::lsp_range_to_rowan_range(&line_index, params.range)?; @@ -25,7 +31,8 @@ impl LanguageService { match it.kind() { SyntaxKind::PLAIN_INSTR => { if quickfix { - if let Some(action) = fix_invalid_mem_arg::act(self, uri, &line_index, &it) + if let Some(action) = + fix_invalid_mem_arg::act(self, uri, &line_index, &it, ¶ms.context) { actions.push(CodeActionOrCommand::CodeAction(action)); } diff --git a/crates/service/src/refactorings/fix_invalid_mem_arg.rs b/crates/service/src/refactorings/fix_invalid_mem_arg.rs index 17f7600..7b3a99c 100644 --- a/crates/service/src/refactorings/fix_invalid_mem_arg.rs +++ b/crates/service/src/refactorings/fix_invalid_mem_arg.rs @@ -1,6 +1,8 @@ use crate::{files::FilesCtx, helpers, InternUri, LanguageService}; use line_index::LineIndex; -use lsp_types::{CodeAction, CodeActionKind, TextEdit, WorkspaceEdit}; +use lsp_types::{ + CodeAction, CodeActionContext, CodeActionKind, NumberOrString, TextEdit, WorkspaceEdit, +}; use rowan::{ast::AstNode, SyntaxElementChildren, TextRange}; use std::collections::HashMap; use wat_syntax::{ast::Operand, SyntaxElement, SyntaxKind, SyntaxNode, WatLanguage}; @@ -10,6 +12,7 @@ pub fn act( uri: InternUri, line_index: &LineIndex, node: &SyntaxNode, + context: &CodeActionContext, ) -> Option { let mut text_edits = vec![]; @@ -86,6 +89,20 @@ pub fn act( ..Default::default() }), is_preferred: Some(true), + diagnostics: Some( + context + .diagnostics + .iter() + .filter(|diagnostic| { + if let Some(NumberOrString::String(s)) = &diagnostic.code { + s.starts_with("syntax/") + } else { + false + } + }) + .cloned() + .collect(), + ), ..Default::default() }) } diff --git a/crates/service/tests/code_action/fix_invalid_mem_arg.rs b/crates/service/tests/code_action/fix_invalid_mem_arg.rs index e7a11ac..95f1b92 100644 --- a/crates/service/tests/code_action/fix_invalid_mem_arg.rs +++ b/crates/service/tests/code_action/fix_invalid_mem_arg.rs @@ -1,6 +1,6 @@ use super::*; use insta::assert_json_snapshot; -use lsp_types::{Position, Range, Uri}; +use lsp_types::{Diagnostic, NumberOrString, Position, Range, Uri}; use wat_service::LanguageService; #[test] @@ -53,3 +53,26 @@ fn around_whitespaces() { )); assert_json_snapshot!(response); } + +#[test] +fn diagnostics() { + let uri = "untitled:test".parse::().unwrap(); + let source = " +(module + (func (i32.load align =1)) +) +"; + let mut service = LanguageService::default(); + service.commit(uri.clone(), source.into()); + let mut params = create_params(uri, Range::new(Position::new(2, 25), Position::new(2, 25))); + params.context = CodeActionContext { + diagnostics: vec![Diagnostic { + message: "syntax error: expected operand".into(), + code: Some(NumberOrString::String("syntax/operand".into())), + ..Default::default() + }], + ..Default::default() + }; + let response = service.code_action(params); + assert_json_snapshot!(response); +} diff --git a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__around_whitespaces.snap b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__around_whitespaces.snap index a4146e9..2448910 100644 --- a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__around_whitespaces.snap +++ b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__around_whitespaces.snap @@ -6,6 +6,7 @@ expression: response { "title": "Fix invalid memory argument", "kind": "quickfix", + "diagnostics": [], "edit": { "changes": { "untitled:test": [ diff --git a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__diagnostics.snap b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__diagnostics.snap new file mode 100644 index 0000000..616f8de --- /dev/null +++ b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__diagnostics.snap @@ -0,0 +1,46 @@ +--- +source: crates/service/tests/code_action/fix_invalid_mem_arg.rs +expression: response +--- +[ + { + "title": "Fix invalid memory argument", + "kind": "quickfix", + "diagnostics": [ + { + "range": { + "start": { + "line": 0, + "character": 0 + }, + "end": { + "line": 0, + "character": 0 + } + }, + "code": "syntax/operand", + "message": "syntax error: expected operand" + } + ], + "edit": { + "changes": { + "untitled:test": [ + { + "range": { + "start": { + "line": 2, + "character": 25 + }, + "end": { + "line": 2, + "character": 26 + } + }, + "newText": "" + } + ] + } + }, + "isPreferred": true + } +] diff --git a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__leading_whitespace.snap b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__leading_whitespace.snap index dffcdcf..1bcdc03 100644 --- a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__leading_whitespace.snap +++ b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__leading_whitespace.snap @@ -6,6 +6,7 @@ expression: response { "title": "Fix invalid memory argument", "kind": "quickfix", + "diagnostics": [], "edit": { "changes": { "untitled:test": [ diff --git a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__trailing_whitespace.snap b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__trailing_whitespace.snap index 3a3253b..5353901 100644 --- a/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__trailing_whitespace.snap +++ b/crates/service/tests/code_action/snapshots/features__code_action__fix_invalid_mem_arg__trailing_whitespace.snap @@ -6,6 +6,7 @@ expression: response { "title": "Fix invalid memory argument", "kind": "quickfix", + "diagnostics": [], "edit": { "changes": { "untitled:test": [