Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add package declaration in declarative part #307

Draft
wants to merge 6 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all 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
48 changes: 48 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,43 @@ 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(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)?;

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(
scope,
Expand Down Expand Up @@ -1184,6 +1231,7 @@ fn get_entity_class(ent: EntRef) -> Option<EntityClass> {
Design::Context(_) => None,
},
AnyEntKind::View(_) => None,
AnyEntKind::Disconnection(_) => None,
}
}

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
5 changes: 5 additions & 0 deletions vhdl_lang/src/analysis/names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down Expand Up @@ -258,6 +259,7 @@ impl<'a> ResolvedName<'a> {
}
AnyEntKind::File(_)
| AnyEntKind::View(_)
| AnyEntKind::Disconnection(_)
| AnyEntKind::InterfaceFile(_)
| AnyEntKind::Component(_)
| AnyEntKind::Concurrent(_)
Expand Down Expand Up @@ -1845,7 +1847,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",
Schottkyc137 marked this conversation as resolved.
Show resolved Hide resolved
Declaration::View(_) => "view",
}
}
Expand Down
3 changes: 3 additions & 0 deletions vhdl_lang/src/analysis/package_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
})
}

Expand Down
102 changes: 101 additions & 1 deletion vhdl_lang/src/analysis/tests/declarations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) 2023, Olof Kraigher [email protected]
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;

Expand Down Expand Up @@ -100,3 +100,103 @@ 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_no_diagnostics(&builder.analyze())
}

#[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,
),
Diagnostic::new(
code.s1("bar"),
"No declaration of 'bar'",
ErrorCode::Unresolved,
),
],
)
}
19 changes: 19 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,22 @@ pub struct ConfigurationSpecification {
pub vunit_bind_inds: Vec<VUnitBindingIndication>,
}

/// LRM 7.4 Guarded Signal List
#[derive(PartialEq, Debug, Clone)]
pub enum GuardedSignalList {
All,
Others,
Ident(WithDecl<Ident>),
}

/// LRM 7.4 Disconnection specification
#[derive(PartialEq, Debug, Clone)]
pub struct DisconnectionSpecification {
pub ident: GuardedSignalList,
pub subtype_indication: SubtypeIndication,
pub expression: WithTokenSpan<Expression>,
}

/// LRM 3.4 Configuration declarations
#[derive(PartialEq, Debug, Clone)]
pub enum ConfigurationDeclarativeItem {
Expand Down
6 changes: 6 additions & 0 deletions vhdl_lang/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,12 @@ impl Display for ConfigurationDeclaration {
}
}

impl Display for DisconnectionSpecification {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "disconnection")
}
}

impl Display for EntityDeclaration {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
// Not used: context_clause, decl, statements
Expand Down
29 changes: 27 additions & 2 deletions vhdl_lang/src/ast/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub enum FoundDeclaration<'a> {
ConcurrentStatement(&'a LabeledConcurrentStatement),
SequentialStatement(&'a LabeledSequentialStatement),
View(&'a ModeViewDeclaration),
GuardedSignalListWithIdent(&'a WithDecl<Ident>),
}

pub trait Searcher {
Expand Down Expand Up @@ -1075,14 +1076,33 @@ 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(disconnect) => {
let DisconnectionSpecification {
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))
Expand Down Expand Up @@ -1697,6 +1717,7 @@ impl<'a> FoundDeclaration<'a> {
FoundDeclaration::SequentialStatement(..) => None,
FoundDeclaration::SubprogramInstantiation(_) => None,
FoundDeclaration::View(view) => view.end_ident_pos,
FoundDeclaration::GuardedSignalListWithIdent(..) => None,
}
}

Expand Down Expand Up @@ -1732,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,
}
}
}
Expand Down Expand Up @@ -1839,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}")
Expand Down
Loading
Loading