Skip to content

Commit a5fa1eb

Browse files
authored
Support include statements in wasm-parser (#1631)
We already had basic support for `include`, but this tests it and fixes it.
1 parent 62cf274 commit a5fa1eb

5 files changed

Lines changed: 135 additions & 8 deletions

File tree

crates/wit-encoder/src/include.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{Ident, Render};
66
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
77
pub struct Include {
88
use_path: Ident,
9-
include_names_list: Vec<String>,
9+
include_names_list: Vec<(String, String)>,
1010
}
1111

1212
impl Include {
@@ -16,11 +16,29 @@ impl Include {
1616
include_names_list: vec![],
1717
}
1818
}
19+
20+
pub fn with(&mut self, id: &str, alias: &str) {
21+
self.include_names_list
22+
.push((id.to_string(), alias.to_string()));
23+
}
1924
}
2025

2126
impl Render for Include {
2227
fn render(&self, f: &mut fmt::Formatter<'_>, opts: &crate::RenderOpts) -> fmt::Result {
23-
write!(f, "{}include {};\n", opts.spaces(), self.use_path)?;
28+
match self.include_names_list.len() {
29+
0 => write!(f, "{}include {};\n", opts.spaces(), self.use_path)?,
30+
len => {
31+
write!(f, "{}include {} with {{ ", opts.spaces(), self.use_path)?;
32+
for (i, (id, alias)) in self.include_names_list.iter().enumerate() {
33+
if i == len - 1 {
34+
write!(f, "{id} as {alias}")?;
35+
} else {
36+
write!(f, "{id} as {alias}, ")?;
37+
}
38+
}
39+
write!(f, " }};\n")?;
40+
}
41+
}
2442
Ok(())
2543
}
2644
}

crates/wit-encoder/src/world.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ impl World {
5252
pub fn function_export(&mut self, value: StandaloneFunc) {
5353
self.item(WorldItem::function_export(value));
5454
}
55-
pub fn include(&mut self, value: impl Into<Ident>) {
56-
self.item(WorldItem::include(value));
55+
pub fn include(&mut self, include: Include) {
56+
self.item(WorldItem::Include(include));
5757
}
5858

5959
/// Set the documentation
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
use pretty_assertions::assert_eq;
2+
use wit_encoder::{Include, Package, PackageName, StandaloneFunc, World};
3+
4+
const PACKAGE: &str = indoc::indoc! {"
5+
package foo:foo;
6+
7+
world foo {
8+
import a: func();
9+
}
10+
11+
world bar {
12+
import a: func();
13+
import b: func();
14+
}
15+
16+
world baz {
17+
import a: func();
18+
import b: func();
19+
import c: func();
20+
}
21+
22+
world quux {
23+
include foo with { a as b };
24+
include bar with { a as b, b as c };
25+
include baz with { a as b, b as c, c as d };
26+
}
27+
"};
28+
29+
#[test]
30+
fn concrete_types() {
31+
let mut package = Package::new(PackageName::new("foo", "foo", None));
32+
33+
let mut world = World::new("foo");
34+
world.function_import(StandaloneFunc::new("a"));
35+
package.world(world);
36+
37+
let mut world = World::new("bar");
38+
world.function_import(StandaloneFunc::new("a"));
39+
world.function_import(StandaloneFunc::new("b"));
40+
package.world(world);
41+
42+
let mut world = World::new("baz");
43+
world.function_import(StandaloneFunc::new("a"));
44+
world.function_import(StandaloneFunc::new("b"));
45+
world.function_import(StandaloneFunc::new("c"));
46+
package.world(world);
47+
48+
let mut world = World::new("quux");
49+
50+
let mut include = Include::new("foo");
51+
include.with("a", "b");
52+
world.include(include);
53+
54+
let mut include = Include::new("bar");
55+
include.with("a", "b");
56+
include.with("b", "c");
57+
world.include(include);
58+
59+
let mut include = Include::new("baz");
60+
include.with("a", "b");
61+
include.with("b", "c");
62+
include.with("c", "d");
63+
world.include(include);
64+
65+
package.world(world);
66+
67+
assert_eq!(package.to_string(), PACKAGE);
68+
}

crates/wit-encoder/tests/include-reps.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use pretty_assertions::assert_eq;
2-
use wit_encoder::{Interface, Package, PackageName, World};
2+
use wit_encoder::{Include, Interface, Package, PackageName, World};
33

44
const PACKAGE: &str = indoc::indoc! {"
55
package foo:foo;
@@ -33,9 +33,9 @@ fn concrete_types() {
3333
package.world(world);
3434

3535
let mut world = World::new("foo");
36-
world.include("bar");
37-
world.include("bar");
38-
world.include("bar");
36+
world.include(Include::new("bar"));
37+
world.include(Include::new("bar"));
38+
world.include(Include::new("bar"));
3939
package.world(world);
4040

4141
assert_eq!(package.to_string(), PACKAGE);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
use pretty_assertions::assert_eq;
2+
use wit_encoder::{Include, Package, PackageName, StandaloneFunc, World};
3+
4+
const PACKAGE: &str = indoc::indoc! {"
5+
package foo:foo;
6+
7+
world foo {
8+
import a: func();
9+
}
10+
11+
world bar {
12+
import a: func();
13+
}
14+
15+
world baz {
16+
include bar;
17+
include foo with { a as b };
18+
}
19+
"};
20+
21+
#[test]
22+
fn concrete_types() {
23+
let mut package = Package::new(PackageName::new("foo", "foo", None));
24+
25+
let mut world = World::new("foo");
26+
world.function_import(StandaloneFunc::new("a"));
27+
package.world(world);
28+
29+
let mut world = World::new("bar");
30+
world.function_import(StandaloneFunc::new("a"));
31+
package.world(world);
32+
33+
let mut world = World::new("baz");
34+
world.include(Include::new("bar"));
35+
let mut include = Include::new("foo");
36+
include.with("a", "b");
37+
world.include(include);
38+
package.world(world);
39+
40+
assert_eq!(package.to_string(), PACKAGE);
41+
}

0 commit comments

Comments
 (0)