Skip to content

Commit b95355f

Browse files
committed
Use library_name for find implementation and add test
1 parent 20ddaae commit b95355f

File tree

5 files changed

+91
-46
lines changed

5 files changed

+91
-46
lines changed

vhdl_lang/src/analysis/named_entity.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,20 @@ impl<'a> AnyEnt<'a> {
289289
self.decl_pos.as_ref()
290290
}
291291

292+
pub fn library_name(&self) -> Option<&Symbol> {
293+
if let AnyEntKind::Library = self.kind() {
294+
if let Designator::Identifier(symbol) = self.designator() {
295+
return Some(symbol);
296+
}
297+
}
298+
299+
if let Some(parent) = self.parent {
300+
parent.library_name()
301+
} else {
302+
None
303+
}
304+
}
305+
292306
pub fn designator(&self) -> &Designator {
293307
&self.designator
294308
}

vhdl_lang/src/analysis/root.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,36 @@ impl DesignRoot {
398398
}
399399
}
400400

401+
pub fn find_implementation<'a>(&'a self, ent: EntRef<'a>) -> Vec<EntRef<'a>> {
402+
if let Designator::Identifier(ident) = ent.designator() {
403+
if let Some(library_name) = ent.library_name() {
404+
match ent.kind() {
405+
// Find entity with same name as component in the library
406+
AnyEntKind::Component(_) => {
407+
if let Some(design) = self.get_design_entity(library_name, ident) {
408+
return vec![design.into()];
409+
}
410+
}
411+
// Find all components with same name as entity in the library
412+
AnyEntKind::Design(Design::Entity(..)) => {
413+
let mut searcher = FindAllEnt::new(self, |ent| {
414+
matches!(ent.kind(), AnyEntKind::Component(_))
415+
&& matches!(
416+
ent.designator(),
417+
Designator::Identifier(comp_ident) if comp_ident == ident
418+
)
419+
});
420+
421+
let _ = self.search_library(library_name, &mut searcher);
422+
return searcher.result;
423+
}
424+
_ => {}
425+
}
426+
}
427+
}
428+
Vec::default()
429+
}
430+
401431
#[cfg(test)]
402432
pub fn search_reference_pos(&self, source: &Source, cursor: Position) -> Option<SrcPos> {
403433
self.search_reference(source, cursor)

vhdl_lang/src/analysis/tests/hierarchy.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,43 @@ fn hierarchy(ent: EntRef) -> String {
163163
ent.designator().to_string()
164164
}
165165
}
166+
167+
#[test]
168+
fn find_implementation_of_entity_vs_component() {
169+
let mut builder = LibraryBuilder::new();
170+
let code = builder.code(
171+
"libname",
172+
"
173+
entity ent0 is
174+
end entity;
175+
176+
architecture a of ent0 is
177+
begin
178+
end architecture;
179+
180+
entity ent1 is
181+
end entity;
182+
183+
architecture a of ent1 is
184+
component ent0 is
185+
end component;
186+
begin
187+
inst: ent0;
188+
end architecture;
189+
190+
",
191+
);
192+
193+
let (root, diagnostics) = builder.get_analyzed_root();
194+
check_no_diagnostics(&diagnostics);
195+
196+
let ent = root
197+
.search_reference(code.source(), code.s1("ent0").start())
198+
.unwrap();
199+
let comp = root
200+
.search_reference(code.source(), code.sa("component ", "ent0").start())
201+
.unwrap();
202+
203+
assert_eq!(root.find_implementation(ent), vec![comp]);
204+
assert_eq!(root.find_implementation(comp), vec![ent]);
205+
}

vhdl_lang/src/project.rs

Lines changed: 6 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@
44
//
55
// Copyright (c) 2018, Olof Kraigher olof.kraigher@gmail.com
66

7-
use crate::analysis::{AnyEnt, AnyEntKind, Design, DesignRoot, EntRef};
8-
use crate::ast::search::FindAllEnt;
9-
use crate::ast::{DesignFile, Designator};
7+
use crate::analysis::{AnyEnt, DesignRoot, EntRef};
8+
use crate::ast::DesignFile;
109
use crate::config::Config;
1110
use crate::data::*;
1211
use crate::syntax::VHDLParser;
@@ -241,49 +240,11 @@ impl Project {
241240
self.root.item_at_cursor(source, cursor)
242241
}
243242

244-
fn get_library(&self, source: &Source) -> Option<Symbol> {
245-
let file = self.files.get(source.file_name())?;
246-
file.library_names.iter().next().cloned()
247-
}
248-
249-
pub fn find_implementation<'a>(
250-
&'a self,
251-
source: &Source,
252-
cursor: Position,
253-
) -> Option<Vec<EntRef<'a>>> {
254-
let ent = self.find_declaration(source, cursor)?;
255-
256-
let ident = if let Designator::Identifier(ident) = ent.designator() {
257-
ident
243+
pub fn find_implementation<'a>(&'a self, source: &Source, cursor: Position) -> Vec<EntRef<'a>> {
244+
if let Some(ent) = self.find_declaration(source, cursor) {
245+
self.root.find_implementation(ent)
258246
} else {
259-
return None;
260-
};
261-
262-
match ent.kind() {
263-
// Find entity with same name as component in the library
264-
AnyEntKind::Component(_) => {
265-
let decl_pos = ent.decl_pos()?;
266-
let library_name = self.get_library(decl_pos.source())?;
267-
let design = self.root.get_design_entity(&library_name, ident)?;
268-
Some(vec![design.into()])
269-
}
270-
// Find all components with same name as entity in the library
271-
AnyEntKind::Design(Design::Entity(..)) => {
272-
let decl_pos = ent.decl_pos()?;
273-
let library_name = self.get_library(decl_pos.source())?;
274-
275-
let mut searcher = FindAllEnt::new(&self.root, |ent| {
276-
matches!(ent.kind(), AnyEntKind::Component(_))
277-
&& matches!(
278-
ent.designator(),
279-
Designator::Identifier(comp_ident) if comp_ident == ident
280-
)
281-
});
282-
283-
let _ = self.root.search_library(&library_name, &mut searcher);
284-
Some(searcher.result)
285-
}
286-
_ => None,
247+
Vec::default()
287248
}
288249
}
289250

vhdl_ls/src/vhdl_server.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -362,7 +362,7 @@ impl VHDLServer {
362362

363363
let ents = self
364364
.project
365-
.find_implementation(&source, from_lsp_pos(params.position))?;
365+
.find_implementation(&source, from_lsp_pos(params.position));
366366

367367
Some(GotoDefinitionResponse::Array(
368368
ents.into_iter()

0 commit comments

Comments
 (0)