Coverage Report

Created: 2026-06-21 07:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wasm-tools/crates/wit-component/src/printing.rs
Line
Count
Source
1
use anyhow::{Result, anyhow, bail};
2
use std::borrow::Cow;
3
use std::collections::HashMap;
4
use std::fmt::Display;
5
use std::mem;
6
use std::ops::Deref;
7
use wit_parser::*;
8
9
/// A utility for printing WebAssembly interface definitions to a string.
10
pub struct WitPrinter<O: Output = OutputToString> {
11
    /// Visitor that holds the WIT document being printed.
12
    pub output: O,
13
14
    // Count of how many items in this current block have been printed to print
15
    // a blank line between each item, but not the first item.
16
    any_items: bool,
17
18
    // Whether to print doc comments.
19
    emit_docs: bool,
20
}
21
22
impl Default for WitPrinter {
23
4.67k
    fn default() -> Self {
24
4.67k
        Self::new(OutputToString::default())
25
4.67k
    }
26
}
27
28
impl<O: Output> WitPrinter<O> {
29
    /// Create new instance.
30
4.67k
    pub fn new(output: O) -> Self {
31
4.67k
        Self {
32
4.67k
            output,
33
4.67k
            any_items: false,
34
4.67k
            emit_docs: true,
35
4.67k
        }
36
4.67k
    }
37
38
    /// Prints the specified `pkg` which is located in `resolve` to `O`.
39
    ///
40
    /// The `nested` list of packages are other packages to include at the end
41
    /// of the output in `package ... { ... }` syntax.
42
4.67k
    pub fn print(&mut self, resolve: &Resolve, pkg: PackageId, nested: &[PackageId]) -> Result<()> {
43
4.67k
        self.print_package(resolve, pkg, true)?;
44
4.67k
        for (i, pkg_id) in nested.iter().enumerate() {
45
852
            if i > 0 {
46
286
                self.output.newline();
47
286
                self.output.newline();
48
566
            }
49
852
            self.print_package(resolve, *pkg_id, false)?;
50
        }
51
4.67k
        Ok(())
52
4.67k
    }
<wit_component::printing::WitPrinter>::print
Line
Count
Source
42
4.67k
    pub fn print(&mut self, resolve: &Resolve, pkg: PackageId, nested: &[PackageId]) -> Result<()> {
43
4.67k
        self.print_package(resolve, pkg, true)?;
44
4.67k
        for (i, pkg_id) in nested.iter().enumerate() {
45
852
            if i > 0 {
46
286
                self.output.newline();
47
286
                self.output.newline();
48
566
            }
49
852
            self.print_package(resolve, *pkg_id, false)?;
50
        }
51
4.67k
        Ok(())
52
4.67k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print
53
54
    /// Configure whether doc comments will be printed.
55
    ///
56
    /// Defaults to true.
57
0
    pub fn emit_docs(&mut self, enabled: bool) -> &mut Self {
58
0
        self.emit_docs = enabled;
59
0
        self
60
0
    }
61
62
    /// Prints the specified `pkg`.
63
    ///
64
    /// If `is_main` is not set, nested package notation is used.
65
5.52k
    pub fn print_package(
66
5.52k
        &mut self,
67
5.52k
        resolve: &Resolve,
68
5.52k
        pkg: PackageId,
69
5.52k
        is_main: bool,
70
5.52k
    ) -> Result<()> {
71
5.52k
        let pkg = &resolve.packages[pkg];
72
5.52k
        self.print_package_outer(pkg)?;
73
74
5.52k
        if is_main {
75
4.67k
            self.output.semicolon();
76
4.67k
            self.output.newline();
77
4.67k
        } else {
78
852
            self.output.indent_start();
79
852
        }
80
81
22.9k
        for (name, id) in pkg.interfaces.iter() {
82
22.9k
            self.print_interface_outer(resolve, *id, name)?;
83
22.9k
            self.output.indent_start();
84
22.9k
            self.print_interface(resolve, *id)?;
85
22.9k
            self.output.indent_end();
86
22.9k
            if is_main {
87
21.6k
                self.output.newline();
88
21.6k
            }
89
        }
90
91
7.38k
        for (name, id) in pkg.worlds.iter() {
92
7.38k
            self.print_docs(&resolve.worlds[*id].docs);
93
7.38k
            self.print_stability(&resolve.worlds[*id].stability);
94
7.38k
            self.output.keyword("world");
95
7.38k
            self.output.str(" ");
96
7.38k
            self.print_name_type(name, TypeKind::WorldDeclaration);
97
7.38k
            self.output.indent_start();
98
7.38k
            self.print_world(resolve, *id)?;
99
7.38k
            self.output.indent_end();
100
        }
101
5.52k
        if !is_main {
102
852
            self.output.indent_end();
103
4.67k
        }
104
5.52k
        Ok(())
105
5.52k
    }
<wit_component::printing::WitPrinter>::print_package
Line
Count
Source
65
5.52k
    pub fn print_package(
66
5.52k
        &mut self,
67
5.52k
        resolve: &Resolve,
68
5.52k
        pkg: PackageId,
69
5.52k
        is_main: bool,
70
5.52k
    ) -> Result<()> {
71
5.52k
        let pkg = &resolve.packages[pkg];
72
5.52k
        self.print_package_outer(pkg)?;
73
74
5.52k
        if is_main {
75
4.67k
            self.output.semicolon();
76
4.67k
            self.output.newline();
77
4.67k
        } else {
78
852
            self.output.indent_start();
79
852
        }
80
81
22.9k
        for (name, id) in pkg.interfaces.iter() {
82
22.9k
            self.print_interface_outer(resolve, *id, name)?;
83
22.9k
            self.output.indent_start();
84
22.9k
            self.print_interface(resolve, *id)?;
85
22.9k
            self.output.indent_end();
86
22.9k
            if is_main {
87
21.6k
                self.output.newline();
88
21.6k
            }
89
        }
90
91
7.38k
        for (name, id) in pkg.worlds.iter() {
92
7.38k
            self.print_docs(&resolve.worlds[*id].docs);
93
7.38k
            self.print_stability(&resolve.worlds[*id].stability);
94
7.38k
            self.output.keyword("world");
95
7.38k
            self.output.str(" ");
96
7.38k
            self.print_name_type(name, TypeKind::WorldDeclaration);
97
7.38k
            self.output.indent_start();
98
7.38k
            self.print_world(resolve, *id)?;
99
7.38k
            self.output.indent_end();
100
        }
101
5.52k
        if !is_main {
102
852
            self.output.indent_end();
103
4.67k
        }
104
5.52k
        Ok(())
105
5.52k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_package
106
107
    /// Print the specified package without its content.
108
    /// Does not print the semicolon nor starts the indentation.
109
5.52k
    pub fn print_package_outer(&mut self, pkg: &Package) -> Result<()> {
110
5.52k
        self.print_docs(&pkg.docs);
111
5.52k
        self.output.keyword("package");
112
5.52k
        self.output.str(" ");
113
5.52k
        self.print_name_type(&pkg.name.namespace, TypeKind::NamespaceDeclaration);
114
5.52k
        self.output.str(":");
115
5.52k
        self.print_name_type(&pkg.name.name, TypeKind::PackageNameDeclaration);
116
5.52k
        if let Some(version) = &pkg.name.version {
117
3.85k
            self.print_name_type(&format!("@{version}"), TypeKind::VersionDeclaration);
118
3.85k
        }
119
5.52k
        Ok(())
120
5.52k
    }
<wit_component::printing::WitPrinter>::print_package_outer
Line
Count
Source
109
5.52k
    pub fn print_package_outer(&mut self, pkg: &Package) -> Result<()> {
110
5.52k
        self.print_docs(&pkg.docs);
111
5.52k
        self.output.keyword("package");
112
5.52k
        self.output.str(" ");
113
5.52k
        self.print_name_type(&pkg.name.namespace, TypeKind::NamespaceDeclaration);
114
5.52k
        self.output.str(":");
115
5.52k
        self.print_name_type(&pkg.name.name, TypeKind::PackageNameDeclaration);
116
5.52k
        if let Some(version) = &pkg.name.version {
117
3.85k
            self.print_name_type(&format!("@{version}"), TypeKind::VersionDeclaration);
118
3.85k
        }
119
5.52k
        Ok(())
120
5.52k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_package_outer
121
122
22.9k
    fn new_item(&mut self) {
123
22.9k
        if self.any_items {
124
16.1k
            self.output.newline();
125
16.1k
        }
126
22.9k
        self.any_items = true;
127
22.9k
    }
<wit_component::printing::WitPrinter>::new_item
Line
Count
Source
122
22.9k
    fn new_item(&mut self) {
123
22.9k
        if self.any_items {
124
16.1k
            self.output.newline();
125
16.1k
        }
126
22.9k
        self.any_items = true;
127
22.9k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::new_item
128
129
    /// Print the given WebAssembly interface without its content.
130
    /// Does not print the semicolon nor starts the indentation.
131
22.9k
    pub fn print_interface_outer(
132
22.9k
        &mut self,
133
22.9k
        resolve: &Resolve,
134
22.9k
        id: InterfaceId,
135
22.9k
        name: &str,
136
22.9k
    ) -> Result<()> {
137
22.9k
        self.print_docs(&resolve.interfaces[id].docs);
138
22.9k
        self.print_stability(&resolve.interfaces[id].stability);
139
22.9k
        self.output.keyword("interface");
140
22.9k
        self.output.str(" ");
141
22.9k
        self.print_name_type(name, TypeKind::InterfaceDeclaration);
142
22.9k
        Ok(())
143
22.9k
    }
<wit_component::printing::WitPrinter>::print_interface_outer
Line
Count
Source
131
22.9k
    pub fn print_interface_outer(
132
22.9k
        &mut self,
133
22.9k
        resolve: &Resolve,
134
22.9k
        id: InterfaceId,
135
22.9k
        name: &str,
136
22.9k
    ) -> Result<()> {
137
22.9k
        self.print_docs(&resolve.interfaces[id].docs);
138
22.9k
        self.print_stability(&resolve.interfaces[id].stability);
139
22.9k
        self.output.keyword("interface");
140
22.9k
        self.output.str(" ");
141
22.9k
        self.print_name_type(name, TypeKind::InterfaceDeclaration);
142
22.9k
        Ok(())
143
22.9k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_interface_outer
144
145
    /// Print the inner content of a given WebAssembly interface.
146
23.8k
    pub fn print_interface(&mut self, resolve: &Resolve, id: InterfaceId) -> Result<()> {
147
23.8k
        let prev_items = mem::replace(&mut self.any_items, false);
148
23.8k
        let interface = &resolve.interfaces[id];
149
150
23.8k
        let mut resource_funcs = HashMap::new();
151
23.8k
        let mut freestanding = Vec::new();
152
23.8k
        for (_, func) in interface.functions.iter() {
153
10.3k
            if let Some(id) = func.kind.resource() {
154
1.65k
                resource_funcs.entry(id).or_insert(Vec::new()).push(func);
155
8.73k
            } else {
156
8.73k
                freestanding.push(func);
157
8.73k
            }
158
        }
159
160
23.8k
        self.print_types(
161
23.8k
            resolve,
162
23.8k
            TypeOwner::Interface(id),
163
23.8k
            interface
164
23.8k
                .types
165
23.8k
                .iter()
166
23.8k
                .map(|(name, id)| (name.as_str(), *id)),
<wit_component::printing::WitPrinter>::print_interface::{closure#0}
Line
Count
Source
166
15.8k
                .map(|(name, id)| (name.as_str(), *id)),
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_interface::{closure#0}
167
23.8k
            &resource_funcs,
168
0
        )?;
169
170
23.8k
        for func in freestanding {
171
8.73k
            self.new_item();
172
8.73k
            self.print_docs(&func.docs);
173
8.73k
            self.print_stability(&func.stability);
174
8.73k
            self.print_name_type(func.item_name(), TypeKind::FunctionFreestanding);
175
8.73k
            self.output.str(": ");
176
8.73k
            self.print_function(resolve, func)?;
177
8.73k
            self.output.semicolon();
178
        }
179
180
23.8k
        self.any_items = prev_items;
181
182
23.8k
        Ok(())
183
23.8k
    }
<wit_component::printing::WitPrinter>::print_interface
Line
Count
Source
146
23.8k
    pub fn print_interface(&mut self, resolve: &Resolve, id: InterfaceId) -> Result<()> {
147
23.8k
        let prev_items = mem::replace(&mut self.any_items, false);
148
23.8k
        let interface = &resolve.interfaces[id];
149
150
23.8k
        let mut resource_funcs = HashMap::new();
151
23.8k
        let mut freestanding = Vec::new();
152
23.8k
        for (_, func) in interface.functions.iter() {
153
10.3k
            if let Some(id) = func.kind.resource() {
154
1.65k
                resource_funcs.entry(id).or_insert(Vec::new()).push(func);
155
8.73k
            } else {
156
8.73k
                freestanding.push(func);
157
8.73k
            }
158
        }
159
160
23.8k
        self.print_types(
161
23.8k
            resolve,
162
23.8k
            TypeOwner::Interface(id),
163
23.8k
            interface
164
23.8k
                .types
165
23.8k
                .iter()
166
23.8k
                .map(|(name, id)| (name.as_str(), *id)),
167
23.8k
            &resource_funcs,
168
0
        )?;
169
170
23.8k
        for func in freestanding {
171
8.73k
            self.new_item();
172
8.73k
            self.print_docs(&func.docs);
173
8.73k
            self.print_stability(&func.stability);
174
8.73k
            self.print_name_type(func.item_name(), TypeKind::FunctionFreestanding);
175
8.73k
            self.output.str(": ");
176
8.73k
            self.print_function(resolve, func)?;
177
8.73k
            self.output.semicolon();
178
        }
179
180
23.8k
        self.any_items = prev_items;
181
182
23.8k
        Ok(())
183
23.8k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_interface
184
185
    /// Print types of an interface.
186
31.2k
    pub fn print_types<'a>(
187
31.2k
        &mut self,
188
31.2k
        resolve: &Resolve,
189
31.2k
        owner: TypeOwner,
190
31.2k
        types: impl Iterator<Item = (&'a str, TypeId)>,
191
31.2k
        resource_funcs: &HashMap<TypeId, Vec<&Function>>,
192
31.2k
    ) -> Result<()> {
193
        // Partition types defined in this interface into either those imported
194
        // from foreign interfaces or those defined locally.
195
31.2k
        let mut types_to_declare = Vec::new();
196
31.2k
        let mut types_to_import: Vec<(_, &_, Vec<_>)> = Vec::new();
197
31.2k
        for (name, ty_id) in types {
198
20.2k
            let ty = &resolve.types[ty_id];
199
8.83k
            if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
200
8.06k
                let other = &resolve.types[other];
201
8.06k
                match other.owner {
202
0
                    TypeOwner::None => {}
203
8.06k
                    other_owner if owner != other_owner => {
204
8.03k
                        let other_name = other
205
8.03k
                            .name
206
8.03k
                            .as_ref()
207
8.03k
                            .ok_or_else(|| anyhow!("cannot import unnamed type"))?;
Unexecuted instantiation: <wit_component::printing::WitPrinter>::print_types::<alloc::vec::into_iter::IntoIter<(&str, id_arena::Id<wit_parser::TypeDef>)>>::{closure#0}
Unexecuted instantiation: <wit_component::printing::WitPrinter>::print_types::<core::iter::adapters::map::Map<indexmap::map::iter::Iter<alloc::string::String, id_arena::Id<wit_parser::TypeDef>>, <wit_component::printing::WitPrinter>::print_interface::{closure#0}>>::{closure#0}
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_types::<_>::{closure#0}
208
8.03k
                        if let Some((owner, stability, list)) = types_to_import.last_mut() {
209
5.80k
                            if *owner == other_owner && ty.stability == **stability {
210
3.72k
                                list.push((name, other_name));
211
3.72k
                                continue;
212
2.08k
                            }
213
2.23k
                        }
214
4.31k
                        types_to_import.push((
215
4.31k
                            other_owner,
216
4.31k
                            &ty.stability,
217
4.31k
                            vec![(name, other_name)],
218
4.31k
                        ));
219
4.31k
                        continue;
220
                    }
221
30
                    _ => {}
222
                }
223
12.2k
            }
224
225
12.2k
            types_to_declare.push(ty_id);
226
        }
227
228
        // Generate a `use` statement for all imported types.
229
31.2k
        let my_pkg = match owner {
230
23.8k
            TypeOwner::Interface(id) => resolve.interfaces[id].package.unwrap(),
231
7.38k
            TypeOwner::World(id) => resolve.worlds[id].package.unwrap(),
232
0
            TypeOwner::None => unreachable!(),
233
        };
234
31.2k
        for (owner, stability, tys) in types_to_import {
235
4.31k
            self.any_items = true;
236
4.31k
            self.print_stability(stability);
237
4.31k
            self.output.keyword("use");
238
4.31k
            self.output.str(" ");
239
4.31k
            let id = match owner {
240
4.31k
                TypeOwner::Interface(id) => id,
241
                // it's only possible to import types from interfaces at
242
                // this time.
243
0
                _ => unreachable!(),
244
            };
245
4.31k
            self.print_path_to_interface(resolve, id, my_pkg)?;
246
4.31k
            self.output.str(".{"); // Note: not changing the indentation.
247
8.03k
            for (i, (my_name, other_name)) in tys.into_iter().enumerate() {
248
8.03k
                if i > 0 {
249
3.72k
                    self.output.str(", ");
250
4.31k
                }
251
8.03k
                if my_name == other_name {
252
1.56k
                    self.print_name_type(my_name, TypeKind::TypeImport);
253
6.47k
                } else {
254
6.47k
                    self.print_name_type(other_name, TypeKind::TypeImport);
255
6.47k
                    self.output.str(" ");
256
6.47k
                    self.output.keyword("as");
257
6.47k
                    self.output.str(" ");
258
6.47k
                    self.print_name_type(my_name, TypeKind::TypeAlias);
259
6.47k
                }
260
            }
261
4.31k
            self.output.str("}"); // Note: not changing the indentation.
262
4.31k
            self.output.semicolon();
263
        }
264
265
31.2k
        for id in types_to_declare {
266
12.2k
            self.new_item();
267
12.2k
            self.print_docs(&resolve.types[id].docs);
268
12.2k
            self.print_stability(&resolve.types[id].stability);
269
12.2k
            match resolve.types[id].kind {
270
1.10k
                TypeDefKind::Resource => self.print_resource(
271
1.10k
                    resolve,
272
1.10k
                    id,
273
1.10k
                    resource_funcs.get(&id).unwrap_or(&Vec::new()),
274
0
                )?,
275
11.1k
                _ => self.declare_type(resolve, &Type::Id(id))?,
276
            }
277
        }
278
279
31.2k
        Ok(())
280
31.2k
    }
<wit_component::printing::WitPrinter>::print_types::<alloc::vec::into_iter::IntoIter<(&str, id_arena::Id<wit_parser::TypeDef>)>>
Line
Count
Source
186
7.38k
    pub fn print_types<'a>(
187
7.38k
        &mut self,
188
7.38k
        resolve: &Resolve,
189
7.38k
        owner: TypeOwner,
190
7.38k
        types: impl Iterator<Item = (&'a str, TypeId)>,
191
7.38k
        resource_funcs: &HashMap<TypeId, Vec<&Function>>,
192
7.38k
    ) -> Result<()> {
193
        // Partition types defined in this interface into either those imported
194
        // from foreign interfaces or those defined locally.
195
7.38k
        let mut types_to_declare = Vec::new();
196
7.38k
        let mut types_to_import: Vec<(_, &_, Vec<_>)> = Vec::new();
197
7.38k
        for (name, ty_id) in types {
198
4.47k
            let ty = &resolve.types[ty_id];
199
1.16k
            if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
200
792
                let other = &resolve.types[other];
201
792
                match other.owner {
202
0
                    TypeOwner::None => {}
203
792
                    other_owner if owner != other_owner => {
204
784
                        let other_name = other
205
784
                            .name
206
784
                            .as_ref()
207
784
                            .ok_or_else(|| anyhow!("cannot import unnamed type"))?;
208
784
                        if let Some((owner, stability, list)) = types_to_import.last_mut() {
209
320
                            if *owner == other_owner && ty.stability == **stability {
210
222
                                list.push((name, other_name));
211
222
                                continue;
212
98
                            }
213
464
                        }
214
562
                        types_to_import.push((
215
562
                            other_owner,
216
562
                            &ty.stability,
217
562
                            vec![(name, other_name)],
218
562
                        ));
219
562
                        continue;
220
                    }
221
8
                    _ => {}
222
                }
223
3.68k
            }
224
225
3.68k
            types_to_declare.push(ty_id);
226
        }
227
228
        // Generate a `use` statement for all imported types.
229
7.38k
        let my_pkg = match owner {
230
0
            TypeOwner::Interface(id) => resolve.interfaces[id].package.unwrap(),
231
7.38k
            TypeOwner::World(id) => resolve.worlds[id].package.unwrap(),
232
0
            TypeOwner::None => unreachable!(),
233
        };
234
7.38k
        for (owner, stability, tys) in types_to_import {
235
562
            self.any_items = true;
236
562
            self.print_stability(stability);
237
562
            self.output.keyword("use");
238
562
            self.output.str(" ");
239
562
            let id = match owner {
240
562
                TypeOwner::Interface(id) => id,
241
                // it's only possible to import types from interfaces at
242
                // this time.
243
0
                _ => unreachable!(),
244
            };
245
562
            self.print_path_to_interface(resolve, id, my_pkg)?;
246
562
            self.output.str(".{"); // Note: not changing the indentation.
247
784
            for (i, (my_name, other_name)) in tys.into_iter().enumerate() {
248
784
                if i > 0 {
249
222
                    self.output.str(", ");
250
562
                }
251
784
                if my_name == other_name {
252
222
                    self.print_name_type(my_name, TypeKind::TypeImport);
253
562
                } else {
254
562
                    self.print_name_type(other_name, TypeKind::TypeImport);
255
562
                    self.output.str(" ");
256
562
                    self.output.keyword("as");
257
562
                    self.output.str(" ");
258
562
                    self.print_name_type(my_name, TypeKind::TypeAlias);
259
562
                }
260
            }
261
562
            self.output.str("}"); // Note: not changing the indentation.
262
562
            self.output.semicolon();
263
        }
264
265
7.38k
        for id in types_to_declare {
266
3.68k
            self.new_item();
267
3.68k
            self.print_docs(&resolve.types[id].docs);
268
3.68k
            self.print_stability(&resolve.types[id].stability);
269
3.68k
            match resolve.types[id].kind {
270
318
                TypeDefKind::Resource => self.print_resource(
271
318
                    resolve,
272
318
                    id,
273
318
                    resource_funcs.get(&id).unwrap_or(&Vec::new()),
274
0
                )?,
275
3.37k
                _ => self.declare_type(resolve, &Type::Id(id))?,
276
            }
277
        }
278
279
7.38k
        Ok(())
280
7.38k
    }
<wit_component::printing::WitPrinter>::print_types::<core::iter::adapters::map::Map<indexmap::map::iter::Iter<alloc::string::String, id_arena::Id<wit_parser::TypeDef>>, <wit_component::printing::WitPrinter>::print_interface::{closure#0}>>
Line
Count
Source
186
23.8k
    pub fn print_types<'a>(
187
23.8k
        &mut self,
188
23.8k
        resolve: &Resolve,
189
23.8k
        owner: TypeOwner,
190
23.8k
        types: impl Iterator<Item = (&'a str, TypeId)>,
191
23.8k
        resource_funcs: &HashMap<TypeId, Vec<&Function>>,
192
23.8k
    ) -> Result<()> {
193
        // Partition types defined in this interface into either those imported
194
        // from foreign interfaces or those defined locally.
195
23.8k
        let mut types_to_declare = Vec::new();
196
23.8k
        let mut types_to_import: Vec<(_, &_, Vec<_>)> = Vec::new();
197
23.8k
        for (name, ty_id) in types {
198
15.8k
            let ty = &resolve.types[ty_id];
199
7.67k
            if let TypeDefKind::Type(Type::Id(other)) = ty.kind {
200
7.27k
                let other = &resolve.types[other];
201
7.27k
                match other.owner {
202
0
                    TypeOwner::None => {}
203
7.27k
                    other_owner if owner != other_owner => {
204
7.25k
                        let other_name = other
205
7.25k
                            .name
206
7.25k
                            .as_ref()
207
7.25k
                            .ok_or_else(|| anyhow!("cannot import unnamed type"))?;
208
7.25k
                        if let Some((owner, stability, list)) = types_to_import.last_mut() {
209
5.48k
                            if *owner == other_owner && ty.stability == **stability {
210
3.49k
                                list.push((name, other_name));
211
3.49k
                                continue;
212
1.98k
                            }
213
1.77k
                        }
214
3.75k
                        types_to_import.push((
215
3.75k
                            other_owner,
216
3.75k
                            &ty.stability,
217
3.75k
                            vec![(name, other_name)],
218
3.75k
                        ));
219
3.75k
                        continue;
220
                    }
221
22
                    _ => {}
222
                }
223
8.54k
            }
224
225
8.56k
            types_to_declare.push(ty_id);
226
        }
227
228
        // Generate a `use` statement for all imported types.
229
23.8k
        let my_pkg = match owner {
230
23.8k
            TypeOwner::Interface(id) => resolve.interfaces[id].package.unwrap(),
231
0
            TypeOwner::World(id) => resolve.worlds[id].package.unwrap(),
232
0
            TypeOwner::None => unreachable!(),
233
        };
234
23.8k
        for (owner, stability, tys) in types_to_import {
235
3.75k
            self.any_items = true;
236
3.75k
            self.print_stability(stability);
237
3.75k
            self.output.keyword("use");
238
3.75k
            self.output.str(" ");
239
3.75k
            let id = match owner {
240
3.75k
                TypeOwner::Interface(id) => id,
241
                // it's only possible to import types from interfaces at
242
                // this time.
243
0
                _ => unreachable!(),
244
            };
245
3.75k
            self.print_path_to_interface(resolve, id, my_pkg)?;
246
3.75k
            self.output.str(".{"); // Note: not changing the indentation.
247
7.25k
            for (i, (my_name, other_name)) in tys.into_iter().enumerate() {
248
7.25k
                if i > 0 {
249
3.49k
                    self.output.str(", ");
250
3.75k
                }
251
7.25k
                if my_name == other_name {
252
1.34k
                    self.print_name_type(my_name, TypeKind::TypeImport);
253
5.91k
                } else {
254
5.91k
                    self.print_name_type(other_name, TypeKind::TypeImport);
255
5.91k
                    self.output.str(" ");
256
5.91k
                    self.output.keyword("as");
257
5.91k
                    self.output.str(" ");
258
5.91k
                    self.print_name_type(my_name, TypeKind::TypeAlias);
259
5.91k
                }
260
            }
261
3.75k
            self.output.str("}"); // Note: not changing the indentation.
262
3.75k
            self.output.semicolon();
263
        }
264
265
23.8k
        for id in types_to_declare {
266
8.56k
            self.new_item();
267
8.56k
            self.print_docs(&resolve.types[id].docs);
268
8.56k
            self.print_stability(&resolve.types[id].stability);
269
8.56k
            match resolve.types[id].kind {
270
782
                TypeDefKind::Resource => self.print_resource(
271
782
                    resolve,
272
782
                    id,
273
782
                    resource_funcs.get(&id).unwrap_or(&Vec::new()),
274
0
                )?,
275
7.78k
                _ => self.declare_type(resolve, &Type::Id(id))?,
276
            }
277
        }
278
279
23.8k
        Ok(())
280
23.8k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_types::<_>
281
282
1.10k
    fn print_resource(&mut self, resolve: &Resolve, id: TypeId, funcs: &[&Function]) -> Result<()> {
283
1.10k
        let ty = &resolve.types[id];
284
1.10k
        self.output.ty("resource", TypeKind::BuiltIn);
285
1.10k
        self.output.str(" ");
286
1.10k
        self.print_name_type(
287
1.10k
            ty.name.as_ref().expect("resources must be named"),
288
1.10k
            TypeKind::Resource,
289
        );
290
1.10k
        if funcs.is_empty() {
291
430
            self.output.semicolon();
292
430
            return Ok(());
293
670
        }
294
670
        self.output.indent_start();
295
2.25k
        for func in funcs {
296
2.25k
            self.print_docs(&func.docs);
297
2.25k
            self.print_stability(&func.stability);
298
299
2.25k
            match &func.kind {
300
244
                FunctionKind::Constructor(_) => {}
301
1.14k
                FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => {
302
1.14k
                    self.print_name_type(func.item_name(), TypeKind::FunctionMethod);
303
1.14k
                    self.output.str(": ");
304
1.14k
                }
305
864
                FunctionKind::Static(_) | FunctionKind::AsyncStatic(_) => {
306
864
                    self.print_name_type(func.item_name(), TypeKind::FunctionStatic);
307
864
                    self.output.str(": ");
308
864
                    self.output.keyword("static");
309
864
                    self.output.str(" ");
310
864
                }
311
0
                FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => unreachable!(),
312
            }
313
2.25k
            self.print_function(resolve, func)?;
314
2.25k
            self.output.semicolon();
315
        }
316
670
        self.output.indent_end();
317
318
670
        Ok(())
319
1.10k
    }
<wit_component::printing::WitPrinter>::print_resource
Line
Count
Source
282
1.10k
    fn print_resource(&mut self, resolve: &Resolve, id: TypeId, funcs: &[&Function]) -> Result<()> {
283
1.10k
        let ty = &resolve.types[id];
284
1.10k
        self.output.ty("resource", TypeKind::BuiltIn);
285
1.10k
        self.output.str(" ");
286
1.10k
        self.print_name_type(
287
1.10k
            ty.name.as_ref().expect("resources must be named"),
288
1.10k
            TypeKind::Resource,
289
        );
290
1.10k
        if funcs.is_empty() {
291
430
            self.output.semicolon();
292
430
            return Ok(());
293
670
        }
294
670
        self.output.indent_start();
295
2.25k
        for func in funcs {
296
2.25k
            self.print_docs(&func.docs);
297
2.25k
            self.print_stability(&func.stability);
298
299
2.25k
            match &func.kind {
300
244
                FunctionKind::Constructor(_) => {}
301
1.14k
                FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => {
302
1.14k
                    self.print_name_type(func.item_name(), TypeKind::FunctionMethod);
303
1.14k
                    self.output.str(": ");
304
1.14k
                }
305
864
                FunctionKind::Static(_) | FunctionKind::AsyncStatic(_) => {
306
864
                    self.print_name_type(func.item_name(), TypeKind::FunctionStatic);
307
864
                    self.output.str(": ");
308
864
                    self.output.keyword("static");
309
864
                    self.output.str(" ");
310
864
                }
311
0
                FunctionKind::Freestanding | FunctionKind::AsyncFreestanding => unreachable!(),
312
            }
313
2.25k
            self.print_function(resolve, func)?;
314
2.25k
            self.output.semicolon();
315
        }
316
670
        self.output.indent_end();
317
318
670
        Ok(())
319
1.10k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_resource
320
321
12.9k
    fn print_function(&mut self, resolve: &Resolve, func: &Function) -> Result<()> {
322
        // Handle the `async` prefix if necessary
323
12.9k
        match &func.kind {
324
            FunctionKind::AsyncFreestanding
325
            | FunctionKind::AsyncMethod(_)
326
7.07k
            | FunctionKind::AsyncStatic(_) => {
327
7.07k
                self.output.keyword("async");
328
7.07k
                self.output.str(" ");
329
7.07k
            }
330
5.87k
            _ => {}
331
        }
332
333
        // Constructors are named slightly differently.
334
12.9k
        match &func.kind {
335
244
            FunctionKind::Constructor(_) => {
336
244
                self.output.keyword("constructor");
337
244
                self.output.str("(");
338
244
            }
339
            FunctionKind::Freestanding
340
            | FunctionKind::AsyncFreestanding
341
            | FunctionKind::Method(_)
342
            | FunctionKind::AsyncMethod(_)
343
            | FunctionKind::Static(_)
344
12.6k
            | FunctionKind::AsyncStatic(_) => {
345
12.6k
                self.output.keyword("func");
346
12.6k
                self.output.str("(");
347
12.6k
            }
348
        }
349
350
        // Methods don't print their `self` argument
351
12.9k
        let params_to_skip = match &func.kind {
352
1.14k
            FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => 1,
353
11.7k
            _ => 0,
354
        };
355
28.7k
        for (i, param) in func.params.iter().skip(params_to_skip).enumerate() {
356
28.7k
            if i > 0 {
357
18.0k
                self.output.str(", ");
358
18.0k
            }
359
28.7k
            self.print_name_param(&param.name);
360
28.7k
            self.output.str(": ");
361
28.7k
            self.print_type_name(resolve, &param.ty)?;
362
        }
363
12.9k
        self.output.str(")");
364
365
        // shorthand constructors don't have their results printed
366
12.9k
        if func.is_constructor_shorthand(resolve) {
367
244
            return Ok(());
368
12.6k
        }
369
370
12.6k
        if let Some(ty) = &func.result {
371
9.64k
            self.output.str(" -> ");
372
9.64k
            self.print_type_name(resolve, ty)?;
373
3.05k
        }
374
12.6k
        Ok(())
375
12.9k
    }
<wit_component::printing::WitPrinter>::print_function
Line
Count
Source
321
12.9k
    fn print_function(&mut self, resolve: &Resolve, func: &Function) -> Result<()> {
322
        // Handle the `async` prefix if necessary
323
12.9k
        match &func.kind {
324
            FunctionKind::AsyncFreestanding
325
            | FunctionKind::AsyncMethod(_)
326
7.07k
            | FunctionKind::AsyncStatic(_) => {
327
7.07k
                self.output.keyword("async");
328
7.07k
                self.output.str(" ");
329
7.07k
            }
330
5.87k
            _ => {}
331
        }
332
333
        // Constructors are named slightly differently.
334
12.9k
        match &func.kind {
335
244
            FunctionKind::Constructor(_) => {
336
244
                self.output.keyword("constructor");
337
244
                self.output.str("(");
338
244
            }
339
            FunctionKind::Freestanding
340
            | FunctionKind::AsyncFreestanding
341
            | FunctionKind::Method(_)
342
            | FunctionKind::AsyncMethod(_)
343
            | FunctionKind::Static(_)
344
12.6k
            | FunctionKind::AsyncStatic(_) => {
345
12.6k
                self.output.keyword("func");
346
12.6k
                self.output.str("(");
347
12.6k
            }
348
        }
349
350
        // Methods don't print their `self` argument
351
12.9k
        let params_to_skip = match &func.kind {
352
1.14k
            FunctionKind::Method(_) | FunctionKind::AsyncMethod(_) => 1,
353
11.7k
            _ => 0,
354
        };
355
28.7k
        for (i, param) in func.params.iter().skip(params_to_skip).enumerate() {
356
28.7k
            if i > 0 {
357
18.0k
                self.output.str(", ");
358
18.0k
            }
359
28.7k
            self.print_name_param(&param.name);
360
28.7k
            self.output.str(": ");
361
28.7k
            self.print_type_name(resolve, &param.ty)?;
362
        }
363
12.9k
        self.output.str(")");
364
365
        // shorthand constructors don't have their results printed
366
12.9k
        if func.is_constructor_shorthand(resolve) {
367
244
            return Ok(());
368
12.6k
        }
369
370
12.6k
        if let Some(ty) = &func.result {
371
9.64k
            self.output.str(" -> ");
372
9.64k
            self.print_type_name(resolve, ty)?;
373
3.05k
        }
374
12.6k
        Ok(())
375
12.9k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_function
376
377
    /// Prints the world `id` within `resolve`.
378
    ///
379
    /// This is a little tricky to preserve round-tripping that WIT wants. This
380
    /// function inherently can't preserve ordering of imports because resource
381
    /// functions aren't guaranteed to be all adjacent to the resource itself
382
    /// they're attached to. That means that at the very least, when printing
383
    /// resource functions, items may be printed out-of-order.
384
    ///
385
    /// To help solve this the printing here is kept in sync with WIT encoding
386
    /// of worlds which is to print items in the order of:
387
    ///
388
    /// * Any imported interface. Ordering between interfaces is preserved.
389
    /// * Any types, including resource functions on those types. Ordering
390
    ///   between types is preserved.
391
    /// * Any functions, which may refer to those types. Ordering between
392
    ///   functions is preserved.
393
    ///
394
    /// This keeps things printed in a roughly topological fashion and makes
395
    /// round-tripping a bit more reliable.
396
7.38k
    fn print_world(&mut self, resolve: &Resolve, id: WorldId) -> Result<()> {
397
7.38k
        let prev_items = mem::replace(&mut self.any_items, false);
398
7.38k
        let world = &resolve.worlds[id];
399
7.38k
        let pkgid = world.package.unwrap();
400
7.38k
        let mut types = Vec::new();
401
7.38k
        let mut resource_funcs = HashMap::new();
402
7.38k
        let mut function_imports_to_print = Vec::new();
403
7.90k
        for (name, import) in world.imports.iter() {
404
7.90k
            match import {
405
4.47k
                WorldItem::Type { id, .. } => match name {
406
4.47k
                    WorldKey::Name(s) => types.push((s.as_str(), *id)),
407
0
                    WorldKey::Interface(_) => unreachable!(),
408
                },
409
                _ => {
410
3.43k
                    if let WorldItem::Function(f) = import {
411
1.84k
                        if let Some(id) = f.kind.resource() {
412
600
                            resource_funcs.entry(id).or_insert(Vec::new()).push(f);
413
600
                            continue;
414
1.24k
                        }
415
1.24k
                        function_imports_to_print.push((name, import));
416
1.24k
                        continue;
417
1.59k
                    }
418
1.59k
                    self.print_world_item(resolve, name, import, pkgid, "import")?;
419
                    // Don't put a blank line between imports, but count
420
                    // imports as having printed something so if anything comes
421
                    // after them then a blank line is printed after imports.
422
1.59k
                    self.any_items = true;
423
                }
424
            }
425
        }
426
7.38k
        self.print_types(
427
7.38k
            resolve,
428
7.38k
            TypeOwner::World(id),
429
7.38k
            types.into_iter(),
430
7.38k
            &resource_funcs,
431
0
        )?;
432
433
7.38k
        for (name, import) in function_imports_to_print {
434
1.24k
            self.print_world_item(resolve, name, import, pkgid, "import")?;
435
1.24k
            self.any_items = true;
436
        }
437
7.38k
        if !world.exports.is_empty() {
438
1.99k
            self.new_item();
439
5.38k
        }
440
7.38k
        for (name, export) in world.exports.iter() {
441
5.83k
            self.print_world_item(resolve, name, export, pkgid, "export")?;
442
        }
443
7.38k
        self.any_items = prev_items;
444
7.38k
        Ok(())
445
7.38k
    }
<wit_component::printing::WitPrinter>::print_world
Line
Count
Source
396
7.38k
    fn print_world(&mut self, resolve: &Resolve, id: WorldId) -> Result<()> {
397
7.38k
        let prev_items = mem::replace(&mut self.any_items, false);
398
7.38k
        let world = &resolve.worlds[id];
399
7.38k
        let pkgid = world.package.unwrap();
400
7.38k
        let mut types = Vec::new();
401
7.38k
        let mut resource_funcs = HashMap::new();
402
7.38k
        let mut function_imports_to_print = Vec::new();
403
7.90k
        for (name, import) in world.imports.iter() {
404
7.90k
            match import {
405
4.47k
                WorldItem::Type { id, .. } => match name {
406
4.47k
                    WorldKey::Name(s) => types.push((s.as_str(), *id)),
407
0
                    WorldKey::Interface(_) => unreachable!(),
408
                },
409
                _ => {
410
3.43k
                    if let WorldItem::Function(f) = import {
411
1.84k
                        if let Some(id) = f.kind.resource() {
412
600
                            resource_funcs.entry(id).or_insert(Vec::new()).push(f);
413
600
                            continue;
414
1.24k
                        }
415
1.24k
                        function_imports_to_print.push((name, import));
416
1.24k
                        continue;
417
1.59k
                    }
418
1.59k
                    self.print_world_item(resolve, name, import, pkgid, "import")?;
419
                    // Don't put a blank line between imports, but count
420
                    // imports as having printed something so if anything comes
421
                    // after them then a blank line is printed after imports.
422
1.59k
                    self.any_items = true;
423
                }
424
            }
425
        }
426
7.38k
        self.print_types(
427
7.38k
            resolve,
428
7.38k
            TypeOwner::World(id),
429
7.38k
            types.into_iter(),
430
7.38k
            &resource_funcs,
431
0
        )?;
432
433
7.38k
        for (name, import) in function_imports_to_print {
434
1.24k
            self.print_world_item(resolve, name, import, pkgid, "import")?;
435
1.24k
            self.any_items = true;
436
        }
437
7.38k
        if !world.exports.is_empty() {
438
1.99k
            self.new_item();
439
5.38k
        }
440
7.38k
        for (name, export) in world.exports.iter() {
441
5.83k
            self.print_world_item(resolve, name, export, pkgid, "export")?;
442
        }
443
7.38k
        self.any_items = prev_items;
444
7.38k
        Ok(())
445
7.38k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_world
446
447
8.66k
    fn print_world_item(
448
8.66k
        &mut self,
449
8.66k
        resolve: &Resolve,
450
8.66k
        name: &WorldKey,
451
8.66k
        item: &WorldItem,
452
8.66k
        cur_pkg: PackageId,
453
8.66k
        import_or_export_keyword: &str,
454
8.66k
    ) -> Result<()> {
455
        // Print docs for this import/export statement. For interfaces, prefer
456
        // the docs attached to the statement itself (`WorldItem::Interface`'s
457
        // `docs`); for an inline `import x: interface { .. }` with no statement
458
        // docs fall back to the interface definition's docs.
459
8.66k
        let docs = match item {
460
6.71k
            WorldItem::Interface { id, docs, .. } => {
461
6.71k
                if docs.contents.is_some() {
462
0
                    Some(docs)
463
6.71k
                } else if matches!(name, WorldKey::Name(_)) {
464
5.66k
                    Some(&resolve.interfaces[*id].docs)
465
                } else {
466
1.05k
                    None
467
                }
468
            }
469
1.95k
            WorldItem::Function(f) => Some(&f.docs),
470
            // Types are handled separately
471
0
            WorldItem::Type { .. } => unreachable!(),
472
        };
473
8.66k
        if let Some(docs) = docs {
474
7.61k
            self.print_docs(docs);
475
7.61k
        }
476
477
8.66k
        self.print_stability(item.stability(resolve));
478
8.66k
        self.output.keyword(import_or_export_keyword);
479
8.66k
        self.output.str(" ");
480
8.66k
        match name {
481
7.61k
            WorldKey::Name(name) => {
482
7.61k
                match item {
483
5.66k
                    WorldItem::Interface { id, .. } => {
484
5.66k
                        self.print_name_type(name, TypeKind::Other);
485
5.66k
                        self.output.str(": ");
486
5.66k
                        if resolve.interfaces[*id].name.is_none() {
487
                            // `import label: interface { .. }` syntax
488
848
                            self.output.keyword("interface");
489
848
                            self.output.indent_start();
490
848
                            self.print_interface(resolve, *id)?;
491
848
                            self.output.indent_end();
492
                        } else {
493
                            // `import label: use-path;` syntax
494
4.81k
                            self.print_path_to_interface(resolve, *id, cur_pkg)?;
495
4.81k
                            self.output.semicolon();
496
                        }
497
                    }
498
1.95k
                    WorldItem::Function(f) => {
499
1.95k
                        self.print_name_type(&f.name, TypeKind::Other);
500
1.95k
                        self.output.str(": ");
501
1.95k
                        self.print_function(resolve, f)?;
502
1.95k
                        self.output.semicolon();
503
                    }
504
                    // Types are handled separately
505
0
                    WorldItem::Type { .. } => unreachable!(),
506
                }
507
            }
508
1.05k
            WorldKey::Interface(id) => {
509
1.05k
                match item {
510
1.05k
                    WorldItem::Interface { id: id2, .. } => assert_eq!(id, id2),
511
0
                    _ => unreachable!(),
512
                }
513
1.05k
                self.print_path_to_interface(resolve, *id, cur_pkg)?;
514
1.05k
                self.output.semicolon();
515
            }
516
        }
517
8.66k
        Ok(())
518
8.66k
    }
<wit_component::printing::WitPrinter>::print_world_item
Line
Count
Source
447
8.66k
    fn print_world_item(
448
8.66k
        &mut self,
449
8.66k
        resolve: &Resolve,
450
8.66k
        name: &WorldKey,
451
8.66k
        item: &WorldItem,
452
8.66k
        cur_pkg: PackageId,
453
8.66k
        import_or_export_keyword: &str,
454
8.66k
    ) -> Result<()> {
455
        // Print docs for this import/export statement. For interfaces, prefer
456
        // the docs attached to the statement itself (`WorldItem::Interface`'s
457
        // `docs`); for an inline `import x: interface { .. }` with no statement
458
        // docs fall back to the interface definition's docs.
459
8.66k
        let docs = match item {
460
6.71k
            WorldItem::Interface { id, docs, .. } => {
461
6.71k
                if docs.contents.is_some() {
462
0
                    Some(docs)
463
6.71k
                } else if matches!(name, WorldKey::Name(_)) {
464
5.66k
                    Some(&resolve.interfaces[*id].docs)
465
                } else {
466
1.05k
                    None
467
                }
468
            }
469
1.95k
            WorldItem::Function(f) => Some(&f.docs),
470
            // Types are handled separately
471
0
            WorldItem::Type { .. } => unreachable!(),
472
        };
473
8.66k
        if let Some(docs) = docs {
474
7.61k
            self.print_docs(docs);
475
7.61k
        }
476
477
8.66k
        self.print_stability(item.stability(resolve));
478
8.66k
        self.output.keyword(import_or_export_keyword);
479
8.66k
        self.output.str(" ");
480
8.66k
        match name {
481
7.61k
            WorldKey::Name(name) => {
482
7.61k
                match item {
483
5.66k
                    WorldItem::Interface { id, .. } => {
484
5.66k
                        self.print_name_type(name, TypeKind::Other);
485
5.66k
                        self.output.str(": ");
486
5.66k
                        if resolve.interfaces[*id].name.is_none() {
487
                            // `import label: interface { .. }` syntax
488
848
                            self.output.keyword("interface");
489
848
                            self.output.indent_start();
490
848
                            self.print_interface(resolve, *id)?;
491
848
                            self.output.indent_end();
492
                        } else {
493
                            // `import label: use-path;` syntax
494
4.81k
                            self.print_path_to_interface(resolve, *id, cur_pkg)?;
495
4.81k
                            self.output.semicolon();
496
                        }
497
                    }
498
1.95k
                    WorldItem::Function(f) => {
499
1.95k
                        self.print_name_type(&f.name, TypeKind::Other);
500
1.95k
                        self.output.str(": ");
501
1.95k
                        self.print_function(resolve, f)?;
502
1.95k
                        self.output.semicolon();
503
                    }
504
                    // Types are handled separately
505
0
                    WorldItem::Type { .. } => unreachable!(),
506
                }
507
            }
508
1.05k
            WorldKey::Interface(id) => {
509
1.05k
                match item {
510
1.05k
                    WorldItem::Interface { id: id2, .. } => assert_eq!(id, id2),
511
0
                    _ => unreachable!(),
512
                }
513
1.05k
                self.print_path_to_interface(resolve, *id, cur_pkg)?;
514
1.05k
                self.output.semicolon();
515
            }
516
        }
517
8.66k
        Ok(())
518
8.66k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_world_item
519
520
10.1k
    fn print_path_to_interface(
521
10.1k
        &mut self,
522
10.1k
        resolve: &Resolve,
523
10.1k
        interface: InterfaceId,
524
10.1k
        cur_pkg: PackageId,
525
10.1k
    ) -> Result<()> {
526
10.1k
        let iface = &resolve.interfaces[interface];
527
10.1k
        if iface.package == Some(cur_pkg) {
528
5.13k
            self.print_name_type(iface.name.as_ref().unwrap(), TypeKind::InterfacePath);
529
5.13k
        } else {
530
5.05k
            let pkg = &resolve.packages[iface.package.unwrap()].name;
531
5.05k
            self.print_name_type(&pkg.namespace, TypeKind::NamespacePath);
532
5.05k
            self.output.str(":");
533
5.05k
            self.print_name_type(&pkg.name, TypeKind::PackageNamePath);
534
5.05k
            self.output.str("/");
535
5.05k
            self.print_name_type(iface.name.as_ref().unwrap(), TypeKind::InterfacePath);
536
5.05k
            if let Some(version) = &pkg.version {
537
4.07k
                self.print_name_type(&format!("@{version}"), TypeKind::VersionPath);
538
4.07k
            }
539
        }
540
10.1k
        Ok(())
541
10.1k
    }
<wit_component::printing::WitPrinter>::print_path_to_interface
Line
Count
Source
520
10.1k
    fn print_path_to_interface(
521
10.1k
        &mut self,
522
10.1k
        resolve: &Resolve,
523
10.1k
        interface: InterfaceId,
524
10.1k
        cur_pkg: PackageId,
525
10.1k
    ) -> Result<()> {
526
10.1k
        let iface = &resolve.interfaces[interface];
527
10.1k
        if iface.package == Some(cur_pkg) {
528
5.13k
            self.print_name_type(iface.name.as_ref().unwrap(), TypeKind::InterfacePath);
529
5.13k
        } else {
530
5.05k
            let pkg = &resolve.packages[iface.package.unwrap()].name;
531
5.05k
            self.print_name_type(&pkg.namespace, TypeKind::NamespacePath);
532
5.05k
            self.output.str(":");
533
5.05k
            self.print_name_type(&pkg.name, TypeKind::PackageNamePath);
534
5.05k
            self.output.str("/");
535
5.05k
            self.print_name_type(iface.name.as_ref().unwrap(), TypeKind::InterfacePath);
536
5.05k
            if let Some(version) = &pkg.version {
537
4.07k
                self.print_name_type(&format!("@{version}"), TypeKind::VersionPath);
538
4.07k
            }
539
        }
540
10.1k
        Ok(())
541
10.1k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_path_to_interface
542
543
    /// Print the name of type `ty`.
544
169k
    pub fn print_type_name(&mut self, resolve: &Resolve, ty: &Type) -> Result<()> {
545
169k
        match ty {
546
57.8k
            Type::Bool => self.output.ty("bool", TypeKind::BuiltIn),
547
2.83k
            Type::U8 => self.output.ty("u8", TypeKind::BuiltIn),
548
1.09k
            Type::U16 => self.output.ty("u16", TypeKind::BuiltIn),
549
1.59k
            Type::U32 => self.output.ty("u32", TypeKind::BuiltIn),
550
1.13k
            Type::U64 => self.output.ty("u64", TypeKind::BuiltIn),
551
1.56k
            Type::S8 => self.output.ty("s8", TypeKind::BuiltIn),
552
1.18k
            Type::S16 => self.output.ty("s16", TypeKind::BuiltIn),
553
1.44k
            Type::S32 => self.output.ty("s32", TypeKind::BuiltIn),
554
3.53k
            Type::S64 => self.output.ty("s64", TypeKind::BuiltIn),
555
2.69k
            Type::F32 => self.output.ty("f32", TypeKind::BuiltIn),
556
3.42k
            Type::F64 => self.output.ty("f64", TypeKind::BuiltIn),
557
6.43k
            Type::Char => self.output.ty("char", TypeKind::BuiltIn),
558
1.28k
            Type::String => self.output.ty("string", TypeKind::BuiltIn),
559
11.3k
            Type::ErrorContext => self.output.ty("error-context", TypeKind::BuiltIn),
560
561
72.3k
            Type::Id(id) => {
562
72.3k
                let ty = &resolve.types[*id];
563
72.3k
                if let Some(name) = &ty.name {
564
1.16k
                    self.print_name_type(name, TypeKind::Other);
565
1.16k
                    return Ok(());
566
71.1k
                }
567
568
71.1k
                match &ty.kind {
569
384
                    TypeDefKind::Handle(h) => {
570
384
                        self.print_handle_type(resolve, h, false)?;
571
                    }
572
                    TypeDefKind::Resource => {
573
0
                        bail!("resolve has an unnamed resource type");
574
                    }
575
15.8k
                    TypeDefKind::Tuple(t) => {
576
15.8k
                        self.print_tuple_type(resolve, t)?;
577
                    }
578
15.2k
                    TypeDefKind::Option(t) => {
579
15.2k
                        self.print_option_type(resolve, t)?;
580
                    }
581
22.2k
                    TypeDefKind::Result(t) => {
582
22.2k
                        self.print_result_type(resolve, t)?;
583
                    }
584
                    TypeDefKind::Record(_) => {
585
0
                        bail!("resolve has an unnamed record type");
586
                    }
587
                    TypeDefKind::Flags(_) => {
588
0
                        bail!("resolve has unnamed flags type")
589
                    }
590
                    TypeDefKind::Enum(_) => {
591
0
                        bail!("resolve has unnamed enum type")
592
                    }
593
                    TypeDefKind::Variant(_) => {
594
0
                        bail!("resolve has unnamed variant type")
595
                    }
596
3.92k
                    TypeDefKind::List(ty) => {
597
3.92k
                        self.output.ty("list", TypeKind::BuiltIn);
598
3.92k
                        self.output.generic_args_start();
599
3.92k
                        self.print_type_name(resolve, ty)?;
600
3.92k
                        self.output.generic_args_end();
601
                    }
602
0
                    TypeDefKind::Map(key_ty, value_ty) => {
603
0
                        self.output.ty("map", TypeKind::BuiltIn);
604
0
                        self.output.generic_args_start();
605
0
                        self.print_type_name(resolve, key_ty)?;
606
0
                        self.output.str(", ");
607
0
                        self.print_type_name(resolve, value_ty)?;
608
0
                        self.output.generic_args_end();
609
                    }
610
1.87k
                    TypeDefKind::FixedLengthList(ty, size) => {
611
1.87k
                        self.output.ty("list", TypeKind::BuiltIn);
612
1.87k
                        self.output.generic_args_start();
613
1.87k
                        self.print_type_name(resolve, ty)?;
614
1.87k
                        self.output.push_str(&format!(", {}", *size));
615
1.87k
                        self.output.generic_args_end();
616
                    }
617
0
                    TypeDefKind::Type(ty) => self.print_type_name(resolve, ty)?,
618
5.82k
                    TypeDefKind::Future(ty) => {
619
5.82k
                        if let Some(ty) = ty {
620
3.33k
                            self.output.push_str("future<");
621
3.33k
                            self.print_type_name(resolve, ty)?;
622
3.33k
                            self.output.push_str(">");
623
2.49k
                        } else {
624
2.49k
                            self.output.push_str("future");
625
2.49k
                        }
626
                    }
627
5.91k
                    TypeDefKind::Stream(ty) => {
628
5.91k
                        if let Some(ty) = ty {
629
5.91k
                            self.output.push_str("stream<");
630
5.91k
                            self.print_type_name(resolve, ty)?;
631
5.91k
                            self.output.push_str(">");
632
0
                        } else {
633
0
                            self.output.push_str("stream");
634
0
                        }
635
                    }
636
0
                    TypeDefKind::Unknown => unreachable!(),
637
                }
638
            }
639
        }
640
641
168k
        Ok(())
642
169k
    }
<wit_component::printing::WitPrinter>::print_type_name
Line
Count
Source
544
169k
    pub fn print_type_name(&mut self, resolve: &Resolve, ty: &Type) -> Result<()> {
545
169k
        match ty {
546
57.8k
            Type::Bool => self.output.ty("bool", TypeKind::BuiltIn),
547
2.83k
            Type::U8 => self.output.ty("u8", TypeKind::BuiltIn),
548
1.09k
            Type::U16 => self.output.ty("u16", TypeKind::BuiltIn),
549
1.59k
            Type::U32 => self.output.ty("u32", TypeKind::BuiltIn),
550
1.13k
            Type::U64 => self.output.ty("u64", TypeKind::BuiltIn),
551
1.56k
            Type::S8 => self.output.ty("s8", TypeKind::BuiltIn),
552
1.18k
            Type::S16 => self.output.ty("s16", TypeKind::BuiltIn),
553
1.44k
            Type::S32 => self.output.ty("s32", TypeKind::BuiltIn),
554
3.53k
            Type::S64 => self.output.ty("s64", TypeKind::BuiltIn),
555
2.69k
            Type::F32 => self.output.ty("f32", TypeKind::BuiltIn),
556
3.42k
            Type::F64 => self.output.ty("f64", TypeKind::BuiltIn),
557
6.43k
            Type::Char => self.output.ty("char", TypeKind::BuiltIn),
558
1.28k
            Type::String => self.output.ty("string", TypeKind::BuiltIn),
559
11.3k
            Type::ErrorContext => self.output.ty("error-context", TypeKind::BuiltIn),
560
561
72.3k
            Type::Id(id) => {
562
72.3k
                let ty = &resolve.types[*id];
563
72.3k
                if let Some(name) = &ty.name {
564
1.16k
                    self.print_name_type(name, TypeKind::Other);
565
1.16k
                    return Ok(());
566
71.1k
                }
567
568
71.1k
                match &ty.kind {
569
384
                    TypeDefKind::Handle(h) => {
570
384
                        self.print_handle_type(resolve, h, false)?;
571
                    }
572
                    TypeDefKind::Resource => {
573
0
                        bail!("resolve has an unnamed resource type");
574
                    }
575
15.8k
                    TypeDefKind::Tuple(t) => {
576
15.8k
                        self.print_tuple_type(resolve, t)?;
577
                    }
578
15.2k
                    TypeDefKind::Option(t) => {
579
15.2k
                        self.print_option_type(resolve, t)?;
580
                    }
581
22.2k
                    TypeDefKind::Result(t) => {
582
22.2k
                        self.print_result_type(resolve, t)?;
583
                    }
584
                    TypeDefKind::Record(_) => {
585
0
                        bail!("resolve has an unnamed record type");
586
                    }
587
                    TypeDefKind::Flags(_) => {
588
0
                        bail!("resolve has unnamed flags type")
589
                    }
590
                    TypeDefKind::Enum(_) => {
591
0
                        bail!("resolve has unnamed enum type")
592
                    }
593
                    TypeDefKind::Variant(_) => {
594
0
                        bail!("resolve has unnamed variant type")
595
                    }
596
3.92k
                    TypeDefKind::List(ty) => {
597
3.92k
                        self.output.ty("list", TypeKind::BuiltIn);
598
3.92k
                        self.output.generic_args_start();
599
3.92k
                        self.print_type_name(resolve, ty)?;
600
3.92k
                        self.output.generic_args_end();
601
                    }
602
0
                    TypeDefKind::Map(key_ty, value_ty) => {
603
0
                        self.output.ty("map", TypeKind::BuiltIn);
604
0
                        self.output.generic_args_start();
605
0
                        self.print_type_name(resolve, key_ty)?;
606
0
                        self.output.str(", ");
607
0
                        self.print_type_name(resolve, value_ty)?;
608
0
                        self.output.generic_args_end();
609
                    }
610
1.87k
                    TypeDefKind::FixedLengthList(ty, size) => {
611
1.87k
                        self.output.ty("list", TypeKind::BuiltIn);
612
1.87k
                        self.output.generic_args_start();
613
1.87k
                        self.print_type_name(resolve, ty)?;
614
1.87k
                        self.output.push_str(&format!(", {}", *size));
615
1.87k
                        self.output.generic_args_end();
616
                    }
617
0
                    TypeDefKind::Type(ty) => self.print_type_name(resolve, ty)?,
618
5.82k
                    TypeDefKind::Future(ty) => {
619
5.82k
                        if let Some(ty) = ty {
620
3.33k
                            self.output.push_str("future<");
621
3.33k
                            self.print_type_name(resolve, ty)?;
622
3.33k
                            self.output.push_str(">");
623
2.49k
                        } else {
624
2.49k
                            self.output.push_str("future");
625
2.49k
                        }
626
                    }
627
5.91k
                    TypeDefKind::Stream(ty) => {
628
5.91k
                        if let Some(ty) = ty {
629
5.91k
                            self.output.push_str("stream<");
630
5.91k
                            self.print_type_name(resolve, ty)?;
631
5.91k
                            self.output.push_str(">");
632
0
                        } else {
633
0
                            self.output.push_str("stream");
634
0
                        }
635
                    }
636
0
                    TypeDefKind::Unknown => unreachable!(),
637
                }
638
            }
639
        }
640
641
168k
        Ok(())
642
169k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_type_name
643
644
384
    fn print_handle_type(
645
384
        &mut self,
646
384
        resolve: &Resolve,
647
384
        handle: &Handle,
648
384
        force_handle_type_printed: bool,
649
384
    ) -> Result<()> {
650
384
        match handle {
651
384
            Handle::Own(ty) => {
652
384
                let ty = &resolve.types[*ty];
653
384
                if force_handle_type_printed {
654
0
                    self.output.ty("own", TypeKind::BuiltIn);
655
0
                    self.output.generic_args_start();
656
384
                }
657
384
                self.print_name_type(
658
384
                    ty.name
659
384
                        .as_ref()
660
384
                        .ok_or_else(|| anyhow!("unnamed resource type"))?,
Unexecuted instantiation: <wit_component::printing::WitPrinter>::print_handle_type::{closure#0}
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_handle_type::{closure#0}
661
384
                    TypeKind::Resource,
662
                );
663
384
                if force_handle_type_printed {
664
0
                    self.output.generic_args_end();
665
384
                }
666
            }
667
668
0
            Handle::Borrow(ty) => {
669
0
                self.output.ty("borrow", TypeKind::BuiltIn);
670
0
                self.output.generic_args_start();
671
0
                let ty = &resolve.types[*ty];
672
0
                self.print_name_type(
673
0
                    ty.name
674
0
                        .as_ref()
675
0
                        .ok_or_else(|| anyhow!("unnamed resource type"))?,
Unexecuted instantiation: <wit_component::printing::WitPrinter>::print_handle_type::{closure#1}
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_handle_type::{closure#1}
676
0
                    TypeKind::Resource,
677
                );
678
0
                self.output.generic_args_end();
679
            }
680
        }
681
682
384
        Ok(())
683
384
    }
<wit_component::printing::WitPrinter>::print_handle_type
Line
Count
Source
644
384
    fn print_handle_type(
645
384
        &mut self,
646
384
        resolve: &Resolve,
647
384
        handle: &Handle,
648
384
        force_handle_type_printed: bool,
649
384
    ) -> Result<()> {
650
384
        match handle {
651
384
            Handle::Own(ty) => {
652
384
                let ty = &resolve.types[*ty];
653
384
                if force_handle_type_printed {
654
0
                    self.output.ty("own", TypeKind::BuiltIn);
655
0
                    self.output.generic_args_start();
656
384
                }
657
384
                self.print_name_type(
658
384
                    ty.name
659
384
                        .as_ref()
660
384
                        .ok_or_else(|| anyhow!("unnamed resource type"))?,
661
384
                    TypeKind::Resource,
662
                );
663
384
                if force_handle_type_printed {
664
0
                    self.output.generic_args_end();
665
384
                }
666
            }
667
668
0
            Handle::Borrow(ty) => {
669
0
                self.output.ty("borrow", TypeKind::BuiltIn);
670
0
                self.output.generic_args_start();
671
0
                let ty = &resolve.types[*ty];
672
0
                self.print_name_type(
673
0
                    ty.name
674
0
                        .as_ref()
675
0
                        .ok_or_else(|| anyhow!("unnamed resource type"))?,
676
0
                    TypeKind::Resource,
677
                );
678
0
                self.output.generic_args_end();
679
            }
680
        }
681
682
384
        Ok(())
683
384
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_handle_type
684
685
16.0k
    fn print_tuple_type(&mut self, resolve: &Resolve, tuple: &Tuple) -> Result<()> {
686
16.0k
        self.output.ty("tuple", TypeKind::BuiltIn);
687
16.0k
        self.output.generic_args_start();
688
52.5k
        for (i, ty) in tuple.types.iter().enumerate() {
689
52.5k
            if i > 0 {
690
36.5k
                self.output.str(", ");
691
36.5k
            }
692
52.5k
            self.print_type_name(resolve, ty)?;
693
        }
694
16.0k
        self.output.generic_args_end();
695
696
16.0k
        Ok(())
697
16.0k
    }
<wit_component::printing::WitPrinter>::print_tuple_type
Line
Count
Source
685
16.0k
    fn print_tuple_type(&mut self, resolve: &Resolve, tuple: &Tuple) -> Result<()> {
686
16.0k
        self.output.ty("tuple", TypeKind::BuiltIn);
687
16.0k
        self.output.generic_args_start();
688
52.5k
        for (i, ty) in tuple.types.iter().enumerate() {
689
52.5k
            if i > 0 {
690
36.5k
                self.output.str(", ");
691
36.5k
            }
692
52.5k
            self.print_type_name(resolve, ty)?;
693
        }
694
16.0k
        self.output.generic_args_end();
695
696
16.0k
        Ok(())
697
16.0k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_tuple_type
698
699
15.3k
    fn print_option_type(&mut self, resolve: &Resolve, payload: &Type) -> Result<()> {
700
15.3k
        self.output.ty("option", TypeKind::BuiltIn);
701
15.3k
        self.output.generic_args_start();
702
15.3k
        self.print_type_name(resolve, payload)?;
703
15.3k
        self.output.generic_args_end();
704
15.3k
        Ok(())
705
15.3k
    }
<wit_component::printing::WitPrinter>::print_option_type
Line
Count
Source
699
15.3k
    fn print_option_type(&mut self, resolve: &Resolve, payload: &Type) -> Result<()> {
700
15.3k
        self.output.ty("option", TypeKind::BuiltIn);
701
15.3k
        self.output.generic_args_start();
702
15.3k
        self.print_type_name(resolve, payload)?;
703
15.3k
        self.output.generic_args_end();
704
15.3k
        Ok(())
705
15.3k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_option_type
706
707
22.4k
    fn print_result_type(&mut self, resolve: &Resolve, result: &Result_) -> Result<()> {
708
2.09k
        match result {
709
            Result_ {
710
17.3k
                ok: Some(ok),
711
17.3k
                err: Some(err),
712
            } => {
713
17.3k
                self.output.ty("result", TypeKind::BuiltIn);
714
17.3k
                self.output.generic_args_start();
715
17.3k
                self.print_type_name(resolve, ok)?;
716
17.3k
                self.output.str(", ");
717
17.3k
                self.print_type_name(resolve, err)?;
718
17.3k
                self.output.generic_args_end();
719
            }
720
            Result_ {
721
                ok: None,
722
1.80k
                err: Some(err),
723
            } => {
724
1.80k
                self.output.ty("result", TypeKind::BuiltIn);
725
1.80k
                self.output.generic_args_start();
726
1.80k
                self.output.str("_, ");
727
1.80k
                self.print_type_name(resolve, err)?;
728
1.80k
                self.output.generic_args_end();
729
            }
730
            Result_ {
731
3.02k
                ok: Some(ok),
732
                err: None,
733
            } => {
734
3.02k
                self.output.ty("result", TypeKind::BuiltIn);
735
3.02k
                self.output.generic_args_start();
736
3.02k
                self.print_type_name(resolve, ok)?;
737
3.02k
                self.output.generic_args_end();
738
            }
739
            Result_ {
740
                ok: None,
741
                err: None,
742
290
            } => {
743
290
                self.output.ty("result", TypeKind::BuiltIn);
744
290
            }
745
        }
746
22.4k
        Ok(())
747
22.4k
    }
<wit_component::printing::WitPrinter>::print_result_type
Line
Count
Source
707
22.4k
    fn print_result_type(&mut self, resolve: &Resolve, result: &Result_) -> Result<()> {
708
2.09k
        match result {
709
            Result_ {
710
17.3k
                ok: Some(ok),
711
17.3k
                err: Some(err),
712
            } => {
713
17.3k
                self.output.ty("result", TypeKind::BuiltIn);
714
17.3k
                self.output.generic_args_start();
715
17.3k
                self.print_type_name(resolve, ok)?;
716
17.3k
                self.output.str(", ");
717
17.3k
                self.print_type_name(resolve, err)?;
718
17.3k
                self.output.generic_args_end();
719
            }
720
            Result_ {
721
                ok: None,
722
1.80k
                err: Some(err),
723
            } => {
724
1.80k
                self.output.ty("result", TypeKind::BuiltIn);
725
1.80k
                self.output.generic_args_start();
726
1.80k
                self.output.str("_, ");
727
1.80k
                self.print_type_name(resolve, err)?;
728
1.80k
                self.output.generic_args_end();
729
            }
730
            Result_ {
731
3.02k
                ok: Some(ok),
732
                err: None,
733
            } => {
734
3.02k
                self.output.ty("result", TypeKind::BuiltIn);
735
3.02k
                self.output.generic_args_start();
736
3.02k
                self.print_type_name(resolve, ok)?;
737
3.02k
                self.output.generic_args_end();
738
            }
739
            Result_ {
740
                ok: None,
741
                err: None,
742
290
            } => {
743
290
                self.output.ty("result", TypeKind::BuiltIn);
744
290
            }
745
        }
746
22.4k
        Ok(())
747
22.4k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_result_type
748
749
11.1k
    fn declare_type(&mut self, resolve: &Resolve, ty: &Type) -> Result<()> {
750
11.1k
        match ty {
751
            Type::Bool
752
            | Type::U8
753
            | Type::U16
754
            | Type::U32
755
            | Type::U64
756
            | Type::S8
757
            | Type::S16
758
            | Type::S32
759
            | Type::S64
760
            | Type::F32
761
            | Type::F64
762
            | Type::Char
763
            | Type::String
764
0
            | Type::ErrorContext => return Ok(()),
765
766
11.1k
            Type::Id(id) => {
767
11.1k
                let ty = &resolve.types[*id];
768
11.1k
                match &ty.kind {
769
0
                    TypeDefKind::Handle(h) => {
770
0
                        self.declare_handle(resolve, ty.name.as_deref(), h)?
771
                    }
772
0
                    TypeDefKind::Resource => panic!("resources should be processed separately"),
773
1.30k
                    TypeDefKind::Record(r) => {
774
1.30k
                        self.declare_record(resolve, ty.name.as_deref(), r)?
775
                    }
776
266
                    TypeDefKind::Tuple(t) => self.declare_tuple(resolve, ty.name.as_deref(), t)?,
777
530
                    TypeDefKind::Flags(f) => self.declare_flags(ty.name.as_deref(), f)?,
778
1.93k
                    TypeDefKind::Variant(v) => {
779
1.93k
                        self.declare_variant(resolve, ty.name.as_deref(), v)?
780
                    }
781
164
                    TypeDefKind::Option(t) => {
782
164
                        self.declare_option(resolve, ty.name.as_deref(), t)?
783
                    }
784
222
                    TypeDefKind::Result(r) => {
785
222
                        self.declare_result(resolve, ty.name.as_deref(), r)?
786
                    }
787
5.86k
                    TypeDefKind::Enum(e) => self.declare_enum(ty.name.as_deref(), e)?,
788
30
                    TypeDefKind::List(inner) => {
789
30
                        self.declare_list(resolve, ty.name.as_deref(), inner)?
790
                    }
791
0
                    TypeDefKind::Map(key, value) => {
792
0
                        self.declare_map(resolve, ty.name.as_deref(), key, value)?
793
                    }
794
8
                    TypeDefKind::FixedLengthList(inner, size) => {
795
8
                        self.declare_fixed_length_list(resolve, ty.name.as_deref(), inner, *size)?
796
                    }
797
804
                    TypeDefKind::Type(inner) => match ty.name.as_deref() {
798
804
                        Some(name) => {
799
804
                            self.output.keyword("type");
800
804
                            self.output.str(" ");
801
804
                            self.print_name_type(name, TypeKind::TypeName);
802
804
                            self.output.str(" = ");
803
804
                            self.print_type_name(resolve, inner)?;
804
804
                            self.output.semicolon();
805
                        }
806
0
                        None => bail!("unnamed type in document"),
807
                    },
808
14
                    TypeDefKind::Future(inner) => {
809
14
                        self.declare_future(resolve, ty.name.as_deref(), inner.as_ref())?
810
                    }
811
6
                    TypeDefKind::Stream(inner) => {
812
6
                        self.declare_stream(resolve, ty.name.as_deref(), inner.as_ref())?
813
                    }
814
0
                    TypeDefKind::Unknown => unreachable!(),
815
                }
816
            }
817
        }
818
11.1k
        Ok(())
819
11.1k
    }
<wit_component::printing::WitPrinter>::declare_type
Line
Count
Source
749
11.1k
    fn declare_type(&mut self, resolve: &Resolve, ty: &Type) -> Result<()> {
750
11.1k
        match ty {
751
            Type::Bool
752
            | Type::U8
753
            | Type::U16
754
            | Type::U32
755
            | Type::U64
756
            | Type::S8
757
            | Type::S16
758
            | Type::S32
759
            | Type::S64
760
            | Type::F32
761
            | Type::F64
762
            | Type::Char
763
            | Type::String
764
0
            | Type::ErrorContext => return Ok(()),
765
766
11.1k
            Type::Id(id) => {
767
11.1k
                let ty = &resolve.types[*id];
768
11.1k
                match &ty.kind {
769
0
                    TypeDefKind::Handle(h) => {
770
0
                        self.declare_handle(resolve, ty.name.as_deref(), h)?
771
                    }
772
0
                    TypeDefKind::Resource => panic!("resources should be processed separately"),
773
1.30k
                    TypeDefKind::Record(r) => {
774
1.30k
                        self.declare_record(resolve, ty.name.as_deref(), r)?
775
                    }
776
266
                    TypeDefKind::Tuple(t) => self.declare_tuple(resolve, ty.name.as_deref(), t)?,
777
530
                    TypeDefKind::Flags(f) => self.declare_flags(ty.name.as_deref(), f)?,
778
1.93k
                    TypeDefKind::Variant(v) => {
779
1.93k
                        self.declare_variant(resolve, ty.name.as_deref(), v)?
780
                    }
781
164
                    TypeDefKind::Option(t) => {
782
164
                        self.declare_option(resolve, ty.name.as_deref(), t)?
783
                    }
784
222
                    TypeDefKind::Result(r) => {
785
222
                        self.declare_result(resolve, ty.name.as_deref(), r)?
786
                    }
787
5.86k
                    TypeDefKind::Enum(e) => self.declare_enum(ty.name.as_deref(), e)?,
788
30
                    TypeDefKind::List(inner) => {
789
30
                        self.declare_list(resolve, ty.name.as_deref(), inner)?
790
                    }
791
0
                    TypeDefKind::Map(key, value) => {
792
0
                        self.declare_map(resolve, ty.name.as_deref(), key, value)?
793
                    }
794
8
                    TypeDefKind::FixedLengthList(inner, size) => {
795
8
                        self.declare_fixed_length_list(resolve, ty.name.as_deref(), inner, *size)?
796
                    }
797
804
                    TypeDefKind::Type(inner) => match ty.name.as_deref() {
798
804
                        Some(name) => {
799
804
                            self.output.keyword("type");
800
804
                            self.output.str(" ");
801
804
                            self.print_name_type(name, TypeKind::TypeName);
802
804
                            self.output.str(" = ");
803
804
                            self.print_type_name(resolve, inner)?;
804
804
                            self.output.semicolon();
805
                        }
806
0
                        None => bail!("unnamed type in document"),
807
                    },
808
14
                    TypeDefKind::Future(inner) => {
809
14
                        self.declare_future(resolve, ty.name.as_deref(), inner.as_ref())?
810
                    }
811
6
                    TypeDefKind::Stream(inner) => {
812
6
                        self.declare_stream(resolve, ty.name.as_deref(), inner.as_ref())?
813
                    }
814
0
                    TypeDefKind::Unknown => unreachable!(),
815
                }
816
            }
817
        }
818
11.1k
        Ok(())
819
11.1k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_type
820
821
0
    fn declare_handle(
822
0
        &mut self,
823
0
        resolve: &Resolve,
824
0
        name: Option<&str>,
825
0
        handle: &Handle,
826
0
    ) -> Result<()> {
827
0
        match name {
828
0
            Some(name) => {
829
0
                self.output.keyword("type");
830
0
                self.output.str(" ");
831
0
                self.print_name_type(name, TypeKind::Resource);
832
0
                self.output.str(" = ");
833
                // Note that the `true` here forces owned handles to be printed
834
                // as `own<T>`. The purpose of this is because `type a = b`, if
835
                // `b` is a resource, is encoded differently as `type a =
836
                // own<b>`. By forcing a handle to be printed here it's staying
837
                // true to what's in the WIT document.
838
0
                self.print_handle_type(resolve, handle, true)?;
839
0
                self.output.semicolon();
840
841
0
                Ok(())
842
            }
843
0
            None => bail!("document has unnamed handle type"),
844
        }
845
0
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter>::declare_handle
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_handle
846
847
1.30k
    fn declare_record(
848
1.30k
        &mut self,
849
1.30k
        resolve: &Resolve,
850
1.30k
        name: Option<&str>,
851
1.30k
        record: &Record,
852
1.30k
    ) -> Result<()> {
853
1.30k
        match name {
854
1.30k
            Some(name) => {
855
1.30k
                self.output.keyword("record");
856
1.30k
                self.output.str(" ");
857
1.30k
                self.print_name_type(name, TypeKind::Record);
858
1.30k
                self.output.indent_start();
859
3.34k
                for field in &record.fields {
860
3.34k
                    self.print_docs(&field.docs);
861
3.34k
                    self.print_name_param(&field.name);
862
3.34k
                    self.output.str(": ");
863
3.34k
                    self.print_type_name(resolve, &field.ty)?;
864
3.34k
                    self.output.str(",");
865
3.34k
                    self.output.newline();
866
                }
867
1.30k
                self.output.indent_end();
868
1.30k
                Ok(())
869
            }
870
0
            None => bail!("document has unnamed record type"),
871
        }
872
1.30k
    }
<wit_component::printing::WitPrinter>::declare_record
Line
Count
Source
847
1.30k
    fn declare_record(
848
1.30k
        &mut self,
849
1.30k
        resolve: &Resolve,
850
1.30k
        name: Option<&str>,
851
1.30k
        record: &Record,
852
1.30k
    ) -> Result<()> {
853
1.30k
        match name {
854
1.30k
            Some(name) => {
855
1.30k
                self.output.keyword("record");
856
1.30k
                self.output.str(" ");
857
1.30k
                self.print_name_type(name, TypeKind::Record);
858
1.30k
                self.output.indent_start();
859
3.34k
                for field in &record.fields {
860
3.34k
                    self.print_docs(&field.docs);
861
3.34k
                    self.print_name_param(&field.name);
862
3.34k
                    self.output.str(": ");
863
3.34k
                    self.print_type_name(resolve, &field.ty)?;
864
3.34k
                    self.output.str(",");
865
3.34k
                    self.output.newline();
866
                }
867
1.30k
                self.output.indent_end();
868
1.30k
                Ok(())
869
            }
870
0
            None => bail!("document has unnamed record type"),
871
        }
872
1.30k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_record
873
874
266
    fn declare_tuple(
875
266
        &mut self,
876
266
        resolve: &Resolve,
877
266
        name: Option<&str>,
878
266
        tuple: &Tuple,
879
266
    ) -> Result<()> {
880
266
        if let Some(name) = name {
881
266
            self.output.keyword("type");
882
266
            self.output.str(" ");
883
266
            self.print_name_type(name, TypeKind::Tuple);
884
266
            self.output.str(" = ");
885
266
            self.print_tuple_type(resolve, tuple)?;
886
266
            self.output.semicolon();
887
0
        }
888
266
        Ok(())
889
266
    }
<wit_component::printing::WitPrinter>::declare_tuple
Line
Count
Source
874
266
    fn declare_tuple(
875
266
        &mut self,
876
266
        resolve: &Resolve,
877
266
        name: Option<&str>,
878
266
        tuple: &Tuple,
879
266
    ) -> Result<()> {
880
266
        if let Some(name) = name {
881
266
            self.output.keyword("type");
882
266
            self.output.str(" ");
883
266
            self.print_name_type(name, TypeKind::Tuple);
884
266
            self.output.str(" = ");
885
266
            self.print_tuple_type(resolve, tuple)?;
886
266
            self.output.semicolon();
887
0
        }
888
266
        Ok(())
889
266
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_tuple
890
891
530
    fn declare_flags(&mut self, name: Option<&str>, flags: &Flags) -> Result<()> {
892
530
        match name {
893
530
            Some(name) => {
894
530
                self.output.keyword("flags");
895
530
                self.output.str(" ");
896
530
                self.print_name_type(name, TypeKind::Flags);
897
530
                self.output.indent_start();
898
1.27k
                for flag in &flags.flags {
899
1.27k
                    self.print_docs(&flag.docs);
900
1.27k
                    self.print_name_case(&flag.name);
901
1.27k
                    self.output.str(",");
902
1.27k
                    self.output.newline();
903
1.27k
                }
904
530
                self.output.indent_end();
905
            }
906
0
            None => bail!("document has unnamed flags type"),
907
        }
908
530
        Ok(())
909
530
    }
<wit_component::printing::WitPrinter>::declare_flags
Line
Count
Source
891
530
    fn declare_flags(&mut self, name: Option<&str>, flags: &Flags) -> Result<()> {
892
530
        match name {
893
530
            Some(name) => {
894
530
                self.output.keyword("flags");
895
530
                self.output.str(" ");
896
530
                self.print_name_type(name, TypeKind::Flags);
897
530
                self.output.indent_start();
898
1.27k
                for flag in &flags.flags {
899
1.27k
                    self.print_docs(&flag.docs);
900
1.27k
                    self.print_name_case(&flag.name);
901
1.27k
                    self.output.str(",");
902
1.27k
                    self.output.newline();
903
1.27k
                }
904
530
                self.output.indent_end();
905
            }
906
0
            None => bail!("document has unnamed flags type"),
907
        }
908
530
        Ok(())
909
530
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_flags
910
911
1.93k
    fn declare_variant(
912
1.93k
        &mut self,
913
1.93k
        resolve: &Resolve,
914
1.93k
        name: Option<&str>,
915
1.93k
        variant: &Variant,
916
1.93k
    ) -> Result<()> {
917
1.93k
        let name = match name {
918
1.93k
            Some(name) => name,
919
0
            None => bail!("document has unnamed variant type"),
920
        };
921
1.93k
        self.output.keyword("variant");
922
1.93k
        self.output.str(" ");
923
1.93k
        self.print_name_type(name, TypeKind::Variant);
924
1.93k
        self.output.indent_start();
925
5.95k
        for case in &variant.cases {
926
5.95k
            self.print_docs(&case.docs);
927
5.95k
            self.print_name_case(&case.name);
928
5.95k
            if let Some(ty) = case.ty {
929
4.74k
                self.output.str("(");
930
4.74k
                self.print_type_name(resolve, &ty)?;
931
4.74k
                self.output.str(")");
932
1.21k
            }
933
5.95k
            self.output.str(",");
934
5.95k
            self.output.newline();
935
        }
936
1.93k
        self.output.indent_end();
937
1.93k
        Ok(())
938
1.93k
    }
<wit_component::printing::WitPrinter>::declare_variant
Line
Count
Source
911
1.93k
    fn declare_variant(
912
1.93k
        &mut self,
913
1.93k
        resolve: &Resolve,
914
1.93k
        name: Option<&str>,
915
1.93k
        variant: &Variant,
916
1.93k
    ) -> Result<()> {
917
1.93k
        let name = match name {
918
1.93k
            Some(name) => name,
919
0
            None => bail!("document has unnamed variant type"),
920
        };
921
1.93k
        self.output.keyword("variant");
922
1.93k
        self.output.str(" ");
923
1.93k
        self.print_name_type(name, TypeKind::Variant);
924
1.93k
        self.output.indent_start();
925
5.95k
        for case in &variant.cases {
926
5.95k
            self.print_docs(&case.docs);
927
5.95k
            self.print_name_case(&case.name);
928
5.95k
            if let Some(ty) = case.ty {
929
4.74k
                self.output.str("(");
930
4.74k
                self.print_type_name(resolve, &ty)?;
931
4.74k
                self.output.str(")");
932
1.21k
            }
933
5.95k
            self.output.str(",");
934
5.95k
            self.output.newline();
935
        }
936
1.93k
        self.output.indent_end();
937
1.93k
        Ok(())
938
1.93k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_variant
939
940
164
    fn declare_option(
941
164
        &mut self,
942
164
        resolve: &Resolve,
943
164
        name: Option<&str>,
944
164
        payload: &Type,
945
164
    ) -> Result<()> {
946
164
        if let Some(name) = name {
947
164
            self.output.keyword("type");
948
164
            self.output.str(" ");
949
164
            self.print_name_type(name, TypeKind::Option);
950
164
            self.output.str(" = ");
951
164
            self.print_option_type(resolve, payload)?;
952
164
            self.output.semicolon();
953
0
        }
954
164
        Ok(())
955
164
    }
<wit_component::printing::WitPrinter>::declare_option
Line
Count
Source
940
164
    fn declare_option(
941
164
        &mut self,
942
164
        resolve: &Resolve,
943
164
        name: Option<&str>,
944
164
        payload: &Type,
945
164
    ) -> Result<()> {
946
164
        if let Some(name) = name {
947
164
            self.output.keyword("type");
948
164
            self.output.str(" ");
949
164
            self.print_name_type(name, TypeKind::Option);
950
164
            self.output.str(" = ");
951
164
            self.print_option_type(resolve, payload)?;
952
164
            self.output.semicolon();
953
0
        }
954
164
        Ok(())
955
164
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_option
956
957
222
    fn declare_result(
958
222
        &mut self,
959
222
        resolve: &Resolve,
960
222
        name: Option<&str>,
961
222
        result: &Result_,
962
222
    ) -> Result<()> {
963
222
        if let Some(name) = name {
964
222
            self.output.keyword("type");
965
222
            self.output.str(" ");
966
222
            self.print_name_type(name, TypeKind::Result);
967
222
            self.output.str(" = ");
968
222
            self.print_result_type(resolve, result)?;
969
222
            self.output.semicolon();
970
0
        }
971
222
        Ok(())
972
222
    }
<wit_component::printing::WitPrinter>::declare_result
Line
Count
Source
957
222
    fn declare_result(
958
222
        &mut self,
959
222
        resolve: &Resolve,
960
222
        name: Option<&str>,
961
222
        result: &Result_,
962
222
    ) -> Result<()> {
963
222
        if let Some(name) = name {
964
222
            self.output.keyword("type");
965
222
            self.output.str(" ");
966
222
            self.print_name_type(name, TypeKind::Result);
967
222
            self.output.str(" = ");
968
222
            self.print_result_type(resolve, result)?;
969
222
            self.output.semicolon();
970
0
        }
971
222
        Ok(())
972
222
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_result
973
974
5.86k
    fn declare_enum(&mut self, name: Option<&str>, enum_: &Enum) -> Result<()> {
975
5.86k
        let name = match name {
976
5.86k
            Some(name) => name,
977
0
            None => bail!("document has unnamed enum type"),
978
        };
979
5.86k
        self.output.keyword("enum");
980
5.86k
        self.output.str(" ");
981
5.86k
        self.print_name_type(name, TypeKind::Enum);
982
5.86k
        self.output.indent_start();
983
30.2k
        for case in &enum_.cases {
984
30.2k
            self.print_docs(&case.docs);
985
30.2k
            self.print_name_case(&case.name);
986
30.2k
            self.output.str(",");
987
30.2k
            self.output.newline();
988
30.2k
        }
989
5.86k
        self.output.indent_end();
990
5.86k
        Ok(())
991
5.86k
    }
<wit_component::printing::WitPrinter>::declare_enum
Line
Count
Source
974
5.86k
    fn declare_enum(&mut self, name: Option<&str>, enum_: &Enum) -> Result<()> {
975
5.86k
        let name = match name {
976
5.86k
            Some(name) => name,
977
0
            None => bail!("document has unnamed enum type"),
978
        };
979
5.86k
        self.output.keyword("enum");
980
5.86k
        self.output.str(" ");
981
5.86k
        self.print_name_type(name, TypeKind::Enum);
982
5.86k
        self.output.indent_start();
983
30.2k
        for case in &enum_.cases {
984
30.2k
            self.print_docs(&case.docs);
985
30.2k
            self.print_name_case(&case.name);
986
30.2k
            self.output.str(",");
987
30.2k
            self.output.newline();
988
30.2k
        }
989
5.86k
        self.output.indent_end();
990
5.86k
        Ok(())
991
5.86k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_enum
992
993
30
    fn declare_list(&mut self, resolve: &Resolve, name: Option<&str>, ty: &Type) -> Result<()> {
994
30
        if let Some(name) = name {
995
30
            self.output.keyword("type");
996
30
            self.output.str(" ");
997
30
            self.print_name_type(name, TypeKind::List);
998
30
            self.output.str(" = ");
999
30
            self.output.ty("list", TypeKind::BuiltIn);
1000
30
            self.output.str("<");
1001
30
            self.print_type_name(resolve, ty)?;
1002
30
            self.output.str(">");
1003
30
            self.output.semicolon();
1004
30
            return Ok(());
1005
0
        }
1006
1007
0
        Ok(())
1008
30
    }
<wit_component::printing::WitPrinter>::declare_list
Line
Count
Source
993
30
    fn declare_list(&mut self, resolve: &Resolve, name: Option<&str>, ty: &Type) -> Result<()> {
994
30
        if let Some(name) = name {
995
30
            self.output.keyword("type");
996
30
            self.output.str(" ");
997
30
            self.print_name_type(name, TypeKind::List);
998
30
            self.output.str(" = ");
999
30
            self.output.ty("list", TypeKind::BuiltIn);
1000
30
            self.output.str("<");
1001
30
            self.print_type_name(resolve, ty)?;
1002
30
            self.output.str(">");
1003
30
            self.output.semicolon();
1004
30
            return Ok(());
1005
0
        }
1006
1007
0
        Ok(())
1008
30
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_list
1009
1010
0
    fn declare_map(
1011
0
        &mut self,
1012
0
        resolve: &Resolve,
1013
0
        name: Option<&str>,
1014
0
        key_ty: &Type,
1015
0
        value_ty: &Type,
1016
0
    ) -> Result<()> {
1017
0
        if let Some(name) = name {
1018
0
            self.output.keyword("type");
1019
0
            self.output.str(" ");
1020
0
            self.print_name_type(name, TypeKind::Map);
1021
0
            self.output.str(" = ");
1022
0
            self.output.ty("map", TypeKind::BuiltIn);
1023
0
            self.output.str("<");
1024
0
            self.print_type_name(resolve, key_ty)?;
1025
0
            self.output.str(", ");
1026
0
            self.print_type_name(resolve, value_ty)?;
1027
0
            self.output.str(">");
1028
0
            self.output.semicolon();
1029
0
            return Ok(());
1030
0
        }
1031
1032
0
        Ok(())
1033
0
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter>::declare_map
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_map
1034
1035
8
    fn declare_fixed_length_list(
1036
8
        &mut self,
1037
8
        resolve: &Resolve,
1038
8
        name: Option<&str>,
1039
8
        ty: &Type,
1040
8
        elements: u32,
1041
8
    ) -> Result<()> {
1042
8
        if let Some(name) = name {
1043
8
            self.output.keyword("type");
1044
8
            self.output.str(" ");
1045
8
            self.print_name_type(name, TypeKind::List);
1046
8
            self.output.str(" = ");
1047
8
            self.output.ty("list", TypeKind::BuiltIn);
1048
8
            self.output.str("<");
1049
8
            self.print_type_name(resolve, ty)?;
1050
8
            self.output.str(&format!(", {elements}"));
1051
8
            self.output.str(">");
1052
8
            self.output.semicolon();
1053
8
            return Ok(());
1054
0
        }
1055
1056
0
        Ok(())
1057
8
    }
<wit_component::printing::WitPrinter>::declare_fixed_length_list
Line
Count
Source
1035
8
    fn declare_fixed_length_list(
1036
8
        &mut self,
1037
8
        resolve: &Resolve,
1038
8
        name: Option<&str>,
1039
8
        ty: &Type,
1040
8
        elements: u32,
1041
8
    ) -> Result<()> {
1042
8
        if let Some(name) = name {
1043
8
            self.output.keyword("type");
1044
8
            self.output.str(" ");
1045
8
            self.print_name_type(name, TypeKind::List);
1046
8
            self.output.str(" = ");
1047
8
            self.output.ty("list", TypeKind::BuiltIn);
1048
8
            self.output.str("<");
1049
8
            self.print_type_name(resolve, ty)?;
1050
8
            self.output.str(&format!(", {elements}"));
1051
8
            self.output.str(">");
1052
8
            self.output.semicolon();
1053
8
            return Ok(());
1054
0
        }
1055
1056
0
        Ok(())
1057
8
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_fixed_length_list
1058
1059
6
    fn declare_stream(
1060
6
        &mut self,
1061
6
        resolve: &Resolve,
1062
6
        name: Option<&str>,
1063
6
        ty: Option<&Type>,
1064
6
    ) -> Result<()> {
1065
6
        if let Some(name) = name {
1066
6
            self.output.keyword("type");
1067
6
            self.output.str(" ");
1068
6
            self.print_name_type(name, TypeKind::Stream);
1069
6
            self.output.str(" = ");
1070
6
            self.output.ty("stream", TypeKind::BuiltIn);
1071
6
            if let Some(ty) = ty {
1072
6
                self.output.str("<");
1073
6
                self.print_type_name(resolve, ty)?;
1074
6
                self.output.str(">");
1075
0
            }
1076
6
            self.output.semicolon();
1077
0
        }
1078
1079
6
        Ok(())
1080
6
    }
<wit_component::printing::WitPrinter>::declare_stream
Line
Count
Source
1059
6
    fn declare_stream(
1060
6
        &mut self,
1061
6
        resolve: &Resolve,
1062
6
        name: Option<&str>,
1063
6
        ty: Option<&Type>,
1064
6
    ) -> Result<()> {
1065
6
        if let Some(name) = name {
1066
6
            self.output.keyword("type");
1067
6
            self.output.str(" ");
1068
6
            self.print_name_type(name, TypeKind::Stream);
1069
6
            self.output.str(" = ");
1070
6
            self.output.ty("stream", TypeKind::BuiltIn);
1071
6
            if let Some(ty) = ty {
1072
6
                self.output.str("<");
1073
6
                self.print_type_name(resolve, ty)?;
1074
6
                self.output.str(">");
1075
0
            }
1076
6
            self.output.semicolon();
1077
0
        }
1078
1079
6
        Ok(())
1080
6
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_stream
1081
1082
14
    fn declare_future(
1083
14
        &mut self,
1084
14
        resolve: &Resolve,
1085
14
        name: Option<&str>,
1086
14
        ty: Option<&Type>,
1087
14
    ) -> Result<()> {
1088
14
        if let Some(name) = name {
1089
14
            self.output.keyword("type");
1090
14
            self.output.str(" ");
1091
14
            self.print_name_type(name, TypeKind::Future);
1092
14
            self.output.str(" = ");
1093
14
            self.output.ty("future", TypeKind::BuiltIn);
1094
14
            if let Some(ty) = ty {
1095
12
                self.output.str("<");
1096
12
                self.print_type_name(resolve, ty)?;
1097
12
                self.output.str(">");
1098
2
            }
1099
14
            self.output.semicolon();
1100
0
        }
1101
1102
14
        Ok(())
1103
14
    }
<wit_component::printing::WitPrinter>::declare_future
Line
Count
Source
1082
14
    fn declare_future(
1083
14
        &mut self,
1084
14
        resolve: &Resolve,
1085
14
        name: Option<&str>,
1086
14
        ty: Option<&Type>,
1087
14
    ) -> Result<()> {
1088
14
        if let Some(name) = name {
1089
14
            self.output.keyword("type");
1090
14
            self.output.str(" ");
1091
14
            self.print_name_type(name, TypeKind::Future);
1092
14
            self.output.str(" = ");
1093
14
            self.output.ty("future", TypeKind::BuiltIn);
1094
14
            if let Some(ty) = ty {
1095
12
                self.output.str("<");
1096
12
                self.print_type_name(resolve, ty)?;
1097
12
                self.output.str(">");
1098
2
            }
1099
14
            self.output.semicolon();
1100
0
        }
1101
1102
14
        Ok(())
1103
14
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::declare_future
1104
1105
188k
    fn escape_name(name: &str) -> Cow<'_, str> {
1106
188k
        if is_keyword(name) {
1107
32
            Cow::Owned(format!("%{name}"))
1108
        } else {
1109
188k
            Cow::Borrowed(name)
1110
        }
1111
188k
    }
<wit_component::printing::WitPrinter>::escape_name
Line
Count
Source
1105
188k
    fn escape_name(name: &str) -> Cow<'_, str> {
1106
188k
        if is_keyword(name) {
1107
32
            Cow::Owned(format!("%{name}"))
1108
        } else {
1109
188k
            Cow::Borrowed(name)
1110
        }
1111
188k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::escape_name
1112
1113
118k
    fn print_name_type(&mut self, name: &str, kind: TypeKind) {
1114
118k
        self.output.ty(Self::escape_name(name).deref(), kind);
1115
118k
    }
<wit_component::printing::WitPrinter>::print_name_type
Line
Count
Source
1113
118k
    fn print_name_type(&mut self, name: &str, kind: TypeKind) {
1114
118k
        self.output.ty(Self::escape_name(name).deref(), kind);
1115
118k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_name_type
1116
1117
32.0k
    fn print_name_param(&mut self, name: &str) {
1118
32.0k
        self.output.param(Self::escape_name(name).deref());
1119
32.0k
    }
<wit_component::printing::WitPrinter>::print_name_param
Line
Count
Source
1117
32.0k
    fn print_name_param(&mut self, name: &str) {
1118
32.0k
        self.output.param(Self::escape_name(name).deref());
1119
32.0k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_name_param
1120
1121
37.4k
    fn print_name_case(&mut self, name: &str) {
1122
37.4k
        self.output.case(Self::escape_name(name).deref());
1123
37.4k
    }
<wit_component::printing::WitPrinter>::print_name_case
Line
Count
Source
1121
37.4k
    fn print_name_case(&mut self, name: &str) {
1122
37.4k
        self.output.case(Self::escape_name(name).deref());
1123
37.4k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_name_case
1124
1125
107k
    fn print_docs(&mut self, docs: &Docs) {
1126
107k
        if self.emit_docs {
1127
107k
            if let Some(contents) = &docs.contents {
1128
0
                for line in contents.lines() {
1129
0
                    self.output.doc(line);
1130
0
                }
1131
107k
            }
1132
0
        }
1133
107k
    }
<wit_component::printing::WitPrinter>::print_docs
Line
Count
Source
1125
107k
    fn print_docs(&mut self, docs: &Docs) {
1126
107k
        if self.emit_docs {
1127
107k
            if let Some(contents) = &docs.contents {
1128
0
                for line in contents.lines() {
1129
0
                    self.output.doc(line);
1130
0
                }
1131
107k
            }
1132
0
        }
1133
107k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_docs
1134
1135
66.5k
    fn print_stability(&mut self, stability: &Stability) {
1136
66.5k
        match stability {
1137
64.1k
            Stability::Unknown => {}
1138
1.83k
            Stability::Stable { since, deprecated } => {
1139
1.83k
                self.output.keyword("@since");
1140
1.83k
                self.output.str("(");
1141
1.83k
                self.output.keyword("version");
1142
1.83k
                self.output.str(" = ");
1143
1.83k
                self.print_name_type(&since.to_string(), TypeKind::VersionAnnotation);
1144
1.83k
                self.output.str(")");
1145
1.83k
                self.output.newline();
1146
1.83k
                if let Some(version) = deprecated {
1147
700
                    self.output.keyword("@deprecated");
1148
700
                    self.output.str("(");
1149
700
                    self.output.keyword("version");
1150
700
                    self.output.str(" = ");
1151
700
                    self.print_name_type(&version.to_string(), TypeKind::VersionAnnotation);
1152
700
                    self.output.str(")");
1153
700
                    self.output.newline();
1154
1.13k
                }
1155
            }
1156
            Stability::Unstable {
1157
570
                feature,
1158
570
                deprecated,
1159
            } => {
1160
570
                self.output.keyword("@unstable");
1161
570
                self.output.str("(");
1162
570
                self.output.keyword("feature");
1163
570
                self.output.str(" = ");
1164
570
                self.output.str(feature);
1165
570
                self.output.str(")");
1166
570
                self.output.newline();
1167
570
                if let Some(version) = deprecated {
1168
0
                    self.output.keyword("@deprecated");
1169
0
                    self.output.str("(");
1170
0
                    self.output.keyword("version");
1171
0
                    self.output.str(" = ");
1172
0
                    self.print_name_type(&version.to_string(), TypeKind::VersionAnnotation);
1173
0
                    self.output.str(")");
1174
0
                    self.output.newline();
1175
570
                }
1176
            }
1177
        }
1178
66.5k
    }
<wit_component::printing::WitPrinter>::print_stability
Line
Count
Source
1135
66.5k
    fn print_stability(&mut self, stability: &Stability) {
1136
66.5k
        match stability {
1137
64.1k
            Stability::Unknown => {}
1138
1.83k
            Stability::Stable { since, deprecated } => {
1139
1.83k
                self.output.keyword("@since");
1140
1.83k
                self.output.str("(");
1141
1.83k
                self.output.keyword("version");
1142
1.83k
                self.output.str(" = ");
1143
1.83k
                self.print_name_type(&since.to_string(), TypeKind::VersionAnnotation);
1144
1.83k
                self.output.str(")");
1145
1.83k
                self.output.newline();
1146
1.83k
                if let Some(version) = deprecated {
1147
700
                    self.output.keyword("@deprecated");
1148
700
                    self.output.str("(");
1149
700
                    self.output.keyword("version");
1150
700
                    self.output.str(" = ");
1151
700
                    self.print_name_type(&version.to_string(), TypeKind::VersionAnnotation);
1152
700
                    self.output.str(")");
1153
700
                    self.output.newline();
1154
1.13k
                }
1155
            }
1156
            Stability::Unstable {
1157
570
                feature,
1158
570
                deprecated,
1159
            } => {
1160
570
                self.output.keyword("@unstable");
1161
570
                self.output.str("(");
1162
570
                self.output.keyword("feature");
1163
570
                self.output.str(" = ");
1164
570
                self.output.str(feature);
1165
570
                self.output.str(")");
1166
570
                self.output.newline();
1167
570
                if let Some(version) = deprecated {
1168
0
                    self.output.keyword("@deprecated");
1169
0
                    self.output.str("(");
1170
0
                    self.output.keyword("version");
1171
0
                    self.output.str(" = ");
1172
0
                    self.print_name_type(&version.to_string(), TypeKind::VersionAnnotation);
1173
0
                    self.output.str(")");
1174
0
                    self.output.newline();
1175
570
                }
1176
            }
1177
        }
1178
66.5k
    }
Unexecuted instantiation: <wit_component::printing::WitPrinter<_>>::print_stability
1179
}
1180
1181
188k
fn is_keyword(name: &str) -> bool {
1182
32
    matches!(
1183
188k
        name,
1184
188k
        "use"
1185
188k
            | "type"
1186
188k
            | "func"
1187
188k
            | "u8"
1188
188k
            | "u16"
1189
188k
            | "u32"
1190
188k
            | "u64"
1191
188k
            | "s8"
1192
188k
            | "s16"
1193
188k
            | "s32"
1194
188k
            | "s64"
1195
188k
            | "f32"
1196
188k
            | "f64"
1197
188k
            | "float32"
1198
188k
            | "float64"
1199
188k
            | "char"
1200
188k
            | "resource"
1201
188k
            | "record"
1202
188k
            | "flags"
1203
188k
            | "variant"
1204
188k
            | "enum"
1205
188k
            | "bool"
1206
188k
            | "string"
1207
188k
            | "option"
1208
188k
            | "result"
1209
188k
            | "future"
1210
188k
            | "stream"
1211
188k
            | "list"
1212
188k
            | "own"
1213
188k
            | "borrow"
1214
188k
            | "_"
1215
188k
            | "as"
1216
188k
            | "from"
1217
188k
            | "static"
1218
188k
            | "interface"
1219
188k
            | "tuple"
1220
188k
            | "world"
1221
188k
            | "import"
1222
188k
            | "export"
1223
188k
            | "package"
1224
188k
            | "with"
1225
188k
            | "include"
1226
188k
            | "constructor"
1227
188k
            | "error-context"
1228
188k
            | "async"
1229
188k
            | "map"
1230
    )
1231
188k
}
1232
1233
/// Trait defining visitor methods driven by [`WitPrinter`](WitPrinter).
1234
///
1235
/// Some methods in this trait have default implementations. These default
1236
/// implementations may rely on helper functions that are not
1237
/// invoked directly by `WitPrinter`.
1238
pub trait Output {
1239
    /// Push a string slice into a buffer or an output.
1240
    ///
1241
    /// Parameter `src` can contain punctuation characters, and must be escaped
1242
    /// when outputting to languages like HTML.
1243
    /// Helper function used exclusively by the default implementations of trait methods.
1244
    /// This function is not called directly by `WitPrinter`.
1245
    /// When overriding all the trait methods, users do not need to handle this function.
1246
    fn push_str(&mut self, src: &str);
1247
1248
    /// Set the appropriate indentation.
1249
    ///
1250
    /// Helper function used exclusively by the default implementations of trait methods.
1251
    /// This function is not called directly by `WitPrinter`.
1252
    /// When overriding all the trait methods, users do not need to handle this function.
1253
    fn indent_if_needed(&mut self) -> bool;
1254
1255
    /// Start of indentation. In WIT this represents ` {\n`.
1256
    fn indent_start(&mut self);
1257
1258
    /// End of indentation. In WIT this represents `}\n`.
1259
    fn indent_end(&mut self);
1260
1261
    /// This method is designed to be used only by the default methods of this trait.
1262
    /// Called only from the default implementation functions of this trait.
1263
772k
    fn indent_and_print(&mut self, src: &str) {
1264
772k
        assert!(!src.contains('\n'));
1265
772k
        let indented = self.indent_if_needed();
1266
772k
        if indented && src.starts_with(' ') {
1267
0
            panic!("cannot add a space at the beginning of a line");
1268
772k
        }
1269
772k
        self.push_str(src);
1270
772k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::indent_and_print
Line
Count
Source
1263
772k
    fn indent_and_print(&mut self, src: &str) {
1264
772k
        assert!(!src.contains('\n'));
1265
772k
        let indented = self.indent_if_needed();
1266
772k
        if indented && src.starts_with(' ') {
1267
0
            panic!("cannot add a space at the beginning of a line");
1268
772k
        }
1269
772k
        self.push_str(src);
1270
772k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::indent_and_print
1271
1272
    /// A newline is added.
1273
    fn newline(&mut self);
1274
1275
    /// A keyword is added. Keywords are hardcoded strings from `[a-z]`, but can start with `@`
1276
    /// when printing a [Feature Gate](https://github.com/WebAssembly/component-model/blob/main/design/mvp/WIT.md#feature-gates)
1277
94.4k
    fn keyword(&mut self, src: &str) {
1278
94.4k
        self.indent_and_print(src);
1279
94.4k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::keyword
Line
Count
Source
1277
94.4k
    fn keyword(&mut self, src: &str) {
1278
94.4k
        self.indent_and_print(src);
1279
94.4k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::keyword
1280
1281
    /// A type is added.
1282
277k
    fn ty(&mut self, src: &str, _kind: TypeKind) {
1283
277k
        self.indent_and_print(src);
1284
277k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::ty
Line
Count
Source
1282
277k
    fn ty(&mut self, src: &str, _kind: TypeKind) {
1283
277k
        self.indent_and_print(src);
1284
277k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::ty
1285
1286
    /// A parameter name of a function, record or a named return is added.
1287
32.0k
    fn param(&mut self, src: &str) {
1288
32.0k
        self.indent_and_print(src);
1289
32.0k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::param
Line
Count
Source
1287
32.0k
    fn param(&mut self, src: &str) {
1288
32.0k
        self.indent_and_print(src);
1289
32.0k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::param
1290
1291
    /// A case belonging to a variant, enum or flags is added.
1292
37.4k
    fn case(&mut self, src: &str) {
1293
37.4k
        self.indent_and_print(src);
1294
37.4k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::case
Line
Count
Source
1292
37.4k
    fn case(&mut self, src: &str) {
1293
37.4k
        self.indent_and_print(src);
1294
37.4k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::case
1295
1296
    /// Generic argument section starts. In WIT this represents the `<` character.
1297
59.4k
    fn generic_args_start(&mut self) {
1298
59.4k
        assert!(
1299
59.4k
            !self.indent_if_needed(),
1300
            "`generic_args_start` is never called after newline"
1301
        );
1302
59.4k
        self.push_str("<");
1303
59.4k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::generic_args_start
Line
Count
Source
1297
59.4k
    fn generic_args_start(&mut self) {
1298
59.4k
        assert!(
1299
59.4k
            !self.indent_if_needed(),
1300
            "`generic_args_start` is never called after newline"
1301
        );
1302
59.4k
        self.push_str("<");
1303
59.4k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::generic_args_start
1304
1305
    /// Generic argument section ends. In WIT this represents the '>' character.
1306
59.4k
    fn generic_args_end(&mut self) {
1307
59.4k
        assert!(
1308
59.4k
            !self.indent_if_needed(),
1309
            "`generic_args_end` is never called after newline"
1310
        );
1311
59.4k
        self.push_str(">");
1312
59.4k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::generic_args_end
Line
Count
Source
1306
59.4k
    fn generic_args_end(&mut self) {
1307
59.4k
        assert!(
1308
59.4k
            !self.indent_if_needed(),
1309
            "`generic_args_end` is never called after newline"
1310
        );
1311
59.4k
        self.push_str(">");
1312
59.4k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::generic_args_end
1313
1314
    /// Called when a single documentation line is added.
1315
    /// The `doc` parameter starts with `///` omitted, and can be an empty string.
1316
0
    fn doc(&mut self, doc: &str) {
1317
0
        assert!(!doc.contains('\n'));
1318
0
        self.indent_if_needed();
1319
0
        self.push_str("///");
1320
0
        if !doc.is_empty() {
1321
0
            self.push_str(" ");
1322
0
            self.push_str(doc);
1323
0
        }
1324
0
        self.newline();
1325
0
    }
Unexecuted instantiation: <wit_component::printing::OutputToString as wit_component::printing::Output>::doc
Unexecuted instantiation: <_ as wit_component::printing::Output>::doc
1326
1327
    /// A semicolon is added.
1328
29.7k
    fn semicolon(&mut self) {
1329
29.7k
        assert!(
1330
29.7k
            !self.indent_if_needed(),
1331
            "`semicolon` is never called after newline"
1332
        );
1333
29.7k
        self.push_str(";");
1334
29.7k
        self.newline();
1335
29.7k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::semicolon
Line
Count
Source
1328
29.7k
    fn semicolon(&mut self) {
1329
29.7k
        assert!(
1330
29.7k
            !self.indent_if_needed(),
1331
            "`semicolon` is never called after newline"
1332
        );
1333
29.7k
        self.push_str(";");
1334
29.7k
        self.newline();
1335
29.7k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::semicolon
1336
1337
    /// Any string that does not have a specialized function is added.
1338
    /// Parameter `src` can contain punctuation characters, and must be escaped
1339
    /// when outputting to languages like HTML.
1340
331k
    fn str(&mut self, src: &str) {
1341
331k
        self.indent_and_print(src);
1342
331k
    }
<wit_component::printing::OutputToString as wit_component::printing::Output>::str
Line
Count
Source
1340
331k
    fn str(&mut self, src: &str) {
1341
331k
        self.indent_and_print(src);
1342
331k
    }
Unexecuted instantiation: <_ as wit_component::printing::Output>::str
1343
}
1344
1345
/// Represents the different kinds of types that can be encountered while
1346
/// visiting a WIT file.
1347
///
1348
/// Each variant refers to the name of the respective element (e.g., function, type, or namespace),
1349
/// not the entire declaration.
1350
#[non_exhaustive]
1351
#[derive(Clone, Copy, Debug)]
1352
pub enum TypeKind {
1353
    /// A built-in type, such as "list" or "option".
1354
    BuiltIn,
1355
    /// An enumeration type name.
1356
    Enum,
1357
    /// An error-context type name.
1358
    ErrorContext,
1359
    /// A flags type name.
1360
    Flags,
1361
    /// A freestanding function name, not associated with any specific type or namespace.
1362
    /// For example, "myfunc" in `myfunc: func() -> string;`.
1363
    FunctionFreestanding,
1364
    /// A method, associated with a resource.
1365
    FunctionMethod,
1366
    /// A static function, associated with a resource.
1367
    FunctionStatic,
1368
    /// A future type name.
1369
    Future,
1370
    /// An interface declaration name.
1371
    InterfaceDeclaration,
1372
    /// An interface name when printing a path, for example in `use`.
1373
    InterfacePath,
1374
    /// A list type name.
1375
    List,
1376
    /// A map type name.
1377
    Map,
1378
    /// A namespace declaration.
1379
    NamespaceDeclaration,
1380
    /// A namespace when printing a path, for example in `use`.
1381
    NamespacePath,
1382
    /// An option type name.
1383
    Option,
1384
    /// A package name declaration.
1385
    PackageNameDeclaration,
1386
    /// A package name when printing a path, for example in `use`.
1387
    PackageNamePath,
1388
    /// A record type name.
1389
    Record,
1390
    /// A resource type name.
1391
    Resource,
1392
    /// A result type name.
1393
    Result,
1394
    /// A stream type name.
1395
    Stream,
1396
    /// A tuple type name.
1397
    Tuple,
1398
    /// A type alias.
1399
    TypeAlias,
1400
    /// An imported type name.
1401
    TypeImport,
1402
    /// A user-defined type name.
1403
    TypeName,
1404
    /// A variant type name.
1405
    Variant,
1406
    /// A version declaration.
1407
    VersionDeclaration,
1408
    /// A version when printing a path, for example in `use`.
1409
    VersionPath,
1410
    /// A version when printing stability annotations, for example in `@since`
1411
    VersionAnnotation,
1412
    /// A world declaration name.
1413
    WorldDeclaration,
1414
    /// A fallback for types that do not fit into any other category.
1415
    Other,
1416
}
1417
1418
/// Helper structure to help maintain an indentation level when printing source,
1419
/// modeled after the support in `wit-bindgen-core`. Indentation is set to two spaces.
1420
#[derive(Default)]
1421
pub struct OutputToString {
1422
    indent: usize,
1423
    output: String,
1424
    // set to true after newline, then to false after first item is indented.
1425
    needs_indent: bool,
1426
}
1427
1428
impl Output for OutputToString {
1429
944k
    fn push_str(&mut self, src: &str) {
1430
944k
        self.output.push_str(src);
1431
944k
    }
1432
1433
963k
    fn indent_if_needed(&mut self) -> bool {
1434
963k
        if self.needs_indent {
1435
155k
            for _ in 0..self.indent {
1436
155k
                // Indenting by two spaces.
1437
155k
                self.output.push_str("  ");
1438
155k
            }
1439
153k
            self.needs_indent = false;
1440
153k
            true
1441
        } else {
1442
809k
            false
1443
        }
1444
963k
    }
1445
1446
42.3k
    fn indent_start(&mut self) {
1447
42.3k
        assert!(
1448
42.3k
            !self.needs_indent,
1449
            "`indent_start` is never called after newline"
1450
        );
1451
42.3k
        self.output.push_str(" {");
1452
42.3k
        self.indent += 1;
1453
42.3k
        self.newline();
1454
42.3k
    }
1455
1456
42.3k
    fn indent_end(&mut self) {
1457
        // Note that a `saturating_sub` is used here to prevent a panic
1458
        // here in the case of invalid code being generated in debug
1459
        // mode. It's typically easier to debug those issues through
1460
        // looking at the source code rather than getting a panic.
1461
42.3k
        self.indent = self.indent.saturating_sub(1);
1462
42.3k
        self.indent_if_needed();
1463
42.3k
        self.output.push('}');
1464
42.3k
        self.newline();
1465
42.3k
    }
1466
1467
201k
    fn newline(&mut self) {
1468
201k
        self.output.push('\n');
1469
201k
        self.needs_indent = true;
1470
201k
    }
1471
}
1472
1473
impl From<OutputToString> for String {
1474
0
    fn from(output: OutputToString) -> String {
1475
0
        output.output
1476
0
    }
1477
}
1478
1479
impl Display for OutputToString {
1480
4.67k
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1481
4.67k
        self.output.fmt(f)
1482
4.67k
    }
1483
}