use crate::core::ExportKind;
use crate::kw;
use crate::parser::{Parse, Parser, Result};
use crate::token::{Id, Index, NameAnnotation, Span};
#[derive(Debug)]
pub struct InlineExportAlias<'a, const CORE: bool> {
pub instance: Index<'a>,
pub name: &'a str,
}
impl<'a, const CORE: bool> Parse<'a> for InlineExportAlias<'a, CORE> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<kw::alias>()?;
if CORE {
parser.parse::<kw::core>()?;
}
parser.parse::<kw::export>()?;
let instance = parser.parse()?;
let name = parser.parse()?;
Ok(Self { instance, name })
}
}
#[derive(Debug)]
pub struct Alias<'a> {
pub span: Span,
pub id: Option<Id<'a>>,
pub name: Option<NameAnnotation<'a>>,
pub target: AliasTarget<'a>,
}
impl<'a> Alias<'a> {
pub fn parse_outer_core_type_alias(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::alias>()?.0;
parser.parse::<kw::outer>()?;
let outer = parser.parse()?;
let index = parser.parse()?;
let (kind, id, name) = parser.parens(|parser| {
let mut kind: ComponentOuterAliasKind = parser.parse()?;
match kind {
ComponentOuterAliasKind::CoreType => {
return Err(parser.error("expected type for outer alias"))
}
ComponentOuterAliasKind::Type => {
kind = ComponentOuterAliasKind::CoreType;
}
_ => return Err(parser.error("expected core type or type for outer alias")),
}
Ok((kind, parser.parse()?, parser.parse()?))
})?;
Ok(Self {
span,
target: AliasTarget::Outer { outer, index, kind },
id,
name,
})
}
}
impl<'a> Parse<'a> for Alias<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let span = parser.parse::<kw::alias>()?.0;
let mut l = parser.lookahead1();
let (target, id, name) = if l.peek::<kw::outer>()? {
parser.parse::<kw::outer>()?;
let outer = parser.parse()?;
let index = parser.parse()?;
let (kind, id, name) =
parser.parens(|parser| Ok((parser.parse()?, parser.parse()?, parser.parse()?)))?;
(AliasTarget::Outer { outer, index, kind }, id, name)
} else if l.peek::<kw::export>()? {
parser.parse::<kw::export>()?;
let instance = parser.parse()?;
let export_name = parser.parse()?;
let (kind, id, name) =
parser.parens(|parser| Ok((parser.parse()?, parser.parse()?, parser.parse()?)))?;
(
AliasTarget::Export {
instance,
name: export_name,
kind,
},
id,
name,
)
} else if l.peek::<kw::core>()? {
parser.parse::<kw::core>()?;
parser.parse::<kw::export>()?;
let instance = parser.parse()?;
let export_name = parser.parse()?;
let (kind, id, name) = parser.parens(|parser| {
parser.parse::<kw::core>()?;
Ok((parser.parse()?, parser.parse()?, parser.parse()?))
})?;
(
AliasTarget::CoreExport {
instance,
name: export_name,
kind,
},
id,
name,
)
} else {
return Err(l.error());
};
Ok(Self {
span,
target,
id,
name,
})
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ComponentExportAliasKind {
CoreModule,
Func,
Value,
Type,
Component,
Instance,
}
impl<'a> Parse<'a> for ComponentExportAliasKind {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::core>()? {
parser.parse::<kw::core>()?;
let mut l = parser.lookahead1();
if l.peek::<kw::module>()? {
parser.parse::<kw::module>()?;
Ok(Self::CoreModule)
} else {
Err(l.error())
}
} else if l.peek::<kw::func>()? {
parser.parse::<kw::func>()?;
Ok(Self::Func)
} else if l.peek::<kw::value>()? {
parser.parse::<kw::value>()?;
Ok(Self::Value)
} else if l.peek::<kw::r#type>()? {
parser.parse::<kw::r#type>()?;
Ok(Self::Type)
} else if l.peek::<kw::component>()? {
parser.parse::<kw::component>()?;
Ok(Self::Component)
} else if l.peek::<kw::instance>()? {
parser.parse::<kw::instance>()?;
Ok(Self::Instance)
} else {
Err(l.error())
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ComponentOuterAliasKind {
CoreModule,
CoreType,
Type,
Component,
}
impl<'a> Parse<'a> for ComponentOuterAliasKind {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut l = parser.lookahead1();
if l.peek::<kw::core>()? {
parser.parse::<kw::core>()?;
let mut l = parser.lookahead1();
if l.peek::<kw::module>()? {
parser.parse::<kw::module>()?;
Ok(Self::CoreModule)
} else if l.peek::<kw::r#type>()? {
parser.parse::<kw::r#type>()?;
Ok(Self::CoreType)
} else {
Err(l.error())
}
} else if l.peek::<kw::r#type>()? {
parser.parse::<kw::r#type>()?;
Ok(Self::Type)
} else if l.peek::<kw::component>()? {
parser.parse::<kw::component>()?;
Ok(Self::Component)
} else {
Err(l.error())
}
}
}
#[derive(Debug)]
pub enum AliasTarget<'a> {
Export {
instance: Index<'a>,
name: &'a str,
kind: ComponentExportAliasKind,
},
CoreExport {
instance: Index<'a>,
name: &'a str,
kind: ExportKind,
},
Outer {
outer: Index<'a>,
index: Index<'a>,
kind: ComponentOuterAliasKind,
},
}