1 | use crate::core::ExportKind; |
2 | use crate::kw; |
3 | use crate::parser::{Parse, Parser, Result}; |
4 | use 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)] |
10 | pub 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 | |
17 | impl<'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)] |
32 | pub 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 | |
44 | impl<'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 | |
76 | impl<'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)] |
140 | pub 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 | |
155 | impl<'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)] |
190 | pub 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 | |
201 | impl<'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)] |
230 | pub 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 | |