@@ -130,6 +130,15 @@ pub struct Opts {
130130 /// Must be specified in addition to the `pkg-name` flag.
131131 #[ cfg_attr( feature = "clap" , clap( long) ) ]
132132 pub print_remote_pkg_version : bool ,
133+
134+ /// When generating Go package names, include the WIT package version even
135+ /// if only one version of that package is referenced by the specified
136+ /// world.
137+ ///
138+ /// By default, the version will only be included in the name if the world
139+ /// references more than one version of the WIT package.
140+ #[ cfg_attr( feature = "clap" , clap( long) ) ]
141+ pub include_versions : bool ,
133142}
134143
135144impl Opts {
@@ -242,7 +251,7 @@ impl Go {
242251 if local == owner && ( exported ^ in_import) {
243252 String :: new ( )
244253 } else {
245- let package = interface_name ( resolve, owner) ;
254+ let package = self . interface_name ( resolve, owner) ;
246255 let package = if exported {
247256 format ! ( "export_{package}" )
248257 } else {
@@ -623,7 +632,7 @@ func Lift{upper_kind}{camel}(handle int32) *witTypes.{upper_kind}Reader[{payload
623632 } else {
624633 format ! (
625634 "{}_" ,
626- interface_name(
635+ self . interface_name(
627636 resolve,
628637 Some (
629638 & self
@@ -735,7 +744,7 @@ impl WorldGenerator for Go {
735744 data. extend ( self . import ( resolve, func, Some ( name) ) ) ;
736745 }
737746 self . interfaces
738- . entry ( interface_name ( resolve, Some ( name) ) )
747+ . entry ( self . interface_name ( resolve, Some ( name) ) )
739748 . or_default ( )
740749 . extend ( data) ;
741750
@@ -754,7 +763,7 @@ impl WorldGenerator for Go {
754763 data. extend ( self . import ( resolve, func, None ) ) ;
755764 }
756765 self . interfaces
757- . entry ( interface_name ( resolve, None ) )
766+ . entry ( self . interface_name ( resolve, None ) )
758767 . or_default ( )
759768 . extend ( data) ;
760769 }
@@ -783,12 +792,13 @@ impl WorldGenerator for Go {
783792
784793 let data = generator. into ( ) ;
785794
795+ let name = self . interface_name ( resolve, Some ( name) ) ;
786796 if exported {
787797 & mut self . export_interfaces
788798 } else {
789799 & mut self . interfaces
790800 }
791- . entry ( interface_name ( resolve , Some ( name) ) )
801+ . entry ( name)
792802 . or_default ( )
793803 . extend ( data) ;
794804 }
@@ -831,7 +841,7 @@ impl WorldGenerator for Go {
831841 }
832842 let data = generator. into ( ) ;
833843 self . interfaces
834- . entry ( interface_name ( resolve, None ) )
844+ . entry ( self . interface_name ( resolve, None ) )
835845 . or_default ( )
836846 . extend ( data) ;
837847 }
@@ -1226,7 +1236,7 @@ func {camel}({go_params}) {go_results} {{
12261236 let sig = resolve. wasm_signature ( variant, func) ;
12271237 let core_module_name = interface. map ( |v| resolve. name_world_key ( v) ) ;
12281238 let export_name = func. legacy_core_export_name ( core_module_name. as_deref ( ) ) ;
1229- let name = func_name ( resolve, interface, func) ;
1239+ let name = self . func_name ( resolve, interface, func) ;
12301240
12311241 let params = sig
12321242 . params
@@ -1351,7 +1361,7 @@ func wasm_export_post_return_{name}(result {results}) {{
13511361 let results = self . func_results ( resolve, func, interface, false , & mut imports) ;
13521362
13531363 self . export_interfaces
1354- . entry ( interface_name ( resolve, interface) )
1364+ . entry ( self . interface_name ( resolve, interface) )
13551365 . or_default ( )
13561366 . extend ( InterfaceData {
13571367 code : format ! (
@@ -1470,12 +1480,13 @@ func wasm_export_{name}({params}) {results} {{
14701480 & func. name ,
14711481 ) ;
14721482
1483+ let name = self . interface_name ( resolve, interface) ;
14731484 if in_import || !exported {
14741485 & mut self . interfaces
14751486 } else {
14761487 & mut self . export_interfaces
14771488 }
1478- . entry ( interface_name ( resolve , interface ) )
1489+ . entry ( name )
14791490 . or_default ( )
14801491 . extend ( data) ;
14811492 }
@@ -1494,6 +1505,47 @@ func wasm_export_{name}({params}) {results} {{
14941505 }
14951506 } )
14961507 }
1508+
1509+ fn interface_name ( & self , resolve : & Resolve , interface : Option < & WorldKey > ) -> String {
1510+ match interface {
1511+ Some ( WorldKey :: Name ( name) ) => name. to_snake_case ( ) ,
1512+ Some ( WorldKey :: Interface ( id) ) => {
1513+ let interface = & resolve. interfaces [ * id] ;
1514+ let package = & resolve. packages [ interface. package . unwrap ( ) ] ;
1515+ let package_has_multiple_versions = resolve. packages . iter ( ) . any ( |( _, p) | {
1516+ p. name . namespace == package. name . namespace
1517+ && p. name . name == package. name . name
1518+ && p. name . version != package. name . version
1519+ } ) ;
1520+ let version = if package_has_multiple_versions || self . opts . include_versions {
1521+ if let Some ( version) = & package. name . version {
1522+ format ! ( "{}_" , version. to_string( ) . replace( [ '.' , '-' , '+' ] , "_" ) )
1523+ } else {
1524+ String :: new ( )
1525+ }
1526+ } else {
1527+ String :: new ( )
1528+ } ;
1529+ let namespace = package. name . namespace . to_snake_case ( ) ;
1530+ let package = package. name . name . to_snake_case ( ) ;
1531+ let interface = interface. name . as_ref ( ) . unwrap ( ) . to_snake_case ( ) ;
1532+ format ! ( "{namespace}_{package}_{version}{interface}" )
1533+ }
1534+ None => "wit_world" . into ( ) ,
1535+ }
1536+ }
1537+
1538+ fn func_name (
1539+ & self ,
1540+ resolve : & Resolve ,
1541+ interface : Option < & WorldKey > ,
1542+ func : & Function ,
1543+ ) -> String {
1544+ let prefix = self . interface_name ( resolve, interface) ;
1545+ let name = func. name . to_snake_case ( ) . replace ( '.' , "_" ) ;
1546+
1547+ format ! ( "{prefix}_{name}" )
1548+ }
14971549}
14981550
14991551struct FunctionGenerator < ' a > {
@@ -1783,7 +1835,10 @@ for index := 0; index < int({length}); index++ {{
17831835 }
17841836
17851837 let name = func. item_name ( ) . to_upper_camel_case ( ) ;
1786- let package = format ! ( "export_{}" , interface_name( resolve, self . interface) ) ;
1838+ let package = format ! (
1839+ "export_{}" ,
1840+ self . generator. interface_name( resolve, self . interface)
1841+ ) ;
17871842
17881843 let call = match & func. kind {
17891844 FunctionKind :: Freestanding | FunctionKind :: AsyncFreestanding => {
@@ -2945,42 +3000,6 @@ const (
29453000 }
29463001}
29473002
2948- fn interface_name ( resolve : & Resolve , interface : Option < & WorldKey > ) -> String {
2949- match interface {
2950- Some ( WorldKey :: Name ( name) ) => name. to_snake_case ( ) ,
2951- Some ( WorldKey :: Interface ( id) ) => {
2952- let interface = & resolve. interfaces [ * id] ;
2953- let package = & resolve. packages [ interface. package . unwrap ( ) ] ;
2954- let package_has_multiple_versions = resolve. packages . iter ( ) . any ( |( _, p) | {
2955- p. name . namespace == package. name . namespace
2956- && p. name . name == package. name . name
2957- && p. name . version != package. name . version
2958- } ) ;
2959- let version = if package_has_multiple_versions {
2960- if let Some ( version) = & package. name . version {
2961- format ! ( "{}_" , version. to_string( ) . replace( [ '.' , '-' , '+' ] , "_" ) )
2962- } else {
2963- String :: new ( )
2964- }
2965- } else {
2966- String :: new ( )
2967- } ;
2968- let namespace = package. name . namespace . to_snake_case ( ) ;
2969- let package = package. name . name . to_snake_case ( ) ;
2970- let interface = interface. name . as_ref ( ) . unwrap ( ) . to_snake_case ( ) ;
2971- format ! ( "{namespace}_{package}_{version}{interface}" )
2972- }
2973- None => "wit_world" . into ( ) ,
2974- }
2975- }
2976-
2977- fn func_name ( resolve : & Resolve , interface : Option < & WorldKey > , func : & Function ) -> String {
2978- let prefix = interface_name ( resolve, interface) ;
2979- let name = func. name . to_snake_case ( ) . replace ( '.' , "_" ) ;
2980-
2981- format ! ( "{prefix}_{name}" )
2982- }
2983-
29843003fn wasm_type ( ty : WasmType ) -> & ' static str {
29853004 match ty {
29863005 WasmType :: I32 => "int32" ,
0 commit comments