wat_service 0.10.0

WebAssembly Text Format language service.
Documentation
use super::{Diagnostic, DiagnosticCtx};
use crate::types_analyzer::{join_types, resolve_br_types};
use bumpalo::collections::Vec as BumpVec;
use wat_syntax::{AmberNode, AmberToken, SyntaxKind};

const DIAGNOSTIC_CODE: &str = "br-table-branches";

pub fn check(
    diagnostics: &mut Vec<Diagnostic>,
    ctx: &DiagnosticCtx,
    node: AmberNode,
    instr_name: AmberToken,
) -> Option<()> {
    if instr_name.text() != "br_table" {
        return None;
    }
    let mut immediates = node.children_by_kind(SyntaxKind::IMMEDIATE);
    let expected = BumpVec::from_iter_in(
        immediates.next().and_then(|immediate| {
            resolve_br_types(ctx.db, ctx.document, ctx.symbol_table, immediate.to_ptr().into())
        })?,
        ctx.bump,
    );
    diagnostics.extend(immediates.filter_map(|immediate| {
        let received = BumpVec::from_iter_in(
            resolve_br_types(ctx.db, ctx.document, ctx.symbol_table, immediate.to_ptr().into())?,
            ctx.bump,
        );
        if received != expected {
            Some(Diagnostic {
                range: immediate.text_range(),
                code: DIAGNOSTIC_CODE.into(),
                message: format!(
                    "type mismatch in `br_table`: expected {}, found {}",
                    join_types(ctx.db, expected.iter(), "", ctx.bump),
                    join_types(ctx.db, received.iter(), "", ctx.bump),
                ),
                ..Default::default()
            })
        } else {
            None
        }
    }));
    Some(())
}