diff --git a/src/lib.rs b/src/lib.rs index 25e5586..f9315e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -18,7 +18,7 @@ use { path::{Path, PathBuf}, str, }, - summary::{Locations, Summary}, + summary::{Locations, Naming, Summary}, tar::Archive, wasm_encoder::{CustomSection, Section as _}, wasmtime::{ @@ -234,13 +234,12 @@ impl BindingsGenerator<'_> { let stream_and_future_indexes = &HashMap::new(); let summary = Summary::try_new( &resolve, - &iter::once(world).collect(), + &iter::once((world, Naming::from_full(self.full_names))).collect(), self.import_interface_names, self.export_interface_names, import_function_indexes, export_function_indexes, stream_and_future_indexes, - self.full_names, )?; let world_module = self.world_module.unwrap_or(DEFAULT_WORLD_MODULE); let world_dir = self.output_dir.join(world_module.replace('.', "/")); @@ -447,12 +446,23 @@ impl ComponentGenerator<'_> { let mut all_worlds = worlds .iter() .copied() - .chain(configs.values().flat_map(|(_, v)| v.iter().copied())) - .collect::>(); + .map(|world| (world, Naming::from_full(self.full_names))) + .chain(configs.values().flat_map(|(config, worlds)| { + worlds.iter().copied().map(|world| { + ( + world, + Naming::from_full(config.config.full_names || self.full_names), + ) + }) + })) + .collect::>(); if all_worlds.is_empty() { // No worlds specified; pick the default one, if available: - all_worlds.insert(select_world(&resolve, None, &packages)?); + all_worlds.insert( + select_world(&resolve, None, &packages)?, + Naming::from_full(self.full_names), + ); } // Now that we've parsed all known WIT files and resolved all relevant @@ -482,7 +492,7 @@ impl ComponentGenerator<'_> { let world = unioned( &mut resolve, - &all_worlds.iter().copied().collect::>(), + &all_worlds.keys().copied().collect::>(), )? .unwrap(); @@ -490,7 +500,7 @@ impl ComponentGenerator<'_> { // each module, union the ones covered by the module into a single // world. - let mut worlds_to_generate = all_worlds.clone(); + let mut worlds_to_generate = all_worlds.keys().copied().collect::>(); let configs = configs .iter() @@ -592,13 +602,6 @@ impl ComponentGenerator<'_> { &imported_function_indexes, &exported_function_indexes, &stream_and_future_indexes, - // TODO: We should restrict the `full_names` setting found in a give - // config file to only the world(s) covered by that config file, if - // feasible. - self.full_names - || configs - .values() - .any(|(config, ..)| config.config.full_names), )?; let need_async = summary.need_async(); @@ -814,7 +817,11 @@ impl ComponentGenerator<'_> { async move { let component = &Component::new(&engine, instrumented)?; if !added_to_linker { - add_wasi_and_stubs(&resolve, &all_worlds, &mut linker)?; + add_wasi_and_stubs( + &resolve, + &all_worlds.keys().copied().collect::>(), + &mut linker, + )?; } let pre = InitPre::new(linker.instantiate_pre(component)?)?; diff --git a/src/summary.rs b/src/summary.rs index a2f170d..ddce5d7 100644 --- a/src/summary.rs +++ b/src/summary.rs @@ -31,6 +31,18 @@ const NOT_IMPLEMENTED: &str = "raise NotImplementedError"; const ASYNC_START_PREFIX: &str = "_async_start_"; +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Naming { + Short, + Full, +} + +impl Naming { + pub fn from_full(full: bool) -> Self { + if full { Self::Full } else { Self::Short } + } +} + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum Direction { Import, @@ -93,6 +105,7 @@ pub struct InterfaceInfo<'a> { package: Option>, name: &'a str, docs: Option<&'a str>, + naming: Naming, } struct FunctionCode { @@ -145,21 +158,18 @@ pub struct Summary<'a> { imported_function_indexes: &'a HashMap<(Option<&'a str>, &'a str), usize>, exported_function_indexes: &'a HashMap<(Option<&'a str>, &'a str), usize>, stream_and_future_indexes: &'a HashMap, - full_names: bool, need_async: bool, } impl<'a> Summary<'a> { - #[expect(clippy::too_many_arguments)] pub fn try_new( resolve: &'a Resolve, - worlds: &IndexSet, + worlds: &IndexMap, import_interface_names: &HashMap<&str, &str>, export_interface_names: &HashMap<&str, &str>, imported_function_indexes: &'a HashMap<(Option<&'a str>, &'a str), usize>, exported_function_indexes: &'a HashMap<(Option<&'a str>, &'a str), usize>, stream_and_future_indexes: &'a HashMap, - full_names: bool, ) -> Result { let mut me = Self { resolve, @@ -181,24 +191,25 @@ impl<'a> Summary<'a> { imported_function_indexes, exported_function_indexes, stream_and_future_indexes, - full_names, need_async: false, }; let mut import_keys_seen = HashSet::new(); let mut export_keys_seen = HashSet::new(); - for &world in worlds { + for (&world, &naming) in worlds { me.visit_functions( &resolve.worlds[world].imports, Direction::Import, world, &mut import_keys_seen, + naming, )?; me.visit_functions( &resolve.worlds[world].exports, Direction::Export, world, &mut export_keys_seen, + naming, )?; } @@ -388,6 +399,7 @@ impl<'a> Summary<'a> { direction: Direction, world: WorldId, keys_seen: &mut HashSet, + naming: Naming, ) -> Result<()> { for (key, item) in items { self.world_keys @@ -433,6 +445,7 @@ impl<'a> Summary<'a> { package, name: item_name, docs: interface.docs.contents.as_deref(), + naming, }; self.resource_state = Some(ResourceState { direction }); @@ -1193,7 +1206,7 @@ impl<'a> Summary<'a> { .or_default() .entry(info.package.map(|p| (p.namespace, p.name))) .or_default() - .insert(info.package.and_then(|p| p.version), id) + .insert(info.package.and_then(|p| p.version), (id, info.naming)) .is_none() ); } @@ -1202,11 +1215,11 @@ impl<'a> Summary<'a> { for (name, packages) in &tree { for (package, versions) in packages { if let Some((package_namespace, package_name)) = package { - for (version, id) in versions { + for (version, &(id, naming)) in versions { assert!( names .insert( - *id, + id, if let Some(version) = version { if let Some(name) = interface_names.get( format!( @@ -1216,7 +1229,7 @@ impl<'a> Summary<'a> { .as_str(), ) { (*name).to_owned() - } else if versions.len() == 1 && !self.full_names { + } else if versions.len() == 1 && naming == Naming::Short { if packages.len() == 1 { (*name).to_owned() } else { @@ -1233,7 +1246,7 @@ impl<'a> Summary<'a> { .as_str() ) { (*name).to_owned() - } else if packages.len() == 1 && !self.full_names { + } else if packages.len() == 1 && naming == Naming::Short { (*name).to_owned() } else { format!("{package_namespace}-{package_name}-{name}",) @@ -1246,7 +1259,7 @@ impl<'a> Summary<'a> { assert!( names .insert( - *versions.get(&None).unwrap(), + versions.get(&None).unwrap().0, (*interface_names.get(*name).unwrap_or(name)).to_owned() ) .is_none() diff --git a/src/test/bar_sdk/componentize-py.toml b/src/test/bar_sdk/componentize-py.toml index 8949185..9c8f5b3 100644 --- a/src/test/bar_sdk/componentize-py.toml +++ b/src/test/bar_sdk/componentize-py.toml @@ -1,2 +1,3 @@ wit_directory = "wit" bindings = "wit" +full_names = true diff --git a/src/test/python_source/app.py b/src/test/python_source/app.py index a745596..7eded4e 100644 --- a/src/test/python_source/app.py +++ b/src/test/python_source/app.py @@ -246,6 +246,6 @@ class FooInterface(foo_exports.FooInterface): def test(self, s: str) -> str: return foo_test(f"{s} FooInterface.test") -class BarInterface(bar_exports.BarInterface): +class BarSdkBarInterface(bar_exports.BarSdkBarInterface): def test(self, s: str) -> str: return bar_test(f"{s} BarInterface.test")