-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
16d9e5e
commit 3dce4cd
Showing
6 changed files
with
107 additions
and
40 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,7 @@ | |
// | ||
// Copyright (c) 2024, Olof Kraigher [email protected] | ||
use crate::analysis::DesignRoot; | ||
use crate::completion::region::any_ent_to_completion_item; | ||
use crate::named_entity::DesignEnt; | ||
use crate::{AnyEntKind, CompletionItem, Design, EntRef, EntityId, HasEntityId}; | ||
use itertools::Itertools; | ||
|
@@ -43,19 +44,15 @@ pub(crate) fn get_visible_entities_from_architecture<'a>( | |
} | ||
entities | ||
.into_iter() | ||
.map(|eid| root.get_ent(eid)) | ||
.map(|ent| match ent.kind() { | ||
AnyEntKind::Design(Design::Entity(..)) => { | ||
let architectures = get_architectures_for_entity(ent, root); | ||
CompletionItem::EntityInstantiation(ent, architectures) | ||
} | ||
_ => CompletionItem::Simple(ent), | ||
}) | ||
.map(|eid| any_ent_to_completion_item(root.get_ent(eid), root)) | ||
.collect_vec() | ||
} | ||
|
||
/// Returns a vec populated with all architectures that belong to a given entity | ||
fn get_architectures_for_entity<'a>(ent: EntRef<'a>, root: &'a DesignRoot) -> Vec<EntRef<'a>> { | ||
pub(crate) fn get_architectures_for_entity<'a>( | ||
ent: EntRef<'a>, | ||
root: &'a DesignRoot, | ||
) -> Vec<EntRef<'a>> { | ||
let Some(lib_symbol) = ent.library_name() else { | ||
return vec![]; | ||
}; | ||
|
@@ -111,8 +108,8 @@ end arch; | |
.search_reference(code.source(), code.s1("my_other_ent").start()) | ||
.unwrap(); | ||
|
||
assert!(options.contains(&CompletionItem::EntityInstantiation(my_ent, vec![]))); | ||
assert!(options.contains(&CompletionItem::EntityInstantiation(my_other_ent, vec![]))); | ||
assert!(options.contains(&CompletionItem::Instantiation(my_ent, vec![]))); | ||
assert!(options.contains(&CompletionItem::Instantiation(my_other_ent, vec![]))); | ||
} | ||
|
||
#[test] | ||
|
@@ -170,7 +167,7 @@ end arch; | |
.search_reference(code2.source(), code2.s1("my_ent2").start()) | ||
.unwrap(); | ||
|
||
assert!(options.contains(&CompletionItem::EntityInstantiation(my_ent2, vec![]))); | ||
assert!(options.contains(&CompletionItem::Instantiation(my_ent2, vec![]))); | ||
|
||
let ent1 = root | ||
.search_reference(code1.source(), code1.s1("my_ent").start()) | ||
|
@@ -183,8 +180,8 @@ end arch; | |
.search_reference(code3.source(), code3.s1("my_ent2").start()) | ||
.unwrap(); | ||
|
||
assert!(options.contains(&CompletionItem::EntityInstantiation(my_ent2, vec![]))); | ||
assert!(options.contains(&CompletionItem::EntityInstantiation(ent1, vec![]))); | ||
assert!(options.contains(&CompletionItem::Instantiation(my_ent2, vec![]))); | ||
assert!(options.contains(&CompletionItem::Instantiation(ent1, vec![]))); | ||
} | ||
|
||
#[test] | ||
|
@@ -238,9 +235,7 @@ end arch; | |
let applicable_options = options | ||
.into_iter() | ||
.filter_map(|option| match option { | ||
CompletionItem::EntityInstantiation(ent, architectures) => { | ||
Some((ent, architectures)) | ||
} | ||
CompletionItem::Instantiation(ent, architectures) => Some((ent, architectures)), | ||
_ => None, | ||
}) | ||
.collect_vec(); | ||
|
@@ -253,4 +248,44 @@ end arch; | |
_ => panic!("Expected entity instantiation"), | ||
} | ||
} | ||
|
||
#[test] | ||
fn component_instantiations() { | ||
let mut builder = LibraryBuilder::new(); | ||
let code = builder.code( | ||
"libname", | ||
"\ | ||
package foo is | ||
component comp_A is | ||
end component; | ||
end foo; | ||
use work.foo.all; | ||
entity my_ent is | ||
end my_ent; | ||
architecture arch1 of my_ent is | ||
component comp_B is | ||
end component; | ||
component comp_C is | ||
end component; | ||
begin | ||
end arch1; | ||
", | ||
); | ||
|
||
let (root, diag) = builder.get_analyzed_root(); | ||
check_no_diagnostics(&diag[..]); | ||
let cursor = code.s1("begin").end(); | ||
let options = list_completion_options(&root, code.source(), cursor); | ||
|
||
for component in ["comp_A", "comp_B", "comp_C"] { | ||
let entity = root | ||
.search_reference(code.source(), code.s1(component).start()) | ||
.unwrap(); | ||
assert!(options.contains(&CompletionItem::Instantiation(entity, vec![]))) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,28 +1,46 @@ | ||
use vhdl_lang::EntRef; | ||
// This Source Code Form is subject to the terms of the Mozilla Public | ||
// License, v. 2.0. If a copy of the MPL was not distributed with this file, | ||
// You can obtain one at http://mozilla.org/MPL/2.0/. | ||
// | ||
// Copyright (c) 2024, Olof Kraigher [email protected] | ||
use crate::analysis::DesignRoot; | ||
use crate::completion::entity_instantiation::get_architectures_for_entity; | ||
use crate::named_entity::{AsUnique, NamedEntities, Region}; | ||
use crate::CompletionItem; | ||
use crate::{AnyEntKind, CompletionItem, Design}; | ||
|
||
pub(crate) fn completion_items_from_region<'a>( | ||
root: &'a DesignRoot, | ||
region: &'a Region<'a>, | ||
) -> impl Iterator<Item = CompletionItem<'a>> { | ||
region | ||
.entities | ||
.values() | ||
.map(named_entities_to_completion_item) | ||
.map(|entities| named_entities_to_completion_item(root, entities)) | ||
} | ||
|
||
fn named_entities_to_completion_item<'a>( | ||
root: &'a DesignRoot, | ||
named_entities: &'a NamedEntities<'a>, | ||
) -> CompletionItem<'a> { | ||
match named_entities { | ||
NamedEntities::Single(ent) => CompletionItem::Simple(ent), | ||
NamedEntities::Single(ent) => any_ent_to_completion_item(ent, root), | ||
NamedEntities::Overloaded(overloaded) => match overloaded.as_unique() { | ||
None => CompletionItem::Overloaded(overloaded.designator().clone(), overloaded.len()), | ||
Some(ent) => CompletionItem::Simple(ent), | ||
}, | ||
} | ||
} | ||
|
||
pub(crate) fn any_ent_to_completion_item<'a>( | ||
ent: EntRef<'a>, | ||
root: &'a DesignRoot, | ||
) -> CompletionItem<'a> { | ||
match ent.kind() { | ||
AnyEntKind::Design(Design::Entity(..)) | AnyEntKind::Component(_) => { | ||
let architectures = get_architectures_for_entity(ent, root); | ||
CompletionItem::Instantiation(ent, architectures) | ||
} | ||
_ => CompletionItem::Simple(ent), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters