wat_service 0.10.2

WebAssembly Text Format language service.
Documentation
use crate::{helpers::LineIndexExt, uri::InternUri};
use line_index::LineIndex;
use lspt::{CodeAction, CodeActionContext, CodeActionKind, TextEdit, Union2, WorkspaceEdit};
use rustc_hash::FxBuildHasher;
use std::collections::HashMap;
use wat_syntax::{NodeOrToken, SyntaxKind, SyntaxNode, ast::support};

pub fn act(
    db: &dyn salsa::Database,
    uri: InternUri,
    line_index: &LineIndex,
    node: &SyntaxNode,
    context: &CodeActionContext,
) -> Option<CodeAction> {
    let mut_token = support::token(node, SyntaxKind::KEYWORD).filter(|keyword| keyword.text() == "mut")?;
    let token_lsp_range = line_index.convert(mut_token.text_range());
    let diagnostic = context.diagnostics.iter().find(|diagnostic| match &diagnostic.code {
        Some(Union2::B(code)) => code == "needless-mut" && diagnostic.range == token_lsp_range,
        _ => false,
    })?;

    let mut text_edits = Vec::with_capacity(4);
    if let Some(l_paren) = support::token(node, SyntaxKind::L_PAREN) {
        text_edits.push(TextEdit {
            range: line_index.convert(l_paren.text_range()),
            new_text: "".into(),
        });
    }
    text_edits.push(TextEdit {
        range: token_lsp_range,
        new_text: "".into(),
    });
    if let Some(whitespace) = mut_token
        .next_sibling_or_token()
        .and_then(NodeOrToken::into_token)
        .filter(|token| token.kind() == SyntaxKind::WHITESPACE)
    {
        text_edits.push(TextEdit {
            range: line_index.convert(whitespace.text_range()),
            new_text: "".into(),
        });
    }
    if let Some(r_paren) = support::token(node, SyntaxKind::R_PAREN) {
        text_edits.push(TextEdit {
            range: line_index.convert(r_paren.text_range()),
            new_text: "".into(),
        });
    }

    if text_edits.is_empty() {
        None
    } else {
        let mut changes = HashMap::with_capacity_and_hasher(1, FxBuildHasher);
        changes.insert(uri.raw(db), text_edits);
        Some(CodeAction {
            title: "Remove `mut`".into(),
            kind: Some(CodeActionKind::QuickFix),
            edit: Some(WorkspaceEdit {
                changes: Some(changes),
                ..Default::default()
            }),
            is_preferred: Some(true),
            diagnostics: Some(vec![diagnostic.clone()]),
            ..Default::default()
        })
    }
}