diff --git a/src/core/sv_parser.rs b/src/core/sv_parser.rs index 6f10670..f41ca47 100644 --- a/src/core/sv_parser.rs +++ b/src/core/sv_parser.rs @@ -9,7 +9,7 @@ use ropey::Rope; use tower_lsp::lsp_types::Url; use sv_parser::{unwrap_node, Locate, RefNode, SyntaxTree}; -use crate::sources::recovery_sv_parse; +use crate::sources::recovery_sv_parse_with_retry; use crate::utils::to_escape_path; use super::hdlparam::{FastHdlparam, Macro}; @@ -28,7 +28,7 @@ pub fn sv_parser(path: &str) -> Option { let doc = Rope::from_str(&text); let uri = Url::from_file_path(&path).unwrap(); - let result = recovery_sv_parse(&doc, &uri, &None, &includes); + let result = recovery_sv_parse_with_retry(&doc, &uri, &None, &includes); // println!("result: {result:?}"); @@ -697,7 +697,7 @@ mod tests { use std::{fs, path::Path}; use super::sv_parser; - const TESTFILES_DIR: &str = "testfiles"; + const TESTFILES_DIR: &str = "/home/dide/project/digital-lsp-server/testfiles"; const DIGTIAL_IDE_TEST: &str = "/home/dide/project/Digital-Test/Digital-IDE-test/user"; macro_rules! unwrap_result { diff --git a/src/request/mod.rs b/src/request/mod.rs index 0301d4c..e1dca25 100644 --- a/src/request/mod.rs +++ b/src/request/mod.rs @@ -17,7 +17,7 @@ use crate::core::sv_parser::make_fast_from_syntaxtree; use crate::core::vhdl_parser::{make_fast_from_design_file, vhdl_parse}; use crate::utils::*; use crate::server::Backend; -use crate::sources::recovery_sv_parse; +use crate::sources::recovery_sv_parse_with_retry; pub mod notification; @@ -160,7 +160,7 @@ fn do_sv_fast(path: &str, backend: &Arc) -> Result { // fast 解析不需要 include let includes: Vec = Vec::new(); - let parse_result = recovery_sv_parse( + let parse_result = recovery_sv_parse_with_retry( &text, &uri, &None, diff --git a/src/sources.rs b/src/sources.rs index 2573ae9..400a211 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -442,6 +442,19 @@ impl Sources { } +pub fn recovery_sv_parse_with_retry( + doc: &Rope, + uri: &Url, + last_change_range: &Option, + inc_paths: &[PathBuf], +) -> Option{ + if let Some(syntax_tree) = recovery_sv_parse(doc, uri, last_change_range, inc_paths, false) { + Some(syntax_tree) + } else { + recovery_sv_parse(doc, uri, last_change_range, inc_paths, true) + } +} + /// 更加稳定地解析 sv 和 v /// 支持遇到错误进行自动修复,然后再解析 pub fn recovery_sv_parse( @@ -449,6 +462,7 @@ pub fn recovery_sv_parse( uri: &Url, last_change_range: &Option, inc_paths: &[PathBuf], + allow_incomplete: bool, ) -> Option { let mut parse_iterations = 1; let mut i = 0; @@ -490,7 +504,7 @@ pub fn recovery_sv_parse( &defines, &includes, true, - true + allow_incomplete ) { Ok((syntax_tree, _)) => { return Some(syntax_tree); @@ -600,7 +614,7 @@ pub fn sv_parser_pipeline( return; } - let syntax_tree = recovery_sv_parse( + let syntax_tree = recovery_sv_parse_with_retry( doc, uri, last_change_range, diff --git a/src/test/mod.rs b/src/test/mod.rs index edafa88..6478223 100644 --- a/src/test/mod.rs +++ b/src/test/mod.rs @@ -1,7 +1,7 @@ mod vhdl; #[allow(unused)] -const TESTFILES_DIR: &str = "testfiles"; +const TESTFILES_DIR: &str = "/home/dide/project/digital-lsp-server/testfiles"; #[allow(unused)] const DIGTIAL_IDE_TEST: &str = "/home/dide/project/Digital-Test/Digital-IDE-test/user"; @@ -182,7 +182,7 @@ mod test_svparse { use ropey::Rope; use tower_lsp::lsp_types::{Position, Range, Url}; - use crate::sources::recovery_sv_parse; + use crate::sources::recovery_sv_parse_with_retry; use super::{INCOMPLETE_EXAMPLE, TEST_FILE}; @@ -203,7 +203,7 @@ mod test_svparse { Position { line: 0, character: 0 }, Position { line: 0, character: 0 }, ); - let result = recovery_sv_parse(&doc, &uri, &Some(last_change_range), &includes); + let result = recovery_sv_parse_with_retry(&doc, &uri, &Some(last_change_range), &includes); match result { Some(syntax_tree) => { println!("success"); @@ -265,7 +265,7 @@ mod test_svparse { let includes: Vec = Vec::new(); let doc = Rope::from_str(&text); let uri = Url::from_file_path(file_path).unwrap(); - let result = recovery_sv_parse(&doc, &uri, &None, &includes); + let result = recovery_sv_parse_with_retry(&doc, &uri, &None, &includes); assert!(result.is_some()); @@ -281,7 +281,7 @@ mod test_svparse { #[cfg(test)] mod test_scope_tree { use std::{fs, path::{Path, PathBuf}}; - use crate::{definition::{get_scopes_from_syntax_tree, GenericScope}, sources::recovery_sv_parse}; + use crate::{definition::{get_scopes_from_syntax_tree, GenericScope}, sources::{recovery_sv_parse, recovery_sv_parse_with_retry}}; use ropey::Rope; use tower_lsp::lsp_types::Url; @@ -297,7 +297,8 @@ mod test_scope_tree { let doc = Rope::from_str(&text); let uri = Url::from_file_path(&file_path).unwrap(); - let result = recovery_sv_parse(&doc, &uri, &None, &includes); + let result = recovery_sv_parse_with_retry(&doc, &uri, &None, &includes); + // let result = recovery_sv_parse(&doc, &uri, &None, &includes, true); if let Some(syntax_tree) = result { let file_url = format!("file://{}", file_path); @@ -380,17 +381,11 @@ mod test_scope_tree { if let Some(ext) = path.extension() { if ext == "v" || ext == "sv" { println!("Test file: {:?}", path); - // TODO: Check Stack Overflow tests - if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/svlog/tools/ivtest/comp1001.sv" { + // TODO: Check Macro tests + if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/svlog/tools/ivtest/macro_with_args.sv" { continue; } - if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/svlog/tools/ivtest/comp1000.sv" { - continue; - } - if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/svlog/tools/ivtest/br_gh330.sv" { - continue; - } - if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/svlog/tools/hdlconv/pri_encoder_using_assign.sv" { + if path.to_str().unwrap() == "/home/dide/project/Digital-Test/Digital-IDE-test/user/src/vlog/element/macro.v" { continue; } let file_path = path.to_str().unwrap();