cairo-language-server 2.17.0-rc.2

The Cairo Language Server
Documentation
use cairo_lang_filesystem::ids::{FileId, SpanInFile};
use cairo_lang_syntax::node::ast::TerminalIdentifier;
use cairo_lang_syntax::node::{SyntaxNode, TypedSyntaxNode};
use cairo_language_common::CommonGroup;
use itertools::Itertools;
use lsp_types::{DocumentHighlight, DocumentHighlightParams};

use crate::lang::db::{AnalysisDatabase, LsSyntaxGroup};
use crate::lang::defs::SymbolSearch;
use crate::lang::lsp::{LsProtoGroup, ToCairo, ToLsp};
use crate::lang::usages::search_scope::SearchScope;

pub fn highlight(
    params: DocumentHighlightParams,
    db: &AnalysisDatabase,
) -> Option<Vec<DocumentHighlight>> {
    let file = db.file_for_url(&params.text_document_position_params.text_document.uri)?;
    let position = params.text_document_position_params.position.to_cairo();

    let identifier = db.find_identifier_at_position(file, position)?.as_syntax_node();

    let default = vec![identifier];
    let highlights = db
        .get_node_resultants(identifier)
        .unwrap_or(&default)
        .iter()
        .filter_map(|node| highlights(db, node, file))
        .flatten()
        .unique()
        .map(|range| DocumentHighlight { range, kind: None })
        .collect();

    Some(highlights)
}

fn highlights<'db>(
    db: &'db AnalysisDatabase,
    syntax_node: &SyntaxNode<'db>,
    file: FileId<'db>,
) -> Option<Vec<lsp_types::Range>> {
    let identifier =
        syntax_node.ancestors_with_self(db).find_map(|node| TerminalIdentifier::cast(db, node))?;
    let symbol_search = SymbolSearch::find_definition(db, &identifier)?;

    let highlights = symbol_search
        .usages(db)
        .include_declaration(true)
        .in_scope(SearchScope::file_with_subfiles(db, file))
        .originating_locations(db)
        .filter(|found| found.file_id == file)
        .filter_map(|SpanInFile { file_id, span }: SpanInFile<'_>| {
            span.position_in_file(db, file_id).as_ref().map(ToLsp::to_lsp)
        })
        .collect();

    Some(highlights)
}