@@ -9,24 +9,12 @@ use std::process::{Command, Stdio};
9
9
use std:: str:: FromStr ;
10
10
use wit_bindgen_core:: abi:: { Bitcast , WasmType } ;
11
11
use wit_bindgen_core:: {
12
- uwriteln, wit_parser:: * , Direction , Files , InterfaceGenerator as _, Source , Types ,
13
- WorldGenerator ,
12
+ uwriteln, wit_parser:: * , Files , InterfaceGenerator as _, Source , Types , WorldGenerator ,
14
13
} ;
15
14
16
15
mod bindgen;
17
16
mod interface;
18
17
19
- #[ derive( Default ) ]
20
- struct ResourceInfo {
21
- // Note that a resource can be both imported and exported (e.g. when
22
- // importing and exporting the same interface which contains one or more
23
- // resources). In that case, this field will be `Import` while we're
24
- // importing the interface and later change to `Export` while we're
25
- // exporting the interface.
26
- direction : Direction ,
27
- owned : bool ,
28
- }
29
-
30
18
struct InterfaceName {
31
19
/// True when this interface name has been remapped through the use of `with` in the `bindgen!`
32
20
/// macro invocation.
@@ -45,12 +33,14 @@ struct RustWasm {
45
33
export_modules : Vec < ( String , Vec < String > ) > ,
46
34
skip : HashSet < String > ,
47
35
interface_names : HashMap < InterfaceId , InterfaceName > ,
48
- resources : HashMap < TypeId , ResourceInfo > ,
36
+ /// Each imported and exported interface is stored in this map. Value indicates if last use was import.
37
+ interface_last_seen_as_import : HashMap < InterfaceId , bool > ,
49
38
import_funcs_called : bool ,
50
39
with_name_counter : usize ,
51
40
// Track the with options that were used. Remapped interfaces provided via `with`
52
41
// are required to be used.
53
42
used_with_opts : HashSet < String > ,
43
+ world : Option < WorldId > ,
54
44
}
55
45
56
46
#[ cfg( feature = "clap" ) ]
@@ -360,7 +350,7 @@ fn name_package_module(resolve: &Resolve, id: PackageId) -> String {
360
350
}
361
351
362
352
impl WorldGenerator for RustWasm {
363
- fn preprocess ( & mut self , resolve : & Resolve , _world : WorldId ) {
353
+ fn preprocess ( & mut self , resolve : & Resolve , world : WorldId ) {
364
354
wit_bindgen_core:: generated_preamble ( & mut self . src , env ! ( "CARGO_PKG_VERSION" ) ) ;
365
355
366
356
// Render some generator options to assist with debugging and/or to help
@@ -391,6 +381,7 @@ impl WorldGenerator for RustWasm {
391
381
uwriteln ! ( self . src, "// * with {with:?}" ) ;
392
382
}
393
383
self . types . analyze ( resolve) ;
384
+ self . world = Some ( world) ;
394
385
}
395
386
396
387
fn import_interface (
@@ -400,6 +391,7 @@ impl WorldGenerator for RustWasm {
400
391
id : InterfaceId ,
401
392
_files : & mut Files ,
402
393
) {
394
+ self . interface_last_seen_as_import . insert ( id, true ) ;
403
395
let wasm_import_module = resolve. name_world_key ( name) ;
404
396
let mut gen = self . interface (
405
397
Identifier :: Interface ( id, name) ,
@@ -442,6 +434,7 @@ impl WorldGenerator for RustWasm {
442
434
id : InterfaceId ,
443
435
_files : & mut Files ,
444
436
) -> Result < ( ) > {
437
+ self . interface_last_seen_as_import . insert ( id, false ) ;
445
438
let mut gen = self . interface ( Identifier :: Interface ( id, name) , None , resolve, false ) ;
446
439
let ( snake, module_path) = gen. start_append_submodule ( name) ;
447
440
if gen. gen . name_interface ( resolve, id, name, true ) {
@@ -450,6 +443,31 @@ impl WorldGenerator for RustWasm {
450
443
gen. types ( id) ;
451
444
gen. generate_exports ( resolve. interfaces [ id] . functions . values ( ) ) ?;
452
445
gen. finish_append_submodule ( & snake, module_path) ;
446
+
447
+ if self . opts . stubs {
448
+ let ( pkg, name) = match name {
449
+ WorldKey :: Name ( name) => ( None , name) ,
450
+ WorldKey :: Interface ( id) => {
451
+ let interface = & resolve. interfaces [ * id] ;
452
+ (
453
+ Some ( interface. package . unwrap ( ) ) ,
454
+ interface. name . as_ref ( ) . unwrap ( ) ,
455
+ )
456
+ }
457
+ } ;
458
+ for ( resource, funcs) in group_by_resource ( resolve. interfaces [ id] . functions . values ( ) ) {
459
+ let world_id = self . world . unwrap ( ) ;
460
+ let mut gen = self . interface ( Identifier :: World ( world_id) , None , resolve, false ) ;
461
+ let pkg = pkg. map ( |pid| {
462
+ let namespace = resolve. packages [ pid] . name . namespace . clone ( ) ;
463
+ let package_module = name_package_module ( resolve, pid) ;
464
+ ( namespace, package_module)
465
+ } ) ;
466
+ gen. generate_stub ( resource, pkg, name, true , & funcs) ;
467
+ let stub = gen. finish ( ) ;
468
+ self . src . push_str ( & stub) ;
469
+ }
470
+ }
453
471
Ok ( ( ) )
454
472
}
455
473
@@ -464,6 +482,16 @@ impl WorldGenerator for RustWasm {
464
482
gen. generate_exports ( funcs. iter ( ) . map ( |f| f. 1 ) ) ?;
465
483
let src = gen. finish ( ) ;
466
484
self . src . push_str ( & src) ;
485
+
486
+ if self . opts . stubs {
487
+ for ( resource, funcs) in group_by_resource ( funcs. iter ( ) . map ( |f| f. 1 ) ) {
488
+ let mut gen = self . interface ( Identifier :: World ( world) , None , resolve, false ) ;
489
+ let world = & resolve. worlds [ world] ;
490
+ gen. generate_stub ( resource, None , & world. name , false , & funcs) ;
491
+ let stub = gen. finish ( ) ;
492
+ self . src . push_str ( & stub) ;
493
+ }
494
+ }
467
495
Ok ( ( ) )
468
496
}
469
497
@@ -541,50 +569,6 @@ impl WorldGenerator for RustWasm {
541
569
542
570
if self . opts . stubs {
543
571
self . src . push_str ( "\n #[derive(Debug)]\n pub struct Stub;\n " ) ;
544
- let world_id = world;
545
- let world = & resolve. worlds [ world] ;
546
- let mut funcs = Vec :: new ( ) ;
547
- for ( name, export) in world. exports . iter ( ) {
548
- let ( pkg, name) = match name {
549
- WorldKey :: Name ( name) => ( None , name) ,
550
- WorldKey :: Interface ( id) => {
551
- let interface = & resolve. interfaces [ * id] ;
552
- (
553
- Some ( interface. package . unwrap ( ) ) ,
554
- interface. name . as_ref ( ) . unwrap ( ) ,
555
- )
556
- }
557
- } ;
558
- match export {
559
- WorldItem :: Function ( func) => {
560
- funcs. push ( func) ;
561
- }
562
- WorldItem :: Interface ( id) => {
563
- for ( resource, funcs) in
564
- group_by_resource ( resolve. interfaces [ * id] . functions . values ( ) )
565
- {
566
- let mut gen =
567
- self . interface ( Identifier :: World ( world_id) , None , resolve, false ) ;
568
- let pkg = pkg. map ( |pid| {
569
- let namespace = resolve. packages [ pid] . name . namespace . clone ( ) ;
570
- let package_module = name_package_module ( resolve, pid) ;
571
- ( namespace, package_module)
572
- } ) ;
573
- gen. generate_stub ( resource, pkg, name, true , & funcs) ;
574
- let stub = gen. finish ( ) ;
575
- self . src . push_str ( & stub) ;
576
- }
577
- }
578
- WorldItem :: Type ( _) => unreachable ! ( ) ,
579
- }
580
- }
581
-
582
- for ( resource, funcs) in group_by_resource ( funcs. into_iter ( ) ) {
583
- let mut gen = self . interface ( Identifier :: World ( world_id) , None , resolve, false ) ;
584
- gen. generate_stub ( resource, None , & world. name , false , & funcs) ;
585
- let stub = gen. finish ( ) ;
586
- self . src . push_str ( & stub) ;
587
- }
588
572
}
589
573
590
574
let mut src = mem:: take ( & mut self . src ) ;
0 commit comments