Coverage Report

Created: 2023-04-25 07:07

/src/wasm-tools/crates/wast/src/component/expand.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::component::*;
2
use crate::core;
3
use crate::gensym;
4
use crate::kw;
5
use crate::token::Id;
6
use crate::token::{Index, Span};
7
use std::collections::HashMap;
8
use std::mem;
9
10
/// Performs an AST "expansion" pass over the component fields provided.
11
///
12
/// This expansion is intended to desugar the AST from various parsed constructs
13
/// to bits and bobs amenable for name resolution as well as binary encoding.
14
/// For example `(import "i" (func))` is split into a type definition followed by
15
/// the import referencing that type definition.
16
///
17
/// Most forms of AST expansion happen in this file and afterwards the AST will
18
/// be handed to the name resolution pass which will convert `Index::Id` to
19
/// `Index::Num` wherever it's found.
20
425
pub fn expand(fields: &mut Vec<ComponentField<'_>>) {
21
425
    Expander::default().expand_component_fields(fields)
22
425
}
23
24
enum AnyType<'a> {
25
    Core(CoreType<'a>),
26
    Component(Type<'a>),
27
}
28
29
impl<'a> From<AnyType<'a>> for ComponentTypeDecl<'a> {
30
0
    fn from(t: AnyType<'a>) -> Self {
31
0
        match t {
32
0
            AnyType::Core(t) => Self::CoreType(t),
33
0
            AnyType::Component(t) => Self::Type(t),
34
        }
35
0
    }
36
}
37
38
impl<'a> From<AnyType<'a>> for InstanceTypeDecl<'a> {
39
0
    fn from(t: AnyType<'a>) -> Self {
40
0
        match t {
41
0
            AnyType::Core(t) => Self::CoreType(t),
42
0
            AnyType::Component(t) => Self::Type(t),
43
        }
44
0
    }
45
}
46
47
impl<'a> From<AnyType<'a>> for ComponentField<'a> {
48
14
    fn from(t: AnyType<'a>) -> Self {
49
14
        match t {
50
0
            AnyType::Core(t) => Self::CoreType(t),
51
14
            AnyType::Component(t) => Self::Type(t),
52
        }
53
14
    }
54
}
55
56
558
#[derive(Default)]
57
struct Expander<'a> {
58
    /// Fields, during processing, which should be prepended to the
59
    /// currently-being-processed field. This should always be empty after
60
    /// processing is complete.
61
    types_to_prepend: Vec<AnyType<'a>>,
62
    component_fields_to_prepend: Vec<ComponentField<'a>>,
63
64
    /// Fields that are appended to the end of the module once everything has
65
    /// finished.
66
    component_fields_to_append: Vec<ComponentField<'a>>,
67
}
68
69
impl<'a> Expander<'a> {
70
425
    fn expand_component_fields(&mut self, fields: &mut Vec<ComponentField<'a>>) {
71
425
        let mut cur = 0;
72
1.39k
        while cur < fields.len() {
73
969
            self.expand_field(&mut fields[cur]);
74
969
            let amt = self.types_to_prepend.len() + self.component_fields_to_prepend.len();
75
969
            fields.splice(cur..cur, self.component_fields_to_prepend.drain(..));
76
969
            fields.splice(cur..cur, self.types_to_prepend.drain(..).map(Into::into));
77
969
            cur += 1 + amt;
78
969
        }
79
425
        fields.append(&mut self.component_fields_to_append);
80
425
    }
81
82
133
    fn expand_decls<T>(&mut self, decls: &mut Vec<T>, expand: fn(&mut Self, &mut T))
83
133
    where
84
133
        T: From<AnyType<'a>>,
85
133
    {
86
133
        let mut cur = 0;
87
502
        while cur < decls.len() {
88
369
            expand(self, &mut decls[cur]);
89
369
            assert!(self.component_fields_to_prepend.is_empty());
90
369
            assert!(self.component_fields_to_append.is_empty());
91
369
            let amt = self.types_to_prepend.len();
92
369
            decls.splice(cur..cur, self.types_to_prepend.drain(..).map(From::from));
93
369
            cur += 1 + amt;
94
        }
95
133
    }
Unexecuted instantiation: <wast::component::expand::Expander>::expand_decls::<wast::component::types::InstanceTypeDecl>
<wast::component::expand::Expander>::expand_decls::<wast::component::types::ComponentTypeDecl>
Line
Count
Source
82
133
    fn expand_decls<T>(&mut self, decls: &mut Vec<T>, expand: fn(&mut Self, &mut T))
83
133
    where
84
133
        T: From<AnyType<'a>>,
85
133
    {
86
133
        let mut cur = 0;
87
502
        while cur < decls.len() {
88
369
            expand(self, &mut decls[cur]);
89
369
            assert!(self.component_fields_to_prepend.is_empty());
90
369
            assert!(self.component_fields_to_append.is_empty());
91
369
            let amt = self.types_to_prepend.len();
92
369
            decls.splice(cur..cur, self.types_to_prepend.drain(..).map(From::from));
93
369
            cur += 1 + amt;
94
        }
95
133
    }
96
97
969
    fn expand_field(&mut self, item: &mut ComponentField<'a>) {
98
969
        let expanded = match item {
99
0
            ComponentField::CoreModule(m) => self.expand_core_module(m),
100
0
            ComponentField::CoreInstance(i) => {
101
0
                self.expand_core_instance(i);
102
0
                None
103
            }
104
0
            ComponentField::CoreType(t) => {
105
0
                self.expand_core_type(t);
106
0
                None
107
            }
108
370
            ComponentField::Component(c) => self.expand_nested_component(c),
109
0
            ComponentField::Instance(i) => self.expand_instance(i),
110
599
            ComponentField::Type(t) => {
111
599
                self.expand_type(t);
112
599
                None
113
            }
114
0
            ComponentField::CanonicalFunc(f) => {
115
0
                self.expand_canonical_func(f);
116
0
                None
117
            }
118
0
            ComponentField::CoreFunc(f) => self.expand_core_func(f),
119
0
            ComponentField::Func(f) => self.expand_func(f),
120
0
            ComponentField::Import(i) => {
121
0
                self.expand_item_sig(&mut i.item);
122
0
                None
123
            }
124
0
            ComponentField::Export(e) => {
125
0
                if let Some(sig) = &mut e.ty {
126
0
                    self.expand_item_sig(&mut sig.0);
127
0
                }
128
0
                None
129
            }
130
0
            ComponentField::Start(_) | ComponentField::Alias(_) | ComponentField::Custom(_) => None,
131
        };
132
133
969
        if let Some(expanded) = expanded {
134
0
            *item = expanded;
135
969
        }
136
969
    }
137
138
0
    fn expand_core_module(&mut self, module: &mut CoreModule<'a>) -> Option<ComponentField<'a>> {
139
0
        for (name, url) in module.exports.names.drain(..) {
140
0
            let id = gensym::fill(module.span, &mut module.id);
141
0
            self.component_fields_to_append
142
0
                .push(ComponentField::Export(ComponentExport {
143
0
                    span: module.span,
144
0
                    id: None,
145
0
                    debug_name: None,
146
0
                    name,
147
0
                    url,
148
0
                    kind: ComponentExportKind::module(module.span, id),
149
0
                    ty: None,
150
0
                }));
151
0
        }
152
0
        match &mut module.kind {
153
            // inline modules are expanded later during resolution
154
0
            CoreModuleKind::Inline { .. } => None,
155
0
            CoreModuleKind::Import { import, ty } => {
156
0
                let idx = self.expand_core_type_use(ty);
157
0
                Some(ComponentField::Import(ComponentImport {
158
0
                    span: module.span,
159
0
                    name: import.name,
160
0
                    url: import.url,
161
0
                    item: ItemSig {
162
0
                        span: module.span,
163
0
                        id: module.id,
164
0
                        name: None,
165
0
                        kind: ItemSigKind::CoreModule(CoreTypeUse::Ref(idx)),
166
0
                    },
167
0
                }))
168
            }
169
        }
170
0
    }
171
172
0
    fn expand_core_instance(&mut self, instance: &mut CoreInstance<'a>) {
173
0
        match &mut instance.kind {
174
0
            CoreInstanceKind::Instantiate { args, .. } => {
175
0
                for arg in args {
176
0
                    self.expand_core_instantiation_arg(&mut arg.kind);
177
0
                }
178
            }
179
0
            CoreInstanceKind::BundleOfExports { .. } => {}
180
        }
181
0
    }
182
183
370
    fn expand_nested_component(
184
370
        &mut self,
185
370
        component: &mut NestedComponent<'a>,
186
370
    ) -> Option<ComponentField<'a>> {
187
370
        for (name, url) in component.exports.names.drain(..) {
188
0
            let id = gensym::fill(component.span, &mut component.id);
189
0
            self.component_fields_to_append
190
0
                .push(ComponentField::Export(ComponentExport {
191
0
                    span: component.span,
192
0
                    id: None,
193
0
                    debug_name: None,
194
0
                    name,
195
0
                    url,
196
0
                    kind: ComponentExportKind::component(component.span, id),
197
0
                    ty: None,
198
0
                }));
199
0
        }
200
370
        match &mut component.kind {
201
370
            NestedComponentKind::Inline(fields) => {
202
370
                expand(fields);
203
370
                None
204
            }
205
0
            NestedComponentKind::Import { import, ty } => {
206
0
                let idx = self.expand_component_type_use(ty);
207
0
                Some(ComponentField::Import(ComponentImport {
208
0
                    span: component.span,
209
0
                    name: import.name,
210
0
                    url: import.url,
211
0
                    item: ItemSig {
212
0
                        span: component.span,
213
0
                        id: component.id,
214
0
                        name: None,
215
0
                        kind: ItemSigKind::Component(ComponentTypeUse::Ref(idx)),
216
0
                    },
217
0
                }))
218
            }
219
        }
220
370
    }
221
222
0
    fn expand_instance(&mut self, instance: &mut Instance<'a>) -> Option<ComponentField<'a>> {
223
0
        for (name, url) in instance.exports.names.drain(..) {
224
0
            let id = gensym::fill(instance.span, &mut instance.id);
225
0
            self.component_fields_to_append
226
0
                .push(ComponentField::Export(ComponentExport {
227
0
                    span: instance.span,
228
0
                    id: None,
229
0
                    debug_name: None,
230
0
                    name,
231
0
                    url,
232
0
                    kind: ComponentExportKind::instance(instance.span, id),
233
0
                    ty: None,
234
0
                }));
235
0
        }
236
0
        match &mut instance.kind {
237
0
            InstanceKind::Import { import, ty } => {
238
0
                let idx = self.expand_component_type_use(ty);
239
0
                Some(ComponentField::Import(ComponentImport {
240
0
                    span: instance.span,
241
0
                    name: import.name,
242
0
                    url: import.url,
243
0
                    item: ItemSig {
244
0
                        span: instance.span,
245
0
                        id: instance.id,
246
0
                        name: None,
247
0
                        kind: ItemSigKind::Instance(ComponentTypeUse::Ref(idx)),
248
0
                    },
249
0
                }))
250
            }
251
0
            InstanceKind::Instantiate { args, .. } => {
252
0
                for arg in args {
253
0
                    self.expand_instantiation_arg(&mut arg.kind);
254
0
                }
255
0
                None
256
            }
257
0
            InstanceKind::BundleOfExports { .. } => None,
258
        }
259
0
    }
260
261
0
    fn expand_canonical_func(&mut self, func: &mut CanonicalFunc<'a>) {
262
0
        match &mut func.kind {
263
0
            CanonicalFuncKind::Lift { ty, .. } => {
264
0
                self.expand_component_type_use(ty);
265
0
            }
266
0
            CanonicalFuncKind::Lower(_) => {}
267
        }
268
0
    }
269
270
0
    fn expand_core_func(&mut self, func: &mut CoreFunc<'a>) -> Option<ComponentField<'a>> {
271
0
        match &mut func.kind {
272
0
            CoreFuncKind::Alias(a) => Some(ComponentField::Alias(Alias {
273
0
                span: func.span,
274
0
                id: func.id,
275
0
                name: func.name,
276
0
                target: AliasTarget::CoreExport {
277
0
                    instance: a.instance,
278
0
                    name: a.name,
279
0
                    kind: core::ExportKind::Func,
280
0
                },
281
0
            })),
282
0
            CoreFuncKind::Lower(info) => Some(ComponentField::CanonicalFunc(CanonicalFunc {
283
0
                span: func.span,
284
0
                id: func.id,
285
0
                name: func.name,
286
0
                kind: CanonicalFuncKind::Lower(mem::take(info)),
287
0
            })),
288
        }
289
0
    }
290
291
0
    fn expand_func(&mut self, func: &mut Func<'a>) -> Option<ComponentField<'a>> {
292
0
        for (name, url) in func.exports.names.drain(..) {
293
0
            let id = gensym::fill(func.span, &mut func.id);
294
0
            self.component_fields_to_append
295
0
                .push(ComponentField::Export(ComponentExport {
296
0
                    span: func.span,
297
0
                    id: None,
298
0
                    debug_name: None,
299
0
                    name,
300
0
                    url,
301
0
                    kind: ComponentExportKind::func(func.span, id),
302
0
                    ty: None,
303
0
                }));
304
0
        }
305
0
        match &mut func.kind {
306
0
            FuncKind::Import { import, ty } => {
307
0
                let idx = self.expand_component_type_use(ty);
308
0
                Some(ComponentField::Import(ComponentImport {
309
0
                    span: func.span,
310
0
                    name: import.name,
311
0
                    url: import.url,
312
0
                    item: ItemSig {
313
0
                        span: func.span,
314
0
                        id: func.id,
315
0
                        name: None,
316
0
                        kind: ItemSigKind::Func(ComponentTypeUse::Ref(idx)),
317
0
                    },
318
0
                }))
319
            }
320
0
            FuncKind::Lift { ty, info } => {
321
0
                let idx = self.expand_component_type_use(ty);
322
0
                Some(ComponentField::CanonicalFunc(CanonicalFunc {
323
0
                    span: func.span,
324
0
                    id: func.id,
325
0
                    name: func.name,
326
0
                    kind: CanonicalFuncKind::Lift {
327
0
                        ty: ComponentTypeUse::Ref(idx),
328
0
                        info: mem::take(info),
329
0
                    },
330
0
                }))
331
            }
332
0
            FuncKind::Alias(a) => Some(ComponentField::Alias(Alias {
333
0
                span: func.span,
334
0
                id: func.id,
335
0
                name: func.name,
336
0
                target: AliasTarget::Export {
337
0
                    instance: a.instance,
338
0
                    name: a.name,
339
0
                    kind: ComponentExportAliasKind::Func,
340
0
                },
341
0
            })),
342
        }
343
0
    }
344
345
0
    fn expand_core_type(&mut self, field: &mut CoreType<'a>) {
346
0
        match &mut field.def {
347
0
            CoreTypeDef::Def(_) => {}
348
0
            CoreTypeDef::Module(m) => self.expand_module_ty(m),
349
        }
350
351
0
        let id = gensym::fill(field.span, &mut field.id);
352
0
        let index = Index::Id(id);
353
0
        match &field.def {
354
0
            CoreTypeDef::Def(_) => {}
355
0
            CoreTypeDef::Module(t) => t.key().insert(self, index),
356
        }
357
0
    }
358
359
968
    fn expand_type(&mut self, field: &mut Type<'a>) {
360
968
        match &mut field.def {
361
9
            TypeDef::Defined(d) => self.expand_defined_ty(d),
362
826
            TypeDef::Func(f) => self.expand_func_ty(f),
363
133
            TypeDef::Component(c) => self.expand_component_ty(c),
364
0
            TypeDef::Instance(i) => self.expand_instance_ty(i),
365
        }
366
367
968
        let id = gensym::fill(field.span, &mut field.id);
368
968
        let index = Index::Id(id);
369
968
        match &field.def {
370
9
            TypeDef::Defined(t) => t.key().insert(self, index),
371
826
            TypeDef::Func(t) => t.key().insert(self, index),
372
133
            TypeDef::Component(t) => t.key().insert(self, index),
373
0
            TypeDef::Instance(t) => t.key().insert(self, index),
374
        }
375
968
        for (name, url) in field.exports.names.drain(..) {
376
0
            self.component_fields_to_append
377
0
                .push(ComponentField::Export(ComponentExport {
378
0
                    span: field.span,
379
0
                    id: None,
380
0
                    debug_name: None,
381
0
                    name,
382
0
                    url,
383
0
                    kind: ComponentExportKind::ty(field.span, id),
384
0
                    ty: None,
385
0
                }));
386
0
        }
387
968
    }
388
389
826
    fn expand_func_ty(&mut self, ty: &mut ComponentFunctionType<'a>) {
390
826
        for param in ty.params.iter_mut() {
391
0
            self.expand_component_val_ty(&mut param.ty);
392
0
        }
393
394
826
        for result in ty.results.iter_mut() {
395
0
            self.expand_component_val_ty(&mut result.ty);
396
0
        }
397
826
    }
398
399
0
    fn expand_module_ty(&mut self, ty: &mut ModuleType<'a>) {
400
0
        use crate::core::resolve::types::{FuncKey, TypeKey, TypeReference};
401
0
402
0
        // Note that this is a custom implementation from everything else in
403
0
        // this file since this is using core wasm types instead of component
404
0
        // types, so a small part of the core wasm expansion process is
405
0
        // inlined here to handle the `TypeUse` from core wasm.
406
0
407
0
        let mut func_type_to_idx = HashMap::new();
408
0
        let mut to_prepend = Vec::new();
409
0
        let mut i = 0;
410
0
        while i < ty.decls.len() {
411
0
            match &mut ty.decls[i] {
412
0
                ModuleTypeDecl::Type(ty) => match &ty.def {
413
0
                    core::TypeDef::Func(f) => {
414
0
                        let id = gensym::fill(ty.span, &mut ty.id);
415
0
                        func_type_to_idx.insert(f.key(), Index::Id(id));
416
0
                    }
417
0
                    core::TypeDef::Struct(_) => {}
418
0
                    core::TypeDef::Array(_) => {}
419
                },
420
0
                ModuleTypeDecl::Alias(_) => {}
421
0
                ModuleTypeDecl::Import(ty) => {
422
0
                    expand_sig(&mut ty.item, &mut to_prepend, &mut func_type_to_idx);
423
0
                }
424
0
                ModuleTypeDecl::Export(_, item) => {
425
0
                    expand_sig(item, &mut to_prepend, &mut func_type_to_idx);
426
0
                }
427
            }
428
0
            ty.decls.splice(i..i, to_prepend.drain(..));
429
0
            i += 1;
430
        }
431
432
0
        fn expand_sig<'a>(
433
0
            item: &mut core::ItemSig<'a>,
434
0
            to_prepend: &mut Vec<ModuleTypeDecl<'a>>,
435
0
            func_type_to_idx: &mut HashMap<FuncKey<'a>, Index<'a>>,
436
0
        ) {
437
0
            match &mut item.kind {
438
0
                core::ItemKind::Func(t) | core::ItemKind::Tag(core::TagType::Exception(t)) => {
439
                    // If the index is already filled in then this is skipped
440
0
                    if t.index.is_some() {
441
0
                        return;
442
0
                    }
443
0
444
0
                    // Otherwise the inline type information is used to
445
0
                    // generate a type into this module if necessary. If the
446
0
                    // function type already exists we reuse the same key,
447
0
                    // otherwise a fresh type definition is created and we use
448
0
                    // that one instead.
449
0
                    let ty = t.inline.take().unwrap_or_default();
450
0
                    let key = ty.key();
451
0
                    if let Some(idx) = func_type_to_idx.get(&key) {
452
0
                        t.index = Some(*idx);
453
0
                        return;
454
0
                    }
455
0
                    let id = gensym::gen(item.span);
456
0
                    to_prepend.push(ModuleTypeDecl::Type(core::Type {
457
0
                        span: item.span,
458
0
                        id: Some(id),
459
0
                        name: None,
460
0
                        def: key.to_def(item.span),
461
0
                        parent: None,
462
0
                    }));
463
0
                    let idx = Index::Id(id);
464
0
                    t.index = Some(idx);
465
                }
466
                core::ItemKind::Global(_)
467
                | core::ItemKind::Table(_)
468
0
                | core::ItemKind::Memory(_) => {}
469
            }
470
0
        }
471
0
    }
472
473
133
    fn expand_component_ty(&mut self, ty: &mut ComponentType<'a>) {
474
369
        Expander::default().expand_decls(&mut ty.decls, |e, decl| match decl {
475
0
            ComponentTypeDecl::CoreType(t) => e.expand_core_type(t),
476
369
            ComponentTypeDecl::Type(t) => e.expand_type(t),
477
0
            ComponentTypeDecl::Alias(_) => {}
478
0
            ComponentTypeDecl::Export(t) => e.expand_item_sig(&mut t.item),
479
0
            ComponentTypeDecl::Import(t) => e.expand_item_sig(&mut t.item),
480
369
        })
481
133
    }
482
483
0
    fn expand_instance_ty(&mut self, ty: &mut InstanceType<'a>) {
484
0
        Expander::default().expand_decls(&mut ty.decls, |e, decl| match decl {
485
0
            InstanceTypeDecl::CoreType(t) => e.expand_core_type(t),
486
0
            InstanceTypeDecl::Type(t) => e.expand_type(t),
487
0
            InstanceTypeDecl::Alias(_) => {}
488
0
            InstanceTypeDecl::Export(t) => e.expand_item_sig(&mut t.item),
489
0
        })
490
0
    }
491
492
0
    fn expand_item_sig(&mut self, ext: &mut ItemSig<'a>) {
493
0
        match &mut ext.kind {
494
0
            ItemSigKind::CoreModule(t) => {
495
0
                self.expand_core_type_use(t);
496
0
            }
497
0
            ItemSigKind::Func(t) => {
498
0
                self.expand_component_type_use(t);
499
0
            }
500
0
            ItemSigKind::Component(t) => {
501
0
                self.expand_component_type_use(t);
502
0
            }
503
0
            ItemSigKind::Instance(t) => {
504
0
                self.expand_component_type_use(t);
505
0
            }
506
0
            ItemSigKind::Value(t) => {
507
0
                self.expand_component_val_ty(&mut t.0);
508
0
            }
509
0
            ItemSigKind::Type(_) => {}
510
        }
511
0
    }
512
513
23
    fn expand_defined_ty(&mut self, ty: &mut ComponentDefinedType<'a>) {
514
23
        match ty {
515
            ComponentDefinedType::Primitive(_)
516
            | ComponentDefinedType::Flags(_)
517
3
            | ComponentDefinedType::Enum(_) => {}
518
0
            ComponentDefinedType::Record(r) => {
519
0
                for field in r.fields.iter_mut() {
520
0
                    self.expand_component_val_ty(&mut field.ty);
521
0
                }
522
            }
523
0
            ComponentDefinedType::Variant(v) => {
524
0
                for case in v.cases.iter_mut() {
525
0
                    if let Some(ty) = &mut case.ty {
526
0
                        self.expand_component_val_ty(ty);
527
0
                    }
528
                }
529
            }
530
0
            ComponentDefinedType::List(t) => {
531
0
                self.expand_component_val_ty(&mut t.element);
532
0
            }
533
2
            ComponentDefinedType::Tuple(t) => {
534
3
                for field in t.fields.iter_mut() {
535
3
                    self.expand_component_val_ty(field);
536
3
                }
537
            }
538
18
            ComponentDefinedType::Union(u) => {
539
42
                for ty in u.types.iter_mut() {
540
42
                    self.expand_component_val_ty(ty);
541
42
                }
542
            }
543
0
            ComponentDefinedType::Option(t) => {
544
0
                self.expand_component_val_ty(&mut t.element);
545
0
            }
546
0
            ComponentDefinedType::Result(r) => {
547
0
                if let Some(ty) = &mut r.ok {
548
0
                    self.expand_component_val_ty(ty);
549
0
                }
550
551
0
                if let Some(ty) = &mut r.err {
552
0
                    self.expand_component_val_ty(ty);
553
0
                }
554
            }
555
        }
556
23
    }
557
558
45
    fn expand_component_val_ty(&mut self, ty: &mut ComponentValType<'a>) {
559
15
        let inline = match ty {
560
            ComponentValType::Inline(ComponentDefinedType::Primitive(_))
561
31
            | ComponentValType::Ref(_) => return,
562
14
            ComponentValType::Inline(inline) => {
563
14
                self.expand_defined_ty(inline);
564
14
                mem::take(inline)
565
            }
566
        };
567
        // If this inline type has already been defined within this context
568
        // then reuse the previously defined type to avoid injecting too many
569
        // types into the type index space.
570
14
        if let Some(idx) = inline.key().lookup(self) {
571
0
            *ty = ComponentValType::Ref(idx);
572
0
            return;
573
14
        }
574
14
575
14
        // And if this type isn't already defined we append it to the index
576
14
        // space with a fresh and unique name.
577
14
        let span = Span::from_offset(0); // FIXME(#613): don't manufacture
578
14
        let id = gensym::gen(span);
579
14
580
14
        self.types_to_prepend.push(inline.into_any_type(span, id));
581
14
582
14
        let idx = Index::Id(id);
583
14
        *ty = ComponentValType::Ref(idx);
584
45
    }
585
586
0
    fn expand_core_type_use<T>(
587
0
        &mut self,
588
0
        item: &mut CoreTypeUse<'a, T>,
589
0
    ) -> CoreItemRef<'a, kw::r#type>
590
0
    where
591
0
        T: TypeReference<'a>,
592
0
    {
593
0
        let span = Span::from_offset(0); // FIXME(#613): don't manufacture
594
0
        let mut inline = match mem::take(item) {
595
            // If this type-use was already a reference to an existing type
596
            // then we put it back the way it was and return the corresponding
597
            // index.
598
0
            CoreTypeUse::Ref(idx) => {
599
0
                *item = CoreTypeUse::Ref(idx.clone());
600
0
                return idx;
601
            }
602
603
            // ... otherwise with an inline type definition we go into
604
            // processing below.
605
0
            CoreTypeUse::Inline(inline) => inline,
606
0
        };
607
0
        inline.expand(self);
608
609
        // If this inline type has already been defined within this context
610
        // then reuse the previously defined type to avoid injecting too many
611
        // types into the type index space.
612
0
        if let Some(idx) = inline.key().lookup(self) {
613
0
            let ret = CoreItemRef {
614
0
                idx,
615
0
                kind: kw::r#type(span),
616
0
                export_name: None,
617
0
            };
618
0
            *item = CoreTypeUse::Ref(ret.clone());
619
0
            return ret;
620
0
        }
621
0
622
0
        // And if this type isn't already defined we append it to the index
623
0
        // space with a fresh and unique name.
624
0
        let id = gensym::gen(span);
625
0
626
0
        self.types_to_prepend.push(inline.into_any_type(span, id));
627
0
628
0
        let idx = Index::Id(id);
629
0
        let ret = CoreItemRef {
630
0
            idx,
631
0
            kind: kw::r#type(span),
632
0
            export_name: None,
633
0
        };
634
0
635
0
        *item = CoreTypeUse::Ref(ret.clone());
636
0
        ret
637
0
    }
638
639
0
    fn expand_component_type_use<T>(
640
0
        &mut self,
641
0
        item: &mut ComponentTypeUse<'a, T>,
642
0
    ) -> ItemRef<'a, kw::r#type>
643
0
    where
644
0
        T: TypeReference<'a>,
645
0
    {
646
0
        let span = Span::from_offset(0); // FIXME(#613): don't manufacture
647
0
        let mut inline = match mem::take(item) {
648
            // If this type-use was already a reference to an existing type
649
            // then we put it back the way it was and return the corresponding
650
            // index.
651
0
            ComponentTypeUse::Ref(idx) => {
652
0
                *item = ComponentTypeUse::Ref(idx.clone());
653
0
                return idx;
654
            }
655
656
            // ... otherwise with an inline type definition we go into
657
            // processing below.
658
0
            ComponentTypeUse::Inline(inline) => inline,
659
0
        };
660
0
        inline.expand(self);
661
662
        // If this inline type has already been defined within this context
663
        // then reuse the previously defined type to avoid injecting too many
664
        // types into the type index space.
665
0
        if let Some(idx) = inline.key().lookup(self) {
666
0
            let ret = ItemRef {
667
0
                idx,
668
0
                kind: kw::r#type(span),
669
0
                export_names: Vec::new(),
670
0
            };
671
0
            *item = ComponentTypeUse::Ref(ret.clone());
672
0
            return ret;
673
0
        }
674
0
675
0
        // And if this type isn't already defined we append it to the index
676
0
        // space with a fresh and unique name.
677
0
        let id = gensym::gen(span);
678
0
679
0
        self.types_to_prepend.push(inline.into_any_type(span, id));
680
0
681
0
        let idx = Index::Id(id);
682
0
        let ret = ItemRef {
683
0
            idx,
684
0
            kind: kw::r#type(span),
685
0
            export_names: Vec::new(),
686
0
        };
687
0
688
0
        *item = ComponentTypeUse::Ref(ret.clone());
689
0
        ret
690
0
    }
Unexecuted instantiation: <wast::component::expand::Expander>::expand_component_type_use::<wast::component::types::InstanceType>
Unexecuted instantiation: <wast::component::expand::Expander>::expand_component_type_use::<wast::component::types::ComponentFunctionType>
Unexecuted instantiation: <wast::component::expand::Expander>::expand_component_type_use::<wast::component::types::ComponentType>
691
692
0
    fn expand_core_instantiation_arg(&mut self, arg: &mut CoreInstantiationArgKind<'a>) {
693
0
        let (span, exports) = match arg {
694
0
            CoreInstantiationArgKind::Instance(_) => return,
695
0
            CoreInstantiationArgKind::BundleOfExports(span, exports) => (*span, mem::take(exports)),
696
0
        };
697
0
        let id = gensym::gen(span);
698
0
        self.component_fields_to_prepend
699
0
            .push(ComponentField::CoreInstance(CoreInstance {
700
0
                span,
701
0
                id: Some(id),
702
0
                name: None,
703
0
                kind: CoreInstanceKind::BundleOfExports(exports),
704
0
            }));
705
0
        *arg = CoreInstantiationArgKind::Instance(CoreItemRef {
706
0
            kind: kw::instance(span),
707
0
            idx: Index::Id(id),
708
0
            export_name: None,
709
0
        });
710
0
    }
711
712
0
    fn expand_instantiation_arg(&mut self, arg: &mut InstantiationArgKind<'a>) {
713
0
        let (span, exports) = match arg {
714
0
            InstantiationArgKind::Item(_) => return,
715
0
            InstantiationArgKind::BundleOfExports(span, exports) => (*span, mem::take(exports)),
716
0
        };
717
0
        let id = gensym::gen(span);
718
0
        self.component_fields_to_prepend
719
0
            .push(ComponentField::Instance(Instance {
720
0
                span,
721
0
                id: Some(id),
722
0
                name: None,
723
0
                exports: Default::default(),
724
0
                kind: InstanceKind::BundleOfExports(exports),
725
0
            }));
726
0
        *arg = InstantiationArgKind::Item(ComponentExportKind::instance(span, id));
727
0
    }
728
}
729
730
trait TypeReference<'a> {
731
    type Key: TypeKey<'a>;
732
    fn key(&self) -> Self::Key;
733
    fn expand(&mut self, cx: &mut Expander<'a>);
734
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a>;
735
}
736
737
impl<'a> TypeReference<'a> for ComponentDefinedType<'a> {
738
    type Key = Todo; // FIXME(#598): should implement this
739
740
23
    fn key(&self) -> Self::Key {
741
23
        Todo
742
23
    }
743
744
0
    fn expand(&mut self, cx: &mut Expander<'a>) {
745
0
        cx.expand_defined_ty(self)
746
0
    }
747
748
14
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a> {
749
14
        AnyType::Component(Type {
750
14
            span,
751
14
            id: Some(id),
752
14
            name: None,
753
14
            exports: Default::default(),
754
14
            def: TypeDef::Defined(self),
755
14
        })
756
14
    }
757
}
758
759
impl<'a> TypeReference<'a> for ComponentType<'a> {
760
    type Key = Todo; // FIXME(#598): should implement this
761
762
133
    fn key(&self) -> Self::Key {
763
133
        Todo
764
133
    }
765
766
0
    fn expand(&mut self, cx: &mut Expander<'a>) {
767
0
        cx.expand_component_ty(self)
768
0
    }
769
770
0
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a> {
771
0
        AnyType::Component(Type {
772
0
            span,
773
0
            id: Some(id),
774
0
            name: None,
775
0
            exports: Default::default(),
776
0
            def: TypeDef::Component(self),
777
0
        })
778
0
    }
779
}
780
781
impl<'a> TypeReference<'a> for ModuleType<'a> {
782
    type Key = Todo; // FIXME(#598): should implement this
783
784
0
    fn key(&self) -> Self::Key {
785
0
        Todo
786
0
    }
787
788
0
    fn expand(&mut self, cx: &mut Expander<'a>) {
789
0
        cx.expand_module_ty(self)
790
0
    }
791
792
0
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a> {
793
0
        AnyType::Core(CoreType {
794
0
            span,
795
0
            id: Some(id),
796
0
            name: None,
797
0
            def: CoreTypeDef::Module(self),
798
0
        })
799
0
    }
800
}
801
802
impl<'a> TypeReference<'a> for InstanceType<'a> {
803
    type Key = Todo; // FIXME(#598): should implement this
804
805
0
    fn key(&self) -> Self::Key {
806
0
        Todo
807
0
    }
808
809
0
    fn expand(&mut self, cx: &mut Expander<'a>) {
810
0
        cx.expand_instance_ty(self)
811
0
    }
812
813
0
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a> {
814
0
        AnyType::Component(Type {
815
0
            span,
816
0
            id: Some(id),
817
0
            name: None,
818
0
            exports: Default::default(),
819
0
            def: TypeDef::Instance(self),
820
0
        })
821
0
    }
822
}
823
824
impl<'a> TypeReference<'a> for ComponentFunctionType<'a> {
825
    type Key = Todo; // FIXME(#598): should implement this
826
827
826
    fn key(&self) -> Self::Key {
828
826
        Todo
829
826
    }
830
831
0
    fn expand(&mut self, cx: &mut Expander<'a>) {
832
0
        cx.expand_func_ty(self)
833
0
    }
834
835
0
    fn into_any_type(self, span: Span, id: Id<'a>) -> AnyType<'a> {
836
0
        AnyType::Component(Type {
837
0
            span,
838
0
            id: Some(id),
839
0
            name: None,
840
0
            exports: Default::default(),
841
0
            def: TypeDef::Func(self),
842
0
        })
843
0
    }
844
}
845
846
trait TypeKey<'a> {
847
    fn lookup(&self, cx: &Expander<'a>) -> Option<Index<'a>>;
848
    fn insert(&self, cx: &mut Expander<'a>, index: Index<'a>);
849
}
850
851
struct Todo;
852
853
impl<'a> TypeKey<'a> for Todo {
854
14
    fn lookup(&self, _cx: &Expander<'a>) -> Option<Index<'a>> {
855
14
        None
856
14
    }
857
858
968
    fn insert(&self, _cx: &mut Expander<'a>, _index: Index<'a>) {}
859
}