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