refactor vhdl lsp service
This commit is contained in:
parent
c40e66f3df
commit
2fcfed4674
102
Cargo.lock
generated
102
Cargo.lock
generated
@ -286,6 +286,15 @@ version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-deque"
|
||||
version = "0.8.5"
|
||||
@ -348,6 +357,7 @@ dependencies = [
|
||||
"tokio",
|
||||
"tower-lsp",
|
||||
"vhdl_lang",
|
||||
"vhdl_ls",
|
||||
"walkdir",
|
||||
"xml",
|
||||
]
|
||||
@ -426,6 +436,29 @@ dependencies = [
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab"
|
||||
dependencies = [
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e13fa619b91fb2381732789fc5de83b45675e882f66623b7d8cb4f643017018d"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"humantime",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
@ -544,6 +577,15 @@ dependencies = [
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuzzy-matcher"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
|
||||
dependencies = [
|
||||
"thread_local",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
@ -609,6 +651,12 @@ version = "1.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946"
|
||||
|
||||
[[package]]
|
||||
name = "humantime"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.61"
|
||||
@ -720,6 +768,18 @@ version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "lsp-server"
|
||||
version = "0.7.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.94.1"
|
||||
@ -733,6 +793,19 @@ dependencies = [
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lsp-types"
|
||||
version = "0.95.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e34d33a8e9b006cd3fc4fe69a921affa097bae4bb65f76271f4644f9a334365"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_repr",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
@ -1462,6 +1535,16 @@ dependencies = [
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.8.0"
|
||||
@ -1578,7 +1661,7 @@ dependencies = [
|
||||
"dashmap",
|
||||
"futures",
|
||||
"httparse",
|
||||
"lsp-types",
|
||||
"lsp-types 0.94.1",
|
||||
"memchr",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1736,6 +1819,23 @@ dependencies = [
|
||||
"syn 2.0.79",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vhdl_ls"
|
||||
version = "0.83.0"
|
||||
dependencies = [
|
||||
"clap 4.5.19",
|
||||
"env_logger",
|
||||
"fnv",
|
||||
"fuzzy-matcher",
|
||||
"log",
|
||||
"lsp-server",
|
||||
"lsp-types 0.95.1",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tower-lsp",
|
||||
"vhdl_lang",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
|
@ -6,6 +6,7 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
sv-parser = { version = "0.13.3", path = "sv-parser/sv-parser"}
|
||||
vhdl_ls = { version = "^0.83.0", path = "vhdl-parser/vhdl_ls" }
|
||||
vhdl_lang = { version = "^0.83.0", path = "vhdl-parser/vhdl_lang" }
|
||||
dirs-next = "2.0"
|
||||
bincode = "1.3"
|
||||
|
@ -1,8 +1,10 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
#[allow(unused)]
|
||||
use log::info;
|
||||
use ropey::{Rope, RopeSlice};
|
||||
use tower_lsp::lsp_types::*;
|
||||
use crate::hover::feature::make_vhdl_module_profile_code;
|
||||
use crate::{hover::feature::make_vhdl_module_profile_code, utils::{from_lsp_pos, to_escape_path}};
|
||||
#[allow(unused)]
|
||||
use crate::{server::LSPServer, sources::LSPSupport, utils::get_language_id_by_uri};
|
||||
|
||||
@ -26,6 +28,27 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
|
||||
doc.position,
|
||||
);
|
||||
|
||||
let project = server.srcs.vhdl_project.read().ok()?;
|
||||
let global_project = project.as_ref().unwrap();
|
||||
let path = match PathBuf::from_str(uri.path()) {
|
||||
Ok(path) => path,
|
||||
Err(error) => {
|
||||
info!("error happen in vhdl <hover>: {:?}", error);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let escape_path = to_escape_path(&path);
|
||||
let project_file = escape_path.as_path();
|
||||
let Some(source) = global_project.project.get_source(project_file) else {
|
||||
return None
|
||||
};
|
||||
let cursor = from_lsp_pos(params.text_document_position.position);
|
||||
|
||||
let vhdl_project_completion_items = global_project.project
|
||||
.list_completion_options(&source, cursor)
|
||||
.into_iter()
|
||||
.map(|item| vhdl_ls::VHDLServer::completion_item_to_tower_lsp_item(item))
|
||||
.collect::<Vec<CompletionItem>>();
|
||||
|
||||
let response = match ¶ms.context {
|
||||
Some(context) => match context.trigger_kind {
|
||||
@ -65,6 +88,8 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
|
||||
make_module_completions(server, &token, &language_id)
|
||||
);
|
||||
|
||||
completion_items.items.extend(vhdl_project_completion_items);
|
||||
|
||||
// 去重
|
||||
completion_items.items.dedup_by_key(|i| i.label.to_string());
|
||||
Some(completion_items)
|
||||
@ -100,6 +125,9 @@ pub fn completion(server: &LSPServer, params: &CompletionParams) -> Option<Compl
|
||||
.cloned()
|
||||
.collect(),
|
||||
);
|
||||
|
||||
comps.items.extend(vhdl_project_completion_items);
|
||||
|
||||
comps.items.dedup_by_key(|i| i.label.clone());
|
||||
Some(comps)
|
||||
}
|
||||
|
@ -1,8 +1,12 @@
|
||||
use crate::sources::LSPSupport;
|
||||
use std::ffi::OsStr;
|
||||
|
||||
#[allow(unused)]
|
||||
use log::info;
|
||||
use ropey::Rope;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use vhdl_lang::Project;
|
||||
|
||||
use crate::sources::LSPSupport;
|
||||
|
||||
/// cleanup the text of a definition so it can be included in completions
|
||||
pub fn clean_type_str(type_str: &str, ident: &str) -> String {
|
||||
@ -749,6 +753,12 @@ impl Definition for ModInst {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct VhdlProject {
|
||||
pub project: Project,
|
||||
pub std_config: vhdl_lang::Config,
|
||||
pub config_file_strs: Vec<String>
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GenericScope {
|
||||
pub ident: String,
|
||||
|
@ -1,7 +1,9 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
#[allow(unused)]
|
||||
use log::info;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use crate::{server::LSPServer, sources::LSPSupport, utils::get_definition_token};
|
||||
use crate::{server::LSPServer, utils::{from_lsp_pos, get_definition_token, srcpos_to_location, to_escape_path}};
|
||||
|
||||
use super::{Definition, Scope};
|
||||
|
||||
@ -16,6 +18,29 @@ pub fn goto_vhdl_definition(server: &LSPServer, params: &GotoDefinitionParams) -
|
||||
let line_text = file.text.line(pos.line as usize);
|
||||
let token: String = get_definition_token(&line_text, pos);
|
||||
|
||||
let project = server.srcs.vhdl_project.read().ok()?;
|
||||
let global_project = project.as_ref().unwrap();
|
||||
let path = match PathBuf::from_str(doc.path()) {
|
||||
Ok(path) => path,
|
||||
Err(error) => {
|
||||
info!("error happen in vhdl <hover>: {:?}", error);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let escape_path = to_escape_path(&path);
|
||||
let project_file = escape_path.as_path();
|
||||
let Some(source) = global_project.project.get_source(project_file) else {
|
||||
return None
|
||||
};
|
||||
|
||||
let ents = global_project.project.find_implementation(&source, from_lsp_pos(pos));
|
||||
|
||||
Some(GotoDefinitionResponse::Array(
|
||||
ents.into_iter()
|
||||
.filter_map(|ent| ent.decl_pos().map(srcpos_to_location))
|
||||
.collect(),
|
||||
))
|
||||
|
||||
// // match include
|
||||
// if let Some(definition) = goto_include_definition(doc, &line_text, pos) {
|
||||
// return Some(definition);
|
||||
@ -28,7 +53,7 @@ pub fn goto_vhdl_definition(server: &LSPServer, params: &GotoDefinitionParams) -
|
||||
|
||||
// match instance
|
||||
|
||||
let scope_tree = server.srcs.scope_tree.read().ok()?;
|
||||
// let scope_tree = server.srcs.scope_tree.read().ok()?;
|
||||
|
||||
// // match position port & param
|
||||
// if let Some(definition) = goto_position_port_param_definition(server, &line_text, doc, pos) {
|
||||
@ -40,13 +65,13 @@ pub fn goto_vhdl_definition(server: &LSPServer, params: &GotoDefinitionParams) -
|
||||
// return Some(definition);
|
||||
// }
|
||||
|
||||
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 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(
|
||||
def.url(),
|
||||
Range::new(def_pos, def_pos),
|
||||
)))
|
||||
// let def_pos = file.text.byte_to_pos(def.byte_idx());
|
||||
// Some(GotoDefinitionResponse::Scalar(Location::new(
|
||||
// def.url(),
|
||||
// Range::new(def_pos, def_pos),
|
||||
// )))
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
use std::{path::PathBuf, str::FromStr};
|
||||
|
||||
#[allow(unused)]
|
||||
use log::info;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use crate::{definition::Scope, server::LSPServer};
|
||||
use vhdl_lang::{EntHierarchy, Token};
|
||||
use crate::{definition::Scope, server::LSPServer, utils::{to_escape_path, to_lsp_range, to_symbol_kind}};
|
||||
|
||||
pub fn document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Option<DocumentSymbolResponse> {
|
||||
// info!("enter document symbol");
|
||||
@ -13,7 +16,66 @@ pub fn document_symbol(server: &LSPServer, params: &DocumentSymbolParams) -> Opt
|
||||
let file = file.read().ok()?;
|
||||
let scope_tree = server.srcs.scope_tree.read().ok()?;
|
||||
|
||||
Some(DocumentSymbolResponse::Nested(
|
||||
scope_tree.as_ref()?.document_symbols(uri, &file.text),
|
||||
))
|
||||
let project = server.srcs.vhdl_project.read().ok()?;
|
||||
let global_project = project.as_ref().unwrap();
|
||||
let path = match PathBuf::from_str(uri.path()) {
|
||||
Ok(path) => path,
|
||||
Err(error) => {
|
||||
info!("error happen in vhdl <hover>: {:?}", error);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let escape_path = to_escape_path(&path);
|
||||
let project_file = escape_path.as_path();
|
||||
let Some(source) = global_project.project.get_source(project_file) else {
|
||||
return None
|
||||
};
|
||||
|
||||
// Some files are mapped to multiple libraries, only use the first library for document symbols
|
||||
let library_name = global_project.project
|
||||
.library_mapping_of(&source)
|
||||
.into_iter()
|
||||
.next()?;
|
||||
|
||||
fn to_document_symbol(
|
||||
EntHierarchy { ent, children }: EntHierarchy,
|
||||
ctx: &Vec<Token>,
|
||||
) -> DocumentSymbol {
|
||||
// Use the declaration position, if it exists,
|
||||
// else the position of the first source range token.
|
||||
// The latter is applicable for unnamed elements, e.g., processes or loops.
|
||||
let selection_pos = ent.decl_pos().unwrap_or(ent.src_span.start_token.pos(ctx));
|
||||
let src_range = ent.src_span.pos(ctx).range();
|
||||
#[allow(deprecated)]
|
||||
DocumentSymbol {
|
||||
name: ent.describe(),
|
||||
kind: to_symbol_kind(ent.kind()),
|
||||
tags: None,
|
||||
detail: None,
|
||||
selection_range: to_lsp_range(selection_pos.range),
|
||||
range: to_lsp_range(src_range),
|
||||
children: if !children.is_empty() {
|
||||
Some(
|
||||
children
|
||||
.into_iter()
|
||||
.map(|hierarchy| to_document_symbol(hierarchy, ctx))
|
||||
.collect(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
},
|
||||
deprecated: None,
|
||||
}
|
||||
}
|
||||
|
||||
Some(DocumentSymbolResponse::Nested(
|
||||
global_project.project
|
||||
.document_symbols(&library_name, &source)
|
||||
.into_iter()
|
||||
.map(|(hierarchy, tokens)| to_document_symbol(hierarchy, tokens))
|
||||
.collect(),
|
||||
))
|
||||
// Some(DocumentSymbolResponse::Nested(
|
||||
// scope_tree.as_ref()?.document_symbols(uri, &file.text),
|
||||
// ))
|
||||
}
|
@ -6,7 +6,7 @@ use ropey::Rope;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use crate::{core::hdlparam::{Instance, Module}, definition::{Definition, DefinitionType, GenericDec, Scope}, hover::{BracketMatchResult, BracketMatcher}, server::LSPServer, sources::LSPSupport};
|
||||
|
||||
use super::{feature::hover_format_digit, get_definition_token, get_language_id_by_uri, to_escape_path};
|
||||
use super::{from_lsp_pos, get_definition_token, get_language_id_by_uri, to_escape_path};
|
||||
|
||||
pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
|
||||
let doc = ¶ms.text_document_position_params.text_document.uri;
|
||||
@ -20,6 +20,30 @@ pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
|
||||
let token: String = get_definition_token(&line_text, pos);
|
||||
let language_id = get_language_id_by_uri(doc);
|
||||
|
||||
let project = server.srcs.vhdl_project.read().ok()?;
|
||||
let global_project = project.as_ref().unwrap();
|
||||
|
||||
let path = match PathBuf::from_str(doc.path()) {
|
||||
Ok(path) => path,
|
||||
Err(error) => {
|
||||
info!("error happen in vhdl <hover>: {:?}", error);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
let escape_path = to_escape_path(&path);
|
||||
let source = global_project.project.get_source(&escape_path)?;
|
||||
|
||||
let ent = global_project.project.find_declaration(&source, from_lsp_pos(pos))?;
|
||||
let value = global_project.project.format_declaration(ent)?;
|
||||
|
||||
Some(Hover {
|
||||
contents: HoverContents::Markup(MarkupContent {
|
||||
kind: MarkupKind::Markdown,
|
||||
value: format!("```vhdl\n{value}\n```"),
|
||||
}),
|
||||
range: None,
|
||||
})
|
||||
|
||||
// // match `include
|
||||
// if let Some(hover) = hover_include(doc, &line_text, pos, &language_id) {
|
||||
// return Some(hover);
|
||||
@ -30,11 +54,11 @@ pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
|
||||
// return Some(hover);
|
||||
// }
|
||||
|
||||
let scope_tree = server.srcs.scope_tree.read().ok()?;
|
||||
let global_scope = scope_tree.as_ref().unwrap();
|
||||
// let scope_tree = server.srcs.scope_tree.read().ok()?;
|
||||
// let global_scope = scope_tree.as_ref().unwrap();
|
||||
|
||||
let symbol_definition: GenericDec = global_scope
|
||||
.get_definition(&token, file.text.pos_to_byte(&pos), doc)?;
|
||||
// let symbol_definition: GenericDec = global_scope
|
||||
// .get_definition(&token, file.text.pos_to_byte(&pos), doc)?;
|
||||
|
||||
// // match positional port param
|
||||
// if let Some(hover) = hover_position_port_param(server, &line_text, doc, pos, &language_id) {
|
||||
@ -47,16 +71,16 @@ pub fn hover(server: &LSPServer, params: &HoverParams) -> Option<Hover> {
|
||||
// }
|
||||
|
||||
// match 正常 symbol
|
||||
if let Some(hover) = hover_common_symbol(server, &token, &symbol_definition, &file, doc, pos, &language_id) {
|
||||
return Some(hover);
|
||||
}
|
||||
// if let Some(hover) = hover_common_symbol(server, &token, &symbol_definition, &file, doc, pos, &language_id) {
|
||||
// return Some(hover);
|
||||
// }
|
||||
|
||||
// match digit 5'b00110
|
||||
if let Some(hover) = hover_format_digit(&line_text, pos, &language_id) {
|
||||
return Some(hover);
|
||||
}
|
||||
// // match digit 5'b00110
|
||||
// if let Some(hover) = hover_format_digit(&line_text, pos, &language_id) {
|
||||
// return Some(hover);
|
||||
// }
|
||||
|
||||
None
|
||||
// None
|
||||
}
|
||||
|
||||
fn make_hover_with_comment(doc: &Rope, line: usize, language_id: &str, exclude_code: bool) -> Option<Hover> {
|
||||
|
@ -22,11 +22,13 @@ use std::env::current_dir;
|
||||
#[allow(unused)]
|
||||
use std::ops::Deref;
|
||||
use std::ops::Range as StdRange;
|
||||
use std::path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::{Arc, Condvar, Mutex, RwLock};
|
||||
use std::thread;
|
||||
use sv_parser::*;
|
||||
use vhdl_lang::Project;
|
||||
use thread::JoinHandle;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use walkdir::WalkDir;
|
||||
@ -144,6 +146,32 @@ impl LSPServer {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let mut vhdl_project = self.srcs.vhdl_project.write().unwrap();
|
||||
match &mut *vhdl_project {
|
||||
Some(vhdl_project) => {
|
||||
let config_file_strs = vhdl_project.config_file_strs.clone()
|
||||
.into_iter()
|
||||
.filter(|x| x != path_string)
|
||||
.collect::<Vec<String>>();
|
||||
let mut messages = Vec::new();
|
||||
let config_str = format!(
|
||||
r#"
|
||||
[libraries]
|
||||
digital_lsp.files = [{}]
|
||||
"#, config_file_strs.join(",")
|
||||
);
|
||||
let config = vhdl_lang::Config::from_str(&config_str, Path::new(""));
|
||||
if let Ok(mut config) = config {
|
||||
config.append(&vhdl_project.std_config, &mut messages);
|
||||
let mut project = Project::from_config(config, &mut messages);
|
||||
project.analyse();
|
||||
*vhdl_project = VhdlProject { project, std_config: vhdl_project.std_config.clone(), config_file_strs };
|
||||
}
|
||||
}
|
||||
None => ()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,6 +242,8 @@ pub struct Sources {
|
||||
pub meta: Arc<RwLock<Vec<Arc<RwLock<SourceMeta>>>>>,
|
||||
/// scope tree 类型的树形结构,用于提供 sv 的 lsp
|
||||
pub scope_tree: Arc<RwLock<Option<GenericScope>>>,
|
||||
// vhdl project, store vhdl design files, do lsp
|
||||
pub vhdl_project: Arc<RwLock<Option<VhdlProject>>>,
|
||||
// include directories, passed to parser to resolve `include
|
||||
pub include_dirs: Arc<RwLock<Vec<PathBuf>>>,
|
||||
// primitive instance text
|
||||
@ -239,6 +269,7 @@ impl Sources {
|
||||
names: Arc::new(RwLock::new(HashMap::new())),
|
||||
meta: Arc::new(RwLock::new(Vec::new())),
|
||||
scope_tree: Arc::new(RwLock::new(None)),
|
||||
vhdl_project: Arc::new(RwLock::new(None)),
|
||||
include_dirs: Arc::new(RwLock::new(Vec::new())),
|
||||
primitive_text: Arc::new(PrimitiveText::new()),
|
||||
hdl_param: Arc::new(HdlParam::new()),
|
||||
@ -280,6 +311,7 @@ impl Sources {
|
||||
}));
|
||||
let source_handle = source.clone();
|
||||
let scope_handle = self.scope_tree.clone();
|
||||
let project_handle = self.vhdl_project.clone();
|
||||
let hdl_param_handle = self.hdl_param.clone();
|
||||
let inc_dirs = self.include_dirs.clone();
|
||||
|
||||
@ -321,6 +353,7 @@ impl Sources {
|
||||
&conf,
|
||||
&source_handle,
|
||||
&scope_handle,
|
||||
&project_handle,
|
||||
&hdl_param_handle,
|
||||
&text,
|
||||
uri,
|
||||
@ -707,6 +740,7 @@ pub fn vhdl_parser_pipeline(
|
||||
conf: &Arc<RwLock<ProjectConfig>>,
|
||||
source_handle: &Arc<RwLock<Source>>,
|
||||
scope_handle: &Arc<RwLock<Option<GenericScope>>>,
|
||||
project_handle: &Arc<RwLock<Option<VhdlProject>>>,
|
||||
hdl_param_handle: &Arc<HdlParam>,
|
||||
doc: &Rope,
|
||||
uri: &Url
|
||||
@ -797,6 +831,65 @@ pub fn vhdl_parser_pipeline(
|
||||
None => *global_scope = scope_tree,
|
||||
}
|
||||
// eprintln!("{:#?}", *global_scope);
|
||||
|
||||
let mut global_project = project_handle.write().unwrap();
|
||||
match &mut *global_project {
|
||||
Some(vhdl_project) => {
|
||||
if let Some(source) = vhdl_project.project.get_source(&escape_path) {
|
||||
source.change(None, &doc.to_string());
|
||||
vhdl_project.project.update_source(&source);
|
||||
vhdl_project.project.analyse();
|
||||
} else {
|
||||
vhdl_project.config_file_strs.push(format!("{:?}", escape_path));
|
||||
let mut messages = Vec::new();
|
||||
let config_str = format!(
|
||||
r#"
|
||||
[libraries]
|
||||
digital_lsp.files = [{}]
|
||||
"#, vhdl_project.config_file_strs.join(",")
|
||||
);
|
||||
let config = vhdl_lang::Config::from_str(&config_str, Path::new(""));
|
||||
if let Ok(mut config) = config {
|
||||
config.append(&vhdl_project.std_config, &mut messages);
|
||||
let mut project = Project::from_config(config, &mut messages);
|
||||
project.analyse();
|
||||
*vhdl_project = VhdlProject { project, std_config: vhdl_project.std_config.clone(), config_file_strs: vhdl_project.config_file_strs.clone() };
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
let std_cfg_path = match PathBuf::from_str(&(extension_path + "/resources/dide-lsp/static/vhdl_libraries/vhdl_ls.toml")) {
|
||||
Ok(path) => path,
|
||||
Err(e) => {
|
||||
info!("error happen in <vhdl_parse_pipeline>: {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
match vhdl_lang::Config::read_file_path(&std_cfg_path) {
|
||||
Ok(std_config) => {
|
||||
let config_str = format!(
|
||||
r#"
|
||||
[libraries]
|
||||
digital_lsp.files = [{:?}]
|
||||
"#, escape_path
|
||||
);
|
||||
let mut config_file_strs = Vec::new();
|
||||
config_file_strs.push(format!("{:?}", escape_path));
|
||||
let config = vhdl_lang::Config::from_str(&config_str, Path::new(""));
|
||||
if let Ok(mut config) = config {
|
||||
let mut messages = Vec::new();
|
||||
config.append(&std_config, &mut messages);
|
||||
let mut project = Project::from_config(config, &mut messages);
|
||||
project.analyse();
|
||||
*global_project = Some(VhdlProject { project, std_config, config_file_strs });
|
||||
}
|
||||
}
|
||||
Err(e) => info!("error happen in <vhdl_parse_pipeline>: Can't load standard vhdl lib from {std_cfg_path:#?} because {e:#?}")
|
||||
}
|
||||
}
|
||||
}
|
||||
drop(global_project);
|
||||
|
||||
drop(global_scope);
|
||||
}
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit eb7ea05f13a133a175352da8ba537ac1717a35cf
|
||||
Subproject commit 2446bd0a812d1667ad7033f10cd27a03967fa15e
|
Loading…
x
Reference in New Issue
Block a user