Coverage Report

Created: 2026-10-31 07:49

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