From 6cea1f359fe2da3c733f8f1fce0b07658bf24af9 Mon Sep 17 00:00:00 2001 From: Karthik Ganeshram Date: Thu, 19 Sep 2024 17:28:16 +0200 Subject: [PATCH] optionally allow output world name when importizing (#1806) Signed-off-by: karthik2804 --- crates/wit-parser/src/resolve.rs | 11 ++- fuzz/src/roundtrip_wit.rs | 2 +- src/bin/wasm-tools/component.rs | 21 +++- tests/cli/importize.wit | 5 + tests/cli/importize.wit.simple-rename.stdout | 97 +++++++++++++++++++ .../cli/importize.wit.simple-toplevel.stdout | 4 + tests/cli/importize.wit.simple.stdout | 4 + tests/cli/importize.wit.toplevel-deps.stdout | 4 + tests/cli/importize.wit.tricky-import.stdout | 4 + tests/cli/importize.wit.trim-imports.stdout | 4 + tests/cli/importize.wit.with-deps.stdout | 4 + 11 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 tests/cli/importize.wit.simple-rename.stdout diff --git a/crates/wit-parser/src/resolve.rs b/crates/wit-parser/src/resolve.rs index 29050291fb..40379ae9a8 100644 --- a/crates/wit-parser/src/resolve.rs +++ b/crates/wit-parser/src/resolve.rs @@ -1021,7 +1021,7 @@ package {name} is defined in two different locations:\n\ /// bindings in a context that is importing the original world. This /// is intended to be used as part of language tooling when depending on /// other components. - pub fn importize(&mut self, world_id: WorldId) -> Result<()> { + pub fn importize(&mut self, world_id: WorldId, out_world_name: Option) -> Result<()> { // Rename the world to avoid having it get confused with the original // name of the world. Add `-importized` to it for now. Precisely how // this new world is created may want to be updated over time if this @@ -1029,8 +1029,13 @@ package {name} is defined in two different locations:\n\ let world = &mut self.worlds[world_id]; let pkg = &mut self.packages[world.package.unwrap()]; pkg.worlds.shift_remove(&world.name); - world.name.push_str("-importized"); - pkg.worlds.insert(world.name.clone(), world_id); + if let Some(name) = out_world_name { + world.name = name.clone(); + pkg.worlds.insert(name, world_id); + } else { + world.name.push_str("-importized"); + pkg.worlds.insert(world.name.clone(), world_id); + } // Trim all non-type definitions from imports. Types can be used by // exported functions, for example, so they're preserved. diff --git a/fuzz/src/roundtrip_wit.rs b/fuzz/src/roundtrip_wit.rs index c1cf5bdf8b..f954bfb583 100644 --- a/fuzz/src/roundtrip_wit.rs +++ b/fuzz/src/roundtrip_wit.rs @@ -62,7 +62,7 @@ pub fn run(u: &mut Unstructured<'_>) -> Result<()> { // valid. log::debug!("... importizing this world"); let mut resolve2 = resolve.clone(); - let _ = resolve2.importize(id); + let _ = resolve2.importize(id, None); } if decoded_bindgens.len() < 2 { diff --git a/src/bin/wasm-tools/component.rs b/src/bin/wasm-tools/component.rs index e8e1b40819..7857d86ebe 100644 --- a/src/bin/wasm-tools/component.rs +++ b/src/bin/wasm-tools/component.rs @@ -511,6 +511,10 @@ pub struct WitOpts { #[clap(long, conflicts_with = "importize_world")] importize: bool, + /// The name of the world to generate when using `--importize` or `importize-world`. + #[clap(long = "importize-out-world-name")] + importize_out_world_name: Option, + /// Generates a WIT world to import a component which corresponds to the /// selected world. /// @@ -549,9 +553,13 @@ impl WitOpts { let mut decoded = self.decode_input()?; if self.importize { - self.importize(&mut decoded, None)?; + self.importize(&mut decoded, None, self.importize_out_world_name.as_ref())?; } else if self.importize_world.is_some() { - self.importize(&mut decoded, self.importize_world.as_deref())?; + self.importize( + &mut decoded, + self.importize_world.as_deref(), + self.importize_out_world_name.as_ref(), + )?; } // Now that the WIT document has been decoded, it's time to emit it. @@ -636,7 +644,12 @@ impl WitOpts { } } - fn importize(&self, decoded: &mut DecodedWasm, world: Option<&str>) -> Result<()> { + fn importize( + &self, + decoded: &mut DecodedWasm, + world: Option<&str>, + out_world_name: Option<&String>, + ) -> Result<()> { let (resolve, world_id) = match (&mut *decoded, world) { (DecodedWasm::Component(resolve, world), None) => (resolve, *world), (DecodedWasm::Component(..), Some(_)) => { @@ -653,7 +666,7 @@ impl WitOpts { // let pkg = decoded.package(); // let world_id = decoded.resolve().select_world(main, None)?; resolve - .importize(world_id) + .importize(world_id, out_world_name.cloned()) .context("failed to move world exports to imports")?; let resolve = mem::take(resolve); *decoded = DecodedWasm::Component(resolve, world_id); diff --git a/tests/cli/importize.wit b/tests/cli/importize.wit index 26a70649e8..46b1d4da53 100644 --- a/tests/cli/importize.wit +++ b/tests/cli/importize.wit @@ -1,4 +1,5 @@ // RUN[simple]: component wit --importize-world simple % +// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % // RUN[simple-component]: component embed --dummy --world simple % | \ // component wit --importize // RUN[with-deps]: component wit --importize-world with-deps % @@ -34,6 +35,10 @@ world simple { export t; } +world simple-rename { + export t; +} + world with-deps { export qux; } diff --git a/tests/cli/importize.wit.simple-rename.stdout b/tests/cli/importize.wit.simple-rename.stdout new file mode 100644 index 0000000000..b921e7e2fc --- /dev/null +++ b/tests/cli/importize.wit.simple-rename.stdout @@ -0,0 +1,97 @@ +/// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % +/// RUN[simple-component]: component embed --dummy --world simple % | / +/// component wit --importize +/// RUN[with-deps]: component wit --importize-world with-deps % +/// RUN[simple-toplevel]: component wit --importize-world simple-toplevel % +/// RUN[toplevel-deps]: component wit --importize-world toplevel-deps % +/// FAIL[fail1]: component wit --importize-world fail1 % +/// RUN[trim-imports]: component wit --importize-world trim-imports % +/// RUN[tricky-import]: component wit --importize-world tricky-import % +package importize:importize; + +interface t { + resource r; +} + +interface bar { + use t.{r}; + + record foo { + x: string, + } + + importize: func(name: r); +} + +interface qux { + use bar.{foo}; + + blah: func(boo: foo); +} + +interface something-else-dep { + type t = u32; +} + +interface a { +} + +interface b { +} + +interface with-dep { + type t = u32; +} + +world simple { + export t; +} +world with-deps { + import t; + import bar; + + export qux; +} +world simple-toplevel { + export foo: func(); + export something: interface { + foo: func(); + } +} +world toplevel-deps { + import something-else-dep; + + type s = u32; + + export bar: func() -> s; + export something-else: interface { + use something-else-dep.{t}; + + bar: func() -> t; + } +} +world fail1 { + type foo = u32; + + export foo: func() -> foo; +} +world trim-imports { + import a; + import foo: func(); + import bar: interface { + } + + type t = u32; + + export b; +} +world tricky-import { + import with-dep; + use with-dep.{t}; + + export f: func() -> t; +} +world test-rename { + import t; +} diff --git a/tests/cli/importize.wit.simple-toplevel.stdout b/tests/cli/importize.wit.simple-toplevel.stdout index 4b27989959..7c79702db0 100644 --- a/tests/cli/importize.wit.simple-toplevel.stdout +++ b/tests/cli/importize.wit.simple-toplevel.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -46,6 +47,9 @@ interface with-dep { world simple { export t; } +world simple-rename { + export t; +} world with-deps { import t; import bar; diff --git a/tests/cli/importize.wit.simple.stdout b/tests/cli/importize.wit.simple.stdout index 74df901e87..80547c60e1 100644 --- a/tests/cli/importize.wit.simple.stdout +++ b/tests/cli/importize.wit.simple.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -43,6 +44,9 @@ interface with-dep { type t = u32; } +world simple-rename { + export t; +} world with-deps { import t; import bar; diff --git a/tests/cli/importize.wit.toplevel-deps.stdout b/tests/cli/importize.wit.toplevel-deps.stdout index 05b41d4ce4..17b1c0e3f8 100644 --- a/tests/cli/importize.wit.toplevel-deps.stdout +++ b/tests/cli/importize.wit.toplevel-deps.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -46,6 +47,9 @@ interface with-dep { world simple { export t; } +world simple-rename { + export t; +} world with-deps { import t; import bar; diff --git a/tests/cli/importize.wit.tricky-import.stdout b/tests/cli/importize.wit.tricky-import.stdout index c237d71a7a..f5cb951cc7 100644 --- a/tests/cli/importize.wit.tricky-import.stdout +++ b/tests/cli/importize.wit.tricky-import.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -46,6 +47,9 @@ interface with-dep { world simple { export t; } +world simple-rename { + export t; +} world with-deps { import t; import bar; diff --git a/tests/cli/importize.wit.trim-imports.stdout b/tests/cli/importize.wit.trim-imports.stdout index 933c035835..a0539ef9c9 100644 --- a/tests/cli/importize.wit.trim-imports.stdout +++ b/tests/cli/importize.wit.trim-imports.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -46,6 +47,9 @@ interface with-dep { world simple { export t; } +world simple-rename { + export t; +} world with-deps { import t; import bar; diff --git a/tests/cli/importize.wit.with-deps.stdout b/tests/cli/importize.wit.with-deps.stdout index 96e7d32024..1a48a0298e 100644 --- a/tests/cli/importize.wit.with-deps.stdout +++ b/tests/cli/importize.wit.with-deps.stdout @@ -1,4 +1,5 @@ /// RUN[simple]: component wit --importize-world simple % +/// RUN[simple-rename]: component wit --importize-world simple-rename --importize-out-world-name test-rename % /// RUN[simple-component]: component embed --dummy --world simple % | / /// component wit --importize /// RUN[with-deps]: component wit --importize-world with-deps % @@ -46,6 +47,9 @@ interface with-dep { world simple { export t; } +world simple-rename { + export t; +} world simple-toplevel { export foo: func(); export something: interface {