use super::*;
use crate::helper::IdentifiersDisplay;
use alloc::rc::Rc;
use nyar_error::FileSpan;
mod display;
mod iters;
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ImportKind {
Shared,
Private,
Test,
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportStatement {
pub annotation: AttributeList,
pub kind: ImportKind,
pub term: ImportTermNode,
pub span: FileSpan,
}
#[derive(Clone, PartialEq, Eq, Hash, From)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ImportTermNode {
Group(ImportGroupNode),
All(ImportAllNode),
Alias(ImportAliasNode),
}
#[derive(Clone, Default, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportGroupNode {
pub path: Vec<IdentifierNode>,
pub terms: Vec<ImportTermNode>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportAllNode {
pub path: Vec<IdentifierNode>,
pub span: Range<u32>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct ImportAliasNode {
pub path: Vec<IdentifierNode>,
pub item: ImportAliasItem,
pub alias: Option<ImportAliasItem>,
pub span: Range<u32>,
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ImportAliasItem {
Attribute(IdentifierNode),
Procedural(IdentifierNode),
Normal(IdentifierNode),
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum ImportResolvedKind {
Empty,
All,
This,
Alias {
item: ImportAliasItem,
name: Option<ImportAliasItem>,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct ImportResolvedItem {
pub path: Vec<Box<str>>,
pub kind: ImportResolvedKind,
pub span: FileSpan,
}
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ImportState {
Explicit,
Implicit,
Duplicate,
Ambiguous,
}
impl ImportResolvedItem {
pub fn extends(&self, path: &[IdentifierNode]) -> Self {
let mut new = self.clone();
new.path.extend(path.iter().map(|s| Box::from(s.name.as_str())));
new
}
fn join_group(&self, group: &ImportGroupNode, items: &mut Vec<ImportResolvedItem>) {
let resolved = self.extends(&group.path);
for term in &group.terms {
term.resolve(&resolved, items);
}
}
fn join_alias(&self, alias: &ImportAliasNode, items: &mut Vec<ImportResolvedItem>) {
let mut resolved = self.extends(&alias.path);
resolved.span.set_range(alias.get_range());
resolved.kind = ImportResolvedKind::Alias { item: alias.item.clone(), name: alias.alias.clone() };
items.push(resolved)
}
fn join_all(&self, all: &ImportAllNode, items: &mut Vec<ImportResolvedItem>) {
let mut resolved = self.extends(&all.path);
resolved.span.set_range(all.get_range());
resolved.kind = ImportResolvedKind::All;
items.push(resolved)
}
}
impl ImportStatement {
pub fn flatten(&self) -> Vec<ImportResolvedItem> {
let root = ImportResolvedItem { path: vec![], kind: ImportResolvedKind::Empty, span: self.span };
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 {
Self::Alias(alias) => parent.join_alias(alias, all),
Self::Group(group) => parent.join_group(group, all),
Self::All(any) => parent.clone().join_all(any, all),
}
}
}