wat_service 0.8.0

WebAssembly Text Format language service.
Documentation
use crate::{data_set::CONST_INSTRS, helpers};
use line_index::LineIndex;
use lspt::{Diagnostic, DiagnosticSeverity, Range, Union2};
use rowan::ast::AstNode;
use wat_syntax::{SyntaxNode, ast::Instr};

const DIAGNOSTIC_CODE: &str = "const-expr";

pub fn check(line_index: &LineIndex, node: &SyntaxNode) -> Option<Diagnostic> {
    let first = node.first_child_by_kind(&Instr::can_cast)?;
    let last = node
        .children()
        .filter(|child| Instr::can_cast(child.kind()))
        .last()?;
    if node.descendants().filter_map(Instr::cast).all(|instr| {
        if let Instr::Plain(plain) = instr {
            plain
                .instr_name()
                .is_some_and(|instr_name| CONST_INSTRS.contains(&instr_name.text()))
        } else {
            false
        }
    }) {
        None
    } else {
        Some(Diagnostic {
            range: Range {
                start: helpers::rowan_pos_to_lsp_pos(line_index, first.text_range().start()),
                end: helpers::rowan_pos_to_lsp_pos(line_index, last.text_range().end()),
            },
            severity: Some(DiagnosticSeverity::Error),
            source: Some("wat".into()),
            code: Some(Union2::B(DIAGNOSTIC_CODE.into())),
            message: "expression must be constant".into(),
            ..Default::default()
        })
    }
}