diff --git a/src/definition/mod.rs b/src/definition/mod.rs index 781d89a..4b43c3d 100644 --- a/src/definition/mod.rs +++ b/src/definition/mod.rs @@ -1,4 +1,4 @@ -use crate::{utils::get_definition_token}; +use crate::utils::get_definition_token; use crate::server::LSPServer; use crate::sources::LSPSupport; diff --git a/src/definition/vhdl.rs b/src/definition/vhdl.rs index 399c669..06a423c 100644 --- a/src/definition/vhdl.rs +++ b/src/definition/vhdl.rs @@ -1,6 +1,35 @@ -use tower_lsp::lsp_types::*; -use crate::server::LSPServer; +use std::{path::PathBuf, str::FromStr}; -pub fn goto_vhdl_definition() { - +use log::info; +use tower_lsp::lsp_types::*; +use crate::{server::LSPServer, utils::{from_lsp_pos, srcpos_to_location, to_escape_path}}; + +pub fn goto_vhdl_definition(server: &LSPServer, params: TextDocumentPositionParams) -> Option { + let uri = ¶ms.text_document.uri; + let file_id = server.srcs.get_id(&uri).to_owned(); + server.srcs.wait_parse_ready(file_id, false); + let projects = server.srcs.design_file_map.read().ok()?; + + let path = match PathBuf::from_str(uri.path()) { + Ok(path) => path, + Err(error) => { + info!("error happen in : {:?}", error); + return None; + } + }; + let escape_path = to_escape_path(&path); + let escape_path_string = escape_path.to_str().unwrap_or(""); + if escape_path_string.len() == 0 { + info!("error happen in [vhdl_parser_pipeline], escape_path_string is empty"); + return None; + } + let project = match projects.get(escape_path_string) { + Some(project) => project, + None => return None + }; + + let source = project.get_source(&escape_path)?; + + let ent = project.find_definition(&source, from_lsp_pos(params.position))?; + Some(srcpos_to_location(ent.decl_pos()?)) } \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 823ef49..043344c 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -4,7 +4,7 @@ use percent_encoding::percent_decode_str; use regex::Regex; use ropey::RopeSlice; use tower_lsp::lsp_types::*; -use vhdl_lang::{ast::ObjectClass, AnyEntKind, Object, Overloaded, Type, Concurrent}; +use vhdl_lang::{ast::ObjectClass, AnyEntKind, Concurrent, Object, Overloaded, SrcPos, Type}; pub mod fast; @@ -252,4 +252,12 @@ pub fn from_lsp_range(range: Range) -> vhdl_lang::Range { start: from_lsp_pos(range.start), end: from_lsp_pos(range.end), } +} + +pub fn srcpos_to_location(pos: &SrcPos) -> Location { + let uri = Url::from_file_path(pos.source.file_name()).unwrap(); + Location { + uri, + range: to_lsp_range(pos.range()), + } } \ No newline at end of file