完成 IP 的支持(还差自动补全)
This commit is contained in:
parent
5540b0b1f2
commit
c8aa5e2dcc
@ -200,6 +200,18 @@ impl Port {
|
|||||||
let port_desc = port_desc_array.join(" ");
|
let port_desc = port_desc_array.join(" ");
|
||||||
port_desc
|
port_desc
|
||||||
}
|
}
|
||||||
|
pub fn to_vhdl_description(&self) -> String {
|
||||||
|
let mut port_desc_array = Vec::<String>::new();
|
||||||
|
|
||||||
|
port_desc_array.push(self.name.to_string());
|
||||||
|
port_desc_array.push(":".to_string());
|
||||||
|
port_desc_array.push(self.dir_type.to_string());
|
||||||
|
let width_string = self.width.replace("[", "(").replace("]", ")").replace(":", " downto ");
|
||||||
|
port_desc_array.push(format!("{}{};", self.net_type.to_lowercase(), width_string));
|
||||||
|
|
||||||
|
let port_desc = port_desc_array.join(" ");
|
||||||
|
port_desc
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parameter {
|
impl Parameter {
|
||||||
@ -207,6 +219,17 @@ impl Parameter {
|
|||||||
let mut param_desc_array = Vec::<String>::new();
|
let mut param_desc_array = Vec::<String>::new();
|
||||||
param_desc_array.push(format!("parameter {}", self.name));
|
param_desc_array.push(format!("parameter {}", self.name));
|
||||||
|
|
||||||
|
if self.init != "unknown" {
|
||||||
|
param_desc_array.push("=".to_string());
|
||||||
|
param_desc_array.push(self.init.to_string());
|
||||||
|
}
|
||||||
|
let param_desc = param_desc_array.join(" ");
|
||||||
|
param_desc
|
||||||
|
}
|
||||||
|
pub fn vhdl_to_vlog_description(&self) -> String {
|
||||||
|
let mut param_desc_array = Vec::<String>::new();
|
||||||
|
param_desc_array.push(format!("parameter {}", self.name));
|
||||||
|
|
||||||
if self.init != "unknown" {
|
if self.init != "unknown" {
|
||||||
param_desc_array.push("=".to_string());
|
param_desc_array.push("=".to_string());
|
||||||
param_desc_array.push(self.init.to_string());
|
param_desc_array.push(self.init.to_string());
|
||||||
@ -499,6 +522,14 @@ impl HdlParam {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 根据 module name 计算出对应的 file type,默认为 common
|
||||||
|
pub fn find_file_type_by_module_name(&self, module_name: &str) -> String {
|
||||||
|
if let Some((_, file_type, _)) = self.find_module_context_by_name(module_name) {
|
||||||
|
return file_type;
|
||||||
|
}
|
||||||
|
"common".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
/// 输入 module 名字,找到 module 定义的文件的路径
|
/// 输入 module 名字,找到 module 定义的文件的路径
|
||||||
pub fn find_module_definition_path(&self, module_name: &str) -> Option<String> {
|
pub fn find_module_definition_path(&self, module_name: &str) -> Option<String> {
|
||||||
let module_name_to_path = self.module_name_to_path.read().unwrap();
|
let module_name_to_path = self.module_name_to_path.read().unwrap();
|
||||||
|
@ -124,7 +124,23 @@ fn goto_instantiation<'a>(
|
|||||||
let def_path = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap();
|
let def_path = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap();
|
||||||
let target_uri = Url::from_file_path(def_path).unwrap();
|
let target_uri = Url::from_file_path(def_path).unwrap();
|
||||||
let target_range = param.range.clone();
|
let target_range = param.range.clone();
|
||||||
let target_range = target_range.to_lsp_range();
|
|
||||||
|
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
|
||||||
|
let target_range = match file_type.as_str() {
|
||||||
|
"common" => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
"ip" => {
|
||||||
|
let mut target_range = target_range.clone();
|
||||||
|
target_range.affine(-1, -1).to_lsp_range()
|
||||||
|
}
|
||||||
|
"primitives" => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let link = vec![LocationLink {
|
let link = vec![LocationLink {
|
||||||
target_uri,
|
target_uri,
|
||||||
@ -153,7 +169,23 @@ fn goto_instantiation<'a>(
|
|||||||
let def_path = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap();
|
let def_path = server.srcs.hdl_param.find_module_definition_path(&module.name).unwrap();
|
||||||
let target_uri = Url::from_file_path(def_path).unwrap();
|
let target_uri = Url::from_file_path(def_path).unwrap();
|
||||||
let target_range = port.range.clone();
|
let target_range = port.range.clone();
|
||||||
let target_range = target_range.to_lsp_range();
|
|
||||||
|
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
|
||||||
|
let target_range = match file_type.as_str() {
|
||||||
|
"common" => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
"ip" => {
|
||||||
|
let mut target_range = target_range.clone();
|
||||||
|
target_range.affine(-1, -1).to_lsp_range()
|
||||||
|
}
|
||||||
|
"primitives" => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
target_range.to_lsp_range()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let link = vec![LocationLink {
|
let link = vec![LocationLink {
|
||||||
target_uri,
|
target_uri,
|
||||||
@ -281,9 +313,8 @@ fn goto_ip_module_declaration_definition(
|
|||||||
if pathbuf.exists() {
|
if pathbuf.exists() {
|
||||||
let target_uri = Url::from_file_path(PathBuf::from_str(&def_path).unwrap()).unwrap();
|
let target_uri = Url::from_file_path(PathBuf::from_str(&def_path).unwrap()).unwrap();
|
||||||
|
|
||||||
let target_range = module.range.clone();
|
let mut target_range = module.range.clone();
|
||||||
info!("target range: {:?}", target_range);
|
let target_range = target_range.affine(-1, -1).to_lsp_range();
|
||||||
let target_range = target_range.to_lsp_range();
|
|
||||||
|
|
||||||
let link = vec![LocationLink {
|
let link = vec![LocationLink {
|
||||||
target_uri,
|
target_uri,
|
||||||
|
@ -229,7 +229,8 @@ fn goto_instantiation<'a>(
|
|||||||
|
|
||||||
for param in &module.params {
|
for param in &module.params {
|
||||||
if token_name == param.name {
|
if token_name == param.name {
|
||||||
let hover = make_param_desc_hover(param, range, language_id);
|
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
|
||||||
|
let hover = make_param_desc_hover(&file_type, param, range, language_id);
|
||||||
return Some(hover);
|
return Some(hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,7 +251,8 @@ fn goto_instantiation<'a>(
|
|||||||
|
|
||||||
for port in &module.ports {
|
for port in &module.ports {
|
||||||
if token_name == port.name {
|
if token_name == port.name {
|
||||||
let hover = make_port_desc_hover(port, range, language_id);
|
let file_type = server.srcs.hdl_param.find_file_type_by_module_name(&instance.inst_type);
|
||||||
|
let hover = make_port_desc_hover(&file_type, port, range, language_id);
|
||||||
return Some(hover);
|
return Some(hover);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -294,21 +296,50 @@ pub fn hover_position_port_param(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_port_desc_hover(port: &crate::core::hdlparam::Port, range: &Range, language_id: &str) -> Hover {
|
fn make_port_desc_hover(file_type: &str, port: &crate::core::hdlparam::Port, range: &Range, language_id: &str) -> Hover {
|
||||||
let language_string = LanguageString {
|
info!("enter make_port_desc_hover, file_type: {}", file_type);
|
||||||
language: language_id.to_string(),
|
|
||||||
value: port.to_description()
|
let (language, value) = match file_type {
|
||||||
|
"common" => {
|
||||||
|
(language_id.to_string(), port.to_description())
|
||||||
|
}
|
||||||
|
"ip" => {
|
||||||
|
("vhdl".to_string(), port.to_vhdl_description())
|
||||||
|
}
|
||||||
|
"primitives" => {
|
||||||
|
(language_id.to_string(), port.to_description())
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
(language_id.to_string(), port.to_description())
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let language_string = LanguageString { language, value };
|
||||||
Hover {
|
Hover {
|
||||||
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
||||||
range: Some(range.clone())
|
range: Some(range.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_param_desc_hover(param: &crate::core::hdlparam::Parameter, range: &Range, language_id: &str) -> Hover {
|
fn make_param_desc_hover(file_type: &str, param: &crate::core::hdlparam::Parameter, range: &Range, language_id: &str) -> Hover {
|
||||||
|
let value = match file_type {
|
||||||
|
"common" => {
|
||||||
|
param.to_description()
|
||||||
|
}
|
||||||
|
"ip" => {
|
||||||
|
param.vhdl_to_vlog_description()
|
||||||
|
}
|
||||||
|
"primitives" => {
|
||||||
|
param.to_description()
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
param.to_description()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let language_string = LanguageString {
|
let language_string = LanguageString {
|
||||||
language: language_id.to_string(),
|
language: language_id.to_string(),
|
||||||
value: param.to_description()
|
value
|
||||||
};
|
};
|
||||||
Hover {
|
Hover {
|
||||||
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
||||||
@ -654,16 +685,7 @@ pub fn make_entity_profile_code(module: &crate::core::hdlparam::Module) -> Strin
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let width_mapper = |width: &str| {
|
|
||||||
if width == "1" {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
width.len() + 5
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
let max_port_length = module.ports.iter().map(|port| port.name.len()).max().unwrap_or(0);
|
let max_port_length = module.ports.iter().map(|port| port.name.len()).max().unwrap_or(0);
|
||||||
let max_net_length = module.ports.iter().map(|port| net_mapper(&port.net_type)).max().unwrap_or(0);
|
|
||||||
// let max_width_length = module.ports.iter().map(|port| width_mapper(&port.width)).max().unwrap_or(0);
|
// let max_width_length = module.ports.iter().map(|port| width_mapper(&port.width)).max().unwrap_or(0);
|
||||||
let max_dir_length = module.ports.iter().map(|port| port.dir_type.len()).max().unwrap_or(0);
|
let max_dir_length = module.ports.iter().map(|port| port.dir_type.len()).max().unwrap_or(0);
|
||||||
|
|
||||||
@ -680,7 +702,7 @@ pub fn make_entity_profile_code(module: &crate::core::hdlparam::Module) -> Strin
|
|||||||
|
|
||||||
// std_logic, signed, unsigned 等等
|
// std_logic, signed, unsigned 等等
|
||||||
if port.net_type != "unknown" {
|
if port.net_type != "unknown" {
|
||||||
port_desc_array.push(port.net_type.to_string());
|
port_desc_array.push(port.net_type.to_lowercase());
|
||||||
}
|
}
|
||||||
|
|
||||||
// (57 downto 0)
|
// (57 downto 0)
|
||||||
|
@ -6,7 +6,7 @@ use flexi_logger::LoggerHandle;
|
|||||||
use log::{debug, info, warn};
|
use log::{debug, info, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::string::ToString;
|
use std::string::ToString;
|
||||||
use std::sync::{Mutex, RwLock};
|
use std::sync::{Arc, Mutex, RwLock};
|
||||||
use tower_lsp::jsonrpc::Result;
|
use tower_lsp::jsonrpc::Result;
|
||||||
use tower_lsp::lsp_types::*;
|
use tower_lsp::lsp_types::*;
|
||||||
use tower_lsp::{Client, LanguageServer};
|
use tower_lsp::{Client, LanguageServer};
|
||||||
@ -16,7 +16,7 @@ pub struct LSPServer {
|
|||||||
pub key_comps: Vec<CompletionItem>,
|
pub key_comps: Vec<CompletionItem>,
|
||||||
pub sys_tasks: Vec<CompletionItem>,
|
pub sys_tasks: Vec<CompletionItem>,
|
||||||
pub directives: Vec<CompletionItem>,
|
pub directives: Vec<CompletionItem>,
|
||||||
pub conf: RwLock<ProjectConfig>,
|
pub conf: Arc<RwLock<ProjectConfig>>,
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
pub log_handle: Mutex<Option<LoggerHandle>>,
|
pub log_handle: Mutex<Option<LoggerHandle>>,
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ impl LSPServer {
|
|||||||
key_comps: keyword_completions(KEYWORDS),
|
key_comps: keyword_completions(KEYWORDS),
|
||||||
sys_tasks: other_completions(SYS_TASKS),
|
sys_tasks: other_completions(SYS_TASKS),
|
||||||
directives: other_completions(DIRECTIVES),
|
directives: other_completions(DIRECTIVES),
|
||||||
conf: RwLock::new(ProjectConfig::default()),
|
conf: Arc::new(RwLock::new(ProjectConfig::default())),
|
||||||
log_handle: Mutex::new(log_handle),
|
log_handle: Mutex::new(log_handle),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -284,6 +284,7 @@ impl LanguageServer for Backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn did_change(&self, params: DidChangeTextDocumentParams) {
|
async fn did_change(&self, params: DidChangeTextDocumentParams) {
|
||||||
|
info!("file did change: {:?}", params.text_document.uri);
|
||||||
// // 如果文件太大则显示错误
|
// // 如果文件太大则显示错误
|
||||||
// if CacheManager::uri_is_big_file(¶ms.text_document.uri) {
|
// if CacheManager::uri_is_big_file(¶ms.text_document.uri) {
|
||||||
// // self.client.show_message(MessageType::WARNING, "考虑到性能问题,对于大于 1MB 的文件不会主动提供语言服务")
|
// // self.client.show_message(MessageType::WARNING, "考虑到性能问题,对于大于 1MB 的文件不会主动提供语言服务")
|
||||||
|
146
src/sources.rs
146
src/sources.rs
@ -8,6 +8,7 @@ use crate::definition::get_scopes_from_syntax_tree;
|
|||||||
use crate::definition::get_scopes_from_vhdl_fast;
|
use crate::definition::get_scopes_from_vhdl_fast;
|
||||||
use crate::diagnostics::{get_diagnostics, is_hidden};
|
use crate::diagnostics::{get_diagnostics, is_hidden};
|
||||||
use crate::server::LSPServer;
|
use crate::server::LSPServer;
|
||||||
|
use crate::server::ProjectConfig;
|
||||||
use crate::utils::to_escape_path;
|
use crate::utils::to_escape_path;
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
use log::info;
|
use log::info;
|
||||||
@ -41,8 +42,6 @@ macro_rules! unwrap_result {
|
|||||||
|
|
||||||
impl LSPServer {
|
impl LSPServer {
|
||||||
pub fn did_open(&self, params: DidOpenTextDocumentParams) -> PublishDiagnosticsParams {
|
pub fn did_open(&self, params: DidOpenTextDocumentParams) -> PublishDiagnosticsParams {
|
||||||
info!("[LSPServer] did open");
|
|
||||||
|
|
||||||
let document: TextDocumentItem = params.text_document;
|
let document: TextDocumentItem = params.text_document;
|
||||||
let uri = document.uri.clone();
|
let uri = document.uri.clone();
|
||||||
|
|
||||||
@ -58,54 +57,69 @@ impl LSPServer {
|
|||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.srcs.add(document);
|
self.srcs.add(self, document);
|
||||||
}
|
}
|
||||||
// diagnostics
|
// diagnostics
|
||||||
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
||||||
let file_id = self.srcs.get_id(&uri);
|
let file_id = self.srcs.get_id(&uri);
|
||||||
let file = self.srcs.get_file(file_id).unwrap();
|
if let Some(file) = self.srcs.get_file(file_id) {
|
||||||
let file = file.read().unwrap();
|
let file = file.read().unwrap();
|
||||||
get_diagnostics(uri, &file.text, urls, &self.conf.read().unwrap())
|
get_diagnostics(uri, &file.text, urls, &self.conf.read().unwrap())
|
||||||
|
} else {
|
||||||
|
PublishDiagnosticsParams {
|
||||||
|
uri,
|
||||||
|
diagnostics: Vec::new(),
|
||||||
|
version: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_change(&self, params: DidChangeTextDocumentParams) {
|
pub fn did_change(&self, params: DidChangeTextDocumentParams) {
|
||||||
let file_id = self.srcs.get_id(¶ms.text_document.uri);
|
let file_id = self.srcs.get_id(¶ms.text_document.uri);
|
||||||
let file = self.srcs.get_file(file_id).unwrap();
|
if let Some(file) = self.srcs.get_file(file_id) {
|
||||||
let mut file = file.write().unwrap();
|
let mut file = file.write().unwrap();
|
||||||
|
|
||||||
// loop through changes and apply
|
// loop through changes and apply
|
||||||
for change in params.content_changes {
|
for change in params.content_changes {
|
||||||
if change.range.is_none() {
|
if change.range.is_none() {
|
||||||
file.text = Rope::from_str(&change.text);
|
file.text = Rope::from_str(&change.text);
|
||||||
} else {
|
} else {
|
||||||
file.text.apply_change(&change);
|
file.text.apply_change(&change);
|
||||||
|
}
|
||||||
|
file.last_change_range = change.range;
|
||||||
}
|
}
|
||||||
file.last_change_range = change.range;
|
file.version = params.text_document.version;
|
||||||
|
drop(file);
|
||||||
|
|
||||||
|
// invalidate syntaxtree and wake parse thread
|
||||||
|
let meta_data = self.srcs.get_meta_data(file_id).unwrap();
|
||||||
|
let (lock, cvar) = &*meta_data.read().unwrap().valid_parse;
|
||||||
|
let mut valid = lock.lock().unwrap();
|
||||||
|
*valid = false;
|
||||||
|
cvar.notify_all();
|
||||||
}
|
}
|
||||||
file.version = params.text_document.version;
|
|
||||||
drop(file);
|
|
||||||
|
|
||||||
// invalidate syntaxtree and wake parse thread
|
|
||||||
let meta_data = self.srcs.get_meta_data(file_id).unwrap();
|
|
||||||
let (lock, cvar) = &*meta_data.read().unwrap().valid_parse;
|
|
||||||
let mut valid = lock.lock().unwrap();
|
|
||||||
*valid = false;
|
|
||||||
cvar.notify_all();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_save(&self, params: DidSaveTextDocumentParams) -> PublishDiagnosticsParams {
|
pub fn did_save(&self, params: DidSaveTextDocumentParams) -> PublishDiagnosticsParams {
|
||||||
info!("[LSPServer] did save");
|
|
||||||
|
|
||||||
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
let urls = self.srcs.names.read().unwrap().keys().cloned().collect();
|
||||||
let file_id = self.srcs.get_id(¶ms.text_document.uri);
|
let file_id = self.srcs.get_id(¶ms.text_document.uri);
|
||||||
let file = self.srcs.get_file(file_id).unwrap();
|
let uri = params.text_document.uri.clone();
|
||||||
let file = file.read().unwrap();
|
|
||||||
get_diagnostics(
|
if let Some(file) = self.srcs.get_file(file_id) {
|
||||||
params.text_document.uri,
|
let file = file.read().unwrap();
|
||||||
&file.text,
|
get_diagnostics(
|
||||||
urls,
|
uri,
|
||||||
&self.conf.read().unwrap(),
|
&file.text,
|
||||||
)
|
urls,
|
||||||
|
&self.conf.read().unwrap(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PublishDiagnosticsParams {
|
||||||
|
uri,
|
||||||
|
diagnostics: Vec::new(),
|
||||||
|
version: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn did_delete_files(&self, params: DeleteFilesParams) {
|
pub fn did_delete_files(&self, params: DeleteFilesParams) {
|
||||||
@ -240,7 +254,7 @@ impl Sources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 增加一个 hdl 文件,并为该文件添加单独的解析线程
|
/// 增加一个 hdl 文件,并为该文件添加单独的解析线程
|
||||||
pub fn add(&self, doc: TextDocumentItem) {
|
pub fn add(&self, server: &LSPServer, doc: TextDocumentItem) {
|
||||||
// 对于当前的文件增加一个解析线程,不断进行解析和同步
|
// 对于当前的文件增加一个解析线程,不断进行解析和同步
|
||||||
#[allow(clippy::mutex_atomic)] // https://github.com/rust-lang/rust-clippy/issues/1516
|
#[allow(clippy::mutex_atomic)] // https://github.com/rust-lang/rust-clippy/issues/1516
|
||||||
let valid_parse = Arc::new((Mutex::new(false), Condvar::new()));
|
let valid_parse = Arc::new((Mutex::new(false), Condvar::new()));
|
||||||
@ -259,6 +273,8 @@ impl Sources {
|
|||||||
let hdl_param_handle = self.hdl_param.clone();
|
let hdl_param_handle = self.hdl_param.clone();
|
||||||
let inc_dirs = self.include_dirs.clone();
|
let inc_dirs = self.include_dirs.clone();
|
||||||
|
|
||||||
|
let conf = server.conf.clone();
|
||||||
|
|
||||||
info!("launch worker to parse {:?}", doc.uri.to_string());
|
info!("launch worker to parse {:?}", doc.uri.to_string());
|
||||||
let language_id = doc.language_id.to_string();
|
let language_id = doc.language_id.to_string();
|
||||||
|
|
||||||
@ -289,6 +305,7 @@ impl Sources {
|
|||||||
match language_id.as_str() {
|
match language_id.as_str() {
|
||||||
"vhdl" => {
|
"vhdl" => {
|
||||||
vhdl_parser_pipeline(
|
vhdl_parser_pipeline(
|
||||||
|
&conf,
|
||||||
&source_handle,
|
&source_handle,
|
||||||
&scope_handle,
|
&scope_handle,
|
||||||
&hdl_param_handle,
|
&hdl_param_handle,
|
||||||
@ -298,6 +315,7 @@ impl Sources {
|
|||||||
},
|
},
|
||||||
"verilog" | "systemverilog" => {
|
"verilog" | "systemverilog" => {
|
||||||
sv_parser_pipeline(
|
sv_parser_pipeline(
|
||||||
|
&conf,
|
||||||
&source_handle,
|
&source_handle,
|
||||||
&scope_handle,
|
&scope_handle,
|
||||||
&hdl_param_handle,
|
&hdl_param_handle,
|
||||||
@ -360,15 +378,16 @@ impl Sources {
|
|||||||
|
|
||||||
/// wait for a valid parse
|
/// wait for a valid parse
|
||||||
pub fn wait_parse_ready(&self, id: usize, wait_valid: bool) {
|
pub fn wait_parse_ready(&self, id: usize, wait_valid: bool) {
|
||||||
let file = self.get_file(id).unwrap();
|
if let Some(file) = self.get_file(id) {
|
||||||
let file = file.read().unwrap();
|
let file = file.read().unwrap();
|
||||||
if file.parse_ir.is_none() || wait_valid {
|
if file.parse_ir.is_none() || wait_valid {
|
||||||
drop(file);
|
drop(file);
|
||||||
let meta_data = self.get_meta_data(id).unwrap();
|
let meta_data = self.get_meta_data(id).unwrap();
|
||||||
let (lock, cvar) = &*meta_data.read().unwrap().valid_parse;
|
let (lock, cvar) = &*meta_data.read().unwrap().valid_parse;
|
||||||
let mut valid = lock.lock().unwrap();
|
let mut valid = lock.lock().unwrap();
|
||||||
while !*valid {
|
while !*valid {
|
||||||
valid = cvar.wait(valid).unwrap();
|
valid = cvar.wait(valid).unwrap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -562,6 +581,7 @@ pub fn recovery_sv_parse(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn sv_parser_pipeline(
|
pub fn sv_parser_pipeline(
|
||||||
|
conf: &Arc<RwLock<ProjectConfig>>,
|
||||||
source_handle: &Arc<RwLock<Source>>,
|
source_handle: &Arc<RwLock<Source>>,
|
||||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||||
hdl_param_handle: &Arc<HdlParam>,
|
hdl_param_handle: &Arc<HdlParam>,
|
||||||
@ -641,6 +661,7 @@ pub fn sv_parser_pipeline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn vhdl_parser_pipeline(
|
pub fn vhdl_parser_pipeline(
|
||||||
|
conf: &Arc<RwLock<ProjectConfig>>,
|
||||||
source_handle: &Arc<RwLock<Source>>,
|
source_handle: &Arc<RwLock<Source>>,
|
||||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||||
hdl_param_handle: &Arc<HdlParam>,
|
hdl_param_handle: &Arc<HdlParam>,
|
||||||
@ -665,30 +686,41 @@ pub fn vhdl_parser_pipeline(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 通过更加精细的方法获取下面的变量
|
let extension_path = {
|
||||||
|
let configure = conf.read().unwrap();
|
||||||
|
configure.extension_path.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
let mut file = source_handle.write().unwrap();
|
let mut file = source_handle.write().unwrap();
|
||||||
let mut scope_tree = if let Some(design_file) = vhdl_parse(&escape_path) {
|
let mut scope_tree = if let Some(design_file) = vhdl_parse(&escape_path) {
|
||||||
//let mut design_files = design_file_handle.write().unwrap();
|
if let Some(mut fast) = make_fast_from_design_file(&design_file) {
|
||||||
|
|
||||||
if let Some(fast) = make_fast_from_design_file(&design_file) {
|
|
||||||
let parse_ir = ParseIR::DesignFile(design_file);
|
let parse_ir = ParseIR::DesignFile(design_file);
|
||||||
file.parse_ir = Some(parse_ir);
|
file.parse_ir = Some(parse_ir);
|
||||||
|
|
||||||
|
let file_type = {
|
||||||
|
let fast_map = hdl_param_handle.path_to_hdl_file.read().unwrap();
|
||||||
|
if let Some(hdl_file) = fast_map.get(escape_path_string) {
|
||||||
|
hdl_file.fast.file_type.to_string()
|
||||||
|
} else {
|
||||||
|
if let Some(relative_path) = escape_path_string.strip_prefix(&extension_path) {
|
||||||
|
if relative_path.starts_with("/user/ip") || relative_path.starts_with("user/ip") {
|
||||||
|
"ip".to_string()
|
||||||
|
} else {
|
||||||
|
"common".to_string()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
"common".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fast.file_type = file_type;
|
||||||
hdl_param_handle.update_fast(escape_path_string.to_string(), fast.clone());
|
hdl_param_handle.update_fast(escape_path_string.to_string(), fast.clone());
|
||||||
let scope_tree = get_scopes_from_vhdl_fast(&fast, doc, uri);
|
let scope_tree = get_scopes_from_vhdl_fast(&fast, doc, uri);
|
||||||
scope_tree
|
scope_tree
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
// let mut msg_printer = MessagePrinter::default();
|
|
||||||
// if let Some(project) = design_files.get_mut("VHDLProject") {
|
|
||||||
// project.digital_lsp_update_config(&escape_path, &mut msg_printer);
|
|
||||||
// } else {
|
|
||||||
// let project = vhdl_lang::Project::new_without_config(&escape_path, &mut msg_printer);
|
|
||||||
// design_files.insert("VHDLProject".to_string(), project);
|
|
||||||
// }
|
|
||||||
} else {
|
} else {
|
||||||
file.parse_ir = None;
|
file.parse_ir = None;
|
||||||
None
|
None
|
||||||
|
Loading…
x
Reference in New Issue
Block a user