/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 | | } |