Skip to content

Commit e52a58a

Browse files
committed
Separate port and generic formals
1 parent c21cfac commit e52a58a

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

vhdl_lang/src/analysis/concurrent.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -198,16 +198,16 @@ impl<'a> AnalyzeContext<'a> {
198198
)?;
199199

200200
if let NamedEntityKind::Entity(ent_region) = ent.kind() {
201-
let formal_region = ent_region.to_entity_formal();
201+
let (generic_region, port_region) = ent_region.to_entity_formal();
202202

203203
self.analyze_assoc_elems_with_formal_region(
204-
&formal_region,
204+
&generic_region,
205205
parent,
206206
&mut instance.generic_map,
207207
diagnostics,
208208
)?;
209209
self.analyze_assoc_elems_with_formal_region(
210-
&formal_region,
210+
&port_region,
211211
parent,
212212
&mut instance.port_map,
213213
diagnostics,
@@ -235,15 +235,15 @@ impl<'a> AnalyzeContext<'a> {
235235
)?;
236236

237237
if let NamedEntityKind::Component(ent_region) = ent.kind() {
238-
let formal_region = ent_region.to_entity_formal();
238+
let (generic_region, port_region) = ent_region.to_entity_formal();
239239
self.analyze_assoc_elems_with_formal_region(
240-
&formal_region,
240+
&generic_region,
241241
parent,
242242
&mut instance.generic_map,
243243
diagnostics,
244244
)?;
245245
self.analyze_assoc_elems_with_formal_region(
246-
&formal_region,
246+
&port_region,
247247
parent,
248248
&mut instance.port_map,
249249
diagnostics,

vhdl_lang/src/analysis/formal_region.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,13 @@
66

77
use std::sync::Arc;
88

9-
use crate::{ast::Designator, Diagnostic, SrcPos};
9+
use crate::{
10+
ast::{Designator, ObjectClass},
11+
Diagnostic, SrcPos,
12+
};
1013

1114
use super::{
12-
region::{NamedEntityKind, Object, Type, TypeEnt},
15+
region::{NamedEntityKind, Object, TypeEnt},
1316
NamedEntity,
1417
};
1518

@@ -40,11 +43,17 @@ impl InterfaceEnt {
4043
}
4144
}
4245

46+
pub fn is_signal(&self) -> bool {
47+
match self.ent.kind() {
48+
NamedEntityKind::Object(obj) => obj.class == ObjectClass::Signal,
49+
_ => false,
50+
}
51+
}
52+
4353
pub fn base_type(&self) -> &TypeEnt {
4454
match self.ent.kind() {
4555
NamedEntityKind::Object(obj) => obj.subtype.base_type(),
4656
NamedEntityKind::InterfaceFile(file_type) => file_type.base_type(),
47-
NamedEntityKind::Type(Type::Subtype(subtype)) => subtype.base_type(),
4857
_ => {
4958
unreachable!();
5059
}

vhdl_lang/src/analysis/region.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -253,19 +253,26 @@ impl<'a> Region<'a> {
253253
self
254254
}
255255

256-
pub fn to_entity_formal(&self) -> FormalRegion {
256+
pub fn to_entity_formal(&self) -> (FormalRegion, FormalRegion) {
257257
// @TODO separate generics and ports
258-
let mut entities = Vec::with_capacity(self.entities.len());
258+
let mut generics = Vec::with_capacity(self.entities.len());
259+
let mut ports = Vec::with_capacity(self.entities.len());
260+
259261
for ent in self.entities.values() {
260262
if let NamedEntities::Single(ent) = ent {
261263
if let Some(ent) = InterfaceEnt::from_any(ent.clone()) {
262-
entities.push(ent);
264+
if ent.is_signal() {
265+
ports.push(ent);
266+
} else {
267+
generics.push(ent);
268+
}
263269
}
264270
}
265271
}
266272
// Sorting by source file position gives declaration order
267-
entities.sort_by_key(|ent| ent.decl_pos().map(|pos| pos.range().start));
268-
FormalRegion::new(entities)
273+
generics.sort_by_key(|ent| ent.decl_pos().map(|pos| pos.range().start));
274+
ports.sort_by_key(|ent| ent.decl_pos().map(|pos| pos.range().start));
275+
(FormalRegion::new(generics), FormalRegion::new(ports))
269276
}
270277

271278
pub fn extend(region: &'a Region<'a>, parent: Option<&'a Region<'a>>) -> Region<'a> {

vhdl_lang/src/analysis/tests/association_formal.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,48 @@ end architecture;
150150
);
151151
}
152152

153+
#[test]
154+
fn does_not_mixup_ports_and_generics() {
155+
let mut builder = LibraryBuilder::new();
156+
let code = builder.code(
157+
"libname",
158+
"
159+
entity ent_inst is
160+
generic (
161+
thegeneric : boolean
162+
);
163+
port (
164+
theport : in boolean
165+
);
166+
end entity;
167+
168+
architecture a of ent_inst is
169+
begin
170+
end architecture;
171+
172+
entity ent is
173+
end entity;
174+
175+
architecture a of ent is
176+
signal sig : boolean;
177+
begin
178+
ent: entity work.ent_inst
179+
generic map (theport => sig)
180+
port map (thegeneric => 0);
181+
end architecture;
182+
",
183+
);
184+
185+
let diagnostics = builder.analyze();
186+
check_diagnostics(
187+
diagnostics,
188+
vec![
189+
Diagnostic::error(code.s("theport", 2), "No declaration of 'theport'"),
190+
Diagnostic::error(code.s("thegeneric", 2), "No declaration of 'thegeneric'"),
191+
],
192+
);
193+
}
194+
153195
#[test]
154196
fn resolve_port_and_surrounding_name() {
155197
let mut builder = LibraryBuilder::new();

0 commit comments

Comments
 (0)