diff --git a/src/custom_request.rs b/src/custom_request.rs index e95aca3..04f4839 100644 --- a/src/custom_request.rs +++ b/src/custom_request.rs @@ -13,6 +13,7 @@ pub struct CustomRequestParams { pub data: Value, } + #[derive(Debug, Deserialize)] pub struct CustomResponse { result: serde_json::Value @@ -25,11 +26,11 @@ impl <'a>tower_lsp::jsonrpc::Method<&'a Arc, (), Result> for Custo type Future = future::Ready>; fn invoke(&self, _server: &'a Arc, _params: ()) -> Self::Future { - future::ready(customRequest()) + future::ready(custom_request()) } } -pub fn customRequest() -> Result { +pub fn custom_request() -> Result { // let command = params[0].clone(); // let message = String::from("receive command: ") + &command; diff --git a/src/definition.rs b/src/definition.rs index 53b6403..7d340e2 100644 --- a/src/definition.rs +++ b/src/definition.rs @@ -1,7 +1,7 @@ use crate::definition::extract_defs::get_ident; use crate::server::LSPServer; use crate::sources::LSPSupport; -use log::{debug, info, trace}; +use log::{debug, info, log, trace}; use ropey::{Rope, RopeSlice}; use sv_parser::*; use tower_lsp::lsp_types::*; @@ -23,18 +23,15 @@ impl LSPServer { let token = get_definition_token(file.text.line(pos.line as usize), pos); // info!("definition token: {}", token); - + let scope_tree = self.srcs.scope_tree.read().ok()?; - // info!("scope tree: {:?}", scope_tree); - - trace!("{:#?}", scope_tree.as_ref()?); let def = scope_tree .as_ref()? + // 获取定义 .get_definition(&token, file.text.pos_to_byte(&pos), &doc)?; let def_pos = file.text.byte_to_pos(def.byte_idx()); - debug!("def: {:?}", def_pos); Some(GotoDefinitionResponse::Scalar(Location::new( def.url(), Range::new(def_pos, def_pos), @@ -275,19 +272,21 @@ pub fn match_definitions( } RefNode::TextMacroDefinition(n) => { let dec = text_macro_def(syntax_tree, n, event_iter, url); + + if dec.is_some() { definitions.push(Box::new(dec?)); } } _ => (), } + Some((scopes, definitions)) } /// convert the syntax tree to a scope tree /// the root node is the global scope pub fn get_scopes(syntax_tree: &SyntaxTree, url: &Url) -> Option { - trace!("{}", syntax_tree); let mut scopes: Vec> = Vec::new(); let mut global_scope: GenericScope = GenericScope::new(url); global_scope.ident = "global".to_string(); diff --git a/src/definition/def_types.rs b/src/definition/def_types.rs index 8f58ca8..bd6efeb 100644 --- a/src/definition/def_types.rs +++ b/src/definition/def_types.rs @@ -1,3 +1,5 @@ +use std::thread::scope; + use crate::sources::LSPSupport; use log::{info, trace}; 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 // we proceed back upwards through the scope tree, adding any definitions that match // the users token @@ -127,7 +129,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send { for def in self.defs() { // 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()); } } @@ -191,12 +193,19 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send { /// scope fn get_definition(&self, token: &str, byte_idx: usize, url: &Url) -> Option { let mut definition: Option = None; + + if token.starts_with("`") { + // 计算宏的定义跳转 + + } + for scope in self.scopes() { if &scope.url() == url && scope.start() <= byte_idx && byte_idx <= scope.end() { definition = scope.get_definition(token, byte_idx, url); break; } } + if definition.is_none() { for def in self.defs() { if def.ident() == token { @@ -219,6 +228,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send { } definition } + /// returns all symbols in a document fn document_symbols(&self, uri: &Url, doc: &Rope) -> Vec { let mut symbols: Vec = Vec::new(); @@ -296,6 +306,7 @@ pub trait Scope: std::fmt::Debug + Definition + Sync + Send { pub enum DefinitionType { Port, Net, + Macro, Data, Modport, Subroutine, @@ -765,6 +776,7 @@ pub struct GenericScope { pub def_type: DefinitionType, pub defs: Vec>, pub scopes: Vec>, + } impl GenericScope { diff --git a/src/definition/extract_defs.rs b/src/definition/extract_defs.rs index 9749ec9..0c3c92d 100644 --- a/src/definition/extract_defs.rs +++ b/src/definition/extract_defs.rs @@ -2,6 +2,7 @@ use crate::definition::def_types::*; use crate::definition::match_definitions; use sv_parser::*; use tower_lsp::lsp_types::*; +use log::{debug, info, log, trace}; pub fn get_ident(tree: &SyntaxTree, node: RefNode) -> (String, usize) { let loc = unwrap_locate!(node).unwrap(); @@ -1003,6 +1004,8 @@ pub fn function_dec( } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::FunctionDeclaration)?; + + // info!("function_dec defs: {:?}", defs); func.scopes = scopes; func.defs.append(&mut defs); Some(func) @@ -1060,8 +1063,11 @@ pub fn task_dec( } } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::TaskDeclaration)?; + // info!("task_dec defs: {:?}", defs); + task.scopes = scopes; task.defs.append(&mut defs); + Some(task) } @@ -1628,10 +1634,14 @@ pub fn module_dec( } } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ModuleDeclaration)?; + + // info!("module_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::MODULE; scope.symbol_kind = SymbolKind::MODULE; + Some(scope) } @@ -1769,10 +1779,14 @@ pub fn interface_dec( } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::InterfaceDeclaration)?; + + // info!("interface_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::INTERFACE; scope.symbol_kind = SymbolKind::INTERFACE; + Some(scope) } @@ -2026,10 +2040,14 @@ pub fn udp_dec( } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::UdpDeclaration)?; + + // info!("udp_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::MODULE; scope.symbol_kind = SymbolKind::MODULE; + Some(scope) } @@ -2169,10 +2187,14 @@ pub fn program_dec( let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ProgramDeclaration)?; + + // info!("program_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::MODULE; scope.symbol_kind = SymbolKind::MODULE; + Some(scope) } @@ -2193,10 +2215,14 @@ pub fn package_dec( let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::PackageDeclaration)?; + + // info!("package_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::MODULE; scope.symbol_kind = SymbolKind::PACKAGE; + Some(scope) } @@ -2222,10 +2248,14 @@ pub fn config_dec( } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ConfigDeclaration)?; + + // info!("config_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); scope.completion_kind = CompletionItemKind::MODULE; scope.symbol_kind = SymbolKind::MODULE; + Some(scope) } @@ -2284,8 +2314,12 @@ pub fn class_dec( } let (scopes, mut defs) = match_until_leave!(tree, event_iter, url, RefNode::ClassDeclaration)?; + + // info!("class_dec defs: {:?}", defs); + scope.scopes = scopes; scope.defs.append(&mut defs); + Some(scope) } @@ -2300,7 +2334,7 @@ pub fn text_macro_def( let ident = get_ident(tree, RefNode::TextMacroIdentifier(&node.nodes.2.nodes.0)); text_macro.ident = ident.0; text_macro.byte_idx = ident.1; - let type_str = &mut text_macro.type_str; + let type_str = &mut text_macro.type_str; advance_until_enter!( type_str, tree, @@ -2308,7 +2342,9 @@ pub fn text_macro_def( RefNode::TextMacroIdentifier, &TextMacroIdentifier ); - text_macro.completion_kind = CompletionItemKind::FUNCTION; + + text_macro.completion_kind = CompletionItemKind::CONSTANT; text_macro.symbol_kind = SymbolKind::FUNCTION; + text_macro.def_type = DefinitionType::Macro; Some(text_macro) } diff --git a/src/sources.rs b/src/sources.rs index dc0bde0..7284eb1 100644 --- a/src/sources.rs +++ b/src/sources.rs @@ -2,6 +2,7 @@ use crate::definition::def_types::*; use crate::definition::get_scopes; use crate::diagnostics::{get_diagnostics, is_hidden}; use crate::server::LSPServer; +use log::info; use log::{debug, error, trace}; use pathdiff::diff_paths; use ropey::{Rope, RopeSlice}; @@ -216,43 +217,41 @@ impl Sources { let uri = &file.uri.clone(); let range = &file.last_change_range.clone(); drop(file); - trace!("{}, parse read: {}", uri, now.elapsed().as_millis()); + let syntax_tree = parse(&text, uri, range, &inc_dirs.read().unwrap()); let mut scope_tree = match &syntax_tree { Some(tree) => get_scopes(tree, uri), None => None, }; - trace!( - "{}, parse read complete: {}", - uri, - now.elapsed().as_millis() - ); + let mut file = source_handle.write().unwrap(); - trace!("{}, parse write: {}", uri, now.elapsed().as_millis()); + file.syntax_tree = syntax_tree; drop(file); - debug!("try write global scope"); + + // 获取 scope_handle 的写权限 + // global_scope 为全局最大的那个 scope,它的 scopes 和 defs 下的元素和每一个文件一一对应 let mut global_scope = scope_handle.write().unwrap(); + match &mut *global_scope { Some(scope) => match &mut scope_tree { Some(tree) => { + // 更新所有 uri 为当前 uri 的文件结构 scope.defs.retain(|x| &x.url() != uri); scope.scopes.retain(|x| &x.url() != uri); + scope.defs.append(&mut tree.defs); scope.scopes.append(&mut tree.scopes); + } None => (), }, + // 使用 scope_tree 来更新全局的 scope None => *global_scope = scope_tree, } // eprintln!("{:#?}", *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(); *valid = true; cvar.notify_all(); @@ -380,9 +379,7 @@ pub fn parse( false, true ) { - Ok((syntax_tree, _)) => { - debug!("parse complete of {}", uri); - trace!("{}", syntax_tree.to_string()); + Ok((syntax_tree, defines)) => { return Some(syntax_tree); } Err(err) => {