Skip to content

Commit e91ccd5

Browse files
committed
field gates, nesting nest statements, doc comments
1 parent 403d1a3 commit e91ccd5

File tree

15 files changed

+156
-59
lines changed

15 files changed

+156
-59
lines changed

crates/wit-component/src/encoding/wit/v2.rs

Lines changed: 43 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::encoding::types::{FunctionKey, ValtypeEncoder};
2-
use anyhow::{bail, Result};
2+
use anyhow::Result;
33
use indexmap::IndexSet;
44
use std::collections::HashMap;
55
use std::mem;
@@ -226,6 +226,20 @@ impl InterfaceEncoder<'_> {
226226
.export(name, ComponentTypeRef::Func(ty));
227227
}
228228
let mut instance = self.pop_instance();
229+
self.encode_nested(iface, &mut instance)?;
230+
231+
let idx = self.outer.type_count();
232+
self.outer.ty().instance(&instance);
233+
self.import_map.insert(interface, self.instances);
234+
self.instances += 1;
235+
Ok(idx)
236+
}
237+
238+
fn encode_nested<'a>(
239+
&'a mut self,
240+
iface: &Interface,
241+
instance: &'a mut InstanceType,
242+
) -> Result<&mut InstanceType> {
229243
for (orig_name, _) in &iface.nested {
230244
let mut pkg_parts = orig_name.split("/");
231245
let pkg = pkg_parts.next().expect("expected projection");
@@ -255,23 +269,40 @@ impl InterfaceEncoder<'_> {
255269
}
256270
inst.encode_valtype(self.resolve, &Type::Id(*id))?;
257271
}
258-
for (_, _) in &nested_iface.nested {
259-
bail!("Using `nest` in a nested interface is not yet supported");
260-
}
261272
let ty = instance.ty();
262-
let nested = inst.pop_instance();
263-
ty.instance(&nested);
273+
let nested_instance = &mut inst.pop_instance();
274+
for (orig_name, _) in &nested_iface.nested {
275+
let mut nest_package_parts = orig_name.split("/");
276+
let nest_pkg = nest_package_parts.next().unwrap();
277+
let nest_iface = nest_package_parts.next().unwrap();
278+
let mut parts = nest_pkg.split(":");
279+
let ns = parts.next().unwrap();
280+
let name = parts.next().unwrap();
281+
let name = PackageName {
282+
namespace: ns.to_string(),
283+
name: name.to_string(),
284+
version: None,
285+
};
286+
let nest_pkg_id = self.resolve.package_names.get(&name).unwrap();
287+
let nested_package = &self.resolve.packages[*nest_pkg_id];
288+
let myguy = nested_package.interfaces.get(nest_iface).unwrap();
289+
let nest = &self.resolve.interfaces[*myguy];
290+
let mut clone = nested_instance.clone();
291+
let deep_instance = self.encode_nested(nest, &mut clone)?;
292+
let deep_ty = nested_instance.ty();
293+
deep_ty.instance(&deep_instance);
294+
nested_instance.export(
295+
orig_name,
296+
ComponentTypeRef::Instance(deep_instance.type_count()),
297+
);
298+
}
299+
ty.instance(&nested_instance);
264300
instance.export(
265301
orig_name,
266302
ComponentTypeRef::Instance(instance.type_count() - 1),
267303
);
268304
}
269-
270-
let idx = self.outer.type_count();
271-
self.outer.ty().instance(&instance);
272-
self.import_map.insert(interface, self.instances);
273-
self.instances += 1;
274-
Ok(idx)
305+
Ok(instance)
275306
}
276307

277308
fn push_instance(&mut self) {

crates/wit-component/src/printing.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ impl WitPrinter {
8484
self.output.push_str(" {\n");
8585
let nested = &resolve.interfaces[*id].nested;
8686
for item in nested {
87+
self.print_stability(&item.1.stability);
88+
self.print_docs(&item.1.docs);
8789
self.output.push_str("nest ");
8890
self.print_name(item.0);
8991
self.output.push_str(";\n")

crates/wit-component/tests/interfaces/doc-comments.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
)
6767
)
6868
(export (;5;) "coverage-world" (type 4))
69-
(@custom "package-docs" "\00{\22docs\22:\22package docs;\22,\22worlds\22:{\22coverage-world\22:{\22docs\22:\22world docs\22,\22interfaces\22:{\22i\22:{\22docs\22:\22world inline interface docs\22,\22funcs\22:{\22f\22:\22inline interface func docs\22},\22types\22:{\22t\22:{\22docs\22:\22inline interface typedef docs\22}}}},\22types\22:{\22t\22:{\22docs\22:\22world typedef docs\22}},\22funcs\22:{\22imp\22:\22world func import docs\22,\22exp\22:\22world func export docs\22}}},\22interfaces\22:{\22coverage-iface\22:{\22docs\22:\22interface docs\22,\22funcs\22:{\22[constructor]res\22:\22constructor docs\22,\22[method]res.m\22:\22method docs\22,\22[static]res.s\22:\22static func docs\22,\22f\22:\22interface func docs\22},\22types\22:{\22t\22:{\22docs\22:\22basic typedef docs\22},\22r\22:{\22docs\22:\22record typedef docs\22,\22items\22:{\22f1\22:\22record field docs\22}},\22fl\22:{\22items\22:{\22f1\22:\22flag docs\22}},\22v\22:{\22items\22:{\22c1\22:\22variant case docs\22}},\22e\22:{\22items\22:{\22c1\22:\22enum case docs\22}}}},\22other-comment-forms\22:{\22docs\22:\22other comment forms\5cn multi-line block\22,\22funcs\22:{\22multiple-lines-split\22:\22one doc line\5cnnon-doc in the middle\5cnanother doc line\22,\22mixed-forms\22:\22mixed forms; line doc\5cnplus block doc\5cn multi-line\22}}}}")
69+
(@custom "package-docs" "\00{\22docs\22:\22package docs;\22,\22worlds\22:{\22coverage-world\22:{\22docs\22:\22world docs\22,\22interfaces\22:{\22i\22:{\22docs\22:\22world inline interface docs\22,\22funcs\22:{\22f\22:\22inline interface func docs\22},\22types\22:{\22t\22:{\22docs\22:\22inline interface typedef docs\22}},\22nested\22:{}}},\22types\22:{\22t\22:{\22docs\22:\22world typedef docs\22}},\22funcs\22:{\22imp\22:\22world func import docs\22,\22exp\22:\22world func export docs\22}}},\22interfaces\22:{\22coverage-iface\22:{\22docs\22:\22interface docs\22,\22funcs\22:{\22[constructor]res\22:\22constructor docs\22,\22[method]res.m\22:\22method docs\22,\22[static]res.s\22:\22static func docs\22,\22f\22:\22interface func docs\22},\22types\22:{\22t\22:{\22docs\22:\22basic typedef docs\22},\22r\22:{\22docs\22:\22record typedef docs\22,\22items\22:{\22f1\22:\22record field docs\22}},\22fl\22:{\22items\22:{\22f1\22:\22flag docs\22}},\22v\22:{\22items\22:{\22c1\22:\22variant case docs\22}},\22e\22:{\22items\22:{\22c1\22:\22enum case docs\22}}},\22nested\22:{}},\22other-comment-forms\22:{\22docs\22:\22other comment forms\5cn multi-line block\22,\22funcs\22:{\22multiple-lines-split\22:\22one doc line\5cnnon-doc in the middle\5cnanother doc line\22,\22mixed-forms\22:\22mixed forms; line doc\5cnplus block doc\5cn multi-line\22},\22nested\22:{}}}}")
7070
(@producers
7171
(processed-by "wit-component" "$CARGO_PKG_VERSION")
7272
)

crates/wit-component/tests/interfaces/nested.wat

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,13 @@
2121
(instance
2222
(type (;0;) (record (field "foo" string)))
2323
(export (;1;) "nestrecord" (type (eq 0)))
24+
(type (;2;)
25+
(instance
26+
(type (;0;) (record (field "foo" string)))
27+
(export (;1;) "nestrecord" (type (eq 0)))
28+
)
29+
)
30+
(export (;0;) "foo:nestnest/deep" (instance (type 2)))
2431
)
2532
)
2633
(export (;0;) "foo:nestee/things" (instance (type 5)))
@@ -102,7 +109,7 @@
102109
)
103110
)
104111
(export (;5;) "my-world" (type 4))
105-
(@custom "package-docs" "\01{\22interfaces\22:{\22something\22:{\22types\22:{\22my-record\22:{\22stability\22:{\22stable\22:{\22since\22:\221.0.0\22}}}}}}}")
112+
(@custom "package-docs" "\01{\22interfaces\22:{\22something\22:{\22types\22:{\22my-record\22:{\22stability\22:{\22stable\22:{\22since\22:\221.0.0\22}}}},\22nested\22:{\22foo:nestee/things\22:{\22docs\22:{\22contents\22:\22nesting can be documented\22},\22stability\22:\22unknown\22},\22foo:nestee/more\22:{\22docs\22:{\22contents\22:null},\22stability\22:{\22stable\22:{\22since\22:\221.0.0\22}}}}}}}")
106113
(@producers
107114
(processed-by "wit-component" "$CARGO_PKG_VERSION")
108115
)

crates/wit-component/tests/interfaces/nested/deps/nestee.wit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package foo:nestee;
22

33
interface things {
4+
//nesting can be documented
5+
@since(version = 1.0.0)
6+
nest foo:nestnest/deep;
47
record nestrecord {
58
foo: string
69
}

crates/wit-component/tests/interfaces/nested/nested.wit

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package foo:thing;
22

33
interface something {
44
use foo:nestee/usable.{usable-record};
5+
//nesting can be documented
56
nest foo:nestee/things;
7+
@since(version = 1.0.0)
68
nest foo:nestee/more;
79
@since(version = 1.0.0)
810
record my-record {

crates/wit-component/tests/interfaces/nested/thing.wit.print

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package foo:thing;
22

33
interface something {
4+
/// nesting can be documented
45
nest foo:nestee/things;
6+
@since(version = 1.0.0)
57
nest foo:nestee/more;
68
use foo:nestee/usable.{usable-record};
79

crates/wit-component/tests/interfaces/resources.wat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
)
181181
)
182182
(export (;11;) "implicit-own-handles3" (type 10))
183-
(@custom "package-docs" "\00{\22worlds\22:{\22implicit-own-handles3\22:{\22types\22:{\22a\22:{\22docs\22:\22there should only be one `list` type despite there looking like two\5cnlist types here\22}}}},\22interfaces\22:{\22implicit-own-handles2\22:{\22types\22:{\22a\22:{\22docs\22:\22the `own` return and list param should be the same `own`\22},\22b\22:{\22docs\22:\22same as above, even when the `list<b>` implicitly-defined `own` comes\5cnbefore an explicitly defined `own`\22},\22c\22:{\22docs\22:\22same as the above, the `own` argument should have the same type as the\5cnreturn value\22}}}}}")
183+
(@custom "package-docs" "\00{\22worlds\22:{\22implicit-own-handles3\22:{\22types\22:{\22a\22:{\22docs\22:\22there should only be one `list` type despite there looking like two\5cnlist types here\22}}}},\22interfaces\22:{\22implicit-own-handles2\22:{\22types\22:{\22a\22:{\22docs\22:\22the `own` return and list param should be the same `own`\22},\22b\22:{\22docs\22:\22same as above, even when the `list<b>` implicitly-defined `own` comes\5cnbefore an explicitly defined `own`\22},\22c\22:{\22docs\22:\22same as the above, the `own` argument should have the same type as the\5cnreturn value\22}},\22nested\22:{}}}}")
184184
(@producers
185185
(processed-by "wit-component" "$CARGO_PKG_VERSION")
186186
)

crates/wit-component/tests/interfaces/wasi-http.wat

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

crates/wit-parser/src/ast.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -562,13 +562,18 @@ enum InterfaceItem<'a> {
562562
}
563563

564564
struct Nest<'a> {
565+
docs: Docs<'a>,
565566
id: PackageName<'a>,
566567
name: Id<'a>,
567-
// attributes: Vec<Attribute<'a>>,
568+
attributes: Vec<Attribute<'a>>,
568569
}
569570

570571
impl<'a> Nest<'a> {
571-
fn parse(tokens: &mut Tokenizer<'a>, _attributes: Vec<Attribute<'a>>) -> Result<Self> {
572+
fn parse(
573+
tokens: &mut Tokenizer<'a>,
574+
docs: Docs<'a>,
575+
attributes: Vec<Attribute<'a>>,
576+
) -> Result<Self> {
572577
tokens.eat(Token::Nest)?;
573578
let id = parse_id(tokens)?;
574579
tokens.expect(Token::Colon)?;
@@ -590,8 +595,9 @@ impl<'a> Nest<'a> {
590595
name: pkg_name,
591596
version,
592597
},
598+
docs,
593599
name,
594-
// attributes,
600+
attributes,
595601
})
596602
}
597603
}
@@ -1032,7 +1038,9 @@ impl<'a> InterfaceItem<'a> {
10321038
NamedFunc::parse(tokens, docs, attributes).map(InterfaceItem::Func)
10331039
}
10341040
Some((_span, Token::Use)) => Use::parse(tokens, attributes).map(InterfaceItem::Use),
1035-
Some((_span, Token::Nest)) => Nest::parse(tokens, attributes).map(InterfaceItem::Nest),
1041+
Some((_span, Token::Nest)) => {
1042+
Nest::parse(tokens, docs, attributes).map(InterfaceItem::Nest)
1043+
}
10361044
other => Err(err_expected(tokens, "`type`, `resource` or `func`", other).into()),
10371045
}
10381046
}

0 commit comments

Comments
 (0)