1
- use id_arena:: Id ;
2
-
3
1
use crate :: {
4
- Enum , Flags , Interface , InterfaceItem , Package , PackageName , Params , Record , Resource ,
2
+ Enum , Flags , Ident , Interface , InterfaceItem , Package , PackageName , Params , Record , Resource ,
5
3
ResourceFunc , Result_ , Results , StandaloneFunc , Tuple , Type , TypeDef , TypeDefKind , Variant ,
6
4
World , WorldItem ,
7
5
} ;
6
+ use id_arena:: Id ;
7
+ use wit_parser:: PackageId ;
8
8
9
9
pub fn packages_from_parsed ( resolve : & wit_parser:: Resolve ) -> Vec < Package > {
10
10
let converter = Converter :: new ( resolve) ;
@@ -24,23 +24,24 @@ impl<'a> Converter<'a> {
24
24
self . resolve
25
25
. packages
26
26
. iter ( )
27
- . map ( |( _ , p) | self . convert_package ( p) )
27
+ . map ( |( p_id , p) | self . convert_package ( p_id , p) )
28
28
. collect ( )
29
29
}
30
30
31
- fn convert_package ( & self , package : & wit_parser:: Package ) -> Package {
31
+ fn convert_package ( & self , package_id : PackageId , package : & wit_parser:: Package ) -> Package {
32
32
let mut output = Package :: new ( self . convert_package_name ( & package. name ) ) ;
33
33
for ( _, id) in & package. interfaces {
34
34
let interface = self . resolve . interfaces . get ( * id) . unwrap ( ) ;
35
35
output. interface ( self . convert_interface (
36
+ package_id,
36
37
interface,
37
38
None ,
38
39
wit_parser:: TypeOwner :: Interface ( * id) ,
39
40
) ) ;
40
41
}
41
42
for ( _, id) in & package. worlds {
42
43
let world = self . resolve . worlds . get ( * id) . unwrap ( ) ;
43
- output. world ( self . convert_world ( world, wit_parser:: TypeOwner :: World ( * id) ) ) ;
44
+ output. world ( self . convert_world ( package_id , world, wit_parser:: TypeOwner :: World ( * id) ) ) ;
44
45
}
45
46
output
46
47
}
@@ -53,33 +54,30 @@ impl<'a> Converter<'a> {
53
54
)
54
55
}
55
56
56
- fn convert_world ( & self , world : & wit_parser:: World , owner : wit_parser:: TypeOwner ) -> World {
57
+ fn convert_world (
58
+ & self ,
59
+ package_id : PackageId ,
60
+ world : & wit_parser:: World ,
61
+ owner : wit_parser:: TypeOwner ,
62
+ ) -> World {
57
63
let mut output = World :: new ( world. name . clone ( ) ) ;
58
64
59
65
for ( key, item) in & world. imports {
60
66
match item {
61
67
wit_parser:: WorldItem :: Interface { id, .. } => {
62
68
let interface = self . resolve . interfaces . get ( * id) . unwrap ( ) ;
63
- output. item ( match & interface. name {
64
- Some ( name) => {
65
- // standalone
66
- WorldItem :: named_interface_import ( name. clone ( ) )
67
- }
68
- None => {
69
- // inlined
70
- let name = match key {
71
- wit_parser:: WorldKey :: Name ( name) => name. clone ( ) ,
72
- wit_parser:: WorldKey :: Interface ( _) => {
73
- unreachable ! ( "inlined interface must have a kye name" )
74
- }
75
- } ;
76
- WorldItem :: inline_interface_import ( self . convert_interface (
77
- interface,
78
- Some ( name) ,
79
- owner,
80
- ) )
81
- }
82
- } ) ;
69
+ let ident = self . interface_ident ( package_id, Some ( key) , interface) ;
70
+
71
+ if interface. name . is_some ( ) {
72
+ output. item ( WorldItem :: named_interface_import ( ident) )
73
+ } else {
74
+ output. item ( WorldItem :: inline_interface_import ( self . convert_interface (
75
+ package_id,
76
+ interface,
77
+ Some ( ident) ,
78
+ owner,
79
+ ) ) )
80
+ }
83
81
}
84
82
wit_parser:: WorldItem :: Function ( func) => {
85
83
if let Some ( func) = self . standalone_func_convert ( func) {
@@ -95,26 +93,17 @@ impl<'a> Converter<'a> {
95
93
match item {
96
94
wit_parser:: WorldItem :: Interface { id, .. } => {
97
95
let interface = self . resolve . interfaces . get ( * id) . unwrap ( ) ;
98
- output. item ( match & interface. name {
99
- Some ( name) => {
100
- // standalone
101
- WorldItem :: named_interface_export ( name. clone ( ) )
102
- }
103
- None => {
104
- // inlined
105
- let name = match key {
106
- wit_parser:: WorldKey :: Name ( name) => name. clone ( ) ,
107
- wit_parser:: WorldKey :: Interface ( _) => {
108
- unreachable ! ( "inlined interface must have a kye name" )
109
- }
110
- } ;
111
- WorldItem :: inline_interface_export ( self . convert_interface (
112
- interface,
113
- Some ( name) ,
114
- owner,
115
- ) )
116
- }
117
- } ) ;
96
+ let ident = self . interface_ident ( package_id, Some ( key) , interface) ;
97
+ if interface. name . is_some ( ) {
98
+ output. item ( WorldItem :: named_interface_export ( ident) ) ;
99
+ } else {
100
+ output. item ( WorldItem :: inline_interface_export ( self . convert_interface (
101
+ package_id,
102
+ interface,
103
+ Some ( ident) ,
104
+ owner,
105
+ ) ) ) ;
106
+ }
118
107
}
119
108
wit_parser:: WorldItem :: Function ( func) => {
120
109
if let Some ( func) = self . standalone_func_convert ( func) {
@@ -132,15 +121,17 @@ impl<'a> Converter<'a> {
132
121
133
122
fn convert_interface (
134
123
& self ,
124
+ package_id : PackageId ,
135
125
interface : & wit_parser:: Interface ,
136
- inlined_name : Option < String > ,
126
+ inlined_name : Option < Ident > ,
137
127
owner : wit_parser:: TypeOwner ,
138
128
) -> Interface {
139
- let mut output = Interface :: new ( interface. name . clone ( ) . unwrap_or_else ( || {
140
- inlined_name
141
- . clone ( )
142
- . expect ( "inlined interface must pass in inlined_name" )
143
- } ) ) ;
129
+ let mut output =
130
+ Interface :: new ( interface. name . clone ( ) . map ( Ident :: new) . unwrap_or_else ( || {
131
+ inlined_name
132
+ . clone ( )
133
+ . expect ( "inlined interface must pass in inlined_name" )
134
+ } ) ) ;
144
135
145
136
for ( _, func) in & interface. functions {
146
137
if let Some ( func) = self . standalone_func_convert ( func) {
@@ -166,24 +157,21 @@ impl<'a> Converter<'a> {
166
157
output. item ( InterfaceItem :: TypeDef ( type_def) ) ;
167
158
}
168
159
} else {
169
- let interface_name = match underlying_type_def. owner {
170
- wit_parser:: TypeOwner :: Interface ( id) => self
171
- . resolve
172
- . interfaces
173
- . get ( id)
174
- . unwrap ( )
175
- . name
176
- . clone ( )
177
- . expect ( "can't use type from inline interface" ) ,
160
+ let interface_ident = match underlying_type_def. owner {
161
+ wit_parser:: TypeOwner :: Interface ( id) => self . interface_ident (
162
+ package_id,
163
+ None ,
164
+ self . resolve . interfaces . get ( id) . unwrap ( ) ,
165
+ ) ,
178
166
_ => panic ! ( "Type not part of an interface" ) ,
179
167
} ;
180
168
let local_type_name = type_def. name . clone ( ) . unwrap ( ) ;
181
169
let underlying_local_type_name = underlying_type_def. name . clone ( ) . unwrap ( ) ;
182
170
if underlying_local_type_name == local_type_name {
183
- output. use_type ( interface_name , local_type_name, None ) ;
171
+ output. use_type ( interface_ident , local_type_name, None ) ;
184
172
} else {
185
173
output. use_type (
186
- interface_name ,
174
+ interface_ident ,
187
175
underlying_local_type_name,
188
176
Some ( local_type_name. into ( ) ) ,
189
177
) ;
@@ -488,6 +476,51 @@ impl<'a> Converter<'a> {
488
476
}
489
477
output
490
478
}
479
+
480
+ fn interface_ident (
481
+ & self ,
482
+ package_id : PackageId ,
483
+ world_key : Option < & wit_parser:: WorldKey > ,
484
+ interface : & wit_parser:: Interface ,
485
+ ) -> Ident {
486
+ match & interface. name {
487
+ Some ( name) => {
488
+ // Standalone
489
+ if interface. package == Some ( package_id) {
490
+ Ident :: new ( name. clone ( ) )
491
+ } else {
492
+ let package = interface
493
+ . package
494
+ . map ( |package_id| self . resolve . packages . get ( package_id) . unwrap ( ) ) ;
495
+
496
+ match package {
497
+ Some ( package) => Ident :: new ( format ! (
498
+ "{}:{}/{}{}" ,
499
+ package. name. namespace,
500
+ package. name. name,
501
+ name,
502
+ package
503
+ . name
504
+ . version
505
+ . as_ref( )
506
+ . map( |version| format!( "@{}" , version) )
507
+ . unwrap_or_else( || "" . to_string( ) )
508
+ ) ) ,
509
+ None => Ident :: new ( name. clone ( ) ) ,
510
+ }
511
+ }
512
+ }
513
+ None => match world_key {
514
+ Some ( world_key) => match world_key {
515
+ wit_parser:: WorldKey :: Name ( name) => Ident :: new ( name. clone ( ) ) ,
516
+ wit_parser:: WorldKey :: Interface ( _) => {
517
+ unreachable ! ( "inlined interface must have a world key name" )
518
+ }
519
+ } ,
520
+ None => panic ! ( "inlined interface requires a world key" ) ,
521
+ } ,
522
+ }
523
+ }
491
524
}
492
525
493
526
fn clean_func_name ( resource_name : & str , method_name : & str ) -> String {
0 commit comments