wat_service 0.7.0

WebAssembly Text Format language service.
Documentation
use crate::{
    LanguageService,
    binder::{SymbolKind, SymbolTable},
    config::LintLevel,
    deprecation,
    document::Document,
    helpers,
};
use line_index::LineIndex;
use lspt::{Diagnostic, DiagnosticSeverity, DiagnosticTag, Union2};

const DIAGNOSTIC_CODE: &str = "deprecated";

pub fn check(
    diagnostics: &mut Vec<Diagnostic>,
    service: &LanguageService,
    document: Document,
    lint_level: LintLevel,
    line_index: &LineIndex,
    symbol_table: &SymbolTable,
) {
    let severity = match lint_level {
        LintLevel::Allow => return,
        LintLevel::Hint => DiagnosticSeverity::Hint,
        LintLevel::Warn => DiagnosticSeverity::Warning,
        LintLevel::Deny => DiagnosticSeverity::Error,
    };
    let deprecation = deprecation::get_deprecation(service, document);
    let deprecated_usage = symbol_table
        .symbols
        .values()
        .filter(|symbol| {
            matches!(
                symbol.kind,
                SymbolKind::Call
                    | SymbolKind::TypeUse
                    | SymbolKind::GlobalRef
                    | SymbolKind::MemoryRef
                    | SymbolKind::TableRef
                    | SymbolKind::TagRef
            )
        })
        .filter_map(|symbol| {
            symbol_table
                .resolved
                .get(&symbol.key)
                .and_then(|def_key| deprecation.get(def_key))
                .map(|reason| Diagnostic {
                    range: helpers::rowan_range_to_lsp_range(line_index, symbol.key.text_range()),
                    severity: Some(severity),
                    source: Some("wat".into()),
                    code: Some(Union2::B(DIAGNOSTIC_CODE.into())),
                    message: if let Some(reason) = reason {
                        format!(
                            "{} `{}` is deprecated: {reason}",
                            symbol.kind,
                            symbol.idx.render(service),
                        )
                    } else {
                        format!(
                            "{} `{}` is deprecated",
                            symbol.kind,
                            symbol.idx.render(service),
                        )
                    },
                    tags: Some(vec![DiagnosticTag::Deprecated]),
                    ..Default::default()
                })
        });
    diagnostics.extend(deprecated_usage);
}