Skip to content

Commit 9fb2019

Browse files
authored
wit-component: Add doc comment printing to WitPrinter (#1167)
Add a configuration option and implementation to print doc comments with associated items.
1 parent a0c46a7 commit 9fb2019

File tree

2 files changed

+63
-3
lines changed

2 files changed

+63
-3
lines changed

crates/wit-component/src/printing.rs

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,36 @@ use std::mem;
55
use wit_parser::*;
66

77
/// A utility for printing WebAssembly interface definitions to a string.
8-
#[derive(Default)]
98
pub struct WitPrinter {
109
output: Output,
1110

1211
// Count of how many items in this current block have been printed to print
1312
// a blank line between each item, but not the first item.
1413
any_items: bool,
14+
15+
// Whether to print doc comments.
16+
emit_docs: bool,
17+
}
18+
19+
impl Default for WitPrinter {
20+
fn default() -> Self {
21+
Self {
22+
output: Default::default(),
23+
any_items: false,
24+
emit_docs: true,
25+
}
26+
}
1527
}
1628

1729
impl WitPrinter {
30+
/// Configure whether doc comments will be printed.
31+
///
32+
/// Defaults to true.
33+
pub fn emit_docs(&mut self, enabled: bool) -> &mut Self {
34+
self.emit_docs = enabled;
35+
self
36+
}
37+
1838
/// Print the given WIT package to a string.
1939
pub fn print(&mut self, resolve: &Resolve, pkgid: PackageId) -> Result<String> {
2040
let pkg = &resolve.packages[pkgid];
@@ -27,6 +47,7 @@ impl WitPrinter {
2747
}
2848
self.output.push_str("\n\n");
2949
for (name, id) in pkg.interfaces.iter() {
50+
self.print_docs(&resolve.interfaces[*id].docs);
3051
self.output.push_str("interface ");
3152
self.print_name(name);
3253
self.output.push_str(" {\n");
@@ -35,6 +56,7 @@ impl WitPrinter {
3556
}
3657

3758
for (name, id) in pkg.worlds.iter() {
59+
self.print_docs(&resolve.worlds[*id].docs);
3860
self.output.push_str("world ");
3961
self.print_name(name);
4062
self.output.push_str(" {\n");
@@ -79,6 +101,7 @@ impl WitPrinter {
79101

80102
for (name, func) in freestanding {
81103
self.new_item();
104+
self.print_docs(&func.docs);
82105
self.print_name(name);
83106
self.output.push_str(": ");
84107
self.print_function(resolve, func)?;
@@ -162,6 +185,7 @@ impl WitPrinter {
162185

163186
for id in types_to_declare {
164187
self.new_item();
188+
self.print_docs(&resolve.types[id].docs);
165189
match resolve.types[id].kind {
166190
TypeDefKind::Resource => self.print_resource(
167191
resolve,
@@ -188,10 +212,12 @@ impl WitPrinter {
188212
match &func.kind {
189213
FunctionKind::Constructor(_) => {}
190214
FunctionKind::Method(_) => {
215+
self.print_docs(&func.docs);
191216
self.print_name(func.item_name());
192217
self.output.push_str(": ");
193218
}
194219
FunctionKind::Static(_) => {
220+
self.print_docs(&func.docs);
195221
self.print_name(func.item_name());
196222
self.output.push_str(": ");
197223
self.output.push_str("static ");
@@ -308,6 +334,16 @@ impl WitPrinter {
308334
cur_pkg: PackageId,
309335
desc: &str,
310336
) -> Result<()> {
337+
// Print inline item docs
338+
if matches!(name, WorldKey::Name(_)) {
339+
self.print_docs(match item {
340+
WorldItem::Interface(id) => &resolve.interfaces[*id].docs,
341+
WorldItem::Function(f) => &f.docs,
342+
// Types are handled separately
343+
WorldItem::Type(_) => unreachable!(),
344+
});
345+
}
346+
311347
self.output.push_str(desc);
312348
self.output.push_str(" ");
313349
match name {
@@ -631,6 +667,7 @@ impl WitPrinter {
631667
self.print_name(name);
632668
self.output.push_str(" {\n");
633669
for field in &record.fields {
670+
self.print_docs(&field.docs);
634671
self.print_name(&field.name);
635672
self.output.push_str(": ");
636673
self.print_type_name(resolve, &field.ty)?;
@@ -666,6 +703,7 @@ impl WitPrinter {
666703
self.print_name(name);
667704
self.output.push_str(" {\n");
668705
for flag in &flags.flags {
706+
self.print_docs(&flag.docs);
669707
self.print_name(&flag.name);
670708
self.output.push_str(",\n");
671709
}
@@ -690,6 +728,7 @@ impl WitPrinter {
690728
self.print_name(name);
691729
self.output.push_str(" {\n");
692730
for case in &variant.cases {
731+
self.print_docs(&case.docs);
693732
self.print_name(&case.name);
694733
if let Some(ty) = case.ty {
695734
self.output.push_str("(");
@@ -716,6 +755,7 @@ impl WitPrinter {
716755
self.print_name(name);
717756
self.output.push_str(" {\n");
718757
for case in &union.cases {
758+
self.print_docs(&case.docs);
719759
self.output.push_str("");
720760
self.print_type_name(resolve, &case.ty)?;
721761
self.output.push_str(",\n");
@@ -765,6 +805,7 @@ impl WitPrinter {
765805
self.print_name(name);
766806
self.output.push_str(" {\n");
767807
for case in &enum_.cases {
808+
self.print_docs(&case.docs);
768809
self.print_name(&case.name);
769810
self.output.push_str(",\n");
770811
}
@@ -791,6 +832,18 @@ impl WitPrinter {
791832
}
792833
self.output.push_str(name);
793834
}
835+
836+
fn print_docs(&mut self, docs: &Docs) {
837+
if self.emit_docs {
838+
if let Some(contents) = &docs.contents {
839+
for line in contents.lines() {
840+
self.output.push_str("/// ");
841+
self.output.push_str(line);
842+
self.output.push_str("\n");
843+
}
844+
}
845+
}
846+
}
794847
}
795848

796849
fn resource_func(f: &Function) -> Option<TypeId> {

src/bin/wasm-tools/component.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,10 @@ pub struct WitOpts {
395395
#[clap(short = 't', long, conflicts_with = "wasm", conflicts_with = "out_dir")]
396396
wat: bool,
397397

398+
/// Do not include doc comments when emitting WIT text.
399+
#[clap(long)]
400+
no_docs: bool,
401+
398402
/// Emit the entire WIT resolution graph instead of just the "top level"
399403
/// package to the output directory specified.
400404
///
@@ -507,6 +511,9 @@ impl WitOpts {
507511
let resolve = decoded.resolve();
508512
let main = decoded.package();
509513

514+
let mut printer = WitPrinter::default();
515+
printer.emit_docs(!self.no_docs);
516+
510517
match &self.out_dir {
511518
Some(dir) => {
512519
assert!(self.output.output_path().is_none());
@@ -526,7 +533,7 @@ impl WitOpts {
526533
}
527534

528535
for (id, pkg) in resolve.packages.iter() {
529-
let output = WitPrinter::default().print(resolve, id)?;
536+
let output = printer.print(resolve, id)?;
530537
let out_dir = if id == main {
531538
dir.clone()
532539
} else {
@@ -553,7 +560,7 @@ impl WitOpts {
553560
}
554561
}
555562
None => {
556-
let output = WitPrinter::default().print(resolve, main)?;
563+
let output = printer.print(resolve, main)?;
557564
self.output.output(Output::Wat(&output))?;
558565
}
559566
}

0 commit comments

Comments
 (0)