@@ -14,6 +14,7 @@ use crate::named_entity::{self, AsUnique, DesignEnt, HasEntityId, NamedEntities,
1414use crate :: syntax:: Kind :: * ;
1515use crate :: syntax:: { Kind , Symbols , Token , TokenAccess , Tokenizer , Value } ;
1616use crate :: { AnyEntKind , Design , EntRef , EntityId , HasTokenSpan , Overloaded , Position , Source } ;
17+ use itertools:: Itertools ;
1718use std:: collections:: HashSet ;
1819use std:: default:: Default ;
1920use std:: iter:: once;
@@ -42,7 +43,10 @@ pub enum CompletionItem<'a> {
4243 /// -- ...
4344 /// );
4445 /// ```
45- EntityInstantiation ( EntRef < ' a > ) ,
46+ ///
47+ /// The second argument is a vector of architectures that are associated
48+ /// to this entity
49+ EntityInstantiation ( EntRef < ' a > , Vec < EntRef < ' a > > ) ,
4650}
4751
4852macro_rules! kind {
@@ -371,7 +375,14 @@ impl<'a> Searcher for CompletionSearcher<'a> {
371375 self . completions = self
372376 . root
373377 . get_visible_entities_from_entity ( ent)
374- . map ( |eid| CompletionItem :: EntityInstantiation ( self . root . get_ent ( eid) ) )
378+ . map ( |eid| {
379+ let ent = self . root . get_ent ( eid) ;
380+ let architectures = get_architectures_for_entity ( ent, self . root ) ;
381+ CompletionItem :: EntityInstantiation (
382+ self . root . get_ent ( eid) ,
383+ architectures,
384+ )
385+ } )
375386 . collect ( )
376387 }
377388 Finished ( Found )
@@ -381,6 +392,23 @@ impl<'a> Searcher for CompletionSearcher<'a> {
381392 }
382393}
383394
395+ /// Returns a vec populated with all architectures that belong to the given entity
396+ fn get_architectures_for_entity < ' a > ( ent : EntRef < ' a > , root : & ' a DesignRoot ) -> Vec < EntRef < ' a > > {
397+ if let Some ( design) = DesignEnt :: from_any ( ent) {
398+ root. public_symbols ( )
399+ . filter ( |sym| match sym. kind ( ) {
400+ AnyEntKind :: Design ( Design :: Architecture ( arch_design) ) => {
401+ arch_design. id ( ) == design. id ( )
402+ }
403+ _ => false ,
404+ } )
405+ . sorted_by_key ( |a| a. decl_pos ( ) )
406+ . collect_vec ( )
407+ } else {
408+ vec ! [ ]
409+ }
410+ }
411+
384412impl DesignRoot {
385413 /// List all entities (entities in this context is a VHDL entity, not a `DesignEnt` or similar)
386414 /// that are visible from another VHDL entity.
@@ -712,8 +740,8 @@ end arch;
712740 assert_eq_unordered (
713741 & options[ ..] ,
714742 & [
715- CompletionItem :: EntityInstantiation ( my_ent) ,
716- CompletionItem :: EntityInstantiation ( my_other_ent) ,
743+ CompletionItem :: EntityInstantiation ( my_ent, vec ! [ ] ) ,
744+ CompletionItem :: EntityInstantiation ( my_other_ent, vec ! [ ] ) ,
717745 ] ,
718746 ) ;
719747 }
@@ -775,11 +803,11 @@ end arch;
775803
776804 assert_eq_unordered (
777805 & options[ ..] ,
778- & [ CompletionItem :: EntityInstantiation ( my_ent2) ] ,
806+ & [ CompletionItem :: EntityInstantiation ( my_ent2, vec ! [ ] ) ] ,
779807 ) ;
780808
781809 let ent1 = root
782- . search_reference ( code1. source ( ) , code2 . s1 ( "my_ent" ) . start ( ) )
810+ . search_reference ( code1. source ( ) , code1 . s1 ( "my_ent" ) . start ( ) )
783811 . unwrap ( ) ;
784812
785813 let cursor = code3. s1 ( "begin" ) . end ( ) ;
@@ -792,9 +820,63 @@ end arch;
792820 assert_eq_unordered (
793821 & options[ ..] ,
794822 & [
795- CompletionItem :: EntityInstantiation ( my_ent2) ,
796- CompletionItem :: EntityInstantiation ( ent1) ,
823+ CompletionItem :: EntityInstantiation ( my_ent2, vec ! [ ] ) ,
824+ CompletionItem :: EntityInstantiation ( ent1, vec ! [ ] ) ,
797825 ] ,
798826 ) ;
799827 }
828+
829+ #[ test]
830+ pub fn entity_with_two_architecture ( ) {
831+ let mut builder = LibraryBuilder :: new ( ) ;
832+ let code1 = builder. code (
833+ "libA" ,
834+ "\
835+ entity my_ent is
836+ end my_ent;
837+
838+ architecture arch1 of my_ent is
839+ begin
840+ end arch1;
841+
842+ architecture arch2 of my_ent is
843+ begin
844+ end arch2;
845+ " ,
846+ ) ;
847+ let code2 = builder. code (
848+ "libA" ,
849+ "\
850+ entity my_ent2 is
851+ end my_ent2;
852+
853+ architecture arch of my_ent2 is
854+ begin
855+
856+ end arch;
857+ " ,
858+ ) ;
859+
860+ let ( root, diag) = builder. get_analyzed_root ( ) ;
861+ check_no_diagnostics ( & diag[ ..] ) ;
862+ let cursor = code2. s ( "begin" , 1 ) . end ( ) ;
863+ let options = list_completion_options ( & root, code2. source ( ) , cursor) ;
864+
865+ let ent = root
866+ . search_reference ( code1. source ( ) , code1. s1 ( "my_ent" ) . start ( ) )
867+ . unwrap ( ) ;
868+
869+ let arch1 = root
870+ . search_reference ( code1. source ( ) , code1. s1 ( "arch1" ) . start ( ) )
871+ . unwrap ( ) ;
872+
873+ let arch2 = root
874+ . search_reference ( code1. source ( ) , code1. s1 ( "arch2" ) . start ( ) )
875+ . unwrap ( ) ;
876+
877+ assert_eq ! (
878+ options,
879+ vec![ CompletionItem :: EntityInstantiation ( ent, vec![ arch1, arch2] ) ]
880+ )
881+ }
800882}
0 commit comments