11use crate :: { uwrite, uwriteln} ;
2+ use anyhow:: { bail, Result } ;
23use heck:: * ;
34use js_component_bindgen:: function_bindgen:: {
45 ErrHandling , FunctionBindgen , ResourceData , ResourceMap , ResourceTable ,
@@ -124,7 +125,13 @@ pub struct Componentization {
124125 pub resource_imports : Vec < ( String , String , u32 ) > ,
125126}
126127
127- pub fn componentize_bindgen ( resolve : & Resolve , id : WorldId , name : & str ) -> Componentization {
128+ pub fn componentize_bindgen (
129+ resolve : & Resolve ,
130+ id : WorldId ,
131+ name : & str ,
132+ guest_imports : & Vec < String > ,
133+ guest_exports : & Vec < String > ,
134+ ) -> Result < Componentization > {
128135 let mut bindgen = JsBindgen {
129136 src : Source :: default ( ) ,
130137 esm_bindgen : EsmBindgen :: default ( ) ,
@@ -147,9 +154,9 @@ pub fn componentize_bindgen(resolve: &Resolve, id: WorldId, name: &str) -> Compo
147154 . local_names
148155 . exclude_globals ( Intrinsic :: get_global_names ( ) ) ;
149156
150- bindgen. imports_bindgen ( ) ;
157+ bindgen. imports_bindgen ( & guest_imports ) ;
151158
152- bindgen. exports_bindgen ( ) ;
159+ bindgen. exports_bindgen ( & guest_exports ) ? ;
153160 bindgen. esm_bindgen . populate_export_aliases ( ) ;
154161
155162 // consolidate import specifiers and generate wrappers
@@ -348,13 +355,13 @@ pub fn componentize_bindgen(resolve: &Resolve, id: WorldId, name: &str) -> Compo
348355 output. push_str ( & js_intrinsics) ;
349356 output. push_str ( & bindgen. src ) ;
350357
351- Componentization {
358+ Ok ( Componentization {
352359 js_bindings : output. to_string ( ) ,
353360 exports : bindgen. exports ,
354361 imports : bindgen. imports ,
355362 import_wrappers,
356363 resource_imports,
357- }
364+ } )
358365}
359366
360367impl JsBindgen < ' _ > {
@@ -363,9 +370,39 @@ impl JsBindgen<'_> {
363370 return intrinsic. name ( ) . to_string ( ) ;
364371 }
365372
366- fn exports_bindgen ( & mut self ) {
373+ fn exports_bindgen ( & mut self , guest_exports : & Vec < String > ) -> Result < ( ) > {
367374 for ( key, export) in & self . resolve . worlds [ self . world ] . exports {
368375 let name = self . resolve . name_world_key ( key) ;
376+
377+ // Do not generate exports when the guest export is not implemented.
378+ // We check both the full interface name - "ns:pkg@v/my-interface" and the
379+ // aliased interface name "myInterface". All other names are always
380+ // camel-case in the check.
381+ match key {
382+ WorldKey :: Interface ( iface) => {
383+ if !guest_exports. contains ( & name) {
384+ let iface = & self . resolve . interfaces [ * iface] ;
385+ if let Some ( name) = iface. name . as_ref ( ) {
386+ let camel_case_name = name. to_lower_camel_case ( ) ;
387+ if !guest_exports. contains ( & camel_case_name) {
388+ bail ! ( "Expected a JS export definition for '{}'" , camel_case_name) ;
389+ }
390+ // TODO: move populate_export_aliases to a preprocessing
391+ // step that doesn't require esm_bindgen, so that we can
392+ // do alias deduping here as well.
393+ } else {
394+ continue ;
395+ }
396+ }
397+ }
398+ WorldKey :: Name ( export_name) => {
399+ let camel_case_name = export_name. to_lower_camel_case ( ) ;
400+ if !guest_exports. contains ( & camel_case_name) {
401+ bail ! ( "Expected a JS export definition for '{}'" , camel_case_name) ;
402+ }
403+ }
404+ }
405+
369406 match export {
370407 WorldItem :: Function ( func) => {
371408 let local_name = self . local_names . create_once ( & func. name ) . to_string ( ) ;
@@ -449,11 +486,15 @@ impl JsBindgen<'_> {
449486 WorldItem :: Type ( _) => { }
450487 }
451488 }
489+ Ok ( ( ) )
452490 }
453491
454- fn imports_bindgen ( & mut self ) {
492+ fn imports_bindgen ( & mut self , guest_imports : & Vec < String > ) {
455493 for ( key, impt) in & self . resolve . worlds [ self . world ] . imports {
456494 let import_name = self . resolve . name_world_key ( key) ;
495+ if !guest_imports. contains ( & import_name) {
496+ continue ;
497+ }
457498 match & impt {
458499 WorldItem :: Function ( f) => {
459500 self . import_bindgen ( import_name, f, false , None ) ;
0 commit comments