实现 position port & param hover
This commit is contained in:
parent
fedde4a4d4
commit
df57c83b0e
@ -1,4 +1,9 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tower_lsp::lsp_types::Position as LspPosition;
|
||||||
|
use tower_lsp::lsp_types::Range as LspRange;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Position {
|
pub struct Position {
|
||||||
@ -6,12 +11,28 @@ pub struct Position {
|
|||||||
pub character: u32
|
pub character: u32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Position {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn to_lsp_position(&self) -> LspPosition {
|
||||||
|
LspPosition { line: self.line, character: self.character }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||||
pub struct Range {
|
pub struct Range {
|
||||||
pub start: Position,
|
pub start: Position,
|
||||||
pub end: Position
|
pub end: Position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Range {
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn to_lsp_range(&self) -> LspRange {
|
||||||
|
let start_pos = self.start.to_lsp_position();
|
||||||
|
let end_pos= self.end.to_lsp_position();
|
||||||
|
LspRange::new(start_pos, end_pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, PartialEq, Deserialize, Clone)]
|
#[derive(Debug, Serialize, PartialEq, Deserialize, Clone)]
|
||||||
pub struct Port {
|
pub struct Port {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
@ -232,63 +253,57 @@ impl FastHdlparam {
|
|||||||
last_module.instances.push(instance);
|
last_module.instances.push(instance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// pub fn print_fast(&self) {
|
pub struct HdlFile {
|
||||||
// if self.content.is_empty() {
|
pub fast: FastHdlparam,
|
||||||
// println!("none module");
|
pub name_to_module: HashMap<String, Module>
|
||||||
// } else {
|
}
|
||||||
// for module in &self.content {
|
|
||||||
// println!("module {}", module.name);
|
pub struct HdlParam {
|
||||||
// if !module.params.is_empty() {
|
/// 路径到 HdlFile 的映射
|
||||||
// println!(" params:");
|
pub path_to_hdl_file: RwLock<HashMap<String, HdlFile>>,
|
||||||
// for param in &module.params {
|
/// 模块名字到其所在的 HdlFile 路径的映射
|
||||||
// println!(" parameter {} {} {}", param.net_type, param.name, param.init);
|
pub module_name_to_path: RwLock<HashMap<String, String>>
|
||||||
// println!(" range start {} {}", param.range.start.line, param.range.start.character);
|
}
|
||||||
// println!(" range end {} {}", param.range.end.line, param.range.end.character);
|
|
||||||
// }
|
impl HdlParam {
|
||||||
// }
|
pub fn new() -> Self {
|
||||||
// if !module.ports.is_empty() {
|
Self {
|
||||||
// println!(" ports:");
|
path_to_hdl_file: RwLock::new(HashMap::<String, HdlFile>::new()),
|
||||||
// for port in &module.ports {
|
module_name_to_path: RwLock::new(HashMap::<String, String>::new())
|
||||||
// if port.width == "1" {
|
}
|
||||||
// println!(" {} {} {}", port.dir_type, port.net_type, port.name);
|
}
|
||||||
// } else {
|
|
||||||
// println!(" {} {} {} {}", port.dir_type, port.net_type, port.width, port.name);
|
pub fn update_fast(&self, path: String, fast: FastHdlparam) {
|
||||||
// }
|
let mut fast_map = self.path_to_hdl_file.write().unwrap();
|
||||||
// println!(" range start {} {}", port.range.start.line, port.range.start.character);
|
// 构建映射
|
||||||
// println!(" range end {} {}", port.range.end.line, port.range.end.character);
|
let mut name_to_module = HashMap::<String, Module>::new();
|
||||||
// }
|
let mut module_name_to_path = self.module_name_to_path.write().unwrap();
|
||||||
// }
|
|
||||||
// if !module.instances.is_empty() {
|
for module in &fast.content {
|
||||||
// println!(" instances:");
|
name_to_module.insert(module.name.to_string(), module.clone());
|
||||||
// for instance in &module.instances {
|
if !module_name_to_path.contains_key(&module.name) {
|
||||||
// println!(" {} {}", instance.inst_type, instance.name);
|
module_name_to_path.insert(module.name.to_string(), path.to_string());
|
||||||
// if instance.instparams.is_none() {
|
}
|
||||||
// println!(" params: {:?}", instance.instparams);
|
}
|
||||||
// } else {
|
|
||||||
// println!(" params:");
|
let file = HdlFile { fast, name_to_module };
|
||||||
// println!(" range start {} {}", instance.instparams.clone().unwrap().start.line,
|
fast_map.insert(path, file);
|
||||||
// instance.instparams.clone().unwrap().start.character);
|
}
|
||||||
// println!(" range end {} {}", instance.instparams.clone().unwrap().end.line,
|
|
||||||
// instance.instparams.clone().unwrap().end.character);
|
pub fn find_module_by_name(&self, name: &str) -> Option<Module> {
|
||||||
// }
|
let module_name_to_path = self.module_name_to_path.read().unwrap();
|
||||||
// if instance.instports.is_none() {
|
if let Some(path) = module_name_to_path.get(name) {
|
||||||
// println!(" ports: {:?}", instance.instports);
|
let fast_map = self.path_to_hdl_file.read().unwrap();
|
||||||
// } else {
|
if let Some(hdl_file) = fast_map.get(path) {
|
||||||
// println!(" ports:");
|
if let Some(module) = hdl_file.name_to_module.get(name) {
|
||||||
// println!(" range start {} {}", instance.instports.clone().unwrap().start.line,
|
return Some(module.clone());
|
||||||
// instance.instports.clone().unwrap().start.character);
|
}
|
||||||
// println!(" range end {} {}", instance.instports.clone().unwrap().end.line,
|
}
|
||||||
// instance.instports.clone().unwrap().end.character);
|
}
|
||||||
// }
|
|
||||||
// println!(" range start {} {}", instance.range.start.line, instance.range.start.character);
|
None
|
||||||
// println!(" range end {} {}", instance.range.end.line, instance.range.end.character);
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// println!(" range start {} {}", module.range.start.line, module.range.start.character);
|
|
||||||
// println!(" range end {} {}", module.range.end.line, module.range.end.character);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
@ -3,6 +3,7 @@ use crate::definition::match_definitions;
|
|||||||
use sv_parser::*;
|
use sv_parser::*;
|
||||||
use tower_lsp::lsp_types::*;
|
use tower_lsp::lsp_types::*;
|
||||||
|
|
||||||
|
/// 找到 node 的 名字,开始的位置和结束的位置
|
||||||
pub fn get_ident(tree: &SyntaxTree, node: RefNode) -> (String, usize) {
|
pub fn get_ident(tree: &SyntaxTree, node: RefNode) -> (String, usize) {
|
||||||
let loc = unwrap_locate!(node).unwrap();
|
let loc = unwrap_locate!(node).unwrap();
|
||||||
let ident_str = tree.get_str(loc).unwrap().to_string();
|
let ident_str = tree.get_str(loc).unwrap().to_string();
|
||||||
|
@ -44,10 +44,9 @@ impl LSPServer {
|
|||||||
|
|
||||||
let scope_tree = self.srcs.scope_tree.read().ok()?;
|
let scope_tree = self.srcs.scope_tree.read().ok()?;
|
||||||
|
|
||||||
let def = scope_tree
|
let byte_idx = file.text.pos_to_byte(&pos);
|
||||||
.as_ref()?
|
let global_scope = scope_tree.as_ref()?;
|
||||||
// 获取定义
|
let def = global_scope.get_definition(&token, byte_idx, &doc)?;
|
||||||
.get_definition(&token, file.text.pos_to_byte(&pos), &doc)?;
|
|
||||||
|
|
||||||
let def_pos = file.text.byte_to_pos(def.byte_idx());
|
let def_pos = file.text.byte_to_pos(def.byte_idx());
|
||||||
Some(GotoDefinitionResponse::Scalar(Location::new(
|
Some(GotoDefinitionResponse::Scalar(Location::new(
|
||||||
|
205
src/hover/mod.rs
205
src/hover/mod.rs
@ -1,9 +1,11 @@
|
|||||||
use std::sync::RwLockReadGuard;
|
use std::collections::HashMap;
|
||||||
|
use std::{path::PathBuf, str::FromStr, sync::RwLockReadGuard};
|
||||||
|
|
||||||
use crate::definition::*;
|
use crate::{core::fast_hdlparam::FastHdlparam, definition::*};
|
||||||
use crate::server::LSPServer;
|
use crate::server::LSPServer;
|
||||||
use crate::sources::LSPSupport;
|
use crate::sources::LSPSupport;
|
||||||
use crate::utils::*;
|
use crate::utils::*;
|
||||||
|
use log::info;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use ropey::{Rope, RopeSlice};
|
use ropey::{Rope, RopeSlice};
|
||||||
use tower_lsp::lsp_types::*;
|
use tower_lsp::lsp_types::*;
|
||||||
@ -36,10 +38,16 @@ impl LSPServer {
|
|||||||
return Some(hover);
|
return Some(hover);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
let scope_tree: RwLockReadGuard<'_, Option<GenericScope>> = self.srcs.scope_tree.read().ok()?;
|
let scope_tree: RwLockReadGuard<'_, Option<GenericScope>> = self.srcs.scope_tree.read().ok()?;
|
||||||
let global_scope = scope_tree.as_ref();
|
let global_scope = scope_tree.as_ref();
|
||||||
|
|
||||||
|
// info!("get scope tree: {:?}", scope_tree);
|
||||||
|
|
||||||
|
// match positional port param
|
||||||
|
if let Some(hover) = hover_position_port_param(self, &line_text, &doc, pos, &language_id) {
|
||||||
|
return Some(hover);
|
||||||
|
}
|
||||||
|
|
||||||
if let Some(global_scope) = global_scope {
|
if let Some(global_scope) = global_scope {
|
||||||
// match 正常 symbol
|
// match 正常 symbol
|
||||||
if let Some(hover) = hover_common_symbol(global_scope, &token, &file, &doc, pos, &language_id) {
|
if let Some(hover) = hover_common_symbol(global_scope, &token, &file, &doc, pos, &language_id) {
|
||||||
@ -209,16 +217,193 @@ fn hover_common_symbol(
|
|||||||
make_hover_with_comment(&file.text, def_line, &language_id)
|
make_hover_with_comment(&file.text, def_line, &language_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 计算 position 赋值的 port 或者 param
|
fn goto_instantiation<'a>(
|
||||||
/// 比如 .clk ( clk ) 中的 .
|
fast: &'a FastHdlparam,
|
||||||
fn hover_position_port(line: &RopeSlice, pos: Position, language_id: &str) -> Option<Hover> {
|
pos: &Position
|
||||||
let position_port_regex = Regex::new(r"[.0-9a-zA-Z]").unwrap();
|
) -> Option<&'a crate::core::fast_hdlparam::Instance> {
|
||||||
if let Some((port_name, range)) = get_word_range_at_position(line, pos, position_port_regex) {
|
for module in &fast.content {
|
||||||
if port_name.starts_with(".") {
|
for instance in &module.instances {
|
||||||
let port_name = &port_name[1..];
|
|
||||||
|
|
||||||
|
if let Some(param_range) = &instance.instparams {
|
||||||
|
let range = param_range.to_lsp_range();
|
||||||
|
// let in_scope = compare_pos(&range.start, pos) != 1 && compare_pos(pos, &range.end) != 1;
|
||||||
|
// info!("pos: {pos:?}, param_range: {range:?}, in_scope: {in_scope:?}");
|
||||||
|
if compare_pos(&range.start, pos) != 1 && compare_pos(pos, &range.end) != 1 {
|
||||||
|
return Some(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(port_range) = &instance.instports {
|
||||||
|
let range = port_range.to_lsp_range();
|
||||||
|
// let in_scope = compare_pos(&range.start, pos) != 1 && compare_pos(pos, &range.end) != 1;
|
||||||
|
// info!("pos: {pos:?}, port_range: {range:?}, in_scope: {in_scope:?}");
|
||||||
|
if compare_pos(&range.start, pos) != 1 && compare_pos(pos, &range.end) != 1 {
|
||||||
|
return Some(instance);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 计算 position 赋值的 port 或者 param
|
||||||
|
/// 比如 .clk ( clk ) 中的 .clk
|
||||||
|
fn hover_position_port_param(
|
||||||
|
server: &LSPServer,
|
||||||
|
line: &RopeSlice,
|
||||||
|
url: &Url,
|
||||||
|
pos: Position,
|
||||||
|
language_id: &str
|
||||||
|
) -> Option<Hover> {
|
||||||
|
let position_port_regex = Regex::new(r"[.0-9a-zA-Z]").unwrap();
|
||||||
|
if let Some((name, range)) = get_word_range_at_position(line, pos, position_port_regex) {
|
||||||
|
if name.starts_with(".") {
|
||||||
|
let name = &name[1..];
|
||||||
|
// 进入最近的 scope 寻找
|
||||||
|
let fast_map = server.srcs.hdl_param.path_to_hdl_file.read().unwrap();
|
||||||
|
let path = PathBuf::from_str(url.path()).unwrap();
|
||||||
|
let path = to_escape_path(&path);
|
||||||
|
let path_string = path.to_str().unwrap();
|
||||||
|
if let Some(hdl_file) = fast_map.get(path_string) {
|
||||||
|
// 先找到属于哪一个 module
|
||||||
|
let fast = &hdl_file.fast;
|
||||||
|
info!("find hdl file: {:?}", fast);
|
||||||
|
if let Some(instance) = goto_instantiation(fast, &pos) {
|
||||||
|
info!("find instance scope: {:?}", instance);
|
||||||
|
if let Some(hover) = hover_position_param(server, instance, &pos, &range, name, language_id) {
|
||||||
|
info!("hover_position_param return");
|
||||||
|
return Some(hover);
|
||||||
|
}
|
||||||
|
if let Some(hover) = hover_position_port(server, instance, &pos, &range, name, language_id) {
|
||||||
|
info!("hover_position_port return");
|
||||||
|
return Some(hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_port_desc_hover(port: &crate::core::fast_hdlparam::Port, range: &Range, language_id: &str) -> Hover {
|
||||||
|
let mut port_desc_array = Vec::<String>::new();
|
||||||
|
port_desc_array.push(port.dir_type.to_string());
|
||||||
|
if port.net_type != "unknown" {
|
||||||
|
port_desc_array.push(port.net_type.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if port.signed != "unsigned" {
|
||||||
|
port_desc_array.push("signed".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
if port.width != "1" {
|
||||||
|
port_desc_array.push(port.width.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
port_desc_array.push(port.name.to_string());
|
||||||
|
let port_desc = port_desc_array.join(" ");
|
||||||
|
let language_string = LanguageString {
|
||||||
|
language: language_id.to_string(),
|
||||||
|
value: port_desc
|
||||||
|
};
|
||||||
|
Hover {
|
||||||
|
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
||||||
|
range: Some(range.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn make_param_desc_hover(param: &crate::core::fast_hdlparam::Parameter, range: &Range, language_id: &str) -> Hover {
|
||||||
|
let mut param_desc_array = Vec::<String>::new();
|
||||||
|
param_desc_array.push(format!("parameter {}", param.name));
|
||||||
|
|
||||||
|
if param.init != "unknown" {
|
||||||
|
param_desc_array.push(param.init.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
let param_desc = param_desc_array.join(" ");
|
||||||
|
let language_string = LanguageString {
|
||||||
|
language: language_id.to_string(),
|
||||||
|
value: param_desc
|
||||||
|
};
|
||||||
|
Hover {
|
||||||
|
contents: HoverContents::Scalar(MarkedString::LanguageString(language_string)),
|
||||||
|
range: Some(range.clone())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// pos1 < pos2 -1
|
||||||
|
/// pos1 = pos2 0
|
||||||
|
/// pos1 > pos2 1
|
||||||
|
fn compare_pos(pos1: &Position, pos2: &Position) -> i32 {
|
||||||
|
if pos1.line > pos2.line {
|
||||||
|
1
|
||||||
|
} else if pos1.line < pos2.line {
|
||||||
|
-1
|
||||||
|
} else if pos1.character > pos2.character {
|
||||||
|
1
|
||||||
|
} else if pos1.character < pos2.character {
|
||||||
|
-1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hover_position_port(
|
||||||
|
server: &LSPServer,
|
||||||
|
instance: &crate::core::fast_hdlparam::Instance,
|
||||||
|
pos: &Position,
|
||||||
|
range: &Range,
|
||||||
|
token_name: &str,
|
||||||
|
language_id: &str
|
||||||
|
) -> Option<Hover> {
|
||||||
|
|
||||||
|
if let Some(inst_port_range) = &instance.instports {
|
||||||
|
let port_range = inst_port_range.to_lsp_range();
|
||||||
|
|
||||||
|
if compare_pos(&port_range.start, pos) != 1 && compare_pos(pos, &port_range.end) != 1 {
|
||||||
|
let module_name = &instance.inst_type;
|
||||||
|
// 确定当前光标在 inst port 内
|
||||||
|
if let Some(module) = server.srcs.hdl_param.find_module_by_name(module_name) {
|
||||||
|
info!("find original module");
|
||||||
|
for port in &module.ports {
|
||||||
|
if token_name == port.name {
|
||||||
|
// 制作 port 的 Hover
|
||||||
|
let hover = make_port_desc_hover(port, range, language_id);
|
||||||
|
return Some(hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn hover_position_param(
|
||||||
|
server: &LSPServer,
|
||||||
|
instance: &crate::core::fast_hdlparam::Instance,
|
||||||
|
pos: &Position,
|
||||||
|
range: &Range,
|
||||||
|
token_name: &str,
|
||||||
|
language_id: &str
|
||||||
|
) -> Option<Hover> {
|
||||||
|
if let Some(inst_param_range) = &instance.instparams {
|
||||||
|
let param_range = inst_param_range.to_lsp_range();
|
||||||
|
if compare_pos(¶m_range.start, pos) != 1 && compare_pos(pos, ¶m_range.end) != 1 {
|
||||||
|
let module_name = &instance.inst_type;
|
||||||
|
// 确定当前光标在 inst port 内
|
||||||
|
if let Some(module) = server.srcs.hdl_param.find_module_by_name(module_name) {
|
||||||
|
for param in &module.params {
|
||||||
|
if token_name == param.name {
|
||||||
|
// 制作 port 的 Hover
|
||||||
|
let hover = make_param_desc_hover(param, range, language_id);
|
||||||
|
return Some(hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
@ -2,5 +2,8 @@ use tower_lsp::lsp_types::*;
|
|||||||
use crate::server::LSPServer;
|
use crate::server::LSPServer;
|
||||||
|
|
||||||
pub fn hover_vhdl(server: &LSPServer, param: &DocumentSymbolParams) -> Option<Hover> {
|
pub fn hover_vhdl(server: &LSPServer, param: &DocumentSymbolParams) -> Option<Hover> {
|
||||||
|
let design_file = server.srcs.design_file_map.write().unwrap();
|
||||||
|
|
||||||
|
|
||||||
None
|
None
|
||||||
}
|
}
|
@ -116,12 +116,10 @@ pub fn do_fast<'a>(path: String, _server: &Arc<Backend>) -> Result<FastHdlparam
|
|||||||
);
|
);
|
||||||
|
|
||||||
if let Some(syntax_tree) = parse_result {
|
if let Some(syntax_tree) = parse_result {
|
||||||
if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
|
if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
|
||||||
let mut fast_map = _server.server.srcs.fast_map.write().unwrap();
|
let hdl_param = _server.server.srcs.hdl_param.clone();
|
||||||
fast_map.insert(path.to_string(), hdlparam);
|
hdl_param.update_fast(path.to_string(), fast.clone());
|
||||||
if let Some(hdlparam) = fast_map.get(&path) {
|
return Ok(fast);
|
||||||
return Ok(hdlparam.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::core::fast_hdlparam::FastHdlparam;
|
use crate::core::fast_hdlparam::FastHdlparam;
|
||||||
|
use crate::core::fast_hdlparam::HdlParam;
|
||||||
use crate::core::sv_parser::make_fast_from_syntaxtree;
|
use crate::core::sv_parser::make_fast_from_syntaxtree;
|
||||||
use crate::core::vhdl_parser::make_fast_from_design_file;
|
use crate::core::vhdl_parser::make_fast_from_design_file;
|
||||||
use crate::core::vhdl_parser::vhdl_parse;
|
use crate::core::vhdl_parser::vhdl_parse;
|
||||||
@ -128,6 +129,7 @@ pub struct Source {
|
|||||||
|
|
||||||
pub enum ParseIR {
|
pub enum ParseIR {
|
||||||
/// 基于 rust_hdl 的IR,存放 VHDL
|
/// 基于 rust_hdl 的IR,存放 VHDL
|
||||||
|
#[allow(unused)]
|
||||||
DesignFile(vhdl_lang::ast::DesignFile),
|
DesignFile(vhdl_lang::ast::DesignFile),
|
||||||
/// 存放 sv 的 IR
|
/// 存放 sv 的 IR
|
||||||
SyntaxTree(sv_parser::SyntaxTree)
|
SyntaxTree(sv_parser::SyntaxTree)
|
||||||
@ -181,8 +183,8 @@ pub struct Sources {
|
|||||||
pub include_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
pub include_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||||
// source directories
|
// source directories
|
||||||
pub source_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
pub source_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||||
// fast result
|
/// hdlparam 后端实现
|
||||||
pub fast_map: Arc<RwLock<HashMap<String, FastHdlparam>>>
|
pub hdl_param: Arc<HdlParam>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::default::Default for Sources {
|
impl std::default::Default for Sources {
|
||||||
@ -201,7 +203,7 @@ impl Sources {
|
|||||||
design_file_map: Arc::new(RwLock::new(HashMap::new())),
|
design_file_map: Arc::new(RwLock::new(HashMap::new())),
|
||||||
include_dirs: Arc::new(RwLock::new(Vec::new())),
|
include_dirs: Arc::new(RwLock::new(Vec::new())),
|
||||||
source_dirs: Arc::new(RwLock::new(Vec::new())),
|
source_dirs: Arc::new(RwLock::new(Vec::new())),
|
||||||
fast_map: Arc::new(RwLock::new(HashMap::new()))
|
hdl_param: Arc::new(HdlParam::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn init(&self) {
|
pub fn init(&self) {
|
||||||
@ -248,7 +250,7 @@ impl Sources {
|
|||||||
let source_handle = source.clone();
|
let source_handle = source.clone();
|
||||||
let scope_handle = self.scope_tree.clone();
|
let scope_handle = self.scope_tree.clone();
|
||||||
let design_file_handle = self.design_file_map.clone();
|
let design_file_handle = self.design_file_map.clone();
|
||||||
let fast_map_handle = self.fast_map.clone();
|
let hdl_param_handle = self.hdl_param.clone();
|
||||||
let inc_dirs = self.include_dirs.clone();
|
let inc_dirs = self.include_dirs.clone();
|
||||||
|
|
||||||
info!("launch worker to parse {:?}", doc.uri.to_string());
|
info!("launch worker to parse {:?}", doc.uri.to_string());
|
||||||
@ -270,7 +272,7 @@ impl Sources {
|
|||||||
"vhdl" => {
|
"vhdl" => {
|
||||||
vhdl_parser_pipeline(
|
vhdl_parser_pipeline(
|
||||||
&design_file_handle,
|
&design_file_handle,
|
||||||
&fast_map_handle,
|
&hdl_param_handle,
|
||||||
uri,
|
uri,
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -278,7 +280,7 @@ impl Sources {
|
|||||||
sv_parser_pipeline(
|
sv_parser_pipeline(
|
||||||
&source_handle,
|
&source_handle,
|
||||||
&scope_handle,
|
&scope_handle,
|
||||||
&fast_map_handle,
|
&hdl_param_handle,
|
||||||
&text,
|
&text,
|
||||||
uri,
|
uri,
|
||||||
range,
|
range,
|
||||||
@ -492,7 +494,7 @@ pub fn recovery_sv_parse(
|
|||||||
pub fn sv_parser_pipeline(
|
pub fn sv_parser_pipeline(
|
||||||
source_handle: &Arc<RwLock<Source>>,
|
source_handle: &Arc<RwLock<Source>>,
|
||||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||||
fast_map_handle: &Arc<RwLock<HashMap<String, FastHdlparam>>>,
|
hdl_param_handle: &Arc<HdlParam>,
|
||||||
doc: &Rope,
|
doc: &Rope,
|
||||||
uri: &Url,
|
uri: &Url,
|
||||||
last_change_range: &Option<Range>,
|
last_change_range: &Option<Range>,
|
||||||
@ -531,9 +533,8 @@ pub fn sv_parser_pipeline(
|
|||||||
|
|
||||||
// 加入语法树 & 更新 fast
|
// 加入语法树 & 更新 fast
|
||||||
if let Some(syntax_tree) = syntax_tree {
|
if let Some(syntax_tree) = syntax_tree {
|
||||||
if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &escape_path) {
|
if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &escape_path) {
|
||||||
let mut fast_map = fast_map_handle.write().unwrap();
|
hdl_param_handle.update_fast(escape_path_string.to_string(), fast);
|
||||||
fast_map.insert(escape_path_string.to_string(), hdlparam);
|
|
||||||
}
|
}
|
||||||
let parse_ir = ParseIR::SyntaxTree(syntax_tree);
|
let parse_ir = ParseIR::SyntaxTree(syntax_tree);
|
||||||
file.parse_ir = Some(parse_ir);
|
file.parse_ir = Some(parse_ir);
|
||||||
@ -567,7 +568,7 @@ pub fn sv_parser_pipeline(
|
|||||||
|
|
||||||
pub fn vhdl_parser_pipeline(
|
pub fn vhdl_parser_pipeline(
|
||||||
design_file_handle: &Arc<RwLock<HashMap<String, DesignFile>>>,
|
design_file_handle: &Arc<RwLock<HashMap<String, DesignFile>>>,
|
||||||
fast_map_handle: &Arc<RwLock<HashMap<String, FastHdlparam>>>,
|
hdl_param_handle: &Arc<HdlParam>,
|
||||||
uri: &Url
|
uri: &Url
|
||||||
) {
|
) {
|
||||||
let path = match PathBuf::from_str(uri.path()) {
|
let path = match PathBuf::from_str(uri.path()) {
|
||||||
@ -585,9 +586,8 @@ pub fn vhdl_parser_pipeline(
|
|||||||
}
|
}
|
||||||
if let Some(design_file) = vhdl_parse(&escape_path) {
|
if let Some(design_file) = vhdl_parse(&escape_path) {
|
||||||
let mut design_files = design_file_handle.write().unwrap();
|
let mut design_files = design_file_handle.write().unwrap();
|
||||||
if let Some(hdlparam) = make_fast_from_design_file(&design_file) {
|
if let Some(fast) = make_fast_from_design_file(&design_file) {
|
||||||
let mut fast_map = fast_map_handle.write().unwrap();
|
hdl_param_handle.update_fast(escape_path_string.to_string(), fast);
|
||||||
fast_map.insert(escape_path_string.to_string(), hdlparam);
|
|
||||||
}
|
}
|
||||||
design_files.insert(escape_path_string.to_string(), design_file);
|
design_files.insert(escape_path_string.to_string(), design_file);
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,10 @@ impl LSPServer {
|
|||||||
/// macro 可以以 ` 开头
|
/// macro 可以以 ` 开头
|
||||||
pub fn find_macros(&self, macro_name: &str) -> Option<(Define, String)> {
|
pub fn find_macros(&self, macro_name: &str) -> Option<(Define, String)> {
|
||||||
let macro_name = macro_name.replace("`", "");
|
let macro_name = macro_name.replace("`", "");
|
||||||
let fast_map = self.srcs.fast_map.read().unwrap();
|
let fast_map = self.srcs.hdl_param.path_to_hdl_file.read().unwrap();
|
||||||
for path in fast_map.keys() {
|
for path in fast_map.keys() {
|
||||||
if let Some(hdlparam) = fast_map.get(path) {
|
if let Some(hdl_file) = fast_map.get(path) {
|
||||||
for define in &hdlparam.fast_macro.defines {
|
for define in &hdl_file.fast.fast_macro.defines {
|
||||||
if define.name == macro_name {
|
if define.name == macro_name {
|
||||||
return Some((define.clone(), path.to_string()));
|
return Some((define.clone(), path.to_string()));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user