11use crate :: bindgen:: { FunctionBindgen , POINTER_SIZE_EXPRESSION } ;
22use crate :: {
33 ConstructorReturnType , FnSig , Identifier , InterfaceName , Ownership , RuntimeItem , RustFlagsRepr ,
4- RustWasm , TypeGeneration , classify_constructor_return_type , full_wit_type_name , int_repr ,
5- to_rust_ident, to_upper_camel_case, wasm_type,
4+ RustWasm , TypeGeneration , TypeSelectors , classify_constructor_return_type , full_wit_type_name ,
5+ int_repr , to_rust_ident, to_upper_camel_case, wasm_type,
66} ;
77use anyhow:: Result ;
88use heck:: * ;
@@ -2087,44 +2087,8 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
20872087 result
20882088 }
20892089
2090- /// The owning interface and its package, when `id` is owned by an interface.
2091- fn type_owner ( & self , id : TypeId ) -> Option < ( InterfaceId , & PackageName ) > {
2092- let TypeOwner :: Interface ( iface_id) = self . resolve . types [ id] . owner else {
2093- return None ;
2094- } ;
2095- let pkg_id = self . resolve . interfaces [ iface_id] . package ?;
2096- Some ( ( iface_id, & self . resolve . packages [ pkg_id] . name ) )
2097- }
2098-
2099- /// Selector keys naming the type itself: its bare wit name and its
2100- /// fully-qualified `ns:pkg/iface/type` name. Qualified keys are written exactly
2101- /// as in `with`, so they carry the package `@version` when versioned.
2102- fn type_identity_keys ( & self , id : TypeId ) -> Vec < String > {
2103- let id = dealias ( self . resolve , id) ;
2104- match self . resolve . types [ id] . name . as_deref ( ) {
2105- Some ( name) => vec ! [ name. to_string( ) , full_wit_type_name( self . resolve, id) ] ,
2106- None => Vec :: new ( ) ,
2107- }
2108- }
2109-
2110- /// Every selector key that matches type `id`: its identity keys plus its
2111- /// owning interface and package.
2112- fn type_selector_keys ( & self , id : TypeId ) -> Vec < String > {
2113- let id = dealias ( self . resolve , id) ;
2114- let mut keys = self . type_identity_keys ( id) ;
2115- if let Some ( ( iface_id, pkg) ) = self . type_owner ( id) {
2116- keys. push ( pkg. to_string ( ) ) ;
2117- if let Some ( iface) = self . resolve . id_of ( iface_id) {
2118- keys. push ( iface) ;
2119- }
2120- }
2121- keys
2122- }
2123-
2124- /// The attributes from `entries` whose selector satisfies `matches`, deduped in
2125- /// configured order, paired with the distinct selectors that matched. The
2126- /// matched selectors are recorded so `finish` can report selectors that matched
2127- /// nothing, exactly as the `with` option reports unused remappings.
2090+ /// Matching attributes, deduped in configured order, plus the selectors that
2091+ /// matched, which `finish` uses to report the ones that did not.
21282092 fn matching_attrs (
21292093 entries : & [ ( String , String ) ] ,
21302094 matches : impl Fn ( & str ) -> bool ,
@@ -2138,62 +2102,25 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
21382102 ( attrs. into_iter ( ) . collect ( ) , used. into_iter ( ) . collect ( ) )
21392103 }
21402104
2141- /// Attributes configured via `additional_type_attributes` for type `id`.
2142- fn additional_type_attrs ( & mut self , id : TypeId ) -> Vec < String > {
2143- let keys = self . type_selector_keys ( id) ;
2105+ fn additional_type_attrs ( & mut self , selectors : & TypeSelectors ) -> Vec < String > {
21442106 let ( attrs, used) =
21452107 Self :: matching_attrs ( & self . r#gen . opts . additional_type_attributes , |sel| {
2146- keys . iter ( ) . any ( |k| k == sel)
2108+ selectors . matches ( sel)
21472109 } ) ;
21482110 self . r#gen . used_type_attr_selectors . extend ( used) ;
21492111 attrs
21502112 }
21512113
2152- /// Attributes configured via `additional_member_attributes` for `member` (a
2153- /// record field or enum/variant case) of type `id`, matched by `<type>.<member>`
2154- /// for any type selector (bare, qualified, interface, or package) or a bare
2155- /// `<member>`.
2156- fn additional_member_attrs ( & mut self , id : TypeId , member : & str ) -> Vec < String > {
2157- let type_keys = self . type_selector_keys ( id) ;
2114+ /// `member` is a record field or an enum/variant case.
2115+ fn additional_member_attrs ( & mut self , selectors : & TypeSelectors , member : & str ) -> Vec < String > {
21582116 let ( attrs, used) =
21592117 Self :: matching_attrs ( & self . r#gen . opts . additional_member_attributes , |sel| {
2160- // member names are dot-free, so the last `.` splits `<type>.<member>`
2161- sel == member
2162- || sel
2163- . rsplit_once ( '.' )
2164- . is_some_and ( |( ty, m) | m == member && type_keys. iter ( ) . any ( |tk| tk == ty) )
2118+ selectors. matches_member ( sel, member)
21652119 } ) ;
21662120 self . r#gen . used_member_attr_selectors . extend ( used) ;
21672121 attrs
21682122 }
21692123
2170- /// Split injected attributes into derive paths and everything else. Derive
2171- /// paths are merged into the generated `#[derive(...)]` so they dedup against
2172- /// the built-in and `additional_derives` derives instead of colliding (E0119);
2173- /// other attributes are emitted verbatim.
2174- fn split_injected_derives ( attrs : & [ String ] ) -> ( Vec < String > , Vec < String > ) {
2175- let mut derives = Vec :: new ( ) ;
2176- let mut others = Vec :: new ( ) ;
2177- for attr in attrs {
2178- match attr
2179- . trim ( )
2180- . strip_prefix ( "#[derive(" )
2181- . and_then ( |s| s. strip_suffix ( ")]" ) )
2182- {
2183- Some ( inner) => derives. extend (
2184- inner
2185- . split ( ',' )
2186- . map ( str:: trim)
2187- . filter ( |p| !p. is_empty ( ) )
2188- . map ( String :: from) ,
2189- ) ,
2190- None => others. push ( attr. clone ( ) ) ,
2191- }
2192- }
2193- ( derives, others)
2194- }
2195-
2196- /// Emit each attribute on its own line, verbatim.
21972124 fn push_attrs ( & mut self , attrs : & [ String ] ) {
21982125 for attr in attrs {
21992126 uwriteln ! ( self . src, "{attr}" ) ;
@@ -2211,12 +2138,12 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
22112138 . cloned ( )
22122139 . collect ( ) ;
22132140 // Computed once, then emitted on every ownership mode below.
2214- let ( injected_derives , injected_attrs ) =
2215- Self :: split_injected_derives ( & self . additional_type_attrs ( id ) ) ;
2141+ let selectors = TypeSelectors :: of ( self . resolve , id ) ;
2142+ let injected_attrs = self . additional_type_attrs ( & selectors ) ;
22162143 let field_attrs: Vec < Vec < String > > = record
22172144 . fields
22182145 . iter ( )
2219- . map ( |f| self . additional_member_attrs ( id , & f. name ) )
2146+ . map ( |f| self . additional_member_attrs ( & selectors , & f. name ) )
22202147 . collect ( ) ;
22212148 for ( name, mode) in self . modes_of ( id) {
22222149 self . rustdoc ( docs) ;
@@ -2235,7 +2162,6 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
22352162 } else if info. is_clone ( ) {
22362163 derives. insert ( "Clone" . to_string ( ) ) ;
22372164 }
2238- derives. extend ( injected_derives. iter ( ) . cloned ( ) ) ;
22392165 if !derives. is_empty ( ) {
22402166 self . push_str ( "#[derive(" ) ;
22412167 self . push_str ( & derives. into_iter ( ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ) ;
@@ -2307,8 +2233,6 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
23072233 {
23082234 self . print_rust_enum (
23092235 id,
2310- // Raw wit case names; `print_rust_enum` upper-camel-cases them at the
2311- // emit site so member selectors still match the wit (kebab) name.
23122236 variant
23132237 . cases
23142238 . iter ( )
@@ -2334,12 +2258,12 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
23342258 . iter ( )
23352259 . cloned ( )
23362260 . collect ( ) ;
2337- let ( injected_derives , injected_attrs ) =
2338- Self :: split_injected_derives ( & self . additional_type_attrs ( id ) ) ;
2261+ let selectors = TypeSelectors :: of ( self . resolve , id ) ;
2262+ let injected_attrs = self . additional_type_attrs ( & selectors ) ;
23392263 let case_attrs: Vec < Vec < String > > = cases
23402264 . clone ( )
23412265 . into_iter ( )
2342- . map ( |( case_name, _, _) | self . additional_member_attrs ( id , & case_name) )
2266+ . map ( |( case_name, _, _) | self . additional_member_attrs ( & selectors , & case_name) )
23432267 . collect ( ) ;
23442268 for ( name, mode) in self . modes_of ( id) {
23452269 self . rustdoc ( docs) ;
@@ -2357,7 +2281,6 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
23572281 } else if info. is_clone ( ) {
23582282 derives. insert ( "Clone" . to_string ( ) ) ;
23592283 }
2360- derives. extend ( injected_derives. iter ( ) . cloned ( ) ) ;
23612284 if !derives. is_empty ( ) {
23622285 self . push_str ( "#[derive(" ) ;
23632286 self . push_str ( & derives. into_iter ( ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ) ;
@@ -2485,9 +2408,8 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
24852408
24862409 let name = to_upper_camel_case ( name) ;
24872410 self . rustdoc ( docs) ;
2488- let ( injected_derives, injected_attrs) =
2489- Self :: split_injected_derives ( & self . additional_type_attrs ( id) ) ;
2490- self . push_attrs ( & injected_attrs) ;
2411+ let selectors = TypeSelectors :: of ( self . resolve , id) ;
2412+ let injected_attrs = self . additional_type_attrs ( & selectors) ;
24912413 self . push_str ( "#[repr(" ) ;
24922414 self . int_repr ( enum_. tag ( ) ) ;
24932415 self . push_str ( ")]\n " ) ;
@@ -2506,14 +2428,14 @@ unsafe fn call_import(&mut self, _params: Self::ParamsLower, _results: *mut u8)
25062428 . into_iter ( )
25072429 . map ( |s| s. to_string ( ) ) ,
25082430 ) ;
2509- derives. extend ( injected_derives) ;
25102431 self . push_str ( "#[derive(" ) ;
25112432 self . push_str ( & derives. into_iter ( ) . collect :: < Vec < _ > > ( ) . join ( ", " ) ) ;
25122433 self . push_str ( ")]\n " ) ;
2434+ self . push_attrs ( & injected_attrs) ;
25132435 self . push_str ( & format ! ( "pub enum {name} {{\n " ) ) ;
25142436 for case in enum_. cases . iter ( ) {
25152437 self . rustdoc ( & case. docs ) ;
2516- let case_attrs = self . additional_member_attrs ( id , & case. name ) ;
2438+ let case_attrs = self . additional_member_attrs ( & selectors , & case. name ) ;
25172439 self . push_attrs ( & case_attrs) ;
25182440 self . push_str ( & case. name . to_upper_camel_case ( ) ) ;
25192441 self . push_str ( ",\n " ) ;
0 commit comments