wat_service 0.1.0

WebAssembly Text Format language service.
Documentation
use crate::{
    binder::{SymbolItemKind, SymbolTable},
    helpers,
    idx::IdentsCtx,
    LanguageService,
};
use line_index::LineIndex;
use lsp_types::{Diagnostic, DiagnosticSeverity};

pub fn check(
    service: &LanguageService,
    diags: &mut Vec<Diagnostic>,
    line_index: &LineIndex,
    symbol_table: &SymbolTable,
) {
    let diagnostics = symbol_table
        .symbols
        .iter()
        .filter(|symbol| match &symbol.kind {
            SymbolItemKind::Module
            | SymbolItemKind::Func
            | SymbolItemKind::Param
            | SymbolItemKind::Local
            | SymbolItemKind::Type
            | SymbolItemKind::GlobalDef
            | SymbolItemKind::MemoryDef
            | SymbolItemKind::TableDef
            | SymbolItemKind::BlockDef => false,
            SymbolItemKind::Call
            | SymbolItemKind::TypeUse
            | SymbolItemKind::GlobalRef
            | SymbolItemKind::MemoryRef
            | SymbolItemKind::TableRef => !symbol_table
                .find_defs(&symbol.key)
                .is_some_and(|defs| defs.count() > 0),
            SymbolItemKind::LocalRef => symbol_table.find_param_or_local_def(&symbol.key).is_none(),
            SymbolItemKind::BlockRef => !symbol_table
                .blocks
                .iter()
                .any(|(ref_key, _, idx)| ref_key == &symbol.key && symbol.idx.is_defined_by(idx)),
        })
        .map(|symbol| Diagnostic {
            range: helpers::rowan_range_to_lsp_range(line_index, symbol.key.ptr.text_range()),
            severity: Some(DiagnosticSeverity::ERROR),
            source: Some("wat".into()),
            message: format!(
                "cannot find `{}` in this scope",
                symbol
                    .idx
                    .name
                    .map(|name| service.lookup_ident(name))
                    .or_else(|| symbol.idx.num.map(|num| num.to_string()))
                    .unwrap_or_default()
            ),
            ..Default::default()
        });
    diags.extend(diagnostics);
}