diff --git a/src/dev_aid/lsp.rs b/src/dev_aid/lsp.rs index 12f5191..f25d9cf 100644 --- a/src/dev_aid/lsp.rs +++ b/src/dev_aid/lsp.rs @@ -6,7 +6,7 @@ use lsp_server::{Connection, Message, Response}; use lsp_types::notification::Notification; -use crate::{arena_alloc::ArenaVector, ast::{IdentifierType, Span}, dev_aid::syntax_highlighting::create_token_ide_info, errors::{CompileError, ErrorCollector, ErrorLevel}, flattening::{WireInstance, WireSource}, linker::{FileData, FileUUID, FileUUIDMarker, Linker, LocationInfo}, parser::perform_full_semantic_parse, tokenizer::{CharLine, TokenizeResult}}; +use crate::{arena_alloc::ArenaVector, ast::{IdentifierType, Span}, dev_aid::syntax_highlighting::create_token_ide_info, errors::{CompileError, ErrorCollector, ErrorLevel}, flattening::{WireInstance, WireSource}, linker::{FileData, FileUUID, FileUUIDMarker, Linker, LocationInfo}, parser::perform_full_semantic_parse, tokenizer::{CharLine, TokenizeResult}, typing::Type}; use super::syntax_highlighting::{IDETokenType, IDEIdentifierType, IDEToken}; @@ -342,10 +342,30 @@ fn main_loop(connection: Connection, params: serde_json::Value, debug : bool) -> println!("got gotoDefinition request: {params:?}"); file_cache.ensure_contains_file(¶ms.text_document_position_params.text_document.uri); - serde_json::to_value(&if let Some((info, range)) = get_hover_info(&file_cache, ¶ms.text_document_position_params) { - - - GotoDefinitionResponse::Array(Vec::new()) + serde_json::to_value(&if let Some((info, _range)) = get_hover_info(&file_cache, ¶ms.text_document_position_params) { + match info { + LocationInfo::WireRef(md, decl_id) => { + let uri = file_cache.uris[md.link_info.file].clone(); + let decl = md.flattened.instructions[decl_id].extract_wire_declaration(); + let range = to_position_range(file_cache.linker.files[md.link_info.file].tokens.get_token_linechar_range(decl.name_token)); + GotoDefinitionResponse::Scalar(Location{uri, range}) + } + LocationInfo::Temporary(_, _, _) => { + GotoDefinitionResponse::Array(Vec::new()) + } + LocationInfo::Type(_) => { + GotoDefinitionResponse::Array(Vec::new()) + } + LocationInfo::Global(id) => { + if let Some(link_info) = file_cache.linker.get_link_info(id) { + let uri = file_cache.uris[link_info.file].clone(); + let range = to_position_range(file_cache.linker.files[link_info.file].tokens.get_span_linechar_range(link_info.name_span)); + GotoDefinitionResponse::Scalar(Location{uri, range}) + } else { + GotoDefinitionResponse::Array(Vec::new()) + } + } + } } else { GotoDefinitionResponse::Array(Vec::new()) }) diff --git a/src/linker.rs b/src/linker.rs index d3f189b..e7d9139 100644 --- a/src/linker.rs +++ b/src/linker.rs @@ -208,8 +208,8 @@ impl Linker { }, } } - fn get_link_info(&self, name_elem : NameElem) -> Option<&LinkInfo> { - match name_elem { + pub fn get_link_info(&self, global : NameElem) -> Option<&LinkInfo> { + match global { NameElem::Module(md_id) => Some(&self.modules[md_id].link_info), NameElem::Type(_) => { None // Can't define types yet @@ -240,7 +240,7 @@ impl Linker { // Conflicting Declarations for item in &self.global_namespace { let NamespaceElement::Colission(colission) = &item.1 else {continue}; - let infos : Box<[Option<&LinkInfo>]> = colission.iter().map(|id| self.get_link_info(*id)).collect(); + let infos : Vec> = colission.iter().map(|id| self.get_link_info(*id)).collect(); for (idx, info) in infos.iter().enumerate() { let Some(info) = info else {continue}; // Is not a builtin @@ -395,8 +395,14 @@ impl Linker { location_builder.update(sm.module_name_span, LocationInfo::Global(NameElem::Module(sm.module_uuid))); } Instruction::Declaration(decl) => { - if let Some(typ) = decl.typ_expr.get_deepest_selected(token_idx) { - location_builder.update(typ.get_span(), LocationInfo::Type(typ)); + match decl.typ_expr.get_deepest_selected(token_idx) { + Some(WrittenType::Named(span, name_id)) => { + location_builder.update(*span, LocationInfo::Global(NameElem::Type(*name_id))); + } + Some(typ) => { + location_builder.update(typ.get_span(), LocationInfo::Type(typ)); + } + None => {} } } Instruction::Wire(wire) => {