use crate::core::scope_tree::common::{Definition, Scope}; use crate::sources::LSPSupport; use crate::utils::{from_uri_to_escape_path_string, get_definition_token}; use crate::server::LspServer; #[allow(unused)] use log::info; use tower_lsp::lsp_types::*; use super::feature::*; pub fn goto_definition(server: &LspServer, params: &GotoDefinitionParams) -> Option { let uri = ¶ms.text_document_position_params.text_document.uri; let pos = params.text_document_position_params.position; let path_string = from_uri_to_escape_path_string(uri).unwrap(); // 等待解析完成 server.db.wait_parse_ready(&path_string, false); let source = server.db.get_source(&path_string)?; let source = source.read().ok()?; let line_text = source.text.line(pos.line as usize); let token: String = get_definition_token(&line_text, pos); // match include if let Some(definition) = goto_include_definition(uri, &line_text, pos) { return Some(definition); } // match macro usage if let Some(definition) = goto_macro_definition(server, &line_text, pos) { return Some(definition); } // match instance let scope_tree = server.db.scope_tree.read().ok()?; // match position port & param if let Some(definition) = goto_position_port_param_definition(server, &line_text, uri, pos) { return Some(definition); } // match module name if let Some(definition) = goto_module_declaration_definition(server, &token) { return Some(definition); } let byte_idx = source.text.pos_to_byte(&pos); let global_scope = scope_tree.as_ref()?; let def = global_scope.get_definition(&token, byte_idx, uri)?; let def_pos = source.text.byte_to_pos(def.byte_idx()); Some(GotoDefinitionResponse::Scalar(Location::new( def.url(), Range::new(def_pos, def_pos), ))) }