解决 include 解析的问题
This commit is contained in:
parent
229fe4dc97
commit
a6717a702e
@ -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<Box<dyn Definition>> = Vec::new();
|
||||
let mut scopes: Vec<Box<dyn Scope>> = 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() {
|
||||
|
@ -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,
|
||||
|
@ -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<FastHdlparam> {
|
||||
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<FastHdlparam> {
|
||||
}
|
||||
|
||||
pub fn make_fast_from_syntaxtree(
|
||||
syntax_tree: &SyntaxTree,
|
||||
path: &PathBuf
|
||||
syntax_tree: &SyntaxTree
|
||||
) -> Result<FastHdlparam, std::io::Error> {
|
||||
// 对不同操作系统文件路径的支持
|
||||
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::<Include>::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<crate::core::hdlparam::Include> {
|
||||
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();
|
||||
|
@ -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(
|
||||
|
@ -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<RwLock<LspConfiguration>>,
|
||||
source_handle: &Arc<RwLock<Source>>,
|
||||
mut file_handle: RwLockWriteGuard<'_, Source>,
|
||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
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<RwLock<LspConfiguration>>,
|
||||
source_handle: &Arc<RwLock<Source>>,
|
||||
mut file_handle: RwLockWriteGuard<'_, Source>,
|
||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||
project_handle: &Arc<RwLock<Option<VhdlProject>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
@ -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());
|
||||
|
Loading…
x
Reference in New Issue
Block a user