save
This commit is contained in:
parent
c8761d2910
commit
92be4bfbd4
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -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
|
||||
|
@ -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"
|
||||
|
1
rust_hdl
1
rust_hdl
@ -1 +0,0 @@
|
||||
Subproject commit 69fba9af8cb981ce1aaeacd20ca74771f12d9aa1
|
@ -11,8 +11,16 @@ impl LSPServer {
|
||||
pub fn completion(&self, params: CompletionParams) -> Option<CompletionResponse> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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<T> {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -28,7 +28,7 @@ pub fn sv_parser(path: &str) -> Option<FastHdlparam> {
|
||||
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) {
|
||||
|
@ -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<GotoDefinitionResponse> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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<Vec<DocumentHighlight>> {
|
||||
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
|
||||
}
|
58
src/document_highlight/sv.rs
Normal file
58
src/document_highlight/sv.rs
Normal file
@ -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<Vec<DocumentHighlight>> {
|
||||
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
|
||||
}
|
@ -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<Vec<DocumentHighlight>> {
|
||||
|
@ -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<DocumentSymbolResponse> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
18
src/document_symbol/sv.rs
Normal file
18
src/document_symbol/sv.rs
Normal file
@ -0,0 +1,18 @@
|
||||
use crate::{definition::Scope, server::LSPServer};
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
||||
pub fn document_symbol(
|
||||
server: &LSPServer,
|
||||
params: &DocumentSymbolParams
|
||||
) -> Option<DocumentSymbolResponse> {
|
||||
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),
|
||||
))
|
||||
}
|
@ -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<DocumentSymbolResponse> {
|
||||
pub fn document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Option<DocumentSymbolResponse> {
|
||||
let uri = ¶ms.text_document.uri;
|
||||
let file_id = server.srcs.get_id(&uri).to_owned();
|
||||
server.srcs.wait_parse_ready(file_id, false);
|
||||
|
@ -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<Hover> {
|
||||
// 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::<MarkedString>::new();
|
||||
markdowns.push(MarkedString::String(port_desc));
|
||||
|
@ -13,8 +13,16 @@ impl LSPServer {
|
||||
pub fn hover(&self, params: HoverParams) -> Option<Hover> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
|
||||
#[allow(unused)]
|
||||
use log::info;
|
||||
|
||||
use crate::{core::hdlparam::Define, server::LSPServer};
|
||||
|
1
vhdl-parser
Submodule
1
vhdl-parser
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 8593beff8c21bd3d3e417ac893b9f317f5386070
|
Loading…
x
Reference in New Issue
Block a user