wat_service 0.5.1

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

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

pub fn check(diagnostics: &mut Vec<Diagnostic>, line_index: &LineIndex, node: &SyntaxNode) {
    diagnostics.extend(
        support::children::<Instr>(node)
            .filter(|instr| match instr {
                Instr::Plain(plain) => {
                    let Some(instr_name) = plain.instr_name() else {
                        return false;
                    };
                    let instr_name = instr_name.text();
                    !instr_name.ends_with(".const")
                        && !matches!(
                            instr_name,
                            "global.get"
                                | "ref.null"
                                | "ref.i31"
                                | "ref.func"
                                | "struct.new"
                                | "struct.new_default"
                                | "array.new"
                                | "array.new_default"
                                | "array.new_fixed"
                                | "any.convert_extern"
                                | "extern.convert_any"
                        )
                }
                Instr::Block(..) => true,
            })
            .map(|instr| Diagnostic {
                range: helpers::rowan_range_to_lsp_range(line_index, instr.syntax().text_range()),
                severity: Some(DiagnosticSeverity::Error),
                source: Some("wat".into()),
                code: Some(Union2::B(DIAGNOSTIC_CODE.into())),
                message: "expression must be constant".into(),
                ..Default::default()
            }),
    );
}