Skip to content

Commit

Permalink
Add architectures to entity completion
Browse files Browse the repository at this point in the history
  • Loading branch information
Schottkyc137 committed Feb 26, 2024
1 parent 924ab79 commit 42247cb
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 10 deletions.
102 changes: 94 additions & 8 deletions vhdl_lang/src/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::named_entity::{self, AsUnique, DesignEnt, HasEntityId, NamedEntities,
use crate::syntax::Kind::*;
use crate::syntax::{Kind, Symbols, Token, TokenAccess, Tokenizer, Value};
use crate::{AnyEntKind, Design, EntRef, EntityId, HasTokenSpan, Overloaded, Position, Source};
use itertools::Itertools;
use std::collections::HashSet;
use std::default::Default;
use std::iter::once;
Expand Down Expand Up @@ -42,7 +43,10 @@ pub enum CompletionItem<'a> {
/// -- ...
/// );
/// ```
EntityInstantiation(EntRef<'a>),
///
/// The second argument is a vector of architectures that are associated
/// to this entity
EntityInstantiation(EntRef<'a>, Vec<EntRef<'a>>),
}

macro_rules! kind {
Expand Down Expand Up @@ -371,7 +375,14 @@ impl<'a> Searcher for CompletionSearcher<'a> {
self.completions = self
.root
.get_visible_entities_from_entity(ent)
.map(|eid| CompletionItem::EntityInstantiation(self.root.get_ent(eid)))
.map(|eid| {
let ent = self.root.get_ent(eid);
let architectures = get_architectures_for_entity(ent, self.root);
CompletionItem::EntityInstantiation(
self.root.get_ent(eid),
architectures,
)
})
.collect()
}
Finished(Found)
Expand All @@ -381,6 +392,23 @@ impl<'a> Searcher for CompletionSearcher<'a> {
}
}

/// Returns a vec populated with all architectures that belong to the given entity
fn get_architectures_for_entity<'a>(ent: EntRef<'a>, root: &'a DesignRoot) -> Vec<EntRef<'a>> {
if let Some(design) = DesignEnt::from_any(ent) {
root.public_symbols()
.filter(|sym| match sym.kind() {
AnyEntKind::Design(Design::Architecture(arch_design)) => {
arch_design.id() == design.id()
}
_ => false,
})
.sorted_by_key(|a| a.decl_pos())
.collect_vec()
} else {
vec![]
}
}

impl DesignRoot {
/// List all entities (entities in this context is a VHDL entity, not a `DesignEnt` or similar)
/// that are visible from another VHDL entity.
Expand Down Expand Up @@ -709,11 +737,15 @@ end arch;
.search_reference(code.source(), code.s1("my_other_ent").start())
.unwrap();

let arch = root

Check failure on line 740 in vhdl_lang/src/completion.rs

View workflow job for this annotation

GitHub Actions / build (vhdl_lang, x86_64-unknown-linux-musl, stable)

unused variable: `arch`

Check warning on line 740 in vhdl_lang/src/completion.rs

View workflow job for this annotation

GitHub Actions / build (vhdl_lang, x86_64-unknown-linux-musl, stable)

unused variable: `arch`

Check failure on line 740 in vhdl_lang/src/completion.rs

View workflow job for this annotation

GitHub Actions / build (vhdl_lang, x86_64-unknown-linux-gnu, stable)

unused variable: `arch`

Check warning on line 740 in vhdl_lang/src/completion.rs

View workflow job for this annotation

GitHub Actions / build (vhdl_lang, x86_64-unknown-linux-gnu, stable)

unused variable: `arch`
.search_reference(code.source(), code.s1("arch ").start())
.unwrap();

assert_eq_unordered(
&options[..],
&[
CompletionItem::EntityInstantiation(my_ent),
CompletionItem::EntityInstantiation(my_other_ent),
CompletionItem::EntityInstantiation(my_ent, vec![]),
CompletionItem::EntityInstantiation(my_other_ent, vec![]),
],
);
}
Expand Down Expand Up @@ -775,11 +807,11 @@ end arch;

assert_eq_unordered(
&options[..],
&[CompletionItem::EntityInstantiation(my_ent2)],
&[CompletionItem::EntityInstantiation(my_ent2, vec![])],
);

let ent1 = root
.search_reference(code1.source(), code2.s1("my_ent").start())
.search_reference(code1.source(), code1.s1("my_ent").start())
.unwrap();

let cursor = code3.s1("begin").end();
Expand All @@ -792,9 +824,63 @@ end arch;
assert_eq_unordered(
&options[..],
&[
CompletionItem::EntityInstantiation(my_ent2),
CompletionItem::EntityInstantiation(ent1),
CompletionItem::EntityInstantiation(my_ent2, vec![]),
CompletionItem::EntityInstantiation(ent1, vec![]),
],
);
}

#[test]
pub fn entity_with_two_architecture() {
let mut builder = LibraryBuilder::new();
let code1 = builder.code(
"libA",
"\
entity my_ent is
end my_ent;
architecture arch1 of my_ent is
begin
end arch1;
architecture arch2 of my_ent is
begin
end arch2;
",
);
let code2 = builder.code(
"libA",
"\
entity my_ent2 is
end my_ent2;
architecture arch of my_ent2 is
begin
end arch;
",
);

let (root, diag) = builder.get_analyzed_root();
check_no_diagnostics(&diag[..]);
let cursor = code2.s("begin", 1).end();
let options = list_completion_options(&root, code2.source(), cursor);

let ent = root
.search_reference(code1.source(), code1.s1("my_ent").start())
.unwrap();

let arch1 = root
.search_reference(code1.source(), code1.s1("arch1").start())
.unwrap();

let arch2 = root
.search_reference(code1.source(), code1.s1("arch2").start())
.unwrap();

assert_eq!(
options,
vec![CompletionItem::EntityInstantiation(ent, vec![arch1, arch2])]
)
}
}
14 changes: 12 additions & 2 deletions vhdl_ls/src/vhdl_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ impl VHDLServer {
kind: Some(CompletionItemKind::KEYWORD),
..Default::default()
},
vhdl_lang::CompletionItem::EntityInstantiation(ent) => {
vhdl_lang::CompletionItem::EntityInstantiation(ent, architectures) => {
let work_name = "work";

let library_names = if let Some(lib_name) = ent.library_name() {
Expand All @@ -325,8 +325,18 @@ impl VHDLServer {
ent.designator
)
};
if architectures.len() > 1 {
line.push_str("(${3|");
for (i, architecture) in architectures.iter().enumerate() {
line.push_str(&architecture.designator().to_string());
if i != architectures.len() - 1 {
line.push(',')
}
}
line.push_str("|})");
}
let (ports, generics) = region.ports_and_generics();
let mut idx = 3;
let mut idx = 4;
let mut interface_ent = |elements: Vec<InterfaceEnt>, purpose: &str| {
line += &*format!("\n {} map(\n", purpose);
for (i, generic) in elements.iter().enumerate() {
Expand Down

0 comments on commit 42247cb

Please sign in to comment.