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