use super::*;
mod display;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportStatement {
pub term: ImportTermNode,
pub span: Range<u32>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ImportTermNode {
Alias(Box<ImportAliasNode>),
Group(Box<ImportGroupNode>),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportGroupNode {
pub path: NamePathNode,
pub group: Vec<ImportTermNode>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportAliasNode {
pub path: NamePathNode,
pub alias: IdentifierNode,
}
impl ImportGroupNode {
pub fn new(path: NamePathNode, group: Vec<ImportTermNode>) -> Self {
Self { path, group }
}
}
impl ImportAliasNode {
pub fn new(path: NamePathNode, alias: IdentifierNode) -> Self {
Self { alias, path }
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportResolvedItem {
pub annotation: Option<Arc<IdentifierNode>>,
pub path: Vec<IdentifierNode>,
pub alias: Option<IdentifierNode>,
}
impl ImportResolvedItem {
pub fn join_external(&self, name: &IdentifierNode) -> Self {
Self { annotation: Some(Arc::new(name.clone())), ..self.clone() }
}
pub fn join_name(&self, name: &IdentifierNode) -> Self {
let mut path = self.path.clone();
path.push(name.clone());
Self { path, ..self.clone() }
}
pub fn join_path(&self, namepath: &[IdentifierNode]) -> Self {
let mut path = self.path.clone();
path.extend_from_slice(namepath);
Self { path, ..self.clone() }
}
pub fn join_alias(&self, alias: &IdentifierNode) -> Self {
Self { alias: Some(alias.clone()), ..self.clone() }
}
}
impl ImportStatement {
pub fn flatten(&self) -> Vec<ImportResolvedItem> {
let root = ImportResolvedItem::default();
let mut all = Vec::new();
self.term.resolve(&root, &mut all);
all
}
}
impl ImportTermNode {
fn resolve(&self, parent: &ImportResolvedItem, all: &mut Vec<ImportResolvedItem>) {
match self {
ImportTermNode::Alias(alias) => {
all.push(parent.join_path(&alias.path.names).join_alias(&alias.alias));
}
ImportTermNode::Group(group) => {
let root = parent.join_path(&group.path.names);
for item in &group.group {
item.resolve(&root, all);
}
}
}
}
}