This commit is contained in:
锦恢 2024-09-15 19:00:08 +08:00
parent 1d90b5a23b
commit 51d106b518
5 changed files with 75 additions and 30 deletions

View File

@ -13,6 +13,7 @@ pub struct CustomRequestParams {
pub data: Value, pub data: Value,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
pub struct CustomResponse { pub struct CustomResponse {
result: serde_json::Value result: serde_json::Value
@ -25,11 +26,11 @@ impl <'a>tower_lsp::jsonrpc::Method<&'a Arc<Backend>, (), Result<i32>> for Custo
type Future = future::Ready<Result<i32>>; type Future = future::Ready<Result<i32>>;
fn invoke(&self, _server: &'a Arc<Backend>, _params: ()) -> Self::Future { fn invoke(&self, _server: &'a Arc<Backend>, _params: ()) -> Self::Future {
future::ready(customRequest()) future::ready(custom_request())
} }
} }
pub fn customRequest() -> Result<i32> { pub fn custom_request() -> Result<i32> {
// let command = params[0].clone(); // let command = params[0].clone();
// let message = String::from("receive command: ") + &command; // let message = String::from("receive command: ") + &command;

View File

@ -1,7 +1,7 @@
use crate::definition::extract_defs::get_ident; use crate::definition::extract_defs::get_ident;
use crate::server::LSPServer; use crate::server::LSPServer;
use crate::sources::LSPSupport; use crate::sources::LSPSupport;
use log::{debug, info, trace}; use log::{debug, info, log, trace};
use ropey::{Rope, RopeSlice}; use ropey::{Rope, RopeSlice};
use sv_parser::*; use sv_parser::*;
use tower_lsp::lsp_types::*; use tower_lsp::lsp_types::*;
@ -26,15 +26,12 @@ impl LSPServer {
let scope_tree = self.srcs.scope_tree.read().ok()?; let scope_tree = self.srcs.scope_tree.read().ok()?;
// info!("scope tree: {:?}", scope_tree);
trace!("{:#?}", scope_tree.as_ref()?);
let def = scope_tree let def = scope_tree
.as_ref()? .as_ref()?
// 获取定义
.get_definition(&token, file.text.pos_to_byte(&pos), &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());
debug!("def: {:?}", def_pos);
Some(GotoDefinitionResponse::Scalar(Location::new( Some(GotoDefinitionResponse::Scalar(Location::new(
def.url(), def.url(),
Range::new(def_pos, def_pos), Range::new(def_pos, def_pos),
@ -275,19 +272,21 @@ pub fn match_definitions(
} }
RefNode::TextMacroDefinition(n) => { RefNode::TextMacroDefinition(n) => {
let dec = text_macro_def(syntax_tree, n, event_iter, url); let dec = text_macro_def(syntax_tree, n, event_iter, url);
if dec.is_some() { if dec.is_some() {
definitions.push(Box::new(dec?)); definitions.push(Box::new(dec?));
} }
} }
_ => (), _ => (),
} }
Some((scopes, definitions)) Some((scopes, definitions))
} }
/// convert the syntax tree to a scope tree /// convert the syntax tree to a scope tree
/// the root node is the global scope /// the root node is the global scope
pub fn get_scopes(syntax_tree: &SyntaxTree, url: &Url) -> Option<GenericScope> { pub fn get_scopes(syntax_tree: &SyntaxTree, url: &Url) -> Option<GenericScope> {
trace!("{}", syntax_tree);
let mut scopes: Vec<Box<dyn Scope>> = Vec::new(); let mut scopes: Vec<Box<dyn Scope>> = Vec::new();
let mut global_scope: GenericScope = GenericScope::new(url); let mut global_scope: GenericScope = GenericScope::new(url);
global_scope.ident = "global".to_string(); global_scope.ident = "global".to_string();

View File

@ -1,3 +1,5 @@
use std::thread::scope;
use crate::sources::LSPSupport; use crate::sources::LSPSupport;
use log::{info, trace}; use log::{info, trace};
use ropey::Rope; use ropey::Rope;
@ -119,7 +121,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
} }
} }
let lowerCaseToken = token.to_lowercase(); let lower_case_token = token.to_lowercase();
// now that we are in the users scope, we can attempt to find a relevant completion // now that we are in the users scope, we can attempt to find a relevant completion
// we proceed back upwards through the scope tree, adding any definitions that match // we proceed back upwards through the scope tree, adding any definitions that match
// the users token // the users token
@ -127,7 +129,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
for def in self.defs() { for def in self.defs() {
// info!("current def: {:?}, trigger token: {}, contain: {}, start with: {}", def, token, completion_idents.contains(&def.ident()), def.starts_with(token)); // info!("current def: {:?}, trigger token: {}, contain: {}, start with: {}", def, token, completion_idents.contains(&def.ident()), def.starts_with(token));
if !completion_idents.contains(&def.ident()) && def.ident().to_lowercase().starts_with(&lowerCaseToken) { if !completion_idents.contains(&def.ident()) && def.ident().to_lowercase().starts_with(&lower_case_token) {
completions.push(def.completion()); completions.push(def.completion());
} }
} }
@ -191,12 +193,19 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
/// scope /// scope
fn get_definition(&self, token: &str, byte_idx: usize, url: &Url) -> Option<GenericDec> { fn get_definition(&self, token: &str, byte_idx: usize, url: &Url) -> Option<GenericDec> {
let mut definition: Option<GenericDec> = None; let mut definition: Option<GenericDec> = None;
if token.starts_with("`") {
// 计算宏的定义跳转
}
for scope in self.scopes() { for scope in self.scopes() {
if &scope.url() == url && scope.start() <= byte_idx && byte_idx <= scope.end() { if &scope.url() == url && scope.start() <= byte_idx && byte_idx <= scope.end() {
definition = scope.get_definition(token, byte_idx, url); definition = scope.get_definition(token, byte_idx, url);
break; break;
} }
} }
if definition.is_none() { if definition.is_none() {
for def in self.defs() { for def in self.defs() {
if def.ident() == token { if def.ident() == token {
@ -219,6 +228,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
} }
definition definition
} }
/// returns all symbols in a document /// returns all symbols in a document
fn document_symbols(&self, uri: &Url, doc: &Rope) -> Vec<DocumentSymbol> { fn document_symbols(&self, uri: &Url, doc: &Rope) -> Vec<DocumentSymbol> {
let mut symbols: Vec<DocumentSymbol> = Vec::new(); let mut symbols: Vec<DocumentSymbol> = Vec::new();
@ -296,6 +306,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send {
pub enum DefinitionType { pub enum DefinitionType {
Port, Port,
Net, Net,
Macro,
Data, Data,
Modport, Modport,
Subroutine, Subroutine,
@ -765,6 +776,7 @@ pub struct GenericScope {
pub def_type: DefinitionType, pub def_type: DefinitionType,
pub defs: Vec<Box<dyn Definition>>, pub defs: Vec<Box<dyn Definition>>,
pub scopes: Vec<Box<dyn Scope>>, pub scopes: Vec<Box<dyn Scope>>,
} }
impl GenericScope { impl GenericScope {

View File

@ -2,6 +2,7 @@ use crate::definition::def_types::*;
use crate::definition::match_definitions; use crate::definition::match_definitions;
use sv_parser::*; use sv_parser::*;
use tower_lsp::lsp_types::*; use tower_lsp::lsp_types::*;
use log::{debug, info, log, trace};
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();
@ -1003,6 +1004,8 @@ pub fn function_dec(
} }
let (scopes, mut defs) = let (scopes, mut defs) =
match_until_leave!(tree, event_iter, url, RefNode::FunctionDeclaration)?; match_until_leave!(tree, event_iter, url, RefNode::FunctionDeclaration)?;
// info!("function_dec defs: {:?}", defs);
func.scopes = scopes; func.scopes = scopes;
func.defs.append(&mut defs); func.defs.append(&mut defs);
Some(func) Some(func)
@ -1060,8 +1063,11 @@ pub fn task_dec(
} }
} }
let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::TaskDeclaration)?; let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::TaskDeclaration)?;
// info!("task_dec defs: {:?}", defs);
task.scopes = scopes; task.scopes = scopes;
task.defs.append(&mut defs); task.defs.append(&mut defs);
Some(task) Some(task)
} }
@ -1628,10 +1634,14 @@ pub fn module_dec(
} }
} }
let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ModuleDeclaration)?; let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ModuleDeclaration)?;
// info!("module_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::MODULE; scope.completion_kind = CompletionItemKind::MODULE;
scope.symbol_kind = SymbolKind::MODULE; scope.symbol_kind = SymbolKind::MODULE;
Some(scope) Some(scope)
} }
@ -1769,10 +1779,14 @@ pub fn interface_dec(
} }
let (scopes, mut defs) = let (scopes, mut defs) =
match_until_leave!(tree, event_iter, url, RefNode::InterfaceDeclaration)?; match_until_leave!(tree, event_iter, url, RefNode::InterfaceDeclaration)?;
// info!("interface_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::INTERFACE; scope.completion_kind = CompletionItemKind::INTERFACE;
scope.symbol_kind = SymbolKind::INTERFACE; scope.symbol_kind = SymbolKind::INTERFACE;
Some(scope) Some(scope)
} }
@ -2026,10 +2040,14 @@ pub fn udp_dec(
} }
let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::UdpDeclaration)?; let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::UdpDeclaration)?;
// info!("udp_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::MODULE; scope.completion_kind = CompletionItemKind::MODULE;
scope.symbol_kind = SymbolKind::MODULE; scope.symbol_kind = SymbolKind::MODULE;
Some(scope) Some(scope)
} }
@ -2169,10 +2187,14 @@ pub fn program_dec(
let (scopes, mut defs) = let (scopes, mut defs) =
match_until_leave!(tree, event_iter, url, RefNode::ProgramDeclaration)?; match_until_leave!(tree, event_iter, url, RefNode::ProgramDeclaration)?;
// info!("program_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::MODULE; scope.completion_kind = CompletionItemKind::MODULE;
scope.symbol_kind = SymbolKind::MODULE; scope.symbol_kind = SymbolKind::MODULE;
Some(scope) Some(scope)
} }
@ -2193,10 +2215,14 @@ pub fn package_dec(
let (scopes, mut defs) = let (scopes, mut defs) =
match_until_leave!(tree, event_iter, url, RefNode::PackageDeclaration)?; match_until_leave!(tree, event_iter, url, RefNode::PackageDeclaration)?;
// info!("package_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::MODULE; scope.completion_kind = CompletionItemKind::MODULE;
scope.symbol_kind = SymbolKind::PACKAGE; scope.symbol_kind = SymbolKind::PACKAGE;
Some(scope) Some(scope)
} }
@ -2222,10 +2248,14 @@ pub fn config_dec(
} }
let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ConfigDeclaration)?; let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ConfigDeclaration)?;
// info!("config_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
scope.completion_kind = CompletionItemKind::MODULE; scope.completion_kind = CompletionItemKind::MODULE;
scope.symbol_kind = SymbolKind::MODULE; scope.symbol_kind = SymbolKind::MODULE;
Some(scope) Some(scope)
} }
@ -2284,8 +2314,12 @@ pub fn class_dec(
} }
let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ClassDeclaration)?; let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ClassDeclaration)?;
// info!("class_dec defs: {:?}", defs);
scope.scopes = scopes; scope.scopes = scopes;
scope.defs.append(&mut defs); scope.defs.append(&mut defs);
Some(scope) Some(scope)
} }
@ -2308,7 +2342,9 @@ pub fn text_macro_def(
RefNode::TextMacroIdentifier, RefNode::TextMacroIdentifier,
&TextMacroIdentifier &TextMacroIdentifier
); );
text_macro.completion_kind = CompletionItemKind::FUNCTION;
text_macro.completion_kind = CompletionItemKind::CONSTANT;
text_macro.symbol_kind = SymbolKind::FUNCTION; text_macro.symbol_kind = SymbolKind::FUNCTION;
text_macro.def_type = DefinitionType::Macro;
Some(text_macro) Some(text_macro)
} }

View File

@ -2,6 +2,7 @@ use crate::definition::def_types::*;
use crate::definition::get_scopes; use crate::definition::get_scopes;
use crate::diagnostics::{get_diagnostics, is_hidden}; use crate::diagnostics::{get_diagnostics, is_hidden};
use crate::server::LSPServer; use crate::server::LSPServer;
use log::info;
use log::{debug, error, trace}; use log::{debug, error, trace};
use pathdiff::diff_paths; use pathdiff::diff_paths;
use ropey::{Rope, RopeSlice}; use ropey::{Rope, RopeSlice};
@ -216,43 +217,41 @@ impl Sources {
let uri = &file.uri.clone(); let uri = &file.uri.clone();
let range = &file.last_change_range.clone(); let range = &file.last_change_range.clone();
drop(file); drop(file);
trace!("{}, parse read: {}", uri, now.elapsed().as_millis());
let syntax_tree = parse(&text, uri, range, &inc_dirs.read().unwrap()); let syntax_tree = parse(&text, uri, range, &inc_dirs.read().unwrap());
let mut scope_tree = match &syntax_tree { let mut scope_tree = match &syntax_tree {
Some(tree) => get_scopes(tree, uri), Some(tree) => get_scopes(tree, uri),
None => None, None => None,
}; };
trace!(
"{}, parse read complete: {}",
uri,
now.elapsed().as_millis()
);
let mut file = source_handle.write().unwrap(); let mut file = source_handle.write().unwrap();
trace!("{}, parse write: {}", uri, now.elapsed().as_millis());
file.syntax_tree = syntax_tree; file.syntax_tree = syntax_tree;
drop(file); drop(file);
debug!("try write global scope");
// 获取 scope_handle 的写权限
// global_scope 为全局最大的那个 scope它的 scopes 和 defs 下的元素和每一个文件一一对应
let mut global_scope = scope_handle.write().unwrap(); let mut global_scope = scope_handle.write().unwrap();
match &mut *global_scope { match &mut *global_scope {
Some(scope) => match &mut scope_tree { Some(scope) => match &mut scope_tree {
Some(tree) => { Some(tree) => {
// 更新所有 uri 为当前 uri 的文件结构
scope.defs.retain(|x| &x.url() != uri); scope.defs.retain(|x| &x.url() != uri);
scope.scopes.retain(|x| &x.url() != uri); scope.scopes.retain(|x| &x.url() != uri);
scope.defs.append(&mut tree.defs); scope.defs.append(&mut tree.defs);
scope.scopes.append(&mut tree.scopes); scope.scopes.append(&mut tree.scopes);
} }
None => (), None => (),
}, },
// 使用 scope_tree 来更新全局的 scope
None => *global_scope = scope_tree, None => *global_scope = scope_tree,
} }
// eprintln!("{:#?}", *global_scope); // eprintln!("{:#?}", *global_scope);
drop(global_scope); drop(global_scope);
trace!("{}, write global scope", uri);
trace!(
"{}, parse write complete: {}",
uri,
now.elapsed().as_millis()
);
let mut valid = lock.lock().unwrap(); let mut valid = lock.lock().unwrap();
*valid = true; *valid = true;
cvar.notify_all(); cvar.notify_all();
@ -380,9 +379,7 @@ pub fn parse(
false, false,
true true
) { ) {
Ok((syntax_tree, _)) => { Ok((syntax_tree, defines)) => {
debug!("parse complete of {}", uri);
trace!("{}", syntax_tree.to_string());
return Some(syntax_tree); return Some(syntax_tree);
} }
Err(err) => { Err(err) => {