diff --git a/crates/wac-parser/src/resolution.rs b/crates/wac-parser/src/resolution.rs index a7aeaa8..b11943f 100644 --- a/crates/wac-parser/src/resolution.rs +++ b/crates/wac-parser/src/resolution.rs @@ -32,25 +32,6 @@ where s.end() } -fn serialize_id_key_map( - map: &IndexMap, V>, - serializer: S, -) -> std::result::Result -where - S: Serializer, - T: Serialize, - V: Serialize, -{ - use serde::ser::SerializeMap; - - let mut s = serializer.serialize_map(Some(map.len()))?; - for (k, v) in map { - s.serialize_entry(&k.index(), v)?; - } - - s.end() -} - fn serialize_id_value_map( map: &IndexMap>, serializer: S, diff --git a/crates/wac-parser/src/resolution/ast.rs b/crates/wac-parser/src/resolution/ast.rs index c8a0d80..52b1516 100644 --- a/crates/wac-parser/src/resolution/ast.rs +++ b/crates/wac-parser/src/resolution/ast.rs @@ -4,7 +4,7 @@ use super::{ FuncResult, Interface, InterfaceId, ItemKind, PrimitiveType, Record, ResolutionResult, Resource, ResourceId, SubtypeChecker, Type, ValueType, Variant, World, WorldId, }; -use crate::{ast, method_extern_name, Item, ItemId, PackageId}; +use crate::{ast, method_extern_name, Item, ItemId, PackageId, UsedType}; use anyhow::Context; use id_arena::Arena; use indexmap::{IndexMap, IndexSet}; @@ -856,7 +856,7 @@ impl<'a> AstResolver<'a> { &mut self, state: &mut State<'a>, use_type: &'a ast::Use<'a>, - uses: &mut IndexMap>, + uses: &mut IndexMap, externs: &mut IndexMap, in_world: bool, ) -> ResolutionResult<()> { @@ -888,9 +888,9 @@ impl<'a> AstResolver<'a> { for item in &use_type.items { let ident = item.as_id.unwrap_or(item.id); - let (index, _, kind) = self.definitions.interfaces[interface] + let kind = self.definitions.interfaces[interface] .exports - .get_full(item.id.string) + .get(item.id.string) .ok_or(Error::UndefinedInterfaceType { name: item.id.string.to_string(), interface_name: name.to_string(), @@ -916,7 +916,13 @@ impl<'a> AstResolver<'a> { }); } - uses.entry(interface).or_default().insert(index); + uses.insert( + ident.string.into(), + UsedType { + interface, + name: item.as_id.map(|_| item.id.string.to_string()), + }, + ); externs.insert(ident.string.into(), *kind); let id = state.current.items.alloc(Item::Use(*kind)); @@ -1772,10 +1778,36 @@ impl<'a> AstResolver<'a> { }); }; - // Ensure the import and the existing import are instances, otherwise - // we cannot merge them - let id = match (kind, state.current.items[import.item].kind()) { - (ItemKind::Instance(id), ItemKind::Instance(_)) => id, + // Merge the existing import item with the given one + return match (kind, state.current.items[import.item].kind()) { + (ItemKind::Instance(id), ItemKind::Instance(_)) => { + log::debug!( + "merging implicit interface import `{name}` ({id})", + id = id.index(), + ); + + let item = import.item; + self.merge_instance_import(state, &name, id, span)?; + Ok(item) + } + (ItemKind::Component(_), ItemKind::Component(_)) => { + todo!("merge component imports") + } + (ItemKind::Func(_), ItemKind::Func(_)) => { + todo!("merge func imports") + } + (ItemKind::Module(_), ItemKind::Module(_)) => { + todo!("merge module imports") + } + (ItemKind::Resource(_), ItemKind::Resource(_)) => { + todo!("merge resource imports") + } + (ItemKind::Type(_), ItemKind::Type(_)) => { + todo!("merge type imports") + } + (ItemKind::Value(_), ItemKind::Value(_)) => { + todo!("merge value imports") + } (_, kind) => { return Err(Error::UnmergeableInstantiationArg { name: name.to_owned(), @@ -1786,15 +1818,6 @@ impl<'a> AstResolver<'a> { }); } }; - - log::debug!( - "merging implicit interface import `{name}` ({id})", - id = id.index(), - ); - - let item = import.item; - self.merge_instance_import(state, &name, id, span)?; - return Ok(item); } log::debug!( @@ -1806,7 +1829,7 @@ impl<'a> AstResolver<'a> { // might be merged in the future with other interface definitions. if let ItemKind::Instance(id) = kind { let mut target = self.definitions.interfaces[id].clone(); - target.uses = self.remap_uses(state, target.uses); + self.remap_uses(state, &mut target.uses); let id = self.definitions.interfaces.alloc(target); log::debug!( "creating new interface definition ({id}) for implicit import `{name}`", @@ -1914,46 +1937,34 @@ impl<'a> AstResolver<'a> { let source = &self.definitions.interfaces[source_id]; // Merge the source and target usings - for (dep, exports) in &source.uses { - target.uses.entry(*dep).or_default().extend(exports); + for (name, used) in &source.uses { + if target.uses.contains_key(name) { + continue; + } + + target.uses.insert(name.clone(), used.clone()); } // Remap the usings to point at imported interfaces - target.uses = self.remap_uses(state, target.uses); + self.remap_uses(state, &mut target.uses); self.definitions.interfaces[target_id] = target; } - fn remap_uses( - &self, - state: &State, - uses: IndexMap>, - ) -> IndexMap> { + fn remap_uses(&self, state: &State, uses: &mut IndexMap) { // Now update all the interface ids in the usings - let mut remapped: IndexMap> = - IndexMap::with_capacity(uses.len()); - for (old_id, exports) in uses { - let old = &self.definitions.interfaces[old_id]; + for used in uses.values_mut() { + let old = &self.definitions.interfaces[used.interface]; let import = &state.imports[old.id.as_deref().unwrap()]; match &state.current.items[import.item] { super::Item::Import(super::Import { kind: ItemKind::Instance(new_id), .. }) => { - let new = &self.definitions.interfaces[*new_id]; - remapped - .entry(*new_id) - .or_default() - .extend(exports.into_iter().map(|old_index| { - new.exports - .get_index_of(old.exports.get_index(old_index).unwrap().0) - .unwrap() - })); + used.interface = *new_id; } _ => unreachable!(), } } - - remapped } fn named_instantiation_arg( diff --git a/crates/wac-parser/src/resolution/encoding.rs b/crates/wac-parser/src/resolution/encoding.rs index 48196c0..1aecb45 100644 --- a/crates/wac-parser/src/resolution/encoding.rs +++ b/crates/wac-parser/src/resolution/encoding.rs @@ -7,6 +7,7 @@ use super::{ }; use crate::{ resolution::FuncResult, CoreExtern, Definition, Import, Instantiation, Item, ItemId, PackageId, + UsedType, }; use anyhow::Result; use indexmap::{map::Entry, IndexMap, IndexSet}; @@ -127,11 +128,11 @@ impl<'a> Encoder<'a> { let encoder = TypeEncoder::new(&self.composition.definitions); let (ty, index) = match definition.kind { ItemKind::Type(ty) => match ty { - Type::Func(id) => (ty, encoder.ty(state, Type::Func(id))?), - Type::Value(id) => (ty, encoder.ty(state, Type::Value(id))?), + Type::Func(id) => (ty, encoder.ty(state, Type::Func(id), None)?), + Type::Value(id) => (ty, encoder.ty(state, Type::Value(id), None)?), Type::Interface(id) => (ty, encoder.interface(state, id)?), Type::World(id) => (ty, encoder.world(state, id)?), - Type::Module(id) => (ty, encoder.ty(state, Type::Module(id))?), + Type::Module(id) => (ty, encoder.ty(state, Type::Module(id), None)?), }, _ => unreachable!("only types can be defined"), }; @@ -164,8 +165,12 @@ impl<'a> Encoder<'a> { let encoder = TypeEncoder::new(&self.composition.definitions); let ty = match import.kind { - ItemKind::Type(ty) => ComponentTypeRef::Type(TypeBounds::Eq(encoder.ty(state, ty)?)), - ItemKind::Func(id) => ComponentTypeRef::Func(encoder.ty(state, Type::Func(id))?), + ItemKind::Type(ty) => { + ComponentTypeRef::Type(TypeBounds::Eq(encoder.ty(state, ty, None)?)) + } + ItemKind::Func(id) => { + ComponentTypeRef::Func(encoder.ty(state, Type::Func(id), None)?) + } ItemKind::Instance(id) => { // Check to see if the instance has already been imported // This may occur when an interface uses another @@ -174,12 +179,14 @@ impl<'a> Encoder<'a> { return Ok(*index); } - ComponentTypeRef::Instance(encoder.ty(state, Type::Interface(id))?) + ComponentTypeRef::Instance(encoder.ty(state, Type::Interface(id), None)?) } ItemKind::Component(id) => { - ComponentTypeRef::Component(encoder.ty(state, Type::World(id))?) + ComponentTypeRef::Component(encoder.ty(state, Type::World(id), None)?) + } + ItemKind::Module(id) => { + ComponentTypeRef::Module(encoder.ty(state, Type::Module(id), None)?) } - ItemKind::Module(id) => ComponentTypeRef::Module(encoder.ty(state, Type::Module(id))?), ItemKind::Value(ty) => ComponentTypeRef::Value(encoder.value_type(state, ty)?), ItemKind::Resource(_) => unreachable!("resources cannot be imported at the top-level"), ItemKind::Instantiation(_) => unreachable!("instantiations cannot be imported"), @@ -392,29 +399,14 @@ impl From for ComponentExportKind { } } -#[derive(Clone, PartialEq, Eq, Hash, Debug)] -enum AliasKey<'a> { - Resource(&'a str), - Type(Type), -} - -impl AliasKey<'_> { - fn as_str(&self, definitions: &Definitions) -> &str { - match self { - AliasKey::Resource(name) => name, - AliasKey::Type(ty) => ty.as_str(definitions), - } - } -} - #[derive(Default)] struct Scope<'a> { /// The map of types to their encoded indexes. type_indexes: IndexMap, /// The map of imported instances in this scope. instances: IndexMap, - /// The map of aliasable types to their encoded indexes. - type_aliases: IndexMap, u32>, + /// The map of import/export name to their alias indexes. + type_aliases: IndexMap<&'a str, u32>, /// The map of resource names to their encoded indexes. resources: IndexMap<&'a str, u32>, encodable: Encodable, @@ -459,18 +451,15 @@ impl<'a> State<'a> { prev.encodable } - fn used_type_index(&mut self, definitions: &Definitions, key: AliasKey) -> Option { - if let Some(index) = self.current.type_aliases.get(&key) { + fn used_type_index(&mut self, name: &str) -> Option { + if let Some(index) = self.current.type_aliases.get(name) { return Some(*index); } if let Some(parent) = self.scopes.last() { - if let Some(outer) = parent.type_aliases.get(&key) { + if let Some(outer) = parent.type_aliases.get(name) { let index = self.current.encodable.type_count(); - log::debug!( - "encoding outer alias for {key} to type index {index}", - key = key.as_str(definitions) - ); + log::debug!("encoding outer alias for `{name}` to type index {index}"); self.current.encodable.alias(Alias::Outer { kind: ComponentOuterAliasKind::Type, count: 1, @@ -491,24 +480,27 @@ impl<'a> TypeEncoder<'a> { Self(defs) } - fn ty(&self, state: &mut State<'a>, ty: Type) -> Result { + fn ty(&self, state: &mut State<'a>, ty: Type, name: Option<&str>) -> Result { if let Some(index) = state.current.type_indexes.get(&ty) { return Ok(*index); } - let index = if let Some(index) = state.used_type_index(self.0, AliasKey::Type(ty)) { - index - } else { - match ty { - Type::Func(id) => self.func_type(state, id)?, - Type::Value(ValueType::Primitive(ty)) => Self::primitive(state, ty), - Type::Value(ValueType::Borrow(id)) => self.borrow(state, id), - Type::Value(ValueType::Own(id)) => self.own(state, id), - Type::Value(ValueType::Defined { id, .. }) => self.defined(state, id)?, - Type::Interface(id) => self.instance(state, id, false)?, - Type::World(id) => self.component(state, id)?, - Type::Module(id) => self.module(state, id), + if let Some(name) = name { + if let Some(index) = state.used_type_index(name) { + state.current.type_indexes.insert(ty, index); + return Ok(index); } + } + + let index = match ty { + Type::Func(id) => self.func_type(state, id)?, + Type::Value(ValueType::Primitive(ty)) => Self::primitive(state, ty), + Type::Value(ValueType::Borrow(id)) => self.borrow(state, id), + Type::Value(ValueType::Own(id)) => self.own(state, id), + Type::Value(ValueType::Defined { id, .. }) => self.defined(state, id)?, + Type::Interface(id) => self.instance(state, id, false)?, + Type::World(id) => self.component(state, id)?, + Type::Module(id) => self.module(state, id), }; state.current.type_indexes.insert(ty, index); @@ -579,45 +571,34 @@ impl<'a> TypeEncoder<'a> { Ok(index) } - fn use_aliases(&self, state: &mut State<'a>, uses: &IndexMap>) { - for (id, exports) in uses { - let interface = &self.0.interfaces[*id]; - let instance = state.current.instances[id]; - for export in exports { - let index = state.current.encodable.type_count(); - let (export, kind) = interface.exports.get_index(*export).unwrap(); - state.current.encodable.alias(Alias::InstanceExport { - instance, - kind: ComponentExportKind::Type, - name: export, - }); + fn use_aliases(&self, state: &mut State<'a>, uses: &'a IndexMap) { + state.current.type_aliases.clear(); + + for (name, used) in uses { + let interface = &self.0.interfaces[used.interface]; + let instance = state.current.instances[&used.interface]; + let index = state.current.encodable.type_count(); + let export: &String = used.name.as_ref().unwrap_or(name); + let kind = interface.exports.get(export).unwrap(); + state.current.encodable.alias(Alias::InstanceExport { + instance, + kind: ComponentExportKind::Type, + name: export, + }); - log::debug!("aliased export `{export}` ({kind:?}) of instance {instance} to type index {index}"); + log::debug!( + "aliased export `{export}` ({kind:?}) of instance {instance} to type index {index}" + ); - match kind { - ItemKind::Resource(id) => { - state - .current - .type_aliases - .insert(AliasKey::Resource(&self.0.resources[*id].name), index); - } - ItemKind::Type(ty) => { - state - .current - .type_aliases - .insert(AliasKey::Type(*ty), index); - } - _ => unreachable!("use of non-type"), - } - } + state.current.type_aliases.insert(name, index); } } fn instance(&self, state: &mut State<'a>, id: InterfaceId, types_only: bool) -> Result { log::debug!("encoding instance type for interface {id}", id = id.index()); let interface = &self.0.interfaces[id]; - for owner in interface.uses.keys() { - self.import_deps(state, self.0, *owner)?; + for used in interface.uses.values() { + self.import_deps(state, self.0, used.interface)?; } // Encode any required aliases @@ -668,8 +649,8 @@ impl<'a> TypeEncoder<'a> { state.push(Encodable::Component(ComponentType::default())); - for dep in world.uses.keys() { - self.import_deps(state, self.0, *dep)?; + for used in world.uses.values() { + self.import_deps(state, self.0, used.interface)?; } self.use_aliases(state, &world.uses); @@ -706,8 +687,8 @@ impl<'a> TypeEncoder<'a> { let interface = &definitions.interfaces[id]; // Depth-first recurse on the dependencies of this interface - for id in interface.uses.keys() { - self.import_deps(state, definitions, *id)?; + for used in interface.uses.values() { + self.import_deps(state, definitions, used.interface)?; } let name = self.0.interfaces[id] @@ -744,8 +725,8 @@ impl<'a> TypeEncoder<'a> { assert!(state.scopes.is_empty()); state.push(Encodable::Component(ComponentType::default())); - for dep in interface.uses.keys() { - self.import_deps(state, self.0, *dep)?; + for used in interface.uses.values() { + self.import_deps(state, self.0, used.interface)?; } let index = self.instance(state, id, false)?; @@ -1004,7 +985,7 @@ impl<'a> TypeEncoder<'a> { kind = kind.as_str(self.0) ); - let index = self.ty(state, ty)?; + let index = self.ty(state, ty, Some(name))?; match kind { ItemKind::Type(_) => { @@ -1052,9 +1033,7 @@ impl<'a> TypeEncoder<'a> { ); let resource = &self.0.resources[id]; - let index = if let Some(outer) = - state.used_type_index(self.0, AliasKey::Resource(&resource.name)) - { + let index = if let Some(outer) = state.used_type_index(name) { // This is an alias to an outer resource type let index = state.current.encodable.type_count(); state @@ -1106,7 +1085,7 @@ impl<'a> TypeEncoder<'a> { kind = kind.as_str(self.0) ); - let index = self.ty(state, ty)?; + let index = self.ty(state, ty, Some(name))?; let index = Self::export_type( state, name, @@ -1137,9 +1116,7 @@ impl<'a> TypeEncoder<'a> { } let resource = &self.0.resources[id]; - let index = if let Some(outer) = - state.used_type_index(self.0, AliasKey::Resource(&resource.name)) - { + let index = if let Some(outer) = state.used_type_index(name) { // This is an alias to an outer resource type let index = Self::export_type(state, name, ComponentTypeRef::Type(TypeBounds::Eq(outer))); diff --git a/crates/wac-parser/src/resolution/package.rs b/crates/wac-parser/src/resolution/package.rs index cc5692f..841aaa4 100644 --- a/crates/wac-parser/src/resolution/package.rs +++ b/crates/wac-parser/src/resolution/package.rs @@ -3,7 +3,7 @@ use super::{ FuncResult, Interface, InterfaceId, ItemKind, Module, ModuleId, Record, Type, ValueType, Variant, World, WorldId, }; -use crate::{Resource, ResourceId}; +use crate::{Resource, ResourceId, UsedType}; use anyhow::{bail, Result}; use indexmap::IndexMap; use semver::Version; @@ -24,6 +24,16 @@ pub struct PackageKey<'a> { pub version: Option<&'a Version>, } +impl fmt::Display for PackageKey<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{name}", name = self.name)?; + if let Some(version) = self.version { + write!(f, "@{version}")?; + } + Ok(()) + } +} + /// Represents information about a package. /// /// A package is expected to be a valid WebAssembly component. @@ -207,7 +217,7 @@ struct TypeConverter<'a> { types: Rc, cache: HashMap, resource_map: HashMap, - owners: HashMap, + owners: HashMap, } impl<'a> TypeConverter<'a> { @@ -224,37 +234,12 @@ impl<'a> TypeConverter<'a> { fn import(&mut self, name: &str) -> Result { let import = self.types.component_entity_type_of_import(name).unwrap(); - self.component_entity_type(name, import) + self.entity(name, import) } fn export(&mut self, name: &str) -> Result { let export = self.types.component_entity_type_of_export(name).unwrap(); - self.component_entity_type(name, export) - } - - fn component_entity_type( - &mut self, - name: &str, - ty: wasm::ComponentEntityType, - ) -> Result { - match ty { - wasm::ComponentEntityType::Module(id) => Ok(ItemKind::Module(self.module_type(id)?)), - wasm::ComponentEntityType::Func(id) => { - Ok(ItemKind::Func(self.component_func_type(id)?)) - } - wasm::ComponentEntityType::Value(ty) => { - Ok(ItemKind::Value(self.component_val_type(ty)?)) - } - wasm::ComponentEntityType::Type { created, .. } => { - Ok(ItemKind::Type(self.ty(created)?)) - } - wasm::ComponentEntityType::Instance(ty) => Ok(ItemKind::Instance( - self.component_instance_type(Some(name), ty)?, - )), - wasm::ComponentEntityType::Component(ty) => { - Ok(ItemKind::Component(self.component_type(Some(name), ty)?)) - } - } + self.entity(name, export) } fn component_func_type(&mut self, id: wasm::ComponentFuncTypeId) -> Result { @@ -378,7 +363,7 @@ impl<'a> TypeConverter<'a> { exports: IndexMap::with_capacity(instance_ty.exports.len()), }); - for (index, (name, ty)) in instance_ty.exports.iter().enumerate() { + for (name, ty) in &instance_ty.exports { let export = self.entity(name, *ty)?; if let wasm::ComponentEntityType::Type { @@ -386,7 +371,7 @@ impl<'a> TypeConverter<'a> { created, } = ty { - self.use_or_own(Owner::Interface(id), index, *referenced, *created); + self.use_or_own(Owner::Interface(id), name, *referenced, *created); } let prev = self.definitions.interfaces[id] @@ -427,19 +412,29 @@ impl<'a> TypeConverter<'a> { fn use_or_own( &mut self, owner: Owner, - index: usize, + name: &str, referenced: ComponentAnyTypeId, created: ComponentAnyTypeId, ) { - if let Some((other, index)) = self.find_owner(referenced) { - match other { - Owner::Interface(interface) if owner != other => { + if let Some((other, orig)) = self.find_owner(referenced) { + match *other { + Owner::Interface(interface) if owner != *other => { + let used = UsedType { + interface, + name: if name != orig { + Some(orig.to_string()) + } else { + None + }, + }; + // Owner is a different interface, so add a using reference let uses = match owner { Owner::Interface(id) => &mut self.definitions.interfaces[id].uses, Owner::World(id) => &mut self.definitions.worlds[id].uses, }; - uses.entry(interface).or_default().insert(index); + + uses.insert(name.to_string(), used); } _ => {} } @@ -447,7 +442,7 @@ impl<'a> TypeConverter<'a> { } // Take ownership of the entity - let prev = self.owners.insert(created, (owner, index)); + let prev = self.owners.insert(created, (owner, name.to_string())); assert!(prev.is_none()); } @@ -469,7 +464,7 @@ impl<'a> TypeConverter<'a> { exports: IndexMap::with_capacity(component_ty.exports.len()), }); - for (index, (name, ty)) in component_ty.imports.iter().enumerate() { + for (name, ty) in &component_ty.imports { let import = self.entity(name, *ty)?; if let wasm::ComponentEntityType::Type { @@ -477,7 +472,7 @@ impl<'a> TypeConverter<'a> { created, } = ty { - self.use_or_own(Owner::World(id), index, *referenced, *created); + self.use_or_own(Owner::World(id), name, *referenced, *created); } let prev = self.definitions.worlds[id] @@ -487,7 +482,7 @@ impl<'a> TypeConverter<'a> { } for (name, ty) in &component_ty.exports { - let ty = self.component_entity_type(name, *ty)?; + let ty = self.entity(name, *ty)?; let prev = self.definitions.worlds[id].exports.insert(name.clone(), ty); assert!(prev.is_none()); } @@ -683,10 +678,10 @@ impl<'a> TypeConverter<'a> { } } - fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<(Owner, usize)> { + fn find_owner(&self, mut id: wasm::ComponentAnyTypeId) -> Option<&(Owner, String)> { let mut prev = None; while prev.is_none() { - prev = self.owners.get(&id).copied(); + prev = self.owners.get(&id); id = match self.types.peel_alias(id) { Some(next) => next, None => break, diff --git a/crates/wac-parser/src/resolution/types.rs b/crates/wac-parser/src/resolution/types.rs index 24fe519..ab008a1 100644 --- a/crates/wac-parser/src/resolution/types.rs +++ b/crates/wac-parser/src/resolution/types.rs @@ -1,7 +1,4 @@ -use super::{ - package::Package, serialize_arena, serialize_id, serialize_id_key_map, serialize_optional_id, - ItemKind, -}; +use super::{package::Package, serialize_arena, serialize_id, serialize_optional_id, ItemKind}; use anyhow::{bail, Context, Result}; use id_arena::{Arena, Id}; use indexmap::{IndexMap, IndexSet}; @@ -379,6 +376,19 @@ pub enum FuncResult { List(IndexMap), } +/// Represents a used type. +#[derive(Debug, Clone, Serialize)] +pub struct UsedType { + /// The interface the type was used from. + #[serde(serialize_with = "serialize_id")] + pub interface: InterfaceId, + /// The original export name. + /// + /// This is `None` when the type was not renamed with an `as` clause. + #[serde(skip_serializing_if = "Option::is_none")] + pub name: Option, +} + /// Represents an interface (i.e. instance type). #[derive(Debug, Clone, Serialize, Default)] #[serde(rename_all = "camelCase")] @@ -396,9 +406,8 @@ pub struct Interface { /// original types. #[serde(skip)] pub remapped_types: IndexMap>, - /// A map from used interface to set of used type export indexes. - #[serde(serialize_with = "serialize_id_key_map")] - pub uses: IndexMap>, + /// A map of exported name to information about the used type. + pub uses: IndexMap, /// The exported items of the interface. pub exports: IndexMap, } @@ -411,9 +420,8 @@ pub struct World { /// /// This may be `None` for worlds representing component types. pub id: Option, - /// A map from used interface to set of used type export indexes. - #[serde(serialize_with = "serialize_id_key_map")] - pub uses: IndexMap>, + /// A map of imported name to information about the used type. + pub uses: IndexMap, /// The imported items of the world. pub imports: IndexMap, /// The exported items of the world. diff --git a/crates/wac-parser/tests/resolution/package-use-item.wac.result b/crates/wac-parser/tests/resolution/package-use-item.wac.result index 3f7f597..1caa174 100644 --- a/crates/wac-parser/tests/resolution/package-use-item.wac.result +++ b/crates/wac-parser/tests/resolution/package-use-item.wac.result @@ -77,9 +77,10 @@ { "id": "foo:bar/qux", "uses": { - "1": [ - 2 - ] + "z": { + "interface": 1, + "name": "c" + } }, "exports": { "z": { @@ -100,11 +101,15 @@ { "id": "test:comp/i@0.0.1", "uses": { - "0": [ - 0, - 1, - 2 - ] + "a": { + "interface": 0 + }, + "b": { + "interface": 0 + }, + "c": { + "interface": 0 + } }, "exports": { "a": { @@ -170,11 +175,15 @@ { "id": "test:comp/w@0.0.1", "uses": { - "2": [ - 1, - 2, - 0 - ] + "x": { + "interface": 2 + }, + "y": { + "interface": 2 + }, + "z": { + "interface": 2 + } }, "imports": { "x": { diff --git a/crates/wac-parser/tests/resolution/package-world-include.wac.result b/crates/wac-parser/tests/resolution/package-world-include.wac.result index 13f5f3c..a8fba6c 100644 --- a/crates/wac-parser/tests/resolution/package-world-include.wac.result +++ b/crates/wac-parser/tests/resolution/package-world-include.wac.result @@ -148,9 +148,9 @@ { "id": "foo:bar/baz", "uses": { - "1": [ - 0 - ] + "x": { + "interface": 1 + } }, "imports": { "foo:bar/i": { diff --git a/crates/wac-parser/tests/resolution/types.wac.result b/crates/wac-parser/tests/resolution/types.wac.result index 98d113f..235c5e1 100644 --- a/crates/wac-parser/tests/resolution/types.wac.result +++ b/crates/wac-parser/tests/resolution/types.wac.result @@ -133,9 +133,13 @@ { "id": "test:comp/i2", "uses": { - "0": [ - 1 - ] + "r": { + "interface": 0 + }, + "z": { + "interface": 0, + "name": "r" + } }, "exports": { "r": { @@ -216,9 +220,9 @@ { "id": "test:comp/w1", "uses": { - "2": [ - 0 - ] + "r": { + "interface": 2 + } }, "imports": { "r": { diff --git a/crates/wac-resolver/src/fs.rs b/crates/wac-resolver/src/fs.rs index b56c954..3cb06e0 100644 --- a/crates/wac-resolver/src/fs.rs +++ b/crates/wac-resolver/src/fs.rs @@ -117,7 +117,10 @@ impl FileSystemPackageResolver { } if !path.is_file() { - log::debug!("package `{path}` does not exist", path = path.display()); + log::debug!( + "package `{key}` does not exist at `{path}`", + path = path.display() + ); if self.error_on_unknown { return Err(Error::UnknownPackage { name: key.name.to_string(), @@ -127,7 +130,10 @@ impl FileSystemPackageResolver { continue; } - log::debug!("loading package from `{path}`", path = path.display()); + log::debug!( + "loading package `{key}` from `{path}`", + path = path.display() + ); let bytes = fs::read(&path) .with_context(|| format!("failed to read package `{path}`", path = path.display())) .map_err(|e| Error::PackageResolutionFailure {