1
1
use crate :: { uwrite, uwriteln} ;
2
+ use anyhow:: { bail, Result } ;
2
3
use heck:: * ;
3
4
use js_component_bindgen:: function_bindgen:: {
4
5
ErrHandling , FunctionBindgen , ResourceData , ResourceMap , ResourceTable ,
@@ -124,7 +125,13 @@ pub struct Componentization {
124
125
pub resource_imports : Vec < ( String , String , u32 ) > ,
125
126
}
126
127
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 > {
128
135
let mut bindgen = JsBindgen {
129
136
src : Source :: default ( ) ,
130
137
esm_bindgen : EsmBindgen :: default ( ) ,
@@ -147,9 +154,9 @@ pub fn componentize_bindgen(resolve: &Resolve, id: WorldId, name: &str) -> Compo
147
154
. local_names
148
155
. exclude_globals ( Intrinsic :: get_global_names ( ) ) ;
149
156
150
- bindgen. imports_bindgen ( ) ;
157
+ bindgen. imports_bindgen ( & guest_imports ) ;
151
158
152
- bindgen. exports_bindgen ( ) ;
159
+ bindgen. exports_bindgen ( & guest_exports ) ? ;
153
160
bindgen. esm_bindgen . populate_export_aliases ( ) ;
154
161
155
162
// consolidate import specifiers and generate wrappers
@@ -348,13 +355,13 @@ pub fn componentize_bindgen(resolve: &Resolve, id: WorldId, name: &str) -> Compo
348
355
output. push_str ( & js_intrinsics) ;
349
356
output. push_str ( & bindgen. src ) ;
350
357
351
- Componentization {
358
+ Ok ( Componentization {
352
359
js_bindings : output. to_string ( ) ,
353
360
exports : bindgen. exports ,
354
361
imports : bindgen. imports ,
355
362
import_wrappers,
356
363
resource_imports,
357
- }
364
+ } )
358
365
}
359
366
360
367
impl JsBindgen < ' _ > {
@@ -363,9 +370,39 @@ impl JsBindgen<'_> {
363
370
return intrinsic. name ( ) . to_string ( ) ;
364
371
}
365
372
366
- fn exports_bindgen ( & mut self ) {
373
+ fn exports_bindgen ( & mut self , guest_exports : & Vec < String > ) -> Result < ( ) > {
367
374
for ( key, export) in & self . resolve . worlds [ self . world ] . exports {
368
375
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
+
369
406
match export {
370
407
WorldItem :: Function ( func) => {
371
408
let local_name = self . local_names . create_once ( & func. name ) . to_string ( ) ;
@@ -449,11 +486,15 @@ impl JsBindgen<'_> {
449
486
WorldItem :: Type ( _) => { }
450
487
}
451
488
}
489
+ Ok ( ( ) )
452
490
}
453
491
454
- fn imports_bindgen ( & mut self ) {
492
+ fn imports_bindgen ( & mut self , guest_imports : & Vec < String > ) {
455
493
for ( key, impt) in & self . resolve . worlds [ self . world ] . imports {
456
494
let import_name = self . resolve . name_world_key ( key) ;
495
+ if !guest_imports. contains ( & import_name) {
496
+ continue ;
497
+ }
457
498
match & impt {
458
499
WorldItem :: Function ( f) => {
459
500
self . import_bindgen ( import_name, f, false , None ) ;
0 commit comments