From dba05d4a47ab786d60d601311dd5d6eb8e9c6ffc Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Thu, 30 May 2024 14:01:15 +0200 Subject: [PATCH 1/6] Add package declaration in declarative part --- vhdl_lang/src/analysis/declarative.rs | 7 +++++++ vhdl_lang/src/analysis/names.rs | 1 + vhdl_lang/src/ast.rs | 1 + vhdl_lang/src/ast/search.rs | 4 ++++ vhdl_lang/src/named_entity.rs | 1 + vhdl_lang/src/syntax/declarative_part.rs | 9 ++++++++- vhdl_lang/src/syntax/design_unit.rs | 23 +++++++++++++++++++++++ 7 files changed, 45 insertions(+), 1 deletion(-) diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index c84be55b..0fcc3285 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -41,6 +41,7 @@ impl Declaration { | SubprogramBody(_) | Use(_) | Package(_) + | PackageDeclaration(_) | Configuration(_) | View(_) ), @@ -61,6 +62,7 @@ impl Declaration { | SubprogramBody(_) | Use(_) | Package(_) + | PackageDeclaration(_) | View(_) ), // LRM: package_body_declarative_item @@ -86,6 +88,7 @@ impl Declaration { | SubprogramBody(_) | Use(_) | Package(_) + | PackageDeclaration(_) ), // LRM: package_declarative_item AnyEntKind::Design(Design::Package(..)) => matches!( @@ -100,6 +103,7 @@ impl Declaration { | SubprogramInstantiation(_) | Use(_) | Package(_) + | PackageDeclaration(_) | View(_) ), _ => { @@ -606,6 +610,9 @@ impl<'a, 't> AnalyzeContext<'a, 't> { scope.add(ent, diagnostics); } } + Declaration::PackageDeclaration(..) => { + // TODO + } Declaration::Configuration(..) => {} Declaration::View(view) => { if let Some(view) = as_fatal(self.analyze_view_declaration( diff --git a/vhdl_lang/src/analysis/names.rs b/vhdl_lang/src/analysis/names.rs index b6d398e3..649a237e 100644 --- a/vhdl_lang/src/analysis/names.rs +++ b/vhdl_lang/src/analysis/names.rs @@ -1845,6 +1845,7 @@ impl Declaration { Declaration::SubprogramBody(_) => "subprogram body", Declaration::Use(_) => "use", Declaration::Package(_) => "package instantiation", + Declaration::PackageDeclaration(_) => "package", Declaration::Configuration(_) => "configuration", Declaration::View(_) => "view", } diff --git a/vhdl_lang/src/ast.rs b/vhdl_lang/src/ast.rs index 110863be..da0c1a22 100644 --- a/vhdl_lang/src/ast.rs +++ b/vhdl_lang/src/ast.rs @@ -852,6 +852,7 @@ pub enum Declaration { SubprogramBody(SubprogramBody), Use(UseClause), Package(PackageInstantiation), + PackageDeclaration(PackageDeclaration), Configuration(ConfigurationSpecification), View(ModeViewDeclaration), } diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index daaeba8c..837fc125 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -1080,6 +1080,10 @@ impl Search for Declaration { return_if_found!(package_instance.search(ctx, searcher)); } + Declaration::PackageDeclaration(ref package_instance) => { + return_if_found!(package_instance.search(ctx, searcher)); // @TODO + } + Declaration::Configuration(_) => { // @TODO } diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index b8c7159a..a9cbe28a 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -631,6 +631,7 @@ impl HasEntityId for Declaration { Declaration::SubprogramBody(body) => body.ent_id(), Declaration::SubprogramInstantiation(decl) => decl.ent_id(), Declaration::Package(pkg) => pkg.ent_id(), + Declaration::PackageDeclaration(_) => None, // @TODO Declaration::Use(_) => None, Declaration::Configuration(_) => None, Declaration::View(decl) => decl.ent_id(), diff --git a/vhdl_lang/src/syntax/declarative_part.rs b/vhdl_lang/src/syntax/declarative_part.rs index 49144074..a7c9b884 100644 --- a/vhdl_lang/src/syntax/declarative_part.rs +++ b/vhdl_lang/src/syntax/declarative_part.rs @@ -10,6 +10,7 @@ use super::common::ParseResult; use super::component_declaration::parse_component_declaration; use super::configuration::parse_configuration_specification; use super::context::parse_use_clause; +use super::design_unit::parse_package_declaration; use super::names::parse_selected_name; use super::object_declaration::{parse_file_declaration, parse_object_declaration}; use super::subprogram::parse_subprogram; @@ -104,7 +105,13 @@ pub fn parse_declarative_part( Type | Subtype => parse_type_declaration(ctx).map(Declaration::Type)?, Component => parse_component_declaration(ctx).map(Declaration::Component)?, Impure | Pure | Function | Procedure => parse_subprogram(ctx)?, - Package => parse_package_instantiation(ctx).map(Declaration::Package)?, + Package => { + if ctx.stream.next_kinds_are(&[Package, Identifier, Is, New]) { + parse_package_instantiation(ctx).map(Declaration::Package)? + } else { + parse_package_declaration(ctx).map(Declaration::PackageDeclaration)? + } + } For => { parse_configuration_specification(ctx).map(Declaration::Configuration)? } diff --git a/vhdl_lang/src/syntax/design_unit.rs b/vhdl_lang/src/syntax/design_unit.rs index 1d0ea17c..a7c04f16 100644 --- a/vhdl_lang/src/syntax/design_unit.rs +++ b/vhdl_lang/src/syntax/design_unit.rs @@ -933,4 +933,27 @@ end entity y; assert_eq!(tok.kind, Context); assert_eq!(tok.pos, code.s1("context").pos()); } + + #[test] + fn parse_package_declaration_in_declarative_part() { + let code = Code::new( + "\ +architecture arch of ent is + package my_pkg is + -- ... + end package; +begin +end arch; + ", + ); + let file = code.design_file(); + let (tokens, _) = &file.design_units[0]; + assert_eq!(tokens[0].kind, Architecture); + assert_eq!(tokens[1].kind, Identifier); + assert_eq!(tokens[5].kind, Package); + assert_eq!(tokens[6].kind, Identifier); + assert_eq!(tokens[7].kind, Is); + assert_eq!(tokens[8].kind, End); + assert_eq!(tokens[9].kind, Package); + } } From d260d937b675dd63496c1d056153270ce7a1756c Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Thu, 30 May 2024 19:17:08 +0200 Subject: [PATCH 2/6] Add package body in declarative part --- vhdl_lang/src/analysis/declarative.rs | 7 +++++++ vhdl_lang/src/analysis/names.rs | 1 + vhdl_lang/src/ast.rs | 1 + vhdl_lang/src/ast/search.rs | 4 ++++ vhdl_lang/src/named_entity.rs | 1 + vhdl_lang/src/syntax/declarative_part.rs | 4 +++- vhdl_lang/src/syntax/design_unit.rs | 23 ++++++++++++++++++----- 7 files changed, 35 insertions(+), 6 deletions(-) diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index 0fcc3285..b89e63ae 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -42,6 +42,7 @@ impl Declaration { | Use(_) | Package(_) | PackageDeclaration(_) + | PackageBody(_) | Configuration(_) | View(_) ), @@ -63,6 +64,7 @@ impl Declaration { | Use(_) | Package(_) | PackageDeclaration(_) + | PackageBody(_) | View(_) ), // LRM: package_body_declarative_item @@ -89,6 +91,7 @@ impl Declaration { | Use(_) | Package(_) | PackageDeclaration(_) + | PackageBody(_) ), // LRM: package_declarative_item AnyEntKind::Design(Design::Package(..)) => matches!( @@ -104,6 +107,7 @@ impl Declaration { | Use(_) | Package(_) | PackageDeclaration(_) + | PackageBody(_) | View(_) ), _ => { @@ -613,6 +617,9 @@ impl<'a, 't> AnalyzeContext<'a, 't> { Declaration::PackageDeclaration(..) => { // TODO } + Declaration::PackageBody(..) => { + // TODO + } Declaration::Configuration(..) => {} Declaration::View(view) => { if let Some(view) = as_fatal(self.analyze_view_declaration( diff --git a/vhdl_lang/src/analysis/names.rs b/vhdl_lang/src/analysis/names.rs index 649a237e..e90b1e01 100644 --- a/vhdl_lang/src/analysis/names.rs +++ b/vhdl_lang/src/analysis/names.rs @@ -1846,6 +1846,7 @@ impl Declaration { Declaration::Use(_) => "use", Declaration::Package(_) => "package instantiation", Declaration::PackageDeclaration(_) => "package", + Declaration::PackageBody(_) => "package body", Declaration::Configuration(_) => "configuration", Declaration::View(_) => "view", } diff --git a/vhdl_lang/src/ast.rs b/vhdl_lang/src/ast.rs index da0c1a22..7ca92f5f 100644 --- a/vhdl_lang/src/ast.rs +++ b/vhdl_lang/src/ast.rs @@ -853,6 +853,7 @@ pub enum Declaration { Use(UseClause), Package(PackageInstantiation), PackageDeclaration(PackageDeclaration), + PackageBody(PackageBody), Configuration(ConfigurationSpecification), View(ModeViewDeclaration), } diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index 837fc125..eae3d784 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -1084,6 +1084,10 @@ impl Search for Declaration { return_if_found!(package_instance.search(ctx, searcher)); // @TODO } + Declaration::PackageBody(ref package_instance) => { + return_if_found!(package_instance.search(ctx, searcher)); // @TODO + } + Declaration::Configuration(_) => { // @TODO } diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index a9cbe28a..073c5584 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -632,6 +632,7 @@ impl HasEntityId for Declaration { Declaration::SubprogramInstantiation(decl) => decl.ent_id(), Declaration::Package(pkg) => pkg.ent_id(), Declaration::PackageDeclaration(_) => None, // @TODO + Declaration::PackageBody(_) => None, // @TODO Declaration::Use(_) => None, Declaration::Configuration(_) => None, Declaration::View(decl) => decl.ent_id(), diff --git a/vhdl_lang/src/syntax/declarative_part.rs b/vhdl_lang/src/syntax/declarative_part.rs index a7c9b884..a479d8c8 100644 --- a/vhdl_lang/src/syntax/declarative_part.rs +++ b/vhdl_lang/src/syntax/declarative_part.rs @@ -10,7 +10,7 @@ use super::common::ParseResult; use super::component_declaration::parse_component_declaration; use super::configuration::parse_configuration_specification; use super::context::parse_use_clause; -use super::design_unit::parse_package_declaration; +use super::design_unit::{parse_package_body, parse_package_declaration}; use super::names::parse_selected_name; use super::object_declaration::{parse_file_declaration, parse_object_declaration}; use super::subprogram::parse_subprogram; @@ -108,6 +108,8 @@ pub fn parse_declarative_part( Package => { if ctx.stream.next_kinds_are(&[Package, Identifier, Is, New]) { parse_package_instantiation(ctx).map(Declaration::Package)? + } else if ctx.stream.next_kinds_are(&[Package, Body]) { + parse_package_body(ctx).map(Declaration::PackageBody)? } else { parse_package_declaration(ctx).map(Declaration::PackageDeclaration)? } diff --git a/vhdl_lang/src/syntax/design_unit.rs b/vhdl_lang/src/syntax/design_unit.rs index a7c04f16..43c72c59 100644 --- a/vhdl_lang/src/syntax/design_unit.rs +++ b/vhdl_lang/src/syntax/design_unit.rs @@ -935,25 +935,38 @@ end entity y; } #[test] - fn parse_package_declaration_in_declarative_part() { + fn parse_package_declaration_and_body_in_declarative_part() { let code = Code::new( "\ +entity ent is +end entity; + architecture arch of ent is package my_pkg is -- ... - end package; + end my_pkg; + package body my_pkg is + -- ... + end package body; begin end arch; ", ); let file = code.design_file(); - let (tokens, _) = &file.design_units[0]; + let (tokens, _) = &file.design_units[1]; assert_eq!(tokens[0].kind, Architecture); - assert_eq!(tokens[1].kind, Identifier); assert_eq!(tokens[5].kind, Package); assert_eq!(tokens[6].kind, Identifier); assert_eq!(tokens[7].kind, Is); assert_eq!(tokens[8].kind, End); - assert_eq!(tokens[9].kind, Package); + assert_eq!(tokens[9].kind, Identifier); + assert_eq!(tokens[10].kind, SemiColon); + assert_eq!(tokens[11].kind, Package); + assert_eq!(tokens[12].kind, Body); + assert_eq!(tokens[13].kind, Identifier); + assert_eq!(tokens[14].kind, Is); + assert_eq!(tokens[15].kind, End); + assert_eq!(tokens[16].kind, Package); + assert_eq!(tokens[17].kind, Body); } } From 1ab28392a6516fac626b2625fb1efde4c5acdb66 Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Thu, 30 May 2024 21:22:24 +0200 Subject: [PATCH 3/6] Add package body and declaration remaining functionality --- vhdl_lang/src/analysis/declarative.rs | 8 ++++---- vhdl_lang/src/analysis/design_unit.rs | 4 ++-- vhdl_lang/src/ast/search.rs | 12 ++++-------- vhdl_lang/src/named_entity.rs | 21 +++++++++++++++++---- 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index b89e63ae..1f04c875 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -614,11 +614,11 @@ impl<'a, 't> AnalyzeContext<'a, 't> { scope.add(ent, diagnostics); } } - Declaration::PackageDeclaration(..) => { - // TODO + Declaration::PackageDeclaration(ref mut unit) => { + self.analyze_package(unit, diagnostics)?; } - Declaration::PackageBody(..) => { - // TODO + Declaration::PackageBody(ref mut unit) => { + self.analyze_package_body(unit, diagnostics)?; } Declaration::Configuration(..) => {} Declaration::View(view) => { diff --git a/vhdl_lang/src/analysis/design_unit.rs b/vhdl_lang/src/analysis/design_unit.rs index f06664d8..925f1bb9 100644 --- a/vhdl_lang/src/analysis/design_unit.rs +++ b/vhdl_lang/src/analysis/design_unit.rs @@ -132,7 +132,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> { Ok(()) } - fn analyze_package( + pub fn analyze_package( &self, unit: &mut PackageDeclaration, diagnostics: &mut dyn DiagnosticHandler, @@ -297,7 +297,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> { Ok(()) } - fn analyze_package_body( + pub fn analyze_package_body( &self, unit: &mut PackageBody, diagnostics: &mut dyn DiagnosticHandler, diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index eae3d784..38bfa549 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -1075,19 +1075,15 @@ impl Search for Declaration { return_if_found!(open_info.search(ctx, searcher)); return_if_found!(file_name.search(ctx, searcher)); } - Declaration::Package(ref package_instance) => { return_if_found!(package_instance.search(ctx, searcher)); } - - Declaration::PackageDeclaration(ref package_instance) => { - return_if_found!(package_instance.search(ctx, searcher)); // @TODO + Declaration::PackageDeclaration(ref decl) => { + return_if_found!(decl.search(ctx, searcher)); } - - Declaration::PackageBody(ref package_instance) => { - return_if_found!(package_instance.search(ctx, searcher)); // @TODO + Declaration::PackageBody(ref body) => { + return_if_found!(body.search(ctx, searcher)); } - Declaration::Configuration(_) => { // @TODO } diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index 073c5584..100f3764 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -8,8 +8,9 @@ use crate::ast::{ AliasDeclaration, AnyDesignUnit, AnyPrimaryUnit, AnySecondaryUnit, Attribute, AttributeDeclaration, AttributeSpecification, ComponentDeclaration, Declaration, Designator, FileDeclaration, HasIdent, Ident, InterfaceFileDeclaration, InterfacePackageDeclaration, - ModeViewDeclaration, ObjectClass, ObjectDeclaration, PackageInstantiation, SubprogramBody, - SubprogramInstantiation, SubprogramSpecification, TypeDeclaration, WithDecl, + ModeViewDeclaration, ObjectClass, ObjectDeclaration, PackageBody, PackageDeclaration, + PackageInstantiation, SubprogramBody, SubprogramInstantiation, SubprogramSpecification, + TypeDeclaration, WithDecl, }; use crate::ast::{ExternalObjectClass, InterfaceDeclaration, InterfaceObjectDeclaration}; use crate::data::*; @@ -631,8 +632,8 @@ impl HasEntityId for Declaration { Declaration::SubprogramBody(body) => body.ent_id(), Declaration::SubprogramInstantiation(decl) => decl.ent_id(), Declaration::Package(pkg) => pkg.ent_id(), - Declaration::PackageDeclaration(_) => None, // @TODO - Declaration::PackageBody(_) => None, // @TODO + Declaration::PackageDeclaration(pkg) => pkg.ent_id(), + Declaration::PackageBody(pkg) => pkg.ent_id(), Declaration::Use(_) => None, Declaration::Configuration(_) => None, Declaration::View(decl) => decl.ent_id(), @@ -652,6 +653,18 @@ impl HasEntityId for PackageInstantiation { } } +impl HasEntityId for PackageDeclaration { + fn ent_id(&self) -> Option { + self.ident.decl.get() + } +} + +impl HasEntityId for PackageBody { + fn ent_id(&self) -> Option { + self.ident.decl.get() + } +} + impl HasEntityId for SubprogramBody { fn ent_id(&self) -> Option { self.specification.ent_id() From 10cbd3d1895010b485914b72f634771e0fd6255a Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Thu, 30 May 2024 23:48:50 +0200 Subject: [PATCH 4/6] Add disconnect specification --- vhdl_lang/src/analysis/declarative.rs | 6 +- vhdl_lang/src/analysis/names.rs | 1 + vhdl_lang/src/ast.rs | 5 ++ vhdl_lang/src/ast/search.rs | 3 + vhdl_lang/src/named_entity.rs | 1 + vhdl_lang/src/syntax.rs | 1 + vhdl_lang/src/syntax/declarative_part.rs | 26 +++++++ vhdl_lang/src/syntax/disconnection.rs | 95 ++++++++++++++++++++++++ 8 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 vhdl_lang/src/syntax/disconnection.rs diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index 1f04c875..72e079db 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -44,6 +44,7 @@ impl Declaration { | PackageDeclaration(_) | PackageBody(_) | Configuration(_) + | Disconnection(_) | View(_) ), // LRM: configuration_declarative_item @@ -65,6 +66,7 @@ impl Declaration { | Package(_) | PackageDeclaration(_) | PackageBody(_) + | Disconnection(_) | View(_) ), // LRM: package_body_declarative_item @@ -76,6 +78,7 @@ impl Declaration { | Overloaded::UninstSubprogram(..), ) | AnyEntKind::Concurrent(Some(Concurrent::Process)) + // LRM protected type body declarative item | AnyEntKind::Type(named_entity::Type::Protected(..)) => matches!( self, Object(ObjectDeclaration { @@ -107,7 +110,7 @@ impl Declaration { | Use(_) | Package(_) | PackageDeclaration(_) - | PackageBody(_) + | Disconnection(_) | View(_) ), _ => { @@ -621,6 +624,7 @@ impl<'a, 't> AnalyzeContext<'a, 't> { self.analyze_package_body(unit, diagnostics)?; } Declaration::Configuration(..) => {} + Declaration::Disconnection(..) => {} // @TODO Declaration::View(view) => { if let Some(view) = as_fatal(self.analyze_view_declaration( scope, diff --git a/vhdl_lang/src/analysis/names.rs b/vhdl_lang/src/analysis/names.rs index e90b1e01..f1b7bd68 100644 --- a/vhdl_lang/src/analysis/names.rs +++ b/vhdl_lang/src/analysis/names.rs @@ -1848,6 +1848,7 @@ impl Declaration { Declaration::PackageDeclaration(_) => "package", Declaration::PackageBody(_) => "package body", Declaration::Configuration(_) => "configuration", + Declaration::Disconnection(_) => "disconnection", Declaration::View(_) => "view", } } diff --git a/vhdl_lang/src/ast.rs b/vhdl_lang/src/ast.rs index 7ca92f5f..fa1247b8 100644 --- a/vhdl_lang/src/ast.rs +++ b/vhdl_lang/src/ast.rs @@ -855,6 +855,7 @@ pub enum Declaration { PackageDeclaration(PackageDeclaration), PackageBody(PackageBody), Configuration(ConfigurationSpecification), + Disconnection(DisconnectionSpecification), View(ModeViewDeclaration), } @@ -1377,6 +1378,10 @@ pub struct ConfigurationSpecification { pub vunit_bind_inds: Vec, } +/// LRM 7.4 Disconnection specification +#[derive(PartialEq, Debug, Clone)] +pub struct DisconnectionSpecification {} + /// LRM 3.4 Configuration declarations #[derive(PartialEq, Debug, Clone)] pub enum ConfigurationDeclarativeItem { diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index 38bfa549..2ca9a3b5 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -1087,6 +1087,9 @@ impl Search for Declaration { Declaration::Configuration(_) => { // @TODO } + Declaration::Disconnection(_) => { + // @TODO + } Declaration::View(view) => { return_if_found!(searcher .search_decl(ctx, FoundDeclaration::View(view)) diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index 100f3764..f2c67181 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -636,6 +636,7 @@ impl HasEntityId for Declaration { Declaration::PackageBody(pkg) => pkg.ent_id(), Declaration::Use(_) => None, Declaration::Configuration(_) => None, + Declaration::Disconnection(_) => None, // TODO Declaration::View(decl) => decl.ent_id(), } } diff --git a/vhdl_lang/src/syntax.rs b/vhdl_lang/src/syntax.rs index f8b20df6..be48a4c9 100644 --- a/vhdl_lang/src/syntax.rs +++ b/vhdl_lang/src/syntax.rs @@ -16,6 +16,7 @@ mod configuration; mod context; mod declarative_part; mod design_unit; +mod disconnection; mod expression; mod interface_declaration; mod names; diff --git a/vhdl_lang/src/syntax/declarative_part.rs b/vhdl_lang/src/syntax/declarative_part.rs index a479d8c8..8fd65f34 100644 --- a/vhdl_lang/src/syntax/declarative_part.rs +++ b/vhdl_lang/src/syntax/declarative_part.rs @@ -19,6 +19,7 @@ use super::type_declaration::parse_type_declaration; use crate::ast::token_range::WithTokenSpan; use crate::ast::{ContextClause, Declaration, PackageInstantiation}; use crate::syntax::concurrent_statement::parse_map_aspect; +use crate::syntax::disconnection::parse_disconnection_specification; use crate::syntax::view::parse_mode_view_declaration; use vhdl_lang::syntax::parser::ParsingContext; @@ -63,6 +64,7 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult { | For | View | Begin + | Disconnect )) } @@ -93,6 +95,7 @@ pub fn parse_declarative_part( | Alias | Begin | End + | Disconnect ) } @@ -186,6 +189,17 @@ pub fn parse_declarative_part( } } + Disconnect => { + match parse_disconnection_specification(ctx).or_recover_until(ctx, is_recover_token) + { + Ok(decl) => declarations.push(decl.map_into(Declaration::Disconnection)), + Err(err) => { + ctx.diagnostics.push(err); + continue; + } + } + } + _ => { use crate::VHDLStandard::*; let expected: &[Kind] = match ctx.standard { @@ -341,4 +355,16 @@ var not_a_var: broken; )], ) } + + #[test] + fn parse_declarative_part_with_disconnection() { + let code = Code::new( + "\ +constant foo: real := 5.1; +disconnect my_signal : integer after 42 ms; +signal bar: std_logic; +", + ); + code.with_stream_no_diagnostics(parse_declarative_part); + } } diff --git a/vhdl_lang/src/syntax/disconnection.rs b/vhdl_lang/src/syntax/disconnection.rs new file mode 100644 index 00000000..b1777f00 --- /dev/null +++ b/vhdl_lang/src/syntax/disconnection.rs @@ -0,0 +1,95 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. +// +// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com + +use super::common::ParseResult; +use super::expression::parse_expression; +use super::names::parse_name; +use super::separated_list::parse_ident_list; +use super::tokens::{Kind::*, TokenSpan}; +use crate::ast::token_range::WithTokenSpan; +use crate::ast::*; +use vhdl_lang::syntax::parser::ParsingContext; + +/// LRM 7.4 Disconnection Specification +pub fn parse_disconnection_specification( + ctx: &mut ParsingContext<'_>, +) -> ParseResult> { + let start_token = ctx.stream.expect_kind(Disconnect)?; + if ctx.stream.next_kind_is(Identifier) { + let _ = parse_ident_list(ctx); + } else if ctx.stream.next_kind_is(All) { + ctx.stream.expect_kind(All)?; + } else { + ctx.stream.expect_kind(Others)?; + } + ctx.stream.expect_kind(Colon)?; + let _ = parse_name(ctx); + ctx.stream.expect_kind(After)?; + let _ = parse_expression(ctx); + let end_token = ctx.stream.expect_kind(SemiColon)?; + Ok(WithTokenSpan::new( + DisconnectionSpecification {}, + TokenSpan::new(start_token, end_token), + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::syntax::test::Code; + + #[test] + fn disconnect_spec_with_scalar_or_composite_signal() { + let code = Code::new( + "\ +disconnect S: T after 42 ms; +", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification), + WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) + ); + } + + #[test] + fn disconnect_spec_with_scalar_or_composite_signal_variant() { + let code = Code::new( + "\ +disconnect foo, bar, foobar : unsigned(3 downto 0) after CLK_PERIOD; +", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification), + WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) + ); + } + + #[test] + fn disconnect_spec_explicit_with_others() { + let code = Code::new( + "\ +disconnect others: std_logic after 42 ms; +", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification), + WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) + ); + } + + #[test] + fn disconnect_spec_explicit_with_all() { + let code = Code::new( + "\ +disconnect all : T after 42 ms; +", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification), + WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) + ); + } +} From 7416d11eb4f7583c5897b5b2c0b60f54c674d9b1 Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Sat, 1 Jun 2024 19:06:45 +0200 Subject: [PATCH 5/6] Refactor disconnect, package body and package declaration --- vhdl_lang/src/analysis/declarative.rs | 10 +- vhdl_lang/src/analysis/tests/declarations.rs | 93 +++++++ vhdl_lang/src/ast.rs | 14 +- vhdl_lang/src/ast/display.rs | 10 + vhdl_lang/src/ast/search.rs | 10 +- vhdl_lang/src/named_entity.rs | 16 +- vhdl_lang/src/syntax/declarative_part.rs | 72 +++--- vhdl_lang/src/syntax/design_unit.rs | 64 +++-- vhdl_lang/src/syntax/disconnection.rs | 259 ++++++++++++++----- 9 files changed, 395 insertions(+), 153 deletions(-) diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index 72e079db..4beaa086 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -624,7 +624,15 @@ impl<'a, 't> AnalyzeContext<'a, 't> { self.analyze_package_body(unit, diagnostics)?; } Declaration::Configuration(..) => {} - Declaration::Disconnection(..) => {} // @TODO + Declaration::Disconnection(ref mut disc) => { + let DisconnectionSpecification { + ident: _, + subtype_indication, + expression, + } = disc; + self.expr_with_ttyp(scope, self.time(), expression, diagnostics)?; + self.analyze_subtype_indication(scope, subtype_indication, diagnostics)?; + } Declaration::View(view) => { if let Some(view) = as_fatal(self.analyze_view_declaration( scope, diff --git a/vhdl_lang/src/analysis/tests/declarations.rs b/vhdl_lang/src/analysis/tests/declarations.rs index fbca954a..fafd3165 100644 --- a/vhdl_lang/src/analysis/tests/declarations.rs +++ b/vhdl_lang/src/analysis/tests/declarations.rs @@ -100,3 +100,96 @@ end entity test; )], ) } + +#[test] +pub fn disconnect_no_analyze_error() { + let mut builder = LibraryBuilder::new(); + let _ = builder.code( + "libname", + "\ +entity ent is +end entity; +architecture arch of ent is + constant foo : time := 10 ns; + disconnect all : integer after foo; +begin +end arch; + ", + ); + check_diagnostics(builder.analyze(), vec![]) +} + +#[test] +pub fn disconnect_expression_error_1() { + let mut builder = LibraryBuilder::new(); + let code = builder.code( + "libname", + "\ +entity ent is +end entity; +architecture arch of ent is + constant foo : time := 10 ns; + disconnect all : integer after bar; +begin +end arch; + ", + ); + check_diagnostics( + builder.analyze(), + vec![Diagnostic::new( + code.s1("bar"), + "No declaration of 'bar'", + ErrorCode::Unresolved, + )], + ) +} + +#[test] +pub fn disconnect_expression_error_2() { + let mut builder = LibraryBuilder::new(); + let code = builder.code( + "libname", + "\ +entity ent is +end entity; +architecture arch of ent is + signal foo : integer; + disconnect all : integer after foo; +begin +end arch; + ", + ); + check_diagnostics( + builder.analyze(), + vec![Diagnostic::new( + code.s1("after foo").s1("foo"), + "signal 'foo' of integer type 'INTEGER' does not match physical type 'TIME'", + ErrorCode::TypeMismatch, + )], + ) +} + +#[test] +pub fn disconnect_type_error_1() { + let mut builder = LibraryBuilder::new(); + let code = builder.code( + "libname", + "\ +entity ent is +end entity; +architecture arch of ent is + signal foo : integer; + disconnect all : bar after 10 ns; +begin +end arch; + ", + ); + check_diagnostics( + builder.analyze(), + vec![Diagnostic::new( + code.s1("bar"), + "No declaration of 'bar'", + ErrorCode::Unresolved, + )], + ) +} diff --git a/vhdl_lang/src/ast.rs b/vhdl_lang/src/ast.rs index fa1247b8..fbb131b7 100644 --- a/vhdl_lang/src/ast.rs +++ b/vhdl_lang/src/ast.rs @@ -1378,9 +1378,21 @@ pub struct ConfigurationSpecification { pub vunit_bind_inds: Vec, } +/// LRM 7.4 Guarded Signal List +#[derive(PartialEq, Debug, Clone)] +pub enum GuardedSignalList { + All, + Others, + Ident(WithDecl) +} + /// LRM 7.4 Disconnection specification #[derive(PartialEq, Debug, Clone)] -pub struct DisconnectionSpecification {} +pub struct DisconnectionSpecification { + pub ident: GuardedSignalList, + pub subtype_indication: SubtypeIndication, + pub expression: WithTokenSpan, +} /// LRM 3.4 Configuration declarations #[derive(PartialEq, Debug, Clone)] diff --git a/vhdl_lang/src/ast/display.rs b/vhdl_lang/src/ast/display.rs index c0ff64a8..b827290a 100644 --- a/vhdl_lang/src/ast/display.rs +++ b/vhdl_lang/src/ast/display.rs @@ -1140,6 +1140,16 @@ impl Display for ConfigurationDeclaration { } } +impl Display for DisconnectionSpecification { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + if let Some(ident) = &self.ident { + write!(f, "disconnection {}", ident) + } else { + write!(f, "disconnection") + } + } +} + impl Display for EntityDeclaration { fn fmt(&self, f: &mut Formatter<'_>) -> Result { // Not used: context_clause, decl, statements diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index 2ca9a3b5..e033724b 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -1087,8 +1087,14 @@ impl Search for Declaration { Declaration::Configuration(_) => { // @TODO } - Declaration::Disconnection(_) => { - // @TODO + Declaration::Disconnection(disconnect) => { + let DisconnectionSpecification { + ident: _, + subtype_indication, + expression, + } = disconnect; + return_if_found!(subtype_indication.search(ctx, searcher)); + return_if_found!(expression.search(ctx, searcher)); } Declaration::View(view) => { return_if_found!(searcher diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index f2c67181..35bc38f1 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -7,10 +7,10 @@ use crate::ast::{ AliasDeclaration, AnyDesignUnit, AnyPrimaryUnit, AnySecondaryUnit, Attribute, AttributeDeclaration, AttributeSpecification, ComponentDeclaration, Declaration, Designator, - FileDeclaration, HasIdent, Ident, InterfaceFileDeclaration, InterfacePackageDeclaration, - ModeViewDeclaration, ObjectClass, ObjectDeclaration, PackageBody, PackageDeclaration, - PackageInstantiation, SubprogramBody, SubprogramInstantiation, SubprogramSpecification, - TypeDeclaration, WithDecl, + DisconnectionSpecification, FileDeclaration, HasIdent, Ident, InterfaceFileDeclaration, + InterfacePackageDeclaration, ModeViewDeclaration, ObjectClass, ObjectDeclaration, PackageBody, + PackageDeclaration, PackageInstantiation, SubprogramBody, SubprogramInstantiation, + SubprogramSpecification, TypeDeclaration, WithDecl, }; use crate::ast::{ExternalObjectClass, InterfaceDeclaration, InterfaceObjectDeclaration}; use crate::data::*; @@ -636,7 +636,7 @@ impl HasEntityId for Declaration { Declaration::PackageBody(pkg) => pkg.ent_id(), Declaration::Use(_) => None, Declaration::Configuration(_) => None, - Declaration::Disconnection(_) => None, // TODO + Declaration::Disconnection(pkg) => pkg.ent_id(), Declaration::View(decl) => decl.ent_id(), } } @@ -660,6 +660,12 @@ impl HasEntityId for PackageDeclaration { } } +impl HasEntityId for DisconnectionSpecification { + fn ent_id(&self) -> Option { + self.ident.as_ref().and_then(|ident| ident.decl.get()) + } +} + impl HasEntityId for PackageBody { fn ent_id(&self) -> Option { self.ident.decl.get() diff --git a/vhdl_lang/src/syntax/declarative_part.rs b/vhdl_lang/src/syntax/declarative_part.rs index 8fd65f34..8c9dfd00 100644 --- a/vhdl_lang/src/syntax/declarative_part.rs +++ b/vhdl_lang/src/syntax/declarative_part.rs @@ -68,37 +68,37 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult { )) } +pub fn is_recover_token(kind: Kind) -> bool { + matches!( + kind, + Type | Subtype + | Component + | Impure + | Pure + | Function + | Procedure + | Package + | For + | File + | Shared + | Constant + | Signal + | Variable + | Attribute + | View + | Use + | Alias + | Begin + | End + | Disconnect + ) +} + pub fn parse_declarative_part( ctx: &mut ParsingContext<'_>, ) -> ParseResult>> { let mut declarations: Vec> = Vec::new(); - fn is_recover_token(kind: Kind) -> bool { - matches!( - kind, - Type | Subtype - | Component - | Impure - | Pure - | Function - | Procedure - | Package - | For - | File - | Shared - | Constant - | Signal - | Variable - | Attribute - | View - | Use - | Alias - | Begin - | End - | Disconnect - ) - } - while let Some(token) = ctx.stream.peek() { let start_token = ctx.stream.get_current_token_id(); match token.kind { @@ -206,10 +206,12 @@ pub fn parse_declarative_part( VHDL2008 | VHDL1993 => &[ Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For, File, Shared, Constant, Signal, Variable, Attribute, Use, Alias, + Disconnect, ], VHDL2019 => &[ Type, Subtype, Component, Impure, Pure, Function, Procedure, Package, For, File, Shared, Constant, Signal, Variable, Attribute, Use, Alias, View, + Disconnect, ], }; ctx.diagnostics.push(token.kinds_error(expected)); @@ -305,7 +307,7 @@ constant x: natural := 5; "Expected 'type', 'subtype', 'component', 'impure', 'pure', \ 'function', 'procedure', 'package', 'for', 'file', \ 'shared', 'constant', 'signal', 'variable', 'attribute', \ - 'use' or 'alias'" + 'use', 'alias' or 'disconnect'" )] ); } @@ -333,7 +335,7 @@ var not_a_var: broken; "Expected 'type', 'subtype', 'component', 'impure', 'pure', \ 'function', 'procedure', 'package', 'for', 'file', \ 'shared', 'constant', 'signal', 'variable', 'attribute', \ - 'use' or 'alias'", + 'use', 'alias' or 'disconnect'", )], ); @@ -351,20 +353,8 @@ var not_a_var: broken; "Expected 'type', 'subtype', 'component', 'impure', 'pure', \ 'function', 'procedure', 'package', 'for', 'file', \ 'shared', 'constant', 'signal', 'variable', 'attribute', \ - 'use', 'alias' or 'view'", + 'use', 'alias', 'view' or 'disconnect'", )], ) } - - #[test] - fn parse_declarative_part_with_disconnection() { - let code = Code::new( - "\ -constant foo: real := 5.1; -disconnect my_signal : integer after 42 ms; -signal bar: std_logic; -", - ); - code.with_stream_no_diagnostics(parse_declarative_part); - } } diff --git a/vhdl_lang/src/syntax/design_unit.rs b/vhdl_lang/src/syntax/design_unit.rs index 43c72c59..9a1a6c6a 100644 --- a/vhdl_lang/src/syntax/design_unit.rs +++ b/vhdl_lang/src/syntax/design_unit.rs @@ -934,39 +934,33 @@ end entity y; assert_eq!(tok.pos, code.s1("context").pos()); } - #[test] - fn parse_package_declaration_and_body_in_declarative_part() { - let code = Code::new( - "\ -entity ent is -end entity; - -architecture arch of ent is - package my_pkg is - -- ... - end my_pkg; - package body my_pkg is - -- ... - end package body; -begin -end arch; - ", - ); - let file = code.design_file(); - let (tokens, _) = &file.design_units[1]; - assert_eq!(tokens[0].kind, Architecture); - assert_eq!(tokens[5].kind, Package); - assert_eq!(tokens[6].kind, Identifier); - assert_eq!(tokens[7].kind, Is); - assert_eq!(tokens[8].kind, End); - assert_eq!(tokens[9].kind, Identifier); - assert_eq!(tokens[10].kind, SemiColon); - assert_eq!(tokens[11].kind, Package); - assert_eq!(tokens[12].kind, Body); - assert_eq!(tokens[13].kind, Identifier); - assert_eq!(tokens[14].kind, Is); - assert_eq!(tokens[15].kind, End); - assert_eq!(tokens[16].kind, Package); - assert_eq!(tokens[17].kind, Body); - } + // #[test] + // fn parse_architecture_body_with_package_decl_and_body() { + // let (code, design_file) = parse_ok( + // " + //architecture arch of ent is + // package my_pkg is + // -- ... + // end my_pkg; + // package body my_pkg is + // -- ... + // end package body; + //begin + //end arch; + //", + // ); + // + //assert_eq!( + // code.with_stream_no_diagnostics(parse_architecture_body()), + // ArchitectureBody { + // span: code.token_span(), + // context_clause: ContextClause::default(), + // ident: code.s1("arch").decl_ident(), + // entity_name: None, // TODO + // begin_token : code.s1("architecture").token(), + // decl : None, + // statements : None, + // end_ident_pos : None, + // }) + // } } diff --git a/vhdl_lang/src/syntax/disconnection.rs b/vhdl_lang/src/syntax/disconnection.rs index b1777f00..03f4c02b 100644 --- a/vhdl_lang/src/syntax/disconnection.rs +++ b/vhdl_lang/src/syntax/disconnection.rs @@ -6,11 +6,13 @@ use super::common::ParseResult; use super::expression::parse_expression; -use super::names::parse_name; -use super::separated_list::parse_ident_list; +//use super::separated_list::parse_ident_list; use super::tokens::{Kind::*, TokenSpan}; use crate::ast::token_range::WithTokenSpan; use crate::ast::*; +use crate::syntax::declarative_part::is_recover_token; +use crate::syntax::subtype_indication::parse_subtype_indication; +use crate::syntax::Kind; use vhdl_lang::syntax::parser::ParsingContext; /// LRM 7.4 Disconnection Specification @@ -18,78 +20,199 @@ pub fn parse_disconnection_specification( ctx: &mut ParsingContext<'_>, ) -> ParseResult> { let start_token = ctx.stream.expect_kind(Disconnect)?; - if ctx.stream.next_kind_is(Identifier) { - let _ = parse_ident_list(ctx); - } else if ctx.stream.next_kind_is(All) { - ctx.stream.expect_kind(All)?; - } else { - ctx.stream.expect_kind(Others)?; + + let ident = GuardedSignalList::All; + if let Some(token) = ctx.stream.peek() { + match token.kind { + All => { + ctx.stream.skip(); + } + Others => { + let ident = GuardedSignalList::Others; + ctx.stream.skip(); + } + _ => { // Identifier + let ident = WithDecl::new(ctx.stream.expect_ident()?); + } + } } + ctx.stream.expect_kind(Colon)?; - let _ = parse_name(ctx); + let subtype_indication = parse_subtype_indication(ctx)?; ctx.stream.expect_kind(After)?; - let _ = parse_expression(ctx); + let expression = parse_expression(ctx)?; let end_token = ctx.stream.expect_kind(SemiColon)?; Ok(WithTokenSpan::new( - DisconnectionSpecification {}, + DisconnectionSpecification { + ident, + subtype_indication, + expression, + }, TokenSpan::new(start_token, end_token), )) } -#[cfg(test)] -mod tests { - use super::*; - use crate::syntax::test::Code; - - #[test] - fn disconnect_spec_with_scalar_or_composite_signal() { - let code = Code::new( - "\ -disconnect S: T after 42 ms; -", - ); - assert_eq!( - code.with_stream_no_diagnostics(parse_disconnection_specification), - WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) - ); - } - - #[test] - fn disconnect_spec_with_scalar_or_composite_signal_variant() { - let code = Code::new( - "\ -disconnect foo, bar, foobar : unsigned(3 downto 0) after CLK_PERIOD; -", - ); - assert_eq!( - code.with_stream_no_diagnostics(parse_disconnection_specification), - WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) - ); - } - - #[test] - fn disconnect_spec_explicit_with_others() { - let code = Code::new( - "\ -disconnect others: std_logic after 42 ms; -", - ); - assert_eq!( - code.with_stream_no_diagnostics(parse_disconnection_specification), - WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) - ); - } - - #[test] - fn disconnect_spec_explicit_with_all() { - let code = Code::new( - "\ -disconnect all : T after 42 ms; -", - ); - assert_eq!( - code.with_stream_no_diagnostics(parse_disconnection_specification), - WithTokenSpan::new(DisconnectionSpecification {}, code.token_span()) - ); - } -} +//#[cfg(test)] +//mod tests { +// use super::*; +// +// use crate::data::Diagnostic; +// use crate::syntax::test::{check_diagnostics, Code}; +// #[test] +// fn disconnect_spec_with_scalar_or_composite_signal() { +// let code = Code::new( +// "\ +//disconnect S: T after 42 ms; +//", +// ); +// assert_eq!( +// code.with_stream_no_diagnostics(parse_disconnection_specification), +// WithTokenSpan::new( +// DisconnectionSpecification { +// ident: code.s1("S").decl_ident(), +// subtype_indication: Some(code.s1("T").subtype_indication()), +// expression: Some(code.s1("42 ms").expr()), +// }, +// code.token_span() +// ) +// ) +// } +// +// #[test] +// fn disconnect_spec_with_scalar_or_composite_signal_variant() { +// let code = Code::new( +// "\ +//disconnect foobar : integer after 100*CLK_PERIOD; +//", +// ); +// assert_eq!( +// code.with_stream_no_diagnostics(parse_disconnection_specification), +// WithTokenSpan::new( +// DisconnectionSpecification { +// ident: Some(code.s1("foobar").decl_ident()), +// subtype_indication: Some(code.s1("integer").subtype_indication()), +// expression: Some(code.s1("100*CLK_PERIOD").expr()), +// }, +// code.token_span() +// ) +// ) +// } +// +// #[test] +// fn disconnect_spec_explicit_with_others() { +// let code = Code::new( +// "\ +//disconnect others: std_logic after bar; +//", +// ); +// assert_eq!( +// code.with_stream_no_diagnostics(parse_disconnection_specification), +// WithTokenSpan::new( +// DisconnectionSpecification { +// ident: None, +// subtype_indication: Some(code.s1("std_logic").subtype_indication()), +// expression: Some(code.s1("bar").expr()), +// }, +// code.token_span() +// ) +// ) +// } +// +// #[test] +// fn disconnect_spec_explicit_with_all() { +// let code = Code::new( +// "\ +//disconnect all : unsigned(3 downto 0) after bar; +//", +// ); +// assert_eq!( +// code.with_stream_no_diagnostics(parse_disconnection_specification), +// WithTokenSpan::new( +// DisconnectionSpecification { +// ident: None, +// subtype_indication: Some(code.s1("unsigned(3 downto 0)").subtype_indication()), +// expression: Some(code.s1("bar").expr()), +// }, +// code.token_span() +// ) +// ) +// } +// +// #[test] +// fn disconnect_spec_syntax_error_1() { +// let code = Code::new( +// "\ +//disconnect ; T after 42 ms; +//", +// ); +// let (_, diag) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// check_diagnostics( +// diag, +// vec![Diagnostic::syntax_error( +// code.s1(";").pos(), +// "Expected '{identifier}', 'all' or 'others'", +// )], +// ); +// } +// +// #[test] +// fn disconnect_spec_syntax_error_2() { +// let code = Code::new( +// "\ +//disconnect 7 after 42 ms; +//", +// ); +// let (_, diag) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// check_diagnostics( +// diag, +// vec![Diagnostic::syntax_error( +// code.s1("7").pos(), +// "Expected '{identifier}', 'all' or 'others'", +// )], +// ); +// } +// +// #[test] +// fn disconnect_spec_syntax_error_3() { +// let code = Code::new( +// "\ +//disconnect foo after 42 ms; +//", +// ); +// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// assert!(decl.is_err()); +// } +// +// #[test] +// fn disconnect_spec_syntax_error_4() { +// let code = Code::new( +// "\ +//disconnect foo : std_logic afterrr 42 ms; +//", +// ); +// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// assert!(decl.is_err()); +// } +// +// #[test] +// fn disconnect_spec_syntax_error_5() { +// let code = Code::new( +// "\ +//disconnect foo : after 42 ms bar; +//", +// ); +// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// assert!(decl.is_err()); +// } +// +// #[test] +// fn disconnect_spec_syntax_error_6() { +// let code = Code::new( +// "\ +//diconnect foo : after 42 ms; +//", +// ); +// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); +// assert!(decl.is_err()); +// } +//} From 9cb17907a895de5ef703fcf7e9906cd51c253314 Mon Sep 17 00:00:00 2001 From: christoph bothe Date: Sun, 2 Jun 2024 22:48:43 +0200 Subject: [PATCH 6/6] More Refactor disconnect, package body and package declaration --- vhdl_lang/src/analysis/declarative.rs | 24 +- vhdl_lang/src/analysis/names.rs | 2 + vhdl_lang/src/analysis/package_instance.rs | 3 + vhdl_lang/src/analysis/tests/declarations.rs | 21 +- vhdl_lang/src/ast.rs | 2 +- vhdl_lang/src/ast/display.rs | 6 +- vhdl_lang/src/ast/search.rs | 14 +- vhdl_lang/src/named_entity.rs | 15 +- vhdl_lang/src/syntax/declarative_part.rs | 12 +- vhdl_lang/src/syntax/disconnection.rs | 361 +++++++++---------- vhdl_ls/src/vhdl_server.rs | 2 + 11 files changed, 257 insertions(+), 205 deletions(-) diff --git a/vhdl_lang/src/analysis/declarative.rs b/vhdl_lang/src/analysis/declarative.rs index 4beaa086..2a7718ff 100644 --- a/vhdl_lang/src/analysis/declarative.rs +++ b/vhdl_lang/src/analysis/declarative.rs @@ -626,12 +626,33 @@ impl<'a, 't> AnalyzeContext<'a, 't> { Declaration::Configuration(..) => {} Declaration::Disconnection(ref mut disc) => { let DisconnectionSpecification { - ident: _, + ident, subtype_indication, expression, } = disc; self.expr_with_ttyp(scope, self.time(), expression, diagnostics)?; self.analyze_subtype_indication(scope, subtype_indication, diagnostics)?; + + let subtype = as_fatal(self.resolve_subtype_indication( + scope, + subtype_indication, + diagnostics, + )); + if let Ok(Some(subtype)) = subtype { + if let GuardedSignalList::Ident(ref mut ident) = ident { + scope.add( + self.arena.define( + self.ctx, + ident, + parent, + AnyEntKind::Disconnection(subtype), + src_span, + Some(self.source()), + ), + diagnostics, + ); + } + } } Declaration::View(view) => { if let Some(view) = as_fatal(self.analyze_view_declaration( @@ -1210,6 +1231,7 @@ fn get_entity_class(ent: EntRef) -> Option { Design::Context(_) => None, }, AnyEntKind::View(_) => None, + AnyEntKind::Disconnection(_) => None, } } diff --git a/vhdl_lang/src/analysis/names.rs b/vhdl_lang/src/analysis/names.rs index f1b7bd68..3343103d 100644 --- a/vhdl_lang/src/analysis/names.rs +++ b/vhdl_lang/src/analysis/names.rs @@ -188,6 +188,7 @@ impl<'a> ResolvedName<'a> { }), AnyEntKind::Type(_) => ResolvedName::Type(TypeEnt::from_any(ent).unwrap()), AnyEntKind::View(_) => ResolvedName::Final(ent), + AnyEntKind::Disconnection(_) => ResolvedName::Final(ent), AnyEntKind::Overloaded(_) => { return Err(( "Internal error. Unreachable as overloaded is handled outside".to_owned(), @@ -258,6 +259,7 @@ impl<'a> ResolvedName<'a> { } AnyEntKind::File(_) | AnyEntKind::View(_) + | AnyEntKind::Disconnection(_) | AnyEntKind::InterfaceFile(_) | AnyEntKind::Component(_) | AnyEntKind::Concurrent(_) diff --git a/vhdl_lang/src/analysis/package_instance.rs b/vhdl_lang/src/analysis/package_instance.rs index b16c8022..8d820fd5 100644 --- a/vhdl_lang/src/analysis/package_instance.rs +++ b/vhdl_lang/src/analysis/package_instance.rs @@ -386,6 +386,9 @@ impl<'a, 't> AnalyzeContext<'a, 't> { } }, AnyEntKind::View(typ) => AnyEntKind::View(self.map_subtype(mapping, *typ)), + AnyEntKind::Disconnection(typ) => { + AnyEntKind::Disconnection(self.map_subtype(mapping, *typ)) + } }) } diff --git a/vhdl_lang/src/analysis/tests/declarations.rs b/vhdl_lang/src/analysis/tests/declarations.rs index fafd3165..1c8231b1 100644 --- a/vhdl_lang/src/analysis/tests/declarations.rs +++ b/vhdl_lang/src/analysis/tests/declarations.rs @@ -3,7 +3,7 @@ // You can obtain one at http://mozilla.org/MPL/2.0/. // // Copyright (c) 2023, Olof Kraigher olof.kraigher@gmail.com -use crate::analysis::tests::{check_diagnostics, LibraryBuilder}; +use crate::analysis::tests::{check_diagnostics, check_no_diagnostics, LibraryBuilder}; use crate::data::error_codes::ErrorCode; use crate::Diagnostic; @@ -116,7 +116,7 @@ begin end arch; ", ); - check_diagnostics(builder.analyze(), vec![]) + check_no_diagnostics(&builder.analyze()) } #[test] @@ -186,10 +186,17 @@ end arch; ); check_diagnostics( builder.analyze(), - vec![Diagnostic::new( - code.s1("bar"), - "No declaration of 'bar'", - ErrorCode::Unresolved, - )], + vec![ + Diagnostic::new( + code.s1("bar"), + "No declaration of 'bar'", + ErrorCode::Unresolved, + ), + Diagnostic::new( + code.s1("bar"), + "No declaration of 'bar'", + ErrorCode::Unresolved, + ), + ], ) } diff --git a/vhdl_lang/src/ast.rs b/vhdl_lang/src/ast.rs index fbb131b7..e7a2118a 100644 --- a/vhdl_lang/src/ast.rs +++ b/vhdl_lang/src/ast.rs @@ -1383,7 +1383,7 @@ pub struct ConfigurationSpecification { pub enum GuardedSignalList { All, Others, - Ident(WithDecl) + Ident(WithDecl), } /// LRM 7.4 Disconnection specification diff --git a/vhdl_lang/src/ast/display.rs b/vhdl_lang/src/ast/display.rs index b827290a..0837d58c 100644 --- a/vhdl_lang/src/ast/display.rs +++ b/vhdl_lang/src/ast/display.rs @@ -1142,11 +1142,7 @@ impl Display for ConfigurationDeclaration { impl Display for DisconnectionSpecification { fn fmt(&self, f: &mut Formatter<'_>) -> Result { - if let Some(ident) = &self.ident { - write!(f, "disconnection {}", ident) - } else { - write!(f, "disconnection") - } + write!(f, "disconnection") } } diff --git a/vhdl_lang/src/ast/search.rs b/vhdl_lang/src/ast/search.rs index e033724b..5d93a8d3 100644 --- a/vhdl_lang/src/ast/search.rs +++ b/vhdl_lang/src/ast/search.rs @@ -67,6 +67,7 @@ pub enum FoundDeclaration<'a> { ConcurrentStatement(&'a LabeledConcurrentStatement), SequentialStatement(&'a LabeledSequentialStatement), View(&'a ModeViewDeclaration), + GuardedSignalListWithIdent(&'a WithDecl), } pub trait Searcher { @@ -1089,13 +1090,19 @@ impl Search for Declaration { } Declaration::Disconnection(disconnect) => { let DisconnectionSpecification { - ident: _, + ident, subtype_indication, expression, } = disconnect; + if let GuardedSignalList::Ident(ident) = ident { + return_if_found!(searcher + .search_decl(ctx, FoundDeclaration::GuardedSignalListWithIdent(ident)) + .or_not_found()); + } return_if_found!(subtype_indication.search(ctx, searcher)); return_if_found!(expression.search(ctx, searcher)); } + Declaration::View(view) => { return_if_found!(searcher .search_decl(ctx, FoundDeclaration::View(view)) @@ -1710,6 +1717,7 @@ impl<'a> FoundDeclaration<'a> { FoundDeclaration::SequentialStatement(..) => None, FoundDeclaration::SubprogramInstantiation(_) => None, FoundDeclaration::View(view) => view.end_ident_pos, + FoundDeclaration::GuardedSignalListWithIdent(..) => None, } } @@ -1745,6 +1753,7 @@ impl<'a> FoundDeclaration<'a> { FoundDeclaration::ConcurrentStatement(value) => &value.label.decl, FoundDeclaration::SequentialStatement(value) => &value.label.decl, FoundDeclaration::View(value) => &value.ident.decl, + FoundDeclaration::GuardedSignalListWithIdent(value) => &value.decl, } } } @@ -1852,6 +1861,9 @@ impl std::fmt::Display for FoundDeclaration<'_> { FoundDeclaration::GenerateBody(value) => { write!(f, "{value}") } + FoundDeclaration::GuardedSignalListWithIdent(value) => { + write!(f, "{value}") + } FoundDeclaration::ConcurrentStatement(value) => { if let Some(ref label) = value.label.tree { write!(f, "{label}") diff --git a/vhdl_lang/src/named_entity.rs b/vhdl_lang/src/named_entity.rs index 35bc38f1..2cf44e8d 100644 --- a/vhdl_lang/src/named_entity.rs +++ b/vhdl_lang/src/named_entity.rs @@ -7,10 +7,10 @@ use crate::ast::{ AliasDeclaration, AnyDesignUnit, AnyPrimaryUnit, AnySecondaryUnit, Attribute, AttributeDeclaration, AttributeSpecification, ComponentDeclaration, Declaration, Designator, - DisconnectionSpecification, FileDeclaration, HasIdent, Ident, InterfaceFileDeclaration, - InterfacePackageDeclaration, ModeViewDeclaration, ObjectClass, ObjectDeclaration, PackageBody, - PackageDeclaration, PackageInstantiation, SubprogramBody, SubprogramInstantiation, - SubprogramSpecification, TypeDeclaration, WithDecl, + DisconnectionSpecification, FileDeclaration, GuardedSignalList, HasIdent, Ident, + InterfaceFileDeclaration, InterfacePackageDeclaration, ModeViewDeclaration, ObjectClass, + ObjectDeclaration, PackageBody, PackageDeclaration, PackageInstantiation, SubprogramBody, + SubprogramInstantiation, SubprogramSpecification, TypeDeclaration, WithDecl, }; use crate::ast::{ExternalObjectClass, InterfaceDeclaration, InterfaceObjectDeclaration}; use crate::data::*; @@ -66,6 +66,7 @@ pub enum AnyEntKind<'a> { Library, Design(Design<'a>), View(Subtype<'a>), + Disconnection(Subtype<'a>), } impl<'a> AnyEntKind<'a> { @@ -129,6 +130,7 @@ impl<'a> AnyEntKind<'a> { Design(design) => design.describe(), Type(typ) => typ.describe(), View(..) => "view", + Disconnection(..) => "disconnection", } } } @@ -662,7 +664,10 @@ impl HasEntityId for PackageDeclaration { impl HasEntityId for DisconnectionSpecification { fn ent_id(&self) -> Option { - self.ident.as_ref().and_then(|ident| ident.decl.get()) + match &self.ident { + GuardedSignalList::Ident(with_decl) => with_decl.decl.get(), + _ => None, + } } } diff --git a/vhdl_lang/src/syntax/declarative_part.rs b/vhdl_lang/src/syntax/declarative_part.rs index 8c9dfd00..919d80ab 100644 --- a/vhdl_lang/src/syntax/declarative_part.rs +++ b/vhdl_lang/src/syntax/declarative_part.rs @@ -190,9 +190,15 @@ pub fn parse_declarative_part( } Disconnect => { - match parse_disconnection_specification(ctx).or_recover_until(ctx, is_recover_token) - { - Ok(decl) => declarations.push(decl.map_into(Declaration::Disconnection)), + let decls: ParseResult>> = + parse_disconnection_specification(ctx).map(|decls| { + decls + .into_iter() + .map(|decl| decl.map_into(Declaration::Disconnection)) + .collect() + }); + match decls.or_recover_until(ctx, is_recover_token) { + Ok(ref mut decls) => declarations.append(decls), Err(err) => { ctx.diagnostics.push(err); continue; diff --git a/vhdl_lang/src/syntax/disconnection.rs b/vhdl_lang/src/syntax/disconnection.rs index 03f4c02b..e5536f03 100644 --- a/vhdl_lang/src/syntax/disconnection.rs +++ b/vhdl_lang/src/syntax/disconnection.rs @@ -6,34 +6,38 @@ use super::common::ParseResult; use super::expression::parse_expression; -//use super::separated_list::parse_ident_list; use super::tokens::{Kind::*, TokenSpan}; use crate::ast::token_range::WithTokenSpan; use crate::ast::*; -use crate::syntax::declarative_part::is_recover_token; use crate::syntax::subtype_indication::parse_subtype_indication; -use crate::syntax::Kind; use vhdl_lang::syntax::parser::ParsingContext; /// LRM 7.4 Disconnection Specification pub fn parse_disconnection_specification( ctx: &mut ParsingContext<'_>, -) -> ParseResult> { +) -> ParseResult>> { let start_token = ctx.stream.expect_kind(Disconnect)?; - - let ident = GuardedSignalList::All; + let mut idents: Vec = Vec::new(); if let Some(token) = ctx.stream.peek() { match token.kind { All => { + idents.push(GuardedSignalList::All); ctx.stream.skip(); } Others => { - let ident = GuardedSignalList::Others; + idents.push(GuardedSignalList::Others); ctx.stream.skip(); } - _ => { // Identifier - let ident = WithDecl::new(ctx.stream.expect_ident()?); - } + _ => loop { + idents.push(GuardedSignalList::Ident(WithDecl::new( + ctx.stream.expect_ident()?, + ))); + if ctx.stream.next_kind_is(Comma) { + ctx.stream.skip(); + } else { + break; + } + }, } } @@ -42,177 +46,170 @@ pub fn parse_disconnection_specification( ctx.stream.expect_kind(After)?; let expression = parse_expression(ctx)?; let end_token = ctx.stream.expect_kind(SemiColon)?; - Ok(WithTokenSpan::new( - DisconnectionSpecification { - ident, - subtype_indication, - expression, - }, - TokenSpan::new(start_token, end_token), - )) + + Ok(idents + .into_iter() + .map(|ident| { + WithTokenSpan::new( + DisconnectionSpecification { + ident, + subtype_indication: subtype_indication.clone(), + expression: expression.clone(), + }, + TokenSpan::new(start_token, end_token), + ) + }) + .collect()) } -//#[cfg(test)] -//mod tests { -// use super::*; -// -// use crate::data::Diagnostic; -// use crate::syntax::test::{check_diagnostics, Code}; -// #[test] -// fn disconnect_spec_with_scalar_or_composite_signal() { -// let code = Code::new( -// "\ -//disconnect S: T after 42 ms; -//", -// ); -// assert_eq!( -// code.with_stream_no_diagnostics(parse_disconnection_specification), -// WithTokenSpan::new( -// DisconnectionSpecification { -// ident: code.s1("S").decl_ident(), -// subtype_indication: Some(code.s1("T").subtype_indication()), -// expression: Some(code.s1("42 ms").expr()), -// }, -// code.token_span() -// ) -// ) -// } -// -// #[test] -// fn disconnect_spec_with_scalar_or_composite_signal_variant() { -// let code = Code::new( -// "\ -//disconnect foobar : integer after 100*CLK_PERIOD; -//", -// ); -// assert_eq!( -// code.with_stream_no_diagnostics(parse_disconnection_specification), -// WithTokenSpan::new( -// DisconnectionSpecification { -// ident: Some(code.s1("foobar").decl_ident()), -// subtype_indication: Some(code.s1("integer").subtype_indication()), -// expression: Some(code.s1("100*CLK_PERIOD").expr()), -// }, -// code.token_span() -// ) -// ) -// } -// -// #[test] -// fn disconnect_spec_explicit_with_others() { -// let code = Code::new( -// "\ -//disconnect others: std_logic after bar; -//", -// ); -// assert_eq!( -// code.with_stream_no_diagnostics(parse_disconnection_specification), -// WithTokenSpan::new( -// DisconnectionSpecification { -// ident: None, -// subtype_indication: Some(code.s1("std_logic").subtype_indication()), -// expression: Some(code.s1("bar").expr()), -// }, -// code.token_span() -// ) -// ) -// } -// -// #[test] -// fn disconnect_spec_explicit_with_all() { -// let code = Code::new( -// "\ -//disconnect all : unsigned(3 downto 0) after bar; -//", -// ); -// assert_eq!( -// code.with_stream_no_diagnostics(parse_disconnection_specification), -// WithTokenSpan::new( -// DisconnectionSpecification { -// ident: None, -// subtype_indication: Some(code.s1("unsigned(3 downto 0)").subtype_indication()), -// expression: Some(code.s1("bar").expr()), -// }, -// code.token_span() -// ) -// ) -// } -// -// #[test] -// fn disconnect_spec_syntax_error_1() { -// let code = Code::new( -// "\ -//disconnect ; T after 42 ms; -//", -// ); -// let (_, diag) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// check_diagnostics( -// diag, -// vec![Diagnostic::syntax_error( -// code.s1(";").pos(), -// "Expected '{identifier}', 'all' or 'others'", -// )], -// ); -// } -// -// #[test] -// fn disconnect_spec_syntax_error_2() { -// let code = Code::new( -// "\ -//disconnect 7 after 42 ms; -//", -// ); -// let (_, diag) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// check_diagnostics( -// diag, -// vec![Diagnostic::syntax_error( -// code.s1("7").pos(), -// "Expected '{identifier}', 'all' or 'others'", -// )], -// ); -// } -// -// #[test] -// fn disconnect_spec_syntax_error_3() { -// let code = Code::new( -// "\ -//disconnect foo after 42 ms; -//", -// ); -// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// assert!(decl.is_err()); -// } -// -// #[test] -// fn disconnect_spec_syntax_error_4() { -// let code = Code::new( -// "\ -//disconnect foo : std_logic afterrr 42 ms; -//", -// ); -// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// assert!(decl.is_err()); -// } -// -// #[test] -// fn disconnect_spec_syntax_error_5() { -// let code = Code::new( -// "\ -//disconnect foo : after 42 ms bar; -//", -// ); -// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// assert!(decl.is_err()); -// } -// -// #[test] -// fn disconnect_spec_syntax_error_6() { -// let code = Code::new( -// "\ -//diconnect foo : after 42 ms; -//", -// ); -// let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); -// assert!(decl.is_err()); -// } -//} +#[cfg(test)] +mod tests { + use super::*; + + use crate::syntax::test::Code; + #[test] + fn disconnect_spec_with_scalar_or_composite_signal() { + let code = Code::new( + "\ + disconnect S: T after 42 ms; + ", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification)[0], + WithTokenSpan::new( + DisconnectionSpecification { + ident: GuardedSignalList::Ident(WithDecl::new(code.s1("S").ident())), + subtype_indication: code.s1("T").subtype_indication(), + expression: code.s1("42 ms").expr(), + }, + code.token_span() + ) + ) + } + + #[test] + fn disconnect_spec_with_scalar_or_composite_signal_variant() { + let code = Code::new( + "\ + disconnect foobar : integer after 100*CLK_PERIOD; + ", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification)[0], + WithTokenSpan::new( + DisconnectionSpecification { + ident: GuardedSignalList::Ident(WithDecl::new(code.s1("foobar").ident())), + subtype_indication: code.s1("integer").subtype_indication(), + expression: code.s1("100*CLK_PERIOD").expr(), + }, + code.token_span() + ) + ) + } + + #[test] + fn disconnect_spec_explicit_with_others() { + let code = Code::new( + "\ + disconnect others: std_logic after bar; + ", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification)[0], + WithTokenSpan::new( + DisconnectionSpecification { + ident: GuardedSignalList::Others, + subtype_indication: code.s1("std_logic").subtype_indication(), + expression: code.s1("bar").expr(), + }, + code.token_span() + ) + ) + } + + #[test] + fn disconnect_spec_explicit_with_all() { + let code = Code::new( + "\ + disconnect all : unsigned(3 downto 0) after bar; + ", + ); + assert_eq!( + code.with_stream_no_diagnostics(parse_disconnection_specification)[0], + WithTokenSpan::new( + DisconnectionSpecification { + ident: GuardedSignalList::All, + subtype_indication: code.s1("unsigned(3 downto 0)").subtype_indication(), + expression: code.s1("bar").expr(), + }, + code.token_span() + ) + ) + } + + #[test] + fn disconnect_spec_syntax_error_1() { + let code = Code::new( + "\ +disconnect ; T after 42 ms; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } + + #[test] + fn disconnect_spec_syntax_error_2() { + let code = Code::new( + "\ +disconnect 7 after 42 ms; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } + + #[test] + fn disconnect_spec_syntax_error_3() { + let code = Code::new( + "\ +disconnect foo after 42 ms; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } + + #[test] + fn disconnect_spec_syntax_error_4() { + let code = Code::new( + "\ +disconnect foo : std_logic afterrr 42 ms; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } + + #[test] + fn disconnect_spec_syntax_error_5() { + let code = Code::new( + "\ +disconnect foo : after 42 ms bar; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } + + #[test] + fn disconnect_spec_syntax_error_6() { + let code = Code::new( + "\ +diconnect foo : after 42 ms; +", + ); + let (decl, _) = code.with_partial_stream_diagnostics(parse_disconnection_specification); + assert!(decl.is_err()); + } +} diff --git a/vhdl_ls/src/vhdl_server.rs b/vhdl_ls/src/vhdl_server.rs index 38877cf8..788ca5f8 100644 --- a/vhdl_ls/src/vhdl_server.rs +++ b/vhdl_ls/src/vhdl_server.rs @@ -900,6 +900,7 @@ fn entity_kind_to_completion_kind(kind: &AnyEntKind) -> CompletionItemKind { AnyEntKind::Library => CompletionItemKind::MODULE, AnyEntKind::Design(_) => CompletionItemKind::MODULE, AnyEntKind::View(_) => CompletionItemKind::INTERFACE, + AnyEntKind::Disconnection(_) => CompletionItemKind::FIELD, } } @@ -1125,6 +1126,7 @@ fn to_symbol_kind(kind: &AnyEntKind) -> SymbolKind { AnyEntKind::Concurrent(_) => SymbolKind::NAMESPACE, AnyEntKind::Library => SymbolKind::NAMESPACE, AnyEntKind::View(_) => SymbolKind::INTERFACE, + AnyEntKind::Disconnection(_) => SymbolKind::FIELD, AnyEntKind::Design(d) => match d { vhdl_lang::Design::Entity(_, _) => SymbolKind::MODULE, vhdl_lang::Design::Architecture(_) => SymbolKind::MODULE,