use crate::{
ValkyrieLanguage,
ast::{Item, NamePath, Namespace},
builder::ValkyrieBuilder,
lexer::token_type::ValkyrieTokenType,
parser::element_type::ValkyrieElementType,
};
use oak_core::{OakError, RedNode, RedTree, Source};
impl<'config> ValkyrieBuilder<'config> {
pub(crate) fn build_namespace<S: Source + ?Sized>(&self, node: RedNode<ValkyrieLanguage>, source: &S) -> Result<Namespace, OakError> {
let span = node.span();
let mut name = NamePath { parts: Vec::new(), span: Default::default() };
let mut annotations = Vec::new();
let mut items = Vec::new();
for child in node.children() {
match child {
RedTree::Leaf(t) => match t.kind {
ValkyrieTokenType::Whitespace | ValkyrieTokenType::Newline | ValkyrieTokenType::LineComment | ValkyrieTokenType::BlockComment => continue,
_ => {}
},
RedTree::Node(n) => match n.green.kind {
ValkyrieElementType::Attribute => {
annotations.push(self.build_attribute(n, source)?);
}
ValkyrieElementType::NamePath => {
name = self.build_name_path(n, source)?;
}
ValkyrieElementType::Namespace => {
let ns = self.build_namespace(n, source)?;
items.push(Item::Namespace(ns));
}
ValkyrieElementType::Class => {
let class = self.build_class(n, source)?;
items.push(Item::Class(class));
}
ValkyrieElementType::Flags => {
let flags = self.build_flags(n, source)?;
items.push(Item::Flags(flags));
}
ValkyrieElementType::Enums => {
let enums = self.build_enums(n, source)?;
items.push(Item::Enums(enums));
}
ValkyrieElementType::Trait => {
let trait_node = self.build_trait(n, source)?;
items.push(Item::Trait(trait_node));
}
ValkyrieElementType::Widget => {
let widget = self.build_widget(n, source)?;
items.push(Item::Widget(widget));
}
ValkyrieElementType::UsingStatement => {
let us = self.build_using(n, source)?;
items.push(Item::Using(us));
}
ValkyrieElementType::Micro => {
let micro = self.build_micro(n, source)?;
items.push(Item::Micro(micro));
}
ValkyrieElementType::Mezzo => {
let mezzo = self.build_mezzo(n, source)?;
items.push(Item::TypeFunction(mezzo));
}
ValkyrieElementType::LetStatement => {
let stmt = self.build_let(n, source)?;
items.push(Item::Statement(stmt));
}
ValkyrieElementType::ExprStatement => {
let stmt = self.build_expr_stmt(n, source)?;
items.push(Item::Statement(stmt));
}
ValkyrieElementType::BlockExpression => {
for inner_child in n.children() {
if let RedTree::Node(inner_n) = inner_child {
if let Ok(item) = self.build_item(inner_n, source) {
items.push(item);
}
}
}
}
_ => {}
},
}
}
Ok(Namespace { name, annotations, items, span })
}
}