diff options
Diffstat (limited to 'third_party/rust/wast/src/component/alias.rs')
-rw-r--r-- | third_party/rust/wast/src/component/alias.rs | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/third_party/rust/wast/src/component/alias.rs b/third_party/rust/wast/src/component/alias.rs new file mode 100644 index 0000000000..3c70a2d371 --- /dev/null +++ b/third_party/rust/wast/src/component/alias.rs @@ -0,0 +1,253 @@ +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. +#[derive(Debug)] +pub struct InlineExportAlias<'a> { + /// The instance to alias the export from. + pub instance: Index<'a>, + /// The name of the export to alias. + pub name: &'a str, +} + +impl<'a> Parse<'a> for InlineExportAlias<'a> { + fn parse(parser: Parser<'a>) -> Result<Self> { + parser.parse::<kw::alias>()?; + 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, + }, +} |