实现 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 tower_lsp::lsp_types::Position as LspPosition;
|
||||
use tower_lsp::lsp_types::Range as LspRange;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, PartialEq, Deserialize)]
|
||||
pub struct Position {
|
||||
@ -6,12 +11,28 @@ pub struct Position {
|
||||
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)]
|
||||
pub struct Range {
|
||||
pub start: 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)]
|
||||
pub struct Port {
|
||||
pub name: String,
|
||||
@ -232,63 +253,57 @@ impl FastHdlparam {
|
||||
last_module.instances.push(instance);
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn print_fast(&self) {
|
||||
// if self.content.is_empty() {
|
||||
// println!("none module");
|
||||
// } else {
|
||||
// for module in &self.content {
|
||||
// println!("module {}", module.name);
|
||||
// if !module.params.is_empty() {
|
||||
// println!(" params:");
|
||||
// for param in &module.params {
|
||||
// println!(" parameter {} {} {}", param.net_type, param.name, param.init);
|
||||
// println!(" range start {} {}", param.range.start.line, param.range.start.character);
|
||||
// println!(" range end {} {}", param.range.end.line, param.range.end.character);
|
||||
// }
|
||||
// }
|
||||
// if !module.ports.is_empty() {
|
||||
// println!(" ports:");
|
||||
// for port in &module.ports {
|
||||
// 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);
|
||||
// }
|
||||
// println!(" range start {} {}", port.range.start.line, port.range.start.character);
|
||||
// println!(" range end {} {}", port.range.end.line, port.range.end.character);
|
||||
// }
|
||||
// }
|
||||
// if !module.instances.is_empty() {
|
||||
// println!(" instances:");
|
||||
// for instance in &module.instances {
|
||||
// println!(" {} {}", instance.inst_type, instance.name);
|
||||
// if instance.instparams.is_none() {
|
||||
// println!(" params: {:?}", instance.instparams);
|
||||
// } else {
|
||||
// println!(" params:");
|
||||
// println!(" range start {} {}", instance.instparams.clone().unwrap().start.line,
|
||||
// instance.instparams.clone().unwrap().start.character);
|
||||
// println!(" range end {} {}", instance.instparams.clone().unwrap().end.line,
|
||||
// instance.instparams.clone().unwrap().end.character);
|
||||
// }
|
||||
// if instance.instports.is_none() {
|
||||
// println!(" ports: {:?}", instance.instports);
|
||||
// } else {
|
||||
// println!(" ports:");
|
||||
// println!(" range start {} {}", instance.instports.clone().unwrap().start.line,
|
||||
// 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);
|
||||
// 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);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
pub struct HdlFile {
|
||||
pub fast: FastHdlparam,
|
||||
pub name_to_module: HashMap<String, Module>
|
||||
}
|
||||
|
||||
pub struct HdlParam {
|
||||
/// 路径到 HdlFile 的映射
|
||||
pub path_to_hdl_file: RwLock<HashMap<String, HdlFile>>,
|
||||
/// 模块名字到其所在的 HdlFile 路径的映射
|
||||
pub module_name_to_path: RwLock<HashMap<String, String>>
|
||||
}
|
||||
|
||||
impl HdlParam {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
path_to_hdl_file: RwLock::new(HashMap::<String, HdlFile>::new()),
|
||||
module_name_to_path: RwLock::new(HashMap::<String, String>::new())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn update_fast(&self, path: String, fast: FastHdlparam) {
|
||||
let mut fast_map = self.path_to_hdl_file.write().unwrap();
|
||||
// 构建映射
|
||||
let mut name_to_module = HashMap::<String, Module>::new();
|
||||
let mut module_name_to_path = self.module_name_to_path.write().unwrap();
|
||||
|
||||
for module in &fast.content {
|
||||
name_to_module.insert(module.name.to_string(), module.clone());
|
||||
if !module_name_to_path.contains_key(&module.name) {
|
||||
module_name_to_path.insert(module.name.to_string(), path.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
let file = HdlFile { fast, name_to_module };
|
||||
fast_map.insert(path, file);
|
||||
}
|
||||
|
||||
pub fn find_module_by_name(&self, name: &str) -> Option<Module> {
|
||||
let module_name_to_path = self.module_name_to_path.read().unwrap();
|
||||
if let Some(path) = module_name_to_path.get(name) {
|
||||
let fast_map = self.path_to_hdl_file.read().unwrap();
|
||||
if let Some(hdl_file) = fast_map.get(path) {
|
||||
if let Some(module) = hdl_file.name_to_module.get(name) {
|
||||
return Some(module.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
}
|
@ -3,6 +3,7 @@ use crate::definition::match_definitions;
|
||||
use sv_parser::*;
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
||||
/// 找到 node 的 名字,开始的位置和结束的位置
|
||||
pub fn get_ident(tree: &SyntaxTree, node: RefNode) -> (String, usize) {
|
||||
let loc = unwrap_locate!(node).unwrap();
|
||||
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 def = scope_tree
|
||||
.as_ref()?
|
||||
// 获取定义
|
||||
.get_definition(&token, file.text.pos_to_byte(&pos), &doc)?;
|
||||
let byte_idx = file.text.pos_to_byte(&pos);
|
||||
let global_scope = scope_tree.as_ref()?;
|
||||
let def = global_scope.get_definition(&token, byte_idx, &doc)?;
|
||||
|
||||
let def_pos = file.text.byte_to_pos(def.byte_idx());
|
||||
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::sources::LSPSupport;
|
||||
use crate::utils::*;
|
||||
use log::info;
|
||||
use regex::Regex;
|
||||
use ropey::{Rope, RopeSlice};
|
||||
use tower_lsp::lsp_types::*;
|
||||
@ -36,10 +38,16 @@ impl LSPServer {
|
||||
return Some(hover);
|
||||
}
|
||||
|
||||
|
||||
let scope_tree: RwLockReadGuard<'_, Option<GenericScope>> = self.srcs.scope_tree.read().ok()?;
|
||||
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 {
|
||||
// match 正常 symbol
|
||||
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)
|
||||
}
|
||||
|
||||
/// 计算 position 赋值的 port 或者 param
|
||||
/// 比如 .clk ( clk ) 中的 .
|
||||
fn hover_position_port(line: &RopeSlice, pos: Position, language_id: &str) -> Option<Hover> {
|
||||
let position_port_regex = Regex::new(r"[.0-9a-zA-Z]").unwrap();
|
||||
if let Some((port_name, range)) = get_word_range_at_position(line, pos, position_port_regex) {
|
||||
if port_name.starts_with(".") {
|
||||
let port_name = &port_name[1..];
|
||||
fn goto_instantiation<'a>(
|
||||
fast: &'a FastHdlparam,
|
||||
pos: &Position
|
||||
) -> Option<&'a crate::core::fast_hdlparam::Instance> {
|
||||
for module in &fast.content {
|
||||
for instance in &module.instances {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/// 计算 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;
|
||||
|
||||
pub fn hover_vhdl(server: &LSPServer, param: &DocumentSymbolParams) -> Option<Hover> {
|
||||
let design_file = server.srcs.design_file_map.write().unwrap();
|
||||
|
||||
|
||||
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 Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
|
||||
let mut fast_map = _server.server.srcs.fast_map.write().unwrap();
|
||||
fast_map.insert(path.to_string(), hdlparam);
|
||||
if let Some(hdlparam) = fast_map.get(&path) {
|
||||
return Ok(hdlparam.clone());
|
||||
}
|
||||
if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &path_buf) {
|
||||
let hdl_param = _server.server.srcs.hdl_param.clone();
|
||||
hdl_param.update_fast(path.to_string(), fast.clone());
|
||||
return Ok(fast);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::core::fast_hdlparam::FastHdlparam;
|
||||
use crate::core::fast_hdlparam::HdlParam;
|
||||
use crate::core::sv_parser::make_fast_from_syntaxtree;
|
||||
use crate::core::vhdl_parser::make_fast_from_design_file;
|
||||
use crate::core::vhdl_parser::vhdl_parse;
|
||||
@ -128,6 +129,7 @@ pub struct Source {
|
||||
|
||||
pub enum ParseIR {
|
||||
/// 基于 rust_hdl 的IR,存放 VHDL
|
||||
#[allow(unused)]
|
||||
DesignFile(vhdl_lang::ast::DesignFile),
|
||||
/// 存放 sv 的 IR
|
||||
SyntaxTree(sv_parser::SyntaxTree)
|
||||
@ -181,8 +183,8 @@ pub struct Sources {
|
||||
pub include_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||
// source directories
|
||||
pub source_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||
// fast result
|
||||
pub fast_map: Arc<RwLock<HashMap<String, FastHdlparam>>>
|
||||
/// hdlparam 后端实现
|
||||
pub hdl_param: Arc<HdlParam>,
|
||||
}
|
||||
|
||||
impl std::default::Default for Sources {
|
||||
@ -201,7 +203,7 @@ impl Sources {
|
||||
design_file_map: Arc::new(RwLock::new(HashMap::new())),
|
||||
include_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) {
|
||||
@ -248,7 +250,7 @@ impl Sources {
|
||||
let source_handle = source.clone();
|
||||
let scope_handle = self.scope_tree.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();
|
||||
|
||||
info!("launch worker to parse {:?}", doc.uri.to_string());
|
||||
@ -270,7 +272,7 @@ impl Sources {
|
||||
"vhdl" => {
|
||||
vhdl_parser_pipeline(
|
||||
&design_file_handle,
|
||||
&fast_map_handle,
|
||||
&hdl_param_handle,
|
||||
uri,
|
||||
);
|
||||
},
|
||||
@ -278,7 +280,7 @@ impl Sources {
|
||||
sv_parser_pipeline(
|
||||
&source_handle,
|
||||
&scope_handle,
|
||||
&fast_map_handle,
|
||||
&hdl_param_handle,
|
||||
&text,
|
||||
uri,
|
||||
range,
|
||||
@ -492,7 +494,7 @@ pub fn recovery_sv_parse(
|
||||
pub fn sv_parser_pipeline(
|
||||
source_handle: &Arc<RwLock<Source>>,
|
||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||
fast_map_handle: &Arc<RwLock<HashMap<String, FastHdlparam>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
doc: &Rope,
|
||||
uri: &Url,
|
||||
last_change_range: &Option<Range>,
|
||||
@ -531,9 +533,8 @@ pub fn sv_parser_pipeline(
|
||||
|
||||
// 加入语法树 & 更新 fast
|
||||
if let Some(syntax_tree) = syntax_tree {
|
||||
if let Ok(hdlparam) = make_fast_from_syntaxtree(&syntax_tree, &escape_path) {
|
||||
let mut fast_map = fast_map_handle.write().unwrap();
|
||||
fast_map.insert(escape_path_string.to_string(), hdlparam);
|
||||
if let Ok(fast) = make_fast_from_syntaxtree(&syntax_tree, &escape_path) {
|
||||
hdl_param_handle.update_fast(escape_path_string.to_string(), fast);
|
||||
}
|
||||
let parse_ir = ParseIR::SyntaxTree(syntax_tree);
|
||||
file.parse_ir = Some(parse_ir);
|
||||
@ -567,7 +568,7 @@ pub fn sv_parser_pipeline(
|
||||
|
||||
pub fn vhdl_parser_pipeline(
|
||||
design_file_handle: &Arc<RwLock<HashMap<String, DesignFile>>>,
|
||||
fast_map_handle: &Arc<RwLock<HashMap<String, FastHdlparam>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
uri: &Url
|
||||
) {
|
||||
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) {
|
||||
let mut design_files = design_file_handle.write().unwrap();
|
||||
if let Some(hdlparam) = make_fast_from_design_file(&design_file) {
|
||||
let mut fast_map = fast_map_handle.write().unwrap();
|
||||
fast_map.insert(escape_path_string.to_string(), hdlparam);
|
||||
if let Some(fast) = make_fast_from_design_file(&design_file) {
|
||||
hdl_param_handle.update_fast(escape_path_string.to_string(), fast);
|
||||
}
|
||||
design_files.insert(escape_path_string.to_string(), design_file);
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ impl LSPServer {
|
||||
/// macro 可以以 ` 开头
|
||||
pub fn find_macros(&self, macro_name: &str) -> Option<(Define, String)> {
|
||||
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() {
|
||||
if let Some(hdlparam) = fast_map.get(path) {
|
||||
for define in &hdlparam.fast_macro.defines {
|
||||
if let Some(hdl_file) = fast_map.get(path) {
|
||||
for define in &hdl_file.fast.fast_macro.defines {
|
||||
if define.name == macro_name {
|
||||
return Some((define.clone(), path.to_string()));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user