Skip to content
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions vhdl_lang/src/analysis/declarative.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ impl Declaration {
| SubprogramBody(_)
| Use(_)
| Package(_)
| PackageDeclaration(_)
| PackageBody(_)
| Configuration(_)
| Disconnection(_)
| View(_)
),
// LRM: configuration_declarative_item
Expand All @@ -61,6 +64,9 @@ impl Declaration {
| SubprogramBody(_)
| Use(_)
| Package(_)
| PackageDeclaration(_)
| PackageBody(_)
| Disconnection(_)
| View(_)
),
// LRM: package_body_declarative_item
Expand All @@ -72,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 {
Expand All @@ -86,6 +93,8 @@ impl Declaration {
| SubprogramBody(_)
| Use(_)
| Package(_)
| PackageDeclaration(_)
| PackageBody(_)
),
// LRM: package_declarative_item
AnyEntKind::Design(Design::Package(..)) => matches!(
Expand All @@ -100,6 +109,8 @@ impl Declaration {
| SubprogramInstantiation(_)
| Use(_)
| Package(_)
| PackageDeclaration(_)
| Disconnection(_)
| View(_)
),
_ => {
Expand Down Expand Up @@ -606,7 +617,14 @@ impl<'a, 't> AnalyzeContext<'a, 't> {
scope.add(ent, diagnostics);
}
}
Declaration::PackageDeclaration(ref mut unit) => {
self.analyze_package(unit, diagnostics)?;
}
Declaration::PackageBody(ref mut unit) => {
self.analyze_package_body(unit, diagnostics)?;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This (and the package declaration analysis) is fine, but I think that this declares them in the global namespace. As I have written in the second comment, check that this is correct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will try to resolve this next tomorrow or so. It is not exactly easy to interpret what the LRM really means, I have to say lol.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, one of the hardest parts of developing a VHDL language server is interpreting the LRM :P

}
Declaration::Configuration(..) => {}
Declaration::Disconnection(..) => {} // @TODO
Declaration::View(view) => {
if let Some(view) = as_fatal(self.analyze_view_declaration(
scope,
Expand Down
4 changes: 2 additions & 2 deletions vhdl_lang/src/analysis/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
3 changes: 3 additions & 0 deletions vhdl_lang/src/analysis/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1845,7 +1845,10 @@ impl Declaration {
Declaration::SubprogramBody(_) => "subprogram body",
Declaration::Use(_) => "use",
Declaration::Package(_) => "package instantiation",
Declaration::PackageDeclaration(_) => "package",
Declaration::PackageBody(_) => "package body",
Declaration::Configuration(_) => "configuration",
Declaration::Disconnection(_) => "disconnection",
Declaration::View(_) => "view",
}
}
Expand Down
7 changes: 7 additions & 0 deletions vhdl_lang/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -852,7 +852,10 @@ pub enum Declaration {
SubprogramBody(SubprogramBody),
Use(UseClause),
Package(PackageInstantiation),
PackageDeclaration(PackageDeclaration),
PackageBody(PackageBody),
Configuration(ConfigurationSpecification),
Disconnection(DisconnectionSpecification),
View(ModeViewDeclaration),
}

Expand Down Expand Up @@ -1375,6 +1378,10 @@ pub struct ConfigurationSpecification {
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
}

/// LRM 7.4 Disconnection specification
#[derive(PartialEq, Debug, Clone)]
pub struct DisconnectionSpecification {}

/// LRM 3.4 Configuration declarations
#[derive(PartialEq, Debug, Clone)]
pub enum ConfigurationDeclarativeItem {
Expand Down
11 changes: 9 additions & 2 deletions vhdl_lang/src/ast/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1075,14 +1075,21 @@ 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 decl) => {
return_if_found!(decl.search(ctx, searcher));
}
Declaration::PackageBody(ref body) => {
return_if_found!(body.search(ctx, searcher));
}
Declaration::Configuration(_) => {
// @TODO
}
Declaration::Disconnection(_) => {
// @TODO
}
Declaration::View(view) => {
return_if_found!(searcher
.search_decl(ctx, FoundDeclaration::View(view))
Expand Down
20 changes: 18 additions & 2 deletions vhdl_lang/src/named_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;
Expand Down Expand Up @@ -631,8 +632,11 @@ impl HasEntityId for Declaration {
Declaration::SubprogramBody(body) => body.ent_id(),
Declaration::SubprogramInstantiation(decl) => decl.ent_id(),
Declaration::Package(pkg) => pkg.ent_id(),
Declaration::PackageDeclaration(pkg) => pkg.ent_id(),
Declaration::PackageBody(pkg) => pkg.ent_id(),
Declaration::Use(_) => None,
Declaration::Configuration(_) => None,
Declaration::Disconnection(_) => None, // TODO
Declaration::View(decl) => decl.ent_id(),
}
}
Expand All @@ -650,6 +654,18 @@ impl HasEntityId for PackageInstantiation {
}
}

impl HasEntityId for PackageDeclaration {
fn ent_id(&self) -> Option<EntityId> {
self.ident.decl.get()
}
}

impl HasEntityId for PackageBody {
fn ent_id(&self) -> Option<EntityId> {
self.ident.decl.get()
}
}

impl HasEntityId for SubprogramBody {
fn ent_id(&self) -> Option<EntityId> {
self.specification.ent_id()
Expand Down
1 change: 1 addition & 0 deletions vhdl_lang/src/syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ mod configuration;
mod context;
mod declarative_part;
mod design_unit;
mod disconnection;
mod expression;
mod interface_declaration;
mod names;
Expand Down
37 changes: 36 additions & 1 deletion vhdl_lang/src/syntax/declarative_part.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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_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;
Expand All @@ -18,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;

Expand Down Expand Up @@ -62,6 +64,7 @@ pub fn is_declarative_part(ctx: &mut ParsingContext) -> ParseResult<bool> {
| For
| View
| Begin
| Disconnect
))
}

Expand Down Expand Up @@ -92,6 +95,7 @@ pub fn parse_declarative_part(
| Alias
| Begin
| End
| Disconnect
)
}

Expand All @@ -104,7 +108,15 @@ 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 if ctx.stream.next_kinds_are(&[Package, Body]) {
parse_package_body(ctx).map(Declaration::PackageBody)?
} else {
parse_package_declaration(ctx).map(Declaration::PackageDeclaration)?
}
}
For => {
parse_configuration_specification(ctx).map(Declaration::Configuration)?
}
Expand Down Expand Up @@ -177,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 {
Expand Down Expand Up @@ -332,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);
}
}
36 changes: 36 additions & 0 deletions vhdl_lang/src/syntax/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -933,4 +933,40 @@ end entity y;
assert_eq!(tok.kind, Context);
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);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test also doesn't do much. It just checks that the tokeniser works, but this is already tested elsewhere. Here, you should check that the AST matches, i.e., that if you parse that snippet, you will find an architecture declaration with package and package body inside. I think you can also omit the entity and just parse the architecture.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I need a little help here. I have tried to do what you said but I find it very hard to fill a default ArchitectureBody with the necessary values. The other tests use this simple_architecture, but I don't think this helps me much. I have put the test I thought of in comments.

}
Loading