Skip to content

Commit

Permalink
Merge pull request #202 from Schottkyc137/refactor-map-aspect
Browse files Browse the repository at this point in the history
Refactor: Vector of AssociationElements to MapAspect
  • Loading branch information
kraigher authored Oct 9, 2023
2 parents 0c9f487 + d208e6f commit f5aa115
Show file tree
Hide file tree
Showing 16 changed files with 256 additions and 151 deletions.
44 changes: 36 additions & 8 deletions vhdl_lang/src/analysis/concurrent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ impl<'a> AnalyzeContext<'a> {
self.analyze_interface_list(&nested, parent, list, diagnostics)?;
}
if let Some(ref mut list) = block.header.generic_map {
self.analyze_assoc_elems(scope, list, diagnostics)?;
self.analyze_assoc_elems(scope, &mut list.list.items[..], diagnostics)?;
}
if let Some(ref mut list) = block.header.port_clause {
self.analyze_interface_list(&nested, parent, list, diagnostics)?;
}
if let Some(ref mut list) = block.header.port_map {
self.analyze_assoc_elems(scope, list, diagnostics)?;
self.analyze_assoc_elems(scope, &mut list.list.items[..], diagnostics)?;
}

self.define_labels_for_concurrent_part(
Expand Down Expand Up @@ -288,14 +288,22 @@ impl<'a> AnalyzeContext<'a> {
&entity_name.pos,
&generic_region,
scope,
&mut instance.generic_map,
instance
.generic_map
.as_mut()
.map(|it| it.list.items.as_mut_slice())
.unwrap_or(&mut []),
diagnostics,
)?;
self.analyze_assoc_elems_with_formal_region(
&entity_name.pos,
&port_region,
scope,
&mut instance.port_map,
instance
.port_map
.as_mut()
.map(|it| it.list.items.as_mut_slice())
.unwrap_or(&mut []),
diagnostics,
)?;
Ok(())
Expand Down Expand Up @@ -326,14 +334,22 @@ impl<'a> AnalyzeContext<'a> {
&component_name.pos,
&generic_region,
scope,
&mut instance.generic_map,
instance
.generic_map
.as_mut()
.map(|it| it.list.items.as_mut_slice())
.unwrap_or(&mut []),
diagnostics,
)?;
self.analyze_assoc_elems_with_formal_region(
&component_name.pos,
&port_region,
scope,
&mut instance.port_map,
instance
.port_map
.as_mut()
.map(|it| it.list.items.as_mut_slice())
.unwrap_or(&mut []),
diagnostics,
)?;
Ok(())
Expand Down Expand Up @@ -366,14 +382,26 @@ impl<'a> AnalyzeContext<'a> {
err.add_to(diagnostics)?;
}

self.analyze_assoc_elems(scope, &mut instance.generic_map, diagnostics)?;
self.analyze_assoc_elems(scope, &mut instance.port_map, diagnostics)?;
self.analyze_map_aspect(scope, &mut instance.generic_map, diagnostics)?;
self.analyze_map_aspect(scope, &mut instance.port_map, diagnostics)?;
}
};

Ok(())
}

pub fn analyze_map_aspect(
&self,
scope: &Scope<'a>,
map: &mut Option<MapAspect>,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
let Some(aspect) = map else {
return Ok(());
};
self.analyze_assoc_elems(scope, aspect.list.items.as_mut_slice(), diagnostics)
}

pub fn sensitivity_list_check(
&self,
scope: &Scope<'a>,
Expand Down
6 changes: 3 additions & 3 deletions vhdl_lang/src/analysis/design_unit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ impl<'a> AnalyzeContext<'a> {
ContextItem::Library(LibraryClause {
ref mut name_list, ..
}) => {
for library_name in name_list.items_mut() {
for library_name in name_list.items.iter_mut() {
if self.work_sym == library_name.item.item {
library_name.set_unique_reference(self.work_library());
diagnostics.push(Diagnostic::hint(
Expand All @@ -503,7 +503,7 @@ impl<'a> AnalyzeContext<'a> {
ContextItem::Context(ContextReference {
ref mut name_list, ..
}) => {
for name in name_list.items_mut() {
for name in name_list.items.iter_mut() {
match name.item {
Name::Selected(..) => {}
_ => {
Expand Down Expand Up @@ -560,7 +560,7 @@ impl<'a> AnalyzeContext<'a> {
use_clause: &mut UseClause,
diagnostics: &mut dyn DiagnosticHandler,
) -> FatalResult {
for name in use_clause.name_list.items_mut() {
for name in use_clause.name_list.items.iter_mut() {
match name.item {
Name::Selected(..) => {}
Name::SelectedAll(..) => {}
Expand Down
5 changes: 3 additions & 2 deletions vhdl_lang/src/analysis/named_entity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,8 +411,9 @@ impl<'a> AnyEnt<'a> {
#[allow(clippy::mut_from_ref)]
unsafe fn unsafe_ref_mut(&self) -> &mut Self {
// NOTE: Use read_volatile to prevent compiler to optimization away assignment to the returned reference
let mut_self: *mut AnyEnt = std::ptr::read_volatile(&self) as *const AnyEnt as *mut AnyEnt;
&mut *mut_self
let const_ptr = std::ptr::read_volatile(&self) as *const Self;
let mut_ptr = const_ptr as *mut Self;
&mut *mut_ptr
}

// Used to update the kind of pre-declared symbols that are visible before they have been fully analyzed
Expand Down
7 changes: 6 additions & 1 deletion vhdl_lang/src/analysis/package_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,12 @@ impl<'a> AnalyzeContext<'a> {
let (generics, other) = package_region.to_package_generic();

let mapping = if let Some(generic_map) = generic_map {
self.package_generic_map(&nested, generics, generic_map, diagnostics)?
self.package_generic_map(
&nested,
generics,
generic_map.list.items.as_mut_slice(),
diagnostics,
)?
} else {
FnvHashMap::default()
};
Expand Down
66 changes: 44 additions & 22 deletions vhdl_lang/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,10 @@ pub mod search;
pub use self::display::*;
pub(crate) use self::util::*;
pub(crate) use any_design_unit::*;
use std::iter;

use crate::analysis::EntityId;
use crate::data::*;
use crate::syntax::{Token, TokenId};
use crate::syntax::{Token, TokenAccess, TokenId};

/// LRM 15.8 Bit string literals
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
Expand Down Expand Up @@ -697,7 +696,7 @@ pub enum SubprogramDefault {
/// LRM 6.5.5 Interface package declaration
#[derive(PartialEq, Debug, Clone)]
pub enum InterfacePackageGenericMapAspect {
Map(Vec<AssociationElement>),
Map(SeparatedList<AssociationElement>),
Box,
Default,
}
Expand Down Expand Up @@ -969,9 +968,9 @@ pub struct BlockStatement {
#[derive(PartialEq, Debug, Clone)]
pub struct BlockHeader {
pub generic_clause: Option<Vec<InterfaceDeclaration>>,
pub generic_map: Option<Vec<AssociationElement>>,
pub generic_map: Option<MapAspect>,
pub port_clause: Option<Vec<InterfaceDeclaration>>,
pub port_map: Option<Vec<AssociationElement>>,
pub port_map: Option<MapAspect>,
}

#[derive(PartialEq, Debug, Clone)]
Expand Down Expand Up @@ -1022,12 +1021,32 @@ pub enum InstantiatedUnit {
Configuration(WithPos<SelectedName>),
}

#[derive(PartialEq, Debug, Clone)]
pub struct MapAspect {
pub start: TokenId, // `generic` or `map`
pub list: SeparatedList<AssociationElement>,
pub closing_paren: TokenId,
}

impl MapAspect {
/// Returns an iterator over the formal elements of this map
pub fn formals(&self) -> impl Iterator<Item = &Designator> {
self.list.formals()
}

/// Returns the span that this aspect encompasses
pub fn span(&self, ctx: &dyn TokenAccess) -> SrcPos {
ctx.get_span(self.start, self.closing_paren)
}
}

/// 11.7 Component instantiation statements
#[derive(PartialEq, Debug, Clone)]
pub struct InstantiationStatement {
pub unit: InstantiatedUnit,
pub generic_map: Vec<AssociationElement>,
pub port_map: Vec<AssociationElement>,
pub generic_map: Option<MapAspect>,
pub port_map: Option<MapAspect>,
pub semicolon: TokenId,
}

/// 11.8 Generate statements
Expand Down Expand Up @@ -1092,23 +1111,26 @@ pub struct LibraryClause {
/// Represents a token-separated list of some generic type `T`
#[derive(PartialEq, Debug, Clone)]
pub struct SeparatedList<T> {
pub first: T,
pub remainder: Vec<(TokenId, T)>,
pub items: Vec<T>,
pub tokens: Vec<TokenId>,
}

impl SeparatedList<AssociationElement> {
/// Returns an iterator over the formal elements of this list
pub fn formals(&self) -> impl Iterator<Item = &Designator> {
self.items.iter().filter_map(|el| match &el.formal {
None => None,
Some(name) => match &name.item {
Name::Designator(desi) => Some(&desi.item),
_ => None,
},
})
}
}

pub type IdentList = SeparatedList<WithRef<Ident>>;
pub type NameList = SeparatedList<WithPos<Name>>;

impl<T> SeparatedList<T> {
pub fn items(&self) -> impl Iterator<Item = &T> {
iter::once(&self.first).chain(self.remainder.iter().map(|it| &it.1))
}

pub fn items_mut(&mut self) -> impl Iterator<Item = &mut T> {
iter::once(&mut self.first).chain(self.remainder.iter_mut().map(|it| &mut it.1))
}
}

/// LRM 12.4. Use clauses
#[derive(PartialEq, Debug, Clone)]
pub struct UseClause {
Expand Down Expand Up @@ -1147,7 +1169,7 @@ pub struct PackageInstantiation {
pub context_clause: ContextClause,
pub ident: WithDecl<Ident>,
pub package_name: WithPos<SelectedName>,
pub generic_map: Option<Vec<AssociationElement>>,
pub generic_map: Option<MapAspect>,
}

/// LRM 7.3 Configuration specification
Expand All @@ -1170,8 +1192,8 @@ pub enum EntityAspect {
#[derive(PartialEq, Debug, Clone)]
pub struct BindingIndication {
pub entity_aspect: Option<EntityAspect>,
pub generic_map: Option<Vec<AssociationElement>>,
pub port_map: Option<Vec<AssociationElement>>,
pub generic_map: Option<MapAspect>,
pub port_map: Option<MapAspect>,
}

/// LRM 7.3 Configuration specification
Expand Down
4 changes: 2 additions & 2 deletions vhdl_lang/src/ast/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -916,7 +916,7 @@ impl Display for InterfacePackageDeclaration {
match &self.generic_map {
InterfacePackageGenericMapAspect::Map(assoc_list) => {
let mut first = true;
for assoc in assoc_list {
for assoc in &assoc_list.items {
if first {
write!(f, "\n {assoc}")?;
} else {
Expand Down Expand Up @@ -1020,7 +1020,7 @@ impl Display for PackageInstantiation {
write!(f, "package {} is new {}", self.ident, self.package_name)?;
if let Some(assoc_list) = &self.generic_map {
let mut first = true;
for assoc in assoc_list {
for assoc in &assoc_list.list.items {
if first {
write!(f, "\n generic map (\n {assoc}")?;
} else {
Expand Down
10 changes: 8 additions & 2 deletions vhdl_lang/src/ast/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ impl Search for WithPos<Target> {

impl<T: Search> Search for SeparatedList<T> {
fn search(&mut self, ctx: &dyn TokenAccess, searcher: &mut impl Searcher) -> SearchResult {
for item in self.items_mut() {
for item in self.items.iter_mut() {
return_if_found!(item.search(ctx, searcher));
}
NotFound
Expand Down Expand Up @@ -1199,7 +1199,7 @@ impl Search for FunctionSpecification {

impl Search for LibraryClause {
fn search(&mut self, ctx: &dyn TokenAccess, searcher: &mut impl Searcher) -> SearchResult {
for name in self.name_list.items_mut() {
for name in self.name_list.items.iter_mut() {
return_if_found!(searcher
.search_pos_with_ref(ctx, &name.item.pos, &mut name.reference)
.or_not_found());
Expand Down Expand Up @@ -1343,6 +1343,12 @@ impl Search for CaseStatement {
}
}

impl Search for MapAspect {
fn search(&mut self, ctx: &dyn TokenAccess, searcher: &mut impl Searcher) -> SearchResult {
self.list.search(ctx, searcher)
}
}

// Search for reference to declaration/definition at cursor
pub struct ItemAtCursor {
source: Source,
Expand Down
Loading

0 comments on commit f5aa115

Please sign in to comment.