Source code

Revision control

Copy as Markdown

Other Tools

use crate::core::ExportKind;
use crate::kw;
use crate::parser::{Parse, Parser, Result};
use crate::token::{Id, Index, NameAnnotation, Span};
/// A inline alias for component exported items.
///
/// Handles both `core export` and `export` aliases
#[derive(Debug)]
pub struct InlineExportAlias<'a, const CORE: bool> {
/// The instance to alias the export from.
pub instance: Index<'a>,
/// The name of the export to alias.
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 })
}
}
/// An alias to a component item.
#[derive(Debug)]
pub struct Alias<'a> {
/// Where this `alias` was defined.
pub span: Span,
/// An identifier that this alias is resolved with (optionally) for name
/// resolution.
pub id: Option<Id<'a>>,
/// An optional name for this alias stored in the custom `name` section.
pub name: Option<NameAnnotation<'a>>,
/// The target of this alias.
pub target: AliasTarget<'a>,
}
impl<'a> Alias<'a> {
/// Parses only an outer type alias.
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,
})
}
}
/// Represents the kind of instance export alias.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ComponentExportAliasKind {
/// The alias is to a core module export.
CoreModule,
/// The alias is to a function export.
Func,
/// The alias is to a value export.
Value,
/// The alias is to a type export.
Type,
/// The alias is to a component export.
Component,
/// The alias is to an instance export.
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())
}
}
}
/// Represents the kind of outer alias.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ComponentOuterAliasKind {
/// The alias is to an outer core module.
CoreModule,
/// The alias is to an outer core type.
CoreType,
/// The alias is to an outer type.
Type,
/// The alias is to an outer component.
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())
}
}
}
/// The target of a component alias.
#[derive(Debug)]
pub enum AliasTarget<'a> {
/// The alias is to an export of a component instance.
Export {
/// The component instance exporting the item.
instance: Index<'a>,
/// The name of the exported item to alias.
name: &'a str,
/// The export kind of the alias.
kind: ComponentExportAliasKind,
},
/// The alias is to an export of a module instance.
CoreExport {
/// The module instance exporting the item.
instance: Index<'a>,
/// The name of the exported item to alias.
name: &'a str,
/// The export kind of the alias.
kind: ExportKind,
},
/// The alias is to an item from an outer component.
Outer {
/// The number of enclosing components to skip.
outer: Index<'a>,
/// The index of the item being aliased.
index: Index<'a>,
/// The outer alias kind.
kind: ComponentOuterAliasKind,
},
}