diff --git a/src/core/sv_parser.rs b/src/core/sv_parser.rs index baef08f..2f22df5 100644 --- a/src/core/sv_parser.rs +++ b/src/core/sv_parser.rs @@ -158,6 +158,55 @@ pub fn make_fast_from_syntaxtree(syntax_tree: &SyntaxTree, path: &PathBuf) -> Re } } } + RefNode::ParameterDeclaration(x) => { + if let Some(id) = unwrap_node!(x, ParameterIdentifier) { + let id = get_identifier(id).unwrap(); + let name = syntax_tree.get_str(&id).unwrap(); + match unwrap_node!(x, ParameterDeclarationParam, ParameterPortDeclarationParamList) { + Some(RefNode::ParameterDeclarationParam(param_node)) => { + // println!("{:?}", param_node); + let keyword_locate = param_node.nodes.0.nodes.0; + // println!("keyword {:#?}", keyword_locate); + let (start_line, start_character) = (id.line, get_column_by_offset(&content, keyword_locate.offset) as u32); + let (mut end_line, mut end_character) = (id.line, start_character + id.len as u32); + let net_type = match unwrap_node!(param_node, DataType) { + Some(RefNode::DataType(data_type)) => { + let id = unwrap_node!(data_type, SimpleIdentifier, Keyword); + if id == None { + "wire" + } else { + let id = get_identifier(id.unwrap()).unwrap(); + syntax_tree.get_str(&id).unwrap() + } + } + _ => "wire" + }; + let init = if let Some(init) = unwrap_node!(param_node, ConstantMintypmaxExpression) { + match init { + RefNode::ConstantMintypmaxExpression(expression) => { + // println!("expression {:?}", x); + let param_init = sv_parser::NeedParseExpression::Parameter(expression.clone()); + let (exp, last_locate) = parse_expression(&syntax_tree, ¶m_init); + (end_line, end_character) = if last_locate != None { + // println!("param {:?} lastlocate {:?}", name, last_locate); + (last_locate.unwrap().line, (get_column_by_offset(&content, last_locate.unwrap().offset) + last_locate.unwrap().len) as u32) + } else { + (end_line, end_character) + }; + // println!("end pos {} {}", end_line, end_character); + exp + } + _ => "unknown".to_string() + } + } else { + "unknown".to_string() + }; + hdlparam.add_parameter(name, net_type, init.as_str(), start_line, start_character, end_line, end_character); + } + _ => () + } + } + } RefNode::PortDeclaration(x) => { if let Some(id) = unwrap_node!(x, InputDeclaration, OutputDeclaration, InoutDeclaration) { let id = get_identifier(id).unwrap(); diff --git a/src/hover/vhdl.rs b/src/hover/vhdl.rs index 24269b5..247fa46 100644 --- a/src/hover/vhdl.rs +++ b/src/hover/vhdl.rs @@ -1,9 +1,47 @@ +use std::{path::PathBuf, str::FromStr}; + +use log::info; use tower_lsp::lsp_types::*; use crate::server::LSPServer; +use super::{from_lsp_pos, to_escape_path}; + pub fn hover(server: &LSPServer, params: &HoverParams) -> Option { - let design_file = server.srcs.design_file_map.write().unwrap(); - - - None + let uri = ¶ms.text_document_position_params.text_document.uri; + let pos = params.text_document_position_params.position; + let file_id = server.srcs.get_id(&uri).to_owned(); + server.srcs.wait_parse_ready(file_id, false); + let projects = server.srcs.design_file_map.read().ok()?; + + let path = match PathBuf::from_str(uri.path()) { + Ok(path) => path, + Err(error) => { + info!("error happen in : {:?}", error); + return None; + } + }; + let escape_path = to_escape_path(&path); + let escape_path_string = escape_path.to_str().unwrap_or(""); + if escape_path_string.len() == 0 { + info!("error happen in [vhdl_parser_pipeline], escape_path_string is empty"); + return None; + } + let project = match projects.get(escape_path_string) { + Some(project) => project, + None => return None + }; + + let source = project.get_source(&escape_path)?; + + let ent = project.find_declaration(&source, from_lsp_pos(pos))?; + + let value = project.format_declaration(ent)?; + + Some(Hover { + contents: HoverContents::Markup(MarkupContent { + kind: MarkupKind::Markdown, + value: format!("```vhdl\n{value}\n```"), + }), + range: None, + }) } \ No newline at end of file