From 805ab71a5ce8ce7af30557dabc20728b0205c68a Mon Sep 17 00:00:00 2001 From: Lukas Scheller Date: Sun, 26 May 2024 17:55:14 +0200 Subject: [PATCH 1/2] Fix: token span for record elements --- vhdl_lang/src/analysis/types.rs | 2 +- vhdl_lang/src/syntax/type_declaration.rs | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/vhdl_lang/src/analysis/types.rs b/vhdl_lang/src/analysis/types.rs index 8e7976ec..b8573f22 100644 --- a/vhdl_lang/src/analysis/types.rs +++ b/vhdl_lang/src/analysis/types.rs @@ -254,7 +254,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> { &mut elem_decl.ident, type_ent.into(), AnyEntKind::ElementDeclaration(subtype), - src_span, + elem_decl.span, Some(self.source()), ); region.add(elem, diagnostics); diff --git a/vhdl_lang/src/syntax/type_declaration.rs b/vhdl_lang/src/syntax/type_declaration.rs index 0ce39536..ae277bd8 100644 --- a/vhdl_lang/src/syntax/type_declaration.rs +++ b/vhdl_lang/src/syntax/type_declaration.rs @@ -16,7 +16,6 @@ use crate::ast::*; use crate::ast::{AbstractLiteral, Range}; use crate::named_entity::Reference; use crate::syntax::names::parse_type_mark; -use crate::HasTokenSpan; use vhdl_lang::syntax::parser::ParsingContext; /// LRM 5.2.2 Enumeration types @@ -81,18 +80,19 @@ fn parse_record_type_definition( return Ok((TypeDefinition::Record(elem_decls), end_ident)); }; + let start_token = ctx.stream.get_current_token_id(); + let idents = parse_identifier_list(ctx)?; ctx.stream.expect_kind(Colon)?; let subtype = parse_subtype_indication(ctx)?; + let end_token = ctx.stream.expect_kind(SemiColon)?; for ident in idents { - let ident_span = ident.token.span(); elem_decls.push(ElementDeclaration { ident: ident.into(), subtype: subtype.clone(), - span: ident_span, + span: TokenSpan::new(start_token, end_token), }); } - ctx.stream.expect_kind(SemiColon)?; } } @@ -531,7 +531,7 @@ end record;", let elem_decl = ElementDeclaration { ident: code.s1("element").decl_ident(), subtype: code.s1("boolean").subtype_indication(), - span: code.s1("element").token_span(), + span: code.s1("element : boolean;").token_span(), }; let type_decl = TypeDeclaration { @@ -560,19 +560,21 @@ end foo;", let elem_decl0a = ElementDeclaration { ident: code.s1("element").decl_ident(), subtype: code.s1("boolean").subtype_indication(), - span: code.s1("element").token_span(), + span: code.s1("element, field : boolean;").token_span(), }; let elem_decl0b = ElementDeclaration { ident: code.s1("field").decl_ident(), subtype: code.s1("boolean").subtype_indication(), - span: code.s1("field").token_span(), + span: code.s1("element, field : boolean;").token_span(), }; let elem_decl1 = ElementDeclaration { ident: code.s1("other_element").decl_ident(), subtype: code.s1("std_logic_vector(0 to 1)").subtype_indication(), - span: code.s1("other_element").token_span(), + span: code + .s1("other_element : std_logic_vector(0 to 1);") + .token_span(), }; let type_decl = TypeDeclaration { From 21c51b330c7c6cde910ab618ecdfa457b3bd83fb Mon Sep 17 00:00:00 2001 From: Giulio Girardi Date: Tue, 4 Jun 2024 20:13:32 +0200 Subject: [PATCH 2/2] Add support for textDocument/documentHighlight request (#308) * Add support for textDocument/documentHighlight request * Search for references only in the current file --- vhdl_lang/src/analysis/root.rs | 6 ++++++ vhdl_lang/src/project.rs | 4 ++++ vhdl_ls/src/stdio_server.rs | 8 ++++++++ vhdl_ls/src/vhdl_server.rs | 25 +++++++++++++++++++++++++ 4 files changed, 43 insertions(+) diff --git a/vhdl_lang/src/analysis/root.rs b/vhdl_lang/src/analysis/root.rs index d08b8d08..6b85317b 100644 --- a/vhdl_lang/src/analysis/root.rs +++ b/vhdl_lang/src/analysis/root.rs @@ -520,6 +520,12 @@ impl DesignRoot { searcher.references } + pub fn find_all_references_in_source(&self, source: &Source, ent: EntRef) -> Vec { + let mut searcher = FindAllReferences::new(self, ent); + let _ = self.search_source(source, &mut searcher); + searcher.references + } + pub fn public_symbols<'a>(&'a self) -> Box> + 'a> { Box::new(self.libraries.values().flat_map(|library| { std::iter::once(self.arenas.get(library.id)).chain(library.units.values().flat_map( diff --git a/vhdl_lang/src/project.rs b/vhdl_lang/src/project.rs index 12b72775..c1ee5409 100644 --- a/vhdl_lang/src/project.rs +++ b/vhdl_lang/src/project.rs @@ -309,6 +309,10 @@ impl Project { self.root.find_all_references(ent) } + pub fn find_all_references_in_source(&self, source: &Source, ent: &AnyEnt) -> Vec { + self.root.find_all_references_in_source(source, ent) + } + /// Get source positions that are not resolved to a declaration /// This is used for development to test where the language server is blind pub fn find_all_unresolved(&self) -> (usize, Vec) { diff --git a/vhdl_ls/src/stdio_server.rs b/vhdl_ls/src/stdio_server.rs index 743e574a..ff2fd329 100644 --- a/vhdl_ls/src/stdio_server.rs +++ b/vhdl_ls/src/stdio_server.rs @@ -190,6 +190,14 @@ impl ConnectionRpcChannel { } Err(request) => request, }; + let request = match extract::(request) { + Ok((id, params)) => { + let result = server.document_highlight(¶ms.text_document_position_params); + self.send_response(lsp_server::Response::new_ok(id, result)); + return; + } + Err(request) => request, + }; let request = match extract::(request) { Ok((id, params)) => { let result = server.text_document_hover(¶ms.text_document_position_params); diff --git a/vhdl_ls/src/vhdl_server.rs b/vhdl_ls/src/vhdl_server.rs index 38877cf8..e2371974 100644 --- a/vhdl_ls/src/vhdl_server.rs +++ b/vhdl_ls/src/vhdl_server.rs @@ -182,6 +182,7 @@ impl VHDLServer { })), workspace_symbol_provider: Some(OneOf::Left(true)), document_symbol_provider: Some(OneOf::Left(true)), + document_highlight_provider: Some(OneOf::Left(true)), completion_provider: Some(CompletionOptions { resolve_provider: Some(true), trigger_characters: Some(trigger_chars), @@ -681,6 +682,30 @@ impl VHDLServer { }) } + pub fn document_highlight( + &mut self, + params: &TextDocumentPositionParams, + ) -> Option> { + let source = self + .project + .get_source(&uri_to_file_name(¶ms.text_document.uri))?; + + let ent = self + .project + .find_declaration(&source, from_lsp_pos(params.position))?; + + Some( + self.project + .find_all_references_in_source(&source, ent) + .iter() + .map(|pos| DocumentHighlight { + range: to_lsp_range(pos.range()), + kind: Some(DocumentHighlightKind::TEXT), + }) + .collect(), + ) + } + pub fn workspace_symbol( &self, params: &WorkspaceSymbolParams,