From a6717a702ee15cd403f5ca685b2f81ac59168ca7 Mon Sep 17 00:00:00 2001 From: LSTM-Kirigaya <1193466151@qq.com> Date: Sun, 5 Jan 2025 21:44:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=A3=E5=86=B3=20include=20=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/scope_tree/mod.rs | 5 +++ src/core/scope_tree/parse.rs | 3 +- src/core/sv_parser.rs | 86 +++++++++++++----------------------- src/request/fast.rs | 2 +- src/sources.rs | 32 ++++++-------- 5 files changed, 52 insertions(+), 76 deletions(-) diff --git a/src/core/scope_tree/mod.rs b/src/core/scope_tree/mod.rs index 24f4975..65fea13 100644 --- a/src/core/scope_tree/mod.rs +++ b/src/core/scope_tree/mod.rs @@ -1,4 +1,5 @@ use crate::core::hdlparam::{self, FastHdlparam}; +use log::info; use ropey::Rope; use sv_parser::*; use tower_lsp::lsp_types::*; @@ -24,6 +25,10 @@ pub fn match_definitions( let mut definitions: Vec> = Vec::new(); let mut scopes: Vec> = Vec::new(); match node { + RefNode::IncludeStatement(n) => { + info!("enter IncludeStatement"); + info!("{:?}", n); + } RefNode::ModuleDeclaration(n) => { let module = module_dec(syntax_tree, n, event_iter, url); if module.is_some() { diff --git a/src/core/scope_tree/parse.rs b/src/core/scope_tree/parse.rs index 1c54a78..91ae67a 100644 --- a/src/core/scope_tree/parse.rs +++ b/src/core/scope_tree/parse.rs @@ -1,6 +1,7 @@ use super::common::*; use super::match_definitions; +#[allow(unused)] use log::info; use sv_parser::*; use tower_lsp::lsp_types::*; @@ -2345,7 +2346,7 @@ pub fn text_macro_def( let ident = get_ident(tree, RefNode::TextMacroIdentifier(&node.nodes.2.nodes.0)); text_macro.ident = ident.0; text_macro.byte_idx = ident.1; - let mut type_str = &mut text_macro.type_str; + let type_str = &mut text_macro.type_str; advance_until_enter!( type_str, diff --git a/src/core/sv_parser.rs b/src/core/sv_parser.rs index 3c2a10d..b51eb56 100644 --- a/src/core/sv_parser.rs +++ b/src/core/sv_parser.rs @@ -13,7 +13,7 @@ use crate::core::hdlparam::{AssignType, Position, Range}; use crate::sources::{recovery_sv_parse_with_retry, LSPSupport}; use crate::utils::to_escape_path; -use super::hdlparam::{self, FastHdlparam, InstParameter, InstPort, Macro}; +use super::hdlparam::{self, FastHdlparam, Include, InstParameter, InstPort, Macro}; macro_rules! advance_until_leave { ($tokens:ident, $tree:ident, $event_iter:ident, $node:path) => {{ @@ -74,7 +74,7 @@ pub fn sv_parser(path: &str) -> Option { let result = recovery_sv_parse_with_retry(&doc, &uri, &None, &includes); if let Some((syntax_tree, _)) = result { - if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path) { + if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree) { return Some(fast); } } @@ -83,17 +83,14 @@ pub fn sv_parser(path: &str) -> Option { } pub fn make_fast_from_syntaxtree( - syntax_tree: &SyntaxTree, - path: &PathBuf + syntax_tree: &SyntaxTree ) -> Result { // 对不同操作系统文件路径的支持 - let path = to_escape_path(path); - let mut fast: FastHdlparam = FastHdlparam { fast_macro: Macro { defines: Vec::new(), errors: Vec::new(), - includes: get_includes(&path), + includes: Vec::::new(), invalid: Vec::new() }, content: Vec::new(), @@ -106,9 +103,34 @@ pub fn make_fast_from_syntaxtree( let doc = Rope::from_str(syntax_tree.text.text()); // 上一个 module 可以在 fast 的 content 的最后一个中找到 - for node in syntax_tree { match node { + RefNode::IncludeCompilerDirective(x) => { + match x { + sv_parser::IncludeCompilerDirective::DoubleQuote(x) => { + let (_, ref keyword, ref literal) = x.nodes; + let (keyword_locate, _) = keyword.nodes; + let (literal_locate, _) = literal.nodes; + let include_path_string = syntax_tree.get_str_trim(literal).unwrap().trim_matches('"'); + let include_range = Range { + start: get_position(&doc, keyword_locate, 0), + end: get_position(&doc, literal_locate, literal_locate.len) + }; + + + fast.fast_macro.includes.push(Include { + path: include_path_string.to_string(), + range: include_range + }); + } + sv_parser::IncludeCompilerDirective::AngleBracket(_) => { + + }, + sv_parser::IncludeCompilerDirective::TextMacroUsage(_) => { + + }, + } + } RefNode::TextMacroDefinition(x) => { if let Some(start) = unwrap_node!(x, TextMacroDefinition) { let start = get_identifier(start).unwrap(); @@ -674,54 +696,6 @@ pub fn get_position(doc: &Rope, locate: Locate, offset: usize) -> Position { hdlparam::Position::from_lsp_position(&pos) } -fn get_includes(path: &PathBuf) -> Vec { - let mut includes = Vec::new(); - - let file = File::open(path).unwrap(); - let reader = BufReader::new(file); - - for (line_number, line_content) in reader.lines().enumerate() { - let line_content = match line_content { - Ok(content) => content, - Err(e) => { - println!("line {} has error {}", line_number, e); - "".to_string() - } - }; - - if line_content.trim().starts_with("`include") { - - let parts: Vec<&str> = line_content.split_whitespace().collect(); - - if parts.len() >= 2 { - let mut path = parts[1].trim(); - if path.starts_with("\"") { - path = path.strip_prefix("\"").unwrap(); - } - if path.ends_with("\"") { - path = path.strip_suffix("\"").unwrap(); - } - - let last_character = line_content.find(path).unwrap() + path.len(); - - includes.push(crate::core::hdlparam::Include { - path: path.to_string(), - range: crate::core::hdlparam::Range { - start: crate::core::hdlparam::Position { - line: (line_number + 1) as u32, character: 1 - }, - end: crate::core::hdlparam::Position { - line: (line_number + 1) as u32, character: last_character as u32 - } - } - }); - } - } - } - - includes -} - #[allow(unused)] fn update_module_range(path: &PathBuf, fast: &mut FastHdlparam) { let file = File::open(path).unwrap(); diff --git a/src/request/fast.rs b/src/request/fast.rs index b6256ad..b81d7a7 100644 --- a/src/request/fast.rs +++ b/src/request/fast.rs @@ -194,7 +194,7 @@ fn do_sv_fast( let sources = &backend.server.db; if let Some((syntax_tree, parse_result)) = parse_result { - if let Ok(mut fast) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) { + if let Ok(mut fast) = make_fast_from_syntaxtree(&syntax_tree) { fast.file_type = file_type.to_string(); let hdl_param = sources.hdl_param.clone(); hdl_param.update_hdl_file( diff --git a/src/sources.rs b/src/sources.rs index 6bc3d24..c573cf3 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -27,6 +27,7 @@ use std::path::Path; use std::path::PathBuf; use std::str::FromStr; use std::sync::Arc; +use std::sync::RwLockWriteGuard; use std::sync::{Condvar, Mutex, RwLock}; use std::thread; use sv_parser::*; @@ -373,17 +374,16 @@ impl DigitalDataBase { { let _unused = fast_lock.read().unwrap(); // 从内存中直接获取增量更新系统维护的代码文本 - let file = parse_loop_used_source_handle.read().unwrap(); + let file = parse_loop_used_source_handle.write().unwrap(); let text = file.text.clone(); let uri = &file.uri.clone(); let range = &file.last_change_range.clone(); - drop(file); match language_id.as_str() { "vhdl" => { vhdl_parser_pipeline( &configuration, - &parse_loop_used_source_handle, + file, &scope_handle, &project_handle, &hdl_param_handle, @@ -394,7 +394,7 @@ impl DigitalDataBase { "verilog" | "systemverilog" => { sv_parser_pipeline( &configuration, - &parse_loop_used_source_handle, + file, &scope_handle, &hdl_param_handle, &text, @@ -681,7 +681,7 @@ pub fn recovery_sv_parse( pub fn sv_parser_pipeline( #[allow(unused)] conf: &Arc>, - source_handle: &Arc>, + mut file_handle: RwLockWriteGuard<'_, Source>, scope_handle: &Arc>>, hdl_param_handle: &Arc, doc: &Rope, @@ -709,12 +709,10 @@ pub fn sv_parser_pipeline( None => None, }; - let mut file = source_handle.write().unwrap(); - // 加入语法树 & 更新 fast if let Some((syntax_tree, parse_result)) = ast { - if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &escape_path) { - info!("update parse_result: {:?}", parse_result); + if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree) { + info!("update: {:?}", fast.fast_macro); hdl_param_handle.update_hdl_file( escape_path_string.to_string(), fast, @@ -723,12 +721,12 @@ pub fn sv_parser_pipeline( ); } - file.finish_at_least_once = true; + file_handle.finish_at_least_once = true; } else { - file.finish_at_least_once = false; + file_handle.finish_at_least_once = false; } - // file.syntax_tree = syntax_tree; - drop(file); + + drop(file_handle); info!("finish parse {:?}", uri.to_string()); @@ -750,13 +748,12 @@ pub fn sv_parser_pipeline( // 使用 scope_tree 来更新全局的 scope None => *global_scope = scope_tree, } - // eprintln!("{:#?}", *global_scope); drop(global_scope); } pub fn vhdl_parser_pipeline( conf: &Arc>, - source_handle: &Arc>, + mut file_handle: RwLockWriteGuard<'_, Source>, scope_handle: &Arc>>, project_handle: &Arc>>, hdl_param_handle: &Arc, @@ -847,7 +844,6 @@ pub fn vhdl_parser_pipeline( let mut global_project = project_handle.write().unwrap(); match &mut *global_project { Some(vhdl_project) => { - let mut source = source_handle.write().unwrap(); let text = doc.to_string(); let mut scope_tree = if let Some(design_file) = vhdl_parse_str(&escape_path, &text) { let arch_and_entity = vhdl_project.project.get_analyzed_units(&escape_path); @@ -886,10 +882,10 @@ pub fn vhdl_parser_pipeline( None } } else { - source.finish_at_least_once = false; + file_handle.finish_at_least_once = false; None }; - drop(source); + drop(file_handle); info!("finish parse {:?}", uri.to_string());