diff --git a/.gitmodules b/.gitmodules index e6a1deb..c21b6dc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,6 @@ [submodule "sv-parser"] path = sv-parser url = https://github.com/Digital-EDA/sv-parser -[submodule "rust_hdl"] - path = rust_hdl - url = https://github.com/Digital-EDA/rust_hdl +[submodule "vhdl-parser"] + path = vhdl-parser + url = https://github.com/Digital-EDA/vhdl-parser diff --git a/Cargo.toml b/Cargo.toml index 06f1401..3402eb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2018" [dependencies] sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"} -vhdl_lang = { version = "^0.83.0", path = "rust_hdl/vhdl_lang" } +vhdl_lang = { version = "^0.83.0", path = "vhdl-parser/vhdl_lang" } dirs-next = "2.0" bincode = "1.3" percent-encoding = "2.1.0" diff --git a/rust_hdl b/rust_hdl deleted file mode 160000 index 69fba9a..0000000 --- a/rust_hdl +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 69fba9af8cb981ce1aaeacd20ca74771f12d9aa1 diff --git a/src/completion/mod.rs b/src/completion/mod.rs index 95ebbe3..6f5ee52 100644 --- a/src/completion/mod.rs +++ b/src/completion/mod.rs @@ -11,8 +11,16 @@ impl LSPServer { pub fn completion(&self, params: CompletionParams) -> Option { let language_id = get_language_id_by_uri(¶ms.text_document_position.text_document.uri); match language_id.as_str() { - "vhdl" => vhdl::completion(self, ¶ms), - "verilog" | "systemverilog" => sv::completion(self, ¶ms), + "vhdl" => vhdl::completion( + self, + ¶ms + ), + + "verilog" | "systemverilog" => sv::completion( + self, + ¶ms + ), + _ => None } } diff --git a/src/core/cache_storage.rs b/src/core/cache_storage.rs index 4636c70..419b578 100644 --- a/src/core/cache_storage.rs +++ b/src/core/cache_storage.rs @@ -1,5 +1,4 @@ -use core::hash; -use std::{borrow::{Borrow, Cow}, collections::HashMap, fs::{self}, hash::{DefaultHasher, Hash, Hasher}, os::unix::thread, path::PathBuf, sync::{Arc, RwLock}}; +use std::{collections::HashMap, fs::{self}, hash::{DefaultHasher, Hash, Hasher}, path::PathBuf, sync::{Arc, RwLock}}; use log::info; use serde::{Deserialize, Serialize}; @@ -11,10 +10,7 @@ use super::hdlparam::FastHdlparam; pub enum CacheResult { Ok(T), NotNeedCache, - CacheNotFound, - NotHit, - FailDeserialize, - Error(String) + CacheNotFound } #[derive(Debug, Serialize, Deserialize, Clone)] @@ -139,10 +135,10 @@ impl CacheManager { std::thread::spawn(move || { info!("save meta to {meta_save_path:?}"); - k_serialize(&meta_save_path, meta); + let _ = k_serialize(&meta_save_path, meta); info!("save index to {cache_save_path:?}"); - k_serialize(&cache_save_path, fast); + let _ = k_serialize(&cache_save_path, fast); }); } diff --git a/src/core/sv_parser.rs b/src/core/sv_parser.rs index 9ca74b0..00518cc 100644 --- a/src/core/sv_parser.rs +++ b/src/core/sv_parser.rs @@ -28,7 +28,7 @@ pub fn sv_parser(path: &str) -> Option { let uri = Url::from_file_path(&path).unwrap(); let result = recovery_sv_parse(&doc, &uri, &None, &includes); - println!("result: {result:?}"); + // println!("result: {result:?}"); if let Some(syntax_tree) = result { if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &path) { diff --git a/src/definition/mod.rs b/src/definition/mod.rs index f6583ef..161a866 100644 --- a/src/definition/mod.rs +++ b/src/definition/mod.rs @@ -10,7 +10,6 @@ pub mod def_types; pub use def_types::*; pub mod feature; -pub use feature::*; pub mod extract_defs; pub use extract_defs::*; @@ -22,8 +21,16 @@ impl LSPServer { pub fn goto_definition(&self, params: GotoDefinitionParams) -> Option { let language_id = get_language_id_by_uri(¶ms.text_document_position_params.text_document.uri); match language_id.as_str() { - "vhdl" => vhdl::goto_vhdl_definition(self, ¶ms), - "verilog" | "systemverilog" => sv::goto_definition(self, ¶ms), + "vhdl" => vhdl::goto_vhdl_definition( + self, + ¶ms + ), + + "verilog" | "systemverilog" => sv::goto_definition( + self, + ¶ms + ), + _ => None } } diff --git a/src/document_highlight/mod.rs b/src/document_highlight/mod.rs index 1530789..a4b9fdf 100644 --- a/src/document_highlight/mod.rs +++ b/src/document_highlight/mod.rs @@ -1,11 +1,8 @@ -use crate::{definition::Scope, server::LSPServer, sources::{LSPSupport, ParseIR, Source}, utils::{get_definition_token, get_language_id_by_uri}}; -use log::info; -use sv_parser::{RefNode, SyntaxTree}; -use vhdl::vhdl_document_highlight; -use crate::definition::extract_defs::get_ident; +use crate::{server::LSPServer, utils::{get_definition_token, get_language_id_by_uri}}; use tower_lsp::lsp_types::*; -pub mod vhdl; +mod sv; +mod vhdl; impl LSPServer { pub fn document_highlight( @@ -24,8 +21,12 @@ impl LSPServer { let language_id = get_language_id_by_uri(&uri); match language_id.as_str() { - "vhdl" => vhdl_document_highlight(self, ¶ms.text_document_position_params), - "verilog" | "systemverilog" => sv_document_highlight( + "vhdl" => vhdl::document_highlight( + self, + ¶ms.text_document_position_params + ), + + "verilog" | "systemverilog" => sv::document_highlight( self, &token, &file, @@ -35,56 +36,4 @@ impl LSPServer { _ => None } } -} - -fn sv_document_highlight( - server: &LSPServer, - token: &str, - file: &Source, - pos: Position, - uri: &Url -) -> Option> { - let scope_tree = server.srcs.scope_tree.read().ok()?; - - // 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), - }; - let syntax_tree = file.parse_ir.as_ref()?; - match syntax_tree { - ParseIR::SyntaxTree(syntax_tree) => { - let references = all_identifiers(&syntax_tree, &token); - Some( - scope_tree - .as_ref()? - .document_highlights(&uri, &file.text, references, byte_idx), - ) - }, - _ => { - info!("error happen in [sv_document_highlight]"); - 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 } \ No newline at end of file diff --git a/src/document_highlight/sv.rs b/src/document_highlight/sv.rs new file mode 100644 index 0000000..999b938 --- /dev/null +++ b/src/document_highlight/sv.rs @@ -0,0 +1,58 @@ +#[allow(unused)] +use log::info; +use sv_parser::{RefNode, SyntaxTree}; +use tower_lsp::lsp_types::*; + +use crate::{definition::{get_ident, Scope}, server::LSPServer, sources::{LSPSupport, ParseIR, Source}}; + +pub fn document_highlight( + server: &LSPServer, + token: &str, + file: &Source, + pos: Position, + uri: &Url +) -> Option> { + let scope_tree = server.srcs.scope_tree.read().ok()?; + + // 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), + }; + let syntax_tree = file.parse_ir.as_ref()?; + match syntax_tree { + ParseIR::SyntaxTree(syntax_tree) => { + let references = all_identifiers(&syntax_tree, &token); + Some( + scope_tree + .as_ref()? + .document_highlights(&uri, &file.text, references, byte_idx), + ) + }, + _ => { + info!("error happen in [sv_document_highlight]"); + 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 +} \ No newline at end of file diff --git a/src/document_highlight/vhdl.rs b/src/document_highlight/vhdl.rs index dba8828..48d75c1 100644 --- a/src/document_highlight/vhdl.rs +++ b/src/document_highlight/vhdl.rs @@ -5,7 +5,7 @@ use tower_lsp::lsp_types::*; use crate::{server::LSPServer, utils::{from_lsp_pos, to_escape_path, to_lsp_range}}; -pub fn vhdl_document_highlight( +pub fn document_highlight( server: &LSPServer, params: &TextDocumentPositionParams ) -> Option> { diff --git a/src/document_symbol/mod.rs b/src/document_symbol/mod.rs index 8d20f8c..3f46f83 100644 --- a/src/document_symbol/mod.rs +++ b/src/document_symbol/mod.rs @@ -1,22 +1,24 @@ use tower_lsp::lsp_types::*; -use crate::{definition::Scope, server::LSPServer}; -pub mod vhdl; +use crate::{server::LSPServer, utils::get_language_id_by_uri}; + +mod sv; +mod vhdl; impl LSPServer { pub fn document_symbol(&self, params: DocumentSymbolParams) -> Option { - let uri = params.text_document.uri; - let file_id = self.srcs.get_id(&uri).to_owned(); - self.srcs.wait_parse_ready(file_id, false); - let file = self.srcs.get_file(file_id)?; - let file = file.read().ok()?; - let scope_tree = self.srcs.scope_tree.read().ok()?; - - - - Some(DocumentSymbolResponse::Nested( - scope_tree.as_ref()?.document_symbols(&uri, &file.text), - )) + let uri = ¶ms.text_document.uri; + let language_id = get_language_id_by_uri(uri); + match language_id.as_str() { + "vhdl" => vhdl::document_symbol( + self, + ¶ms + ), + "verilog" | "systemverilog" => sv::document_symbol( + self, + ¶ms + ), + _ => None + } } } - diff --git a/src/document_symbol/sv.rs b/src/document_symbol/sv.rs new file mode 100644 index 0000000..9bbae29 --- /dev/null +++ b/src/document_symbol/sv.rs @@ -0,0 +1,18 @@ +use crate::{definition::Scope, server::LSPServer}; +use tower_lsp::lsp_types::*; + +pub fn document_symbol( + server: &LSPServer, + params: &DocumentSymbolParams +) -> Option { + let uri = ¶ms.text_document.uri; + let file_id = server.srcs.get_id(uri).to_owned(); + server.srcs.wait_parse_ready(file_id, false); + let file = server.srcs.get_file(file_id)?; + let file = file.read().ok()?; + let scope_tree = server.srcs.scope_tree.read().ok()?; + + Some(DocumentSymbolResponse::Nested( + scope_tree.as_ref()?.document_symbols(uri, &file.text), + )) +} \ No newline at end of file diff --git a/src/document_symbol/vhdl.rs b/src/document_symbol/vhdl.rs index 716c7e9..7f996cd 100644 --- a/src/document_symbol/vhdl.rs +++ b/src/document_symbol/vhdl.rs @@ -7,7 +7,7 @@ use std::path::PathBuf; use std::str::FromStr; use vhdl_lang::{EntHierarchy, Token}; -pub fn vhdl_document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Option { +pub fn document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Option { let uri = ¶ms.text_document.uri; let file_id = server.srcs.get_id(&uri).to_owned(); server.srcs.wait_parse_ready(file_id, false); diff --git a/src/hover/feature.rs b/src/hover/feature.rs index b2dd1c0..4c93fd1 100644 --- a/src/hover/feature.rs +++ b/src/hover/feature.rs @@ -5,7 +5,7 @@ use regex::Regex; use ropey::RopeSlice; use tower_lsp::lsp_types::{Hover, HoverContents, LanguageString, MarkedString, Position, Range, Url}; -use crate::{core::hdlparam::{Define, FastHdlparam, Module}, definition::{DefinitionType, GenericDec}, server::LSPServer}; +use crate::{core::hdlparam::{Define, FastHdlparam}, definition::{DefinitionType, GenericDec}, server::LSPServer}; use super::{get_word_range_at_position, resolve_path, to_escape_path}; @@ -343,28 +343,49 @@ pub fn hover_module_declaration( definition: &GenericDec, language_id: &str ) -> Option { - // let module_info = match definition.def_type { - // DefinitionType::GenericScope => { - // let pathbuf = PathBuf::from_str(definition.url.path()).unwrap(); - // let path_string = to_escape_path(&pathbuf).to_str().unwrap(); - // let hdlparam = &server.srcs.hdl_param; - // let mut result: Option<(Module, String)> = None; + let module_info = match definition.def_type { + DefinitionType::GenericScope => { + let pathbuf = PathBuf::from_str(definition.url.path()).unwrap(); + let pathbuf = to_escape_path(&pathbuf); + let path_string = pathbuf.to_str().unwrap(); + + let hdlparam = &server.srcs.hdl_param; + let search_result = || { + if let Some(hdl_file) = hdlparam.path_to_hdl_file.read().unwrap().get(path_string) { + for module in &hdl_file.fast.content { + if module.name == definition.ident { + return Some((module.clone(), path_string.to_string())); + } + } + } + + None + }; + search_result() + } + + _ => { + let search_result = || { + if let Some(module) = server.srcs.hdl_param.find_module_by_name(token_name) { + let path_string = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap_or("unknown".to_string()); + return Some((module, path_string)); + } + None + }; + search_result() + } + }; + + if let Some((module, path_string)) = module_info { + let path_uri = Url::from_file_path(path_string.to_string()).unwrap().to_string(); + let def_row = module.range.start.line; + let def_col = module.range.start.character; + let define_info = format!("Definition [{path_string}]({path_uri}#L{def_row}:{def_col})"); - // if let Some(hdl_file) = hdlparam.path_to_hdl_file.read().unwrap().get(path_string) { - // for module in &hdl_file.fast.content { - // if module.name == definition.ident { - // return Some((module.clone(), path_string.to_string())) - // } - // } - // } - // None - // } - // _ => None - // }; - if let Some(module) = server.srcs.hdl_param.find_module_by_name(token_name) { let port_num = module.ports.len(); let param_num = module.params.len(); let instance_num = module.instances.len(); + let port_desc = format!("`port` {port_num}, `param` {param_num}, `instantiation` {instance_num}"); // 统计 dir @@ -382,9 +403,6 @@ pub fn hover_module_declaration( } let io_desc = format!("`input` {input_count}, `output` {output_count}, `inout` {inout_count}"); - - let path_string = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap_or("unknown".to_string()); - let define_info = format!("define in {path_string}"); let mut markdowns = Vec::::new(); markdowns.push(MarkedString::String(port_desc)); diff --git a/src/hover/mod.rs b/src/hover/mod.rs index ac20a77..47f4681 100644 --- a/src/hover/mod.rs +++ b/src/hover/mod.rs @@ -13,8 +13,16 @@ impl LSPServer { pub fn hover(&self, params: HoverParams) -> Option { let language_id = get_language_id_by_uri(¶ms.text_document_position_params.text_document.uri); match language_id.as_str() { - "vhdl" => vhdl::hover(self, ¶ms), - "verilog" | "systemverilog" => sv::hover(self, ¶ms), + "vhdl" => vhdl::hover( + self, + ¶ms + ), + + "verilog" | "systemverilog" => sv::hover( + self, + ¶ms + ), + _ => None } } diff --git a/src/hover/sv.rs b/src/hover/sv.rs index fc9d680..405bbb5 100644 --- a/src/hover/sv.rs +++ b/src/hover/sv.rs @@ -2,7 +2,7 @@ use log::info; use regex::Regex; use ropey::Rope; use tower_lsp::lsp_types::*; -use crate::{core::hdlparam::{HdlFile, Instance, Module}, hover::{to_escape_path, BracketMatchResult, BracketMatcher}, server::LSPServer, sources::LSPSupport}; +use crate::{core::hdlparam::{Instance, Module}, hover::{to_escape_path, BracketMatchResult, BracketMatcher}, server::LSPServer, sources::LSPSupport}; use super::feature::*; use std::{path::PathBuf, str::FromStr, sync::RwLockReadGuard}; diff --git a/src/sources.rs b/src/sources.rs index 06a854d..50023ad 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -127,7 +127,7 @@ pub struct Source { } pub enum ParseIR { - /// 基于 rust_hdl 的IR,存放 VHDL + /// 基于 vhdl-parser 的IR,存放 VHDL #[allow(unused)] VHDLProject(vhdl_lang::Project), /// 存放 sv 的 IR @@ -487,7 +487,7 @@ pub fn recovery_sv_parse( let com_define = Define { identifier: not_found_macro_name.to_string(), arguments: Vec::new(), - text: Some(DefineText {text: "dide-undefined".to_string(), origin: None}) + text: Some(DefineText {text: "UNKNOWN_MACRO".to_string(), origin: None}) }; defines.insert(not_found_macro_name, Some(com_define)); parse_iterations += 1; diff --git a/src/test/mod.rs b/src/test/mod.rs index 3c57d2b..acf6eb0 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -54,7 +54,7 @@ mod test_fast { #[test] fn test_parent() { - let fast = sv_parser("/home/dide/project/Digital-Test/Digital-IDE-temp/user/src/vlog/bigfile/axil_crossbar.v"); + let fast = sv_parser("/home/dide/project/Digital-Test/Digital-IDE-temp/user/src/svlog/std2017/dependence/parent.sv"); let fast = fast.unwrap(); println!("{:#?}", fast.content); } @@ -427,7 +427,6 @@ mod test_file { #[test] fn test_cache() { - let test_path = "/home/dide/project/digital-lsp-server/.cache"; - fs::create_dir_all("/home/dide/project/digital-lsp-server/.cache"); + let _ = fs::create_dir_all("/home/dide/project/digital-lsp-server/.cache"); } } \ No newline at end of file diff --git a/src/utils/fast.rs b/src/utils/fast.rs index 139ccbe..3fc8326 100644 --- a/src/utils/fast.rs +++ b/src/utils/fast.rs @@ -1,4 +1,4 @@ - +#[allow(unused)] use log::info; use crate::{core::hdlparam::Define, server::LSPServer}; diff --git a/vhdl-parser b/vhdl-parser new file mode 160000 index 0000000..8593bef --- /dev/null +++ b/vhdl-parser @@ -0,0 +1 @@ +Subproject commit 8593beff8c21bd3d3e417ac893b9f317f5386070