add primitives port hover

This commit is contained in:
light-ly 2024-11-13 02:14:00 +08:00
parent eb210bb3b7
commit 41b2db2eba
2 changed files with 71 additions and 10 deletions

View File

@ -5,6 +5,7 @@ use std::{collections::HashMap, fs::File};
use std::io::{BufReader, Read}; use std::io::{BufReader, Read};
use bincode::Error; use bincode::Error;
use regex::Regex;
use ropey::Rope; use ropey::Rope;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
use sv_parser::{unwrap_node, RefNode}; use sv_parser::{unwrap_node, RefNode};
@ -28,6 +29,27 @@ impl PrimitiveText {
let mut text_map = self.name_to_text.write().unwrap(); let mut text_map = self.name_to_text.write().unwrap();
text_map.insert(name.to_owned(), text.to_owned()); text_map.insert(name.to_owned(), text.to_owned());
} }
pub fn get_comment(&self, name: &str, text: &str) -> String {
if let Some(comment) = PrimitiveText::extract_pattern_comments(text).get(name) {
(*comment).clone()
} else {
"".to_string()
}
}
fn extract_pattern_comments(text: &str) -> HashMap<String, String> {
let re = Regex::new(r"\s*\.(?P<x>[^\(]+)\((?P<y>[^\)]+)\)(?:,)?\s*//\s*(?P<z>.+)").unwrap();
text.lines()
.filter_map(|line| {
re.captures(line).map(|caps| {
let name = caps.name("x").unwrap().as_str().to_string();
let comment = caps.name("z").unwrap().as_str().to_string();
(name, comment)
})
})
.collect()
}
} }
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
@ -102,7 +124,7 @@ fn xml_parser(path: &str) -> Result<PrimitiveXml, Error> {
} }
} }
Ok((primitive_xml)) Ok(primitive_xml)
} }
fn xml_parse_template(parser: &mut EventReader<BufReader<File>>) -> Option<(String, Template)> { fn xml_parse_template(parser: &mut EventReader<BufReader<File>>) -> Option<(String, Template)> {
@ -242,10 +264,11 @@ fn xml_parse_text(text: &str) -> Option<(String, String, FastHdlparam)> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::{fs::{self, File}, io::Write, path::Path}; use std::{fs::{self, File}, io::Write, path::Path};
use super::{init_parse_primitive_files, xml_parser}; use super::{init_parse_primitive_files, xml_parser};
const TESTFILE: &str = "D:\\work\\playground\\digital-lsp-server\\primitive_files\\verilog2.xml"; const TESTFILE: &str = "primitive_files/verilog2.xml";
const TESTDIR: &str = "/home/dide/project/Digital-Test/Digital-IDE-test/user/factory/xilinx"; const TESTDIR: &str = "primitive_files";
#[test] #[test]
fn gen_primitive_bin() { fn gen_primitive_bin() {

View File

@ -1,11 +1,11 @@
use std::{path::PathBuf, str::FromStr}; use std::{path::PathBuf, str::FromStr, sync::Arc};
use log::info; use log::info;
use regex::Regex; use regex::Regex;
use ropey::RopeSlice; use ropey::RopeSlice;
use tower_lsp::lsp_types::{Hover, HoverContents, LanguageString, MarkedString, Position, Range, Url}; use tower_lsp::lsp_types::{Hover, HoverContents, LanguageString, MarkedString, Position, Range, Url};
use crate::{core::{self, hdlparam::{Define, FastHdlparam}}, definition::{DefinitionType, GenericDec}, server::LSPServer}; use crate::{core::{self, hdlparam::{Define, FastHdlparam}, primitive_parser::PrimitiveText}, server::LSPServer};
use super::{get_language_id_by_path_str, get_word_range_at_position, resolve_path, to_escape_path}; use super::{get_language_id_by_path_str, get_word_range_at_position, resolve_path, to_escape_path};
@ -249,13 +249,27 @@ fn goto_instantiation<'a>(
// info!("port_range: {port_range:#?}"); // info!("port_range: {port_range:#?}");
// info!("position port find belong module: {:?}", module); // info!("position port find belong module: {:?}", module);
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
if file_type == "primitives" {
let primitives_text = server.srcs.primitive_text.clone();
let instance_assignments = &module.instances.first().unwrap().intstport_assignments;
for assignment in instance_assignments {
if assignment.port.clone().unwrap() == token_name {
let hover = make_primitives_port_desc_hover(
primitives_text, &instance.inst_type,
assignment, range, language_id
);
return Some(hover);
}
}
} else {
for port in &module.ports { for port in &module.ports {
if token_name == port.name { if token_name == port.name {
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
let hover = make_port_desc_hover(&file_type, port, range, language_id); let hover = make_port_desc_hover(&file_type, port, range, language_id);
return Some(hover); return Some(hover);
} }
} }
}
return None; return None;
} }
} }
@ -296,6 +310,30 @@ pub fn hover_position_port_param(
None None
} }
fn make_primitives_port_desc_hover(
primitives_text: Arc<PrimitiveText>,
primitives_name: &str,
inst_port: &crate::core::hdlparam::InstPort,
range: &Range, language_id: &str) -> Hover {
let name = inst_port.port.clone().unwrap();
let text_map = primitives_text.name_to_text.read().unwrap();
let comment = if let Some(text) = text_map.get(primitives_name) {
primitives_text.get_comment(&name, text)
} else {
"".to_string()
};
let language_string = LanguageString {
language: language_id.to_string(),
value: name + " // " + &comment,
};
Hover {
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
range: Some(range.clone())
}
}
fn make_port_desc_hover(file_type: &str, port: &crate::core::hdlparam::Port, range: &Range, language_id: &str) -> Hover { fn make_port_desc_hover(file_type: &str, port: &crate::core::hdlparam::Port, range: &Range, language_id: &str) -> Hover {
info!("enter make_port_desc_hover, file_type: {}", file_type); info!("enter make_port_desc_hover, file_type: {}", file_type);