Coverage Report

Created: 2025-01-09 07:53

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