Skip to content

Commit 458ff31

Browse files
authored
Include docs in imports and exports. (#960)
Include the parsed documentation comment in the AST's `Import` and `Export` records so that, for example, documentation for the following function can be included in the generated bindings. ``` default world component { /// Say hello! export hello-world: func() -> string } ``` This will make the documentation generated by `cargo-component doc` added in bytecodealliance/cargo-component#63 more useful, and will allow me to fix a bug in a test which is supposed to be testing that the documentation comments show up.
1 parent cfb51b3 commit 458ff31

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

crates/wit-parser/src/ast.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,8 @@ pub enum WorldItem<'a> {
150150
impl<'a> WorldItem<'a> {
151151
fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result<WorldItem<'a>> {
152152
match tokens.clone().next()? {
153-
Some((_span, Token::Import)) => Import::parse(tokens).map(WorldItem::Import),
154-
Some((_span, Token::Export)) => Export::parse(tokens).map(WorldItem::Export),
153+
Some((_span, Token::Import)) => Import::parse(tokens, docs).map(WorldItem::Import),
154+
Some((_span, Token::Export)) => Export::parse(tokens, docs).map(WorldItem::Export),
155155
Some((_span, Token::Use)) => Use::parse(tokens).map(WorldItem::Use),
156156
Some((_span, Token::Type)) => TypeDef::parse(tokens, docs).map(WorldItem::Type),
157157
Some((_span, Token::Flags)) => TypeDef::parse_flags(tokens, docs).map(WorldItem::Type),
@@ -174,32 +174,34 @@ impl<'a> WorldItem<'a> {
174174
}
175175

176176
pub struct Import<'a> {
177+
docs: Docs<'a>,
177178
name: Id<'a>,
178179
kind: ExternKind<'a>,
179180
}
180181

181182
impl<'a> Import<'a> {
182-
fn parse(tokens: &mut Tokenizer<'a>) -> Result<Import<'a>> {
183+
fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result<Import<'a>> {
183184
tokens.expect(Token::Import)?;
184185
let name = parse_id(tokens)?;
185186
tokens.expect(Token::Colon)?;
186187
let kind = ExternKind::parse(tokens)?;
187-
Ok(Import { name, kind })
188+
Ok(Import { docs, name, kind })
188189
}
189190
}
190191

191192
pub struct Export<'a> {
193+
docs: Docs<'a>,
192194
name: Id<'a>,
193195
kind: ExternKind<'a>,
194196
}
195197

196198
impl<'a> Export<'a> {
197-
fn parse(tokens: &mut Tokenizer<'a>) -> Result<Export<'a>> {
199+
fn parse(tokens: &mut Tokenizer<'a>, docs: Docs<'a>) -> Result<Export<'a>> {
198200
tokens.expect(Token::Export)?;
199201
let name = parse_id(tokens)?;
200202
tokens.expect(Token::Colon)?;
201203
let kind = ExternKind::parse(tokens)?;
202-
Ok(Export { name, kind })
204+
Ok(Export { docs, name, kind })
203205
}
204206
}
205207

crates/wit-parser/src/ast/resolve.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -432,18 +432,20 @@ impl<'a> Resolver<'a> {
432432
let mut imported_interfaces = HashMap::new();
433433
let mut exported_interfaces = HashMap::new();
434434
for item in world.items.iter() {
435-
let (name, kind, desc, spans, interfaces) = match item {
435+
let (docs, name, kind, desc, spans, interfaces) = match item {
436436
// handled in `resolve_types`
437437
ast::WorldItem::Use(_) | ast::WorldItem::Type(_) => continue,
438438

439439
ast::WorldItem::Import(import) => (
440+
&import.docs,
440441
&import.name,
441442
&import.kind,
442443
"import",
443444
&mut import_spans,
444445
&mut imported_interfaces,
445446
),
446447
ast::WorldItem::Export(export) => (
448+
&export.docs,
447449
&export.name,
448450
&export.kind,
449451
"export",
@@ -462,7 +464,7 @@ impl<'a> Resolver<'a> {
462464
}
463465
.into());
464466
}
465-
let world_item = self.resolve_world_item(name.name, document, kind)?;
467+
let world_item = self.resolve_world_item(docs, name.name, document, kind)?;
466468
if let WorldItem::Interface(id) = world_item {
467469
if interfaces.insert(id, name.name).is_some() {
468470
return Err(Error {
@@ -492,14 +494,15 @@ impl<'a> Resolver<'a> {
492494

493495
fn resolve_world_item(
494496
&mut self,
497+
docs: &ast::Docs<'a>,
495498
name: &str,
496499
document: DocumentId,
497500
kind: &ast::ExternKind<'a>,
498501
) -> Result<WorldItem> {
499502
match kind {
500503
ast::ExternKind::Interface(_span, items) => {
501504
let prev = mem::take(&mut self.type_lookup);
502-
let id = self.resolve_interface(document, None, items, &Default::default())?;
505+
let id = self.resolve_interface(document, None, items, docs)?;
503506
self.type_lookup = prev;
504507
Ok(WorldItem::Interface(id))
505508
}
@@ -508,7 +511,7 @@ impl<'a> Resolver<'a> {
508511
Ok(WorldItem::Interface(id))
509512
}
510513
ast::ExternKind::Func(func) => {
511-
let func = self.resolve_function(Docs::default(), name, func)?;
514+
let func = self.resolve_function(docs, name, func)?;
512515
Ok(WorldItem::Function(func))
513516
}
514517
}
@@ -519,7 +522,7 @@ impl<'a> Resolver<'a> {
519522
document: DocumentId,
520523
name: Option<&'a str>,
521524
fields: &[ast::InterfaceItem<'a>],
522-
docs: &super::Docs<'a>,
525+
docs: &ast::Docs<'a>,
523526
) -> Result<InterfaceId> {
524527
let docs = self.docs(docs);
525528
let interface_id = self.interfaces.alloc(Interface {
@@ -558,19 +561,16 @@ impl<'a> Resolver<'a> {
558561
// defined.
559562
for field in fields {
560563
match field {
561-
ast::InterfaceItem::Value(value) => {
562-
let docs = self.docs(&value.docs);
563-
match &value.kind {
564-
ValueKind::Func(func) => {
565-
self.define_interface_name(&value.name, TypeOrItem::Item("function"))?;
566-
let func = self.resolve_function(docs, value.name.name, func)?;
567-
let prev = self.interfaces[interface_id]
568-
.functions
569-
.insert(value.name.name.to_string(), func);
570-
assert!(prev.is_none());
571-
}
564+
ast::InterfaceItem::Value(value) => match &value.kind {
565+
ValueKind::Func(func) => {
566+
self.define_interface_name(&value.name, TypeOrItem::Item("function"))?;
567+
let func = self.resolve_function(&value.docs, value.name.name, func)?;
568+
let prev = self.interfaces[interface_id]
569+
.functions
570+
.insert(value.name.name.to_string(), func);
571+
assert!(prev.is_none());
572572
}
573-
}
573+
},
574574
ast::InterfaceItem::Use(_) | ast::InterfaceItem::TypeDef(_) => {}
575575
}
576576
}
@@ -680,7 +680,13 @@ impl<'a> Resolver<'a> {
680680
Ok(())
681681
}
682682

683-
fn resolve_function(&mut self, docs: Docs, name: &str, func: &ast::Func) -> Result<Function> {
683+
fn resolve_function(
684+
&mut self,
685+
docs: &ast::Docs<'_>,
686+
name: &str,
687+
func: &ast::Func,
688+
) -> Result<Function> {
689+
let docs = self.docs(docs);
684690
let params = self.resolve_params(&func.params)?;
685691
let results = self.resolve_results(&func.results)?;
686692
Ok(Function {

0 commit comments

Comments
 (0)