#[allow(unused)] use log::info; use sv_parser::{RefNode, SyntaxTree}; use tower_lsp::lsp_types::*; use crate::{server::LspServer, sources::{AstLike, LSPSupport, Source}, utils::from_uri_to_escape_path_string}; use crate::core::scope_tree::parse::get_ident; use crate::core::scope_tree::common::Scope; pub fn document_highlight( server: &LspServer, token: &str, file: &Source, pos: Position, uri: &Url ) -> Option> { let scope_tree = server.db.scope_tree.read().ok()?; let path_string = from_uri_to_escape_path_string(uri).unwrap(); // use the byte_idx of the definition if possible, otherwise use the cursor let byte_idx = match scope_tree.as_ref()?.get_definition(token, file.text.pos_to_byte(&pos), uri) { Some(def) => def.byte_idx, None => file.text.pos_to_byte(&pos), }; // 获取对应的 AST let path_to_hdl_file = server.db.hdl_param.path_to_hdl_file.read().unwrap(); if let Some(hdl_file) = path_to_hdl_file.get(&path_string) { if let Some(AstLike::Svlog(syntax_tree)) = &hdl_file.ast_like { let references = all_identifiers(&syntax_tree, &token); let highlights = scope_tree.as_ref()?.document_highlights(&uri, &file.text, references, byte_idx); Some(highlights) } else { None } } else { None } } /// return all identifiers in a syntax tree matching a given token fn all_identifiers(syntax_tree: &SyntaxTree, token: &str) -> Vec<(String, usize)> { let mut idents: Vec<(String, usize)> = Vec::new(); for node in syntax_tree { if let RefNode::Identifier(_) = node { let (ident, byte_idx) = get_ident(syntax_tree, node); if ident == token { idents.push((ident, byte_idx)); } } } idents }