57 lines
1.8 KiB
Rust

#[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<Vec<DocumentHighlight>> {
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
}