wat_service 0.5.1

WebAssembly Text Format language service.
Documentation
use crate::{
    binder::{SymbolKey, SymbolTable},
    helpers,
    idx::IdentsCtx,
    uri::{InternUri, UrisCtx},
    LanguageService,
};
use line_index::LineIndex;
use lspt::{CodeAction, CodeActionKind, TextEdit, WorkspaceEdit};
use rustc_hash::FxBuildHasher;
use std::collections::HashMap;
use wat_syntax::SyntaxNode;

pub fn act(
    service: &LanguageService,
    uri: InternUri,
    line_index: &LineIndex,
    symbol_table: &SymbolTable,
    node: &SyntaxNode,
) -> Option<CodeAction> {
    let ref_key = SymbolKey::new(node);
    let ref_idx = &symbol_table
        .symbols
        .iter()
        .find(|symbol| symbol.key == ref_key)?
        .idx;
    let def_idx = symbol_table
        .find_def(ref_key)
        .or_else(|| symbol_table.find_param_or_local_def(ref_key))
        .map(|def| &def.idx)
        .or_else(|| {
            symbol_table
                .blocks
                .iter()
                .find(|block| block.ref_key == ref_key)
                .map(|block| &block.def_idx)
        })?;
    let def_num = def_idx.num?;
    let def_name = def_idx.name?;
    let (new_text, title) = if ref_idx.name.is_some() {
        (
            def_num.to_string(),
            "Convert identifier to numeric idx".into(),
        )
    } else {
        (
            service.lookup_ident(def_name).to_string(),
            "Convert numeric idx to identifier".into(),
        )
    };

    let mut changes = HashMap::with_capacity_and_hasher(1, FxBuildHasher);
    changes.insert(
        service.lookup_uri(uri),
        vec![TextEdit {
            range: helpers::rowan_range_to_lsp_range(line_index, node.text_range()),
            new_text,
        }],
    );
    Some(CodeAction {
        title,
        kind: Some(CodeActionKind::RefactorRewrite),
        edit: Some(WorkspaceEdit {
            changes: Some(changes),
            ..Default::default()
        }),
        ..Default::default()
    })
}