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