riscv_analysis_lsp 0.1.0-alpha

RISC-V static analysis tool -- LSP helpers
Documentation
use lsp_types::CompletionItem;

use riscv_analysis::parser::{Inst, LabelString, Register};

pub enum RVCompletionItem {
    Inst(Inst),
    Register(Register),
    Label(LabelString),
    FunctionLabel(LabelString),
}

impl From<Register> for RVCompletionItem {
    fn from(value: Register) -> Self {
        RVCompletionItem::Register(value)
    }
}

impl From<Inst> for RVCompletionItem {
    fn from(value: Inst) -> Self {
        RVCompletionItem::Inst(value)
    }
}

impl From<LabelString> for RVCompletionItem {
    fn from(value: LabelString) -> Self {
        RVCompletionItem::Label(value)
    }
}

impl From<RVCompletionItem> for CompletionItem {
    fn from(value: RVCompletionItem) -> Self {
        match value {
            RVCompletionItem::Register(r) => {
                let mut item = CompletionItem::new_simple(
                    r.to_string(),
                    format!(
                        "Register {}",
                        r.all_representations()
                            .into_iter()
                            .collect::<Vec<String>>()
                            .join(", ")
                    ),
                );
                item.kind = Some(lsp_types::CompletionItemKind::VARIABLE);
                item.filter_text = Some(
                    r.all_representations()
                        .into_iter()
                        .collect::<Vec<String>>()
                        .join(" "),
                );
                item
            }
            RVCompletionItem::Inst(i) => {
                let mut item =
                    CompletionItem::new_simple(i.to_string(), format!("Instruction {i}"));
                item.kind = Some(lsp_types::CompletionItemKind::FUNCTION);
                item
            }
            RVCompletionItem::Label(l) => {
                CompletionItem::new_simple(l.to_string(), format!("Label {l}"))
            }
            RVCompletionItem::FunctionLabel(l) => {
                CompletionItem::new_simple(l.to_string(), format!("Function {l}"))
            }
        }
    }
}

impl RVCompletionItem {
    fn get_registers() -> Vec<CompletionItem> {
        Register::all()
            .into_iter()
            .map(|r| RVCompletionItem::from(r).into())
            .collect()
    }

    fn get_instructions() -> Vec<CompletionItem> {
        Inst::all()
            .into_iter()
            .map(|i| RVCompletionItem::from(i).into())
            .collect()
    }

    pub fn get_all() -> Vec<CompletionItem> {
        let mut items = RVCompletionItem::get_registers();
        items.extend(RVCompletionItem::get_instructions());
        items
    }
}