1use crate::core::ExportKind;
2use crate::kw;
3use crate::parser::{Parse, Parser, Result};
4use crate::token::{Id, Index, NameAnnotation, Span};
5
6/// A inline alias for component exported items.
7///
8/// Handles both `core export` and `export` aliases
9#[derive(Debug)]
10pub struct InlineExportAlias<'a, const CORE: bool> {
11 /// The instance to alias the export from.
12 pub instance: Index<'a>,
13 /// The name of the export to alias.
14 pub name: &'a str,
15}
16
17impl<'a, const CORE: bool> Parse<'a> for InlineExportAlias<'a, CORE> {
18 fn parse(parser: Parser<'a>) -> Result<Self> {
19 parser.parse::<kw::alias>()?;
20 if CORE {
21 parser.parse::<kw::core>()?;
22 }
23 parser.parse::<kw::export>()?;
24 let instance: Index<'a> = parser.parse()?;
25 let name: &'a str = parser.parse()?;
26 Ok(Self { instance, name })
27 }
28}
29
30/// An alias to a component item.
31#[derive(Debug)]
32pub struct Alias<'a> {
33 /// Where this `alias` was defined.
34 pub span: Span,
35 /// An identifier that this alias is resolved with (optionally) for name
36 /// resolution.
37 pub id: Option<Id<'a>>,
38 /// An optional name for this alias stored in the custom `name` section.
39 pub name: Option<NameAnnotation<'a>>,
40 /// The target of this alias.
41 pub target: AliasTarget<'a>,
42}
43
44impl<'a> Alias<'a> {
45 /// Parses only an outer type alias.
46 pub fn parse_outer_core_type_alias(parser: Parser<'a>) -> Result<Self> {
47 let span = parser.parse::<kw::alias>()?.0;
48 parser.parse::<kw::outer>()?;
49 let outer = parser.parse()?;
50 let index = parser.parse()?;
51
52 let (kind, id, name) = parser.parens(|parser| {
53 let mut kind: ComponentOuterAliasKind = parser.parse()?;
54 match kind {
55 ComponentOuterAliasKind::CoreType => {
56 return Err(parser.error("expected type for outer alias"))
57 }
58 ComponentOuterAliasKind::Type => {
59 kind = ComponentOuterAliasKind::CoreType;
60 }
61 _ => return Err(parser.error("expected core type or type for outer alias")),
62 }
63
64 Ok((kind, parser.parse()?, parser.parse()?))
65 })?;
66
67 Ok(Self {
68 span,
69 target: AliasTarget::Outer { outer, index, kind },
70 id,
71 name,
72 })
73 }
74}
75
76impl<'a> Parse<'a> for Alias<'a> {
77 fn parse(parser: Parser<'a>) -> Result<Self> {
78 let span = parser.parse::<kw::alias>()?.0;
79
80 let mut l = parser.lookahead1();
81
82 let (target, id, name) = if l.peek::<kw::outer>()? {
83 parser.parse::<kw::outer>()?;
84 let outer = parser.parse()?;
85 let index = parser.parse()?;
86 let (kind, id, name) =
87 parser.parens(|parser| Ok((parser.parse()?, parser.parse()?, parser.parse()?)))?;
88
89 (AliasTarget::Outer { outer, index, kind }, id, name)
90 } else if l.peek::<kw::export>()? {
91 parser.parse::<kw::export>()?;
92 let instance = parser.parse()?;
93 let export_name = parser.parse()?;
94 let (kind, id, name) =
95 parser.parens(|parser| Ok((parser.parse()?, parser.parse()?, parser.parse()?)))?;
96
97 (
98 AliasTarget::Export {
99 instance,
100 name: export_name,
101 kind,
102 },
103 id,
104 name,
105 )
106 } else if l.peek::<kw::core>()? {
107 parser.parse::<kw::core>()?;
108 parser.parse::<kw::export>()?;
109 let instance = parser.parse()?;
110 let export_name = parser.parse()?;
111 let (kind, id, name) = parser.parens(|parser| {
112 parser.parse::<kw::core>()?;
113 Ok((parser.parse()?, parser.parse()?, parser.parse()?))
114 })?;
115
116 (
117 AliasTarget::CoreExport {
118 instance,
119 name: export_name,
120 kind,
121 },
122 id,
123 name,
124 )
125 } else {
126 return Err(l.error());
127 };
128
129 Ok(Self {
130 span,
131 target,
132 id,
133 name,
134 })
135 }
136}
137
138/// Represents the kind of instance export alias.
139#[derive(Debug, Copy, Clone, PartialEq, Eq)]
140pub enum ComponentExportAliasKind {
141 /// The alias is to a core module export.
142 CoreModule,
143 /// The alias is to a function export.
144 Func,
145 /// The alias is to a value export.
146 Value,
147 /// The alias is to a type export.
148 Type,
149 /// The alias is to a component export.
150 Component,
151 /// The alias is to an instance export.
152 Instance,
153}
154
155impl<'a> Parse<'a> for ComponentExportAliasKind {
156 fn parse(parser: Parser<'a>) -> Result<Self> {
157 let mut l = parser.lookahead1();
158 if l.peek::<kw::core>()? {
159 parser.parse::<kw::core>()?;
160 let mut l = parser.lookahead1();
161 if l.peek::<kw::module>()? {
162 parser.parse::<kw::module>()?;
163 Ok(Self::CoreModule)
164 } else {
165 Err(l.error())
166 }
167 } else if l.peek::<kw::func>()? {
168 parser.parse::<kw::func>()?;
169 Ok(Self::Func)
170 } else if l.peek::<kw::value>()? {
171 parser.parse::<kw::value>()?;
172 Ok(Self::Value)
173 } else if l.peek::<kw::r#type>()? {
174 parser.parse::<kw::r#type>()?;
175 Ok(Self::Type)
176 } else if l.peek::<kw::component>()? {
177 parser.parse::<kw::component>()?;
178 Ok(Self::Component)
179 } else if l.peek::<kw::instance>()? {
180 parser.parse::<kw::instance>()?;
181 Ok(Self::Instance)
182 } else {
183 Err(l.error())
184 }
185 }
186}
187
188/// Represents the kind of outer alias.
189#[derive(Debug, Copy, Clone, PartialEq, Eq)]
190pub enum ComponentOuterAliasKind {
191 /// The alias is to an outer core module.
192 CoreModule,
193 /// The alias is to an outer core type.
194 CoreType,
195 /// The alias is to an outer type.
196 Type,
197 /// The alias is to an outer component.
198 Component,
199}
200
201impl<'a> Parse<'a> for ComponentOuterAliasKind {
202 fn parse(parser: Parser<'a>) -> Result<Self> {
203 let mut l = parser.lookahead1();
204 if l.peek::<kw::core>()? {
205 parser.parse::<kw::core>()?;
206 let mut l = parser.lookahead1();
207 if l.peek::<kw::module>()? {
208 parser.parse::<kw::module>()?;
209 Ok(Self::CoreModule)
210 } else if l.peek::<kw::r#type>()? {
211 parser.parse::<kw::r#type>()?;
212 Ok(Self::CoreType)
213 } else {
214 Err(l.error())
215 }
216 } else if l.peek::<kw::r#type>()? {
217 parser.parse::<kw::r#type>()?;
218 Ok(Self::Type)
219 } else if l.peek::<kw::component>()? {
220 parser.parse::<kw::component>()?;
221 Ok(Self::Component)
222 } else {
223 Err(l.error())
224 }
225 }
226}
227
228/// The target of a component alias.
229#[derive(Debug)]
230pub enum AliasTarget<'a> {
231 /// The alias is to an export of a component instance.
232 Export {
233 /// The component instance exporting the item.
234 instance: Index<'a>,
235 /// The name of the exported item to alias.
236 name: &'a str,
237 /// The export kind of the alias.
238 kind: ComponentExportAliasKind,
239 },
240 /// The alias is to an export of a module instance.
241 CoreExport {
242 /// The module instance exporting the item.
243 instance: Index<'a>,
244 /// The name of the exported item to alias.
245 name: &'a str,
246 /// The export kind of the alias.
247 kind: ExportKind,
248 },
249 /// The alias is to an item from an outer component.
250 Outer {
251 /// The number of enclosing components to skip.
252 outer: Index<'a>,
253 /// The index of the item being aliased.
254 index: Index<'a>,
255 /// The outer alias kind.
256 kind: ComponentOuterAliasKind,
257 },
258}
259