@@ -25,22 +25,23 @@ use crate::generator::{
25
25
use crate :: idl_type:: ToIdlType ;
26
26
use crate :: traverse:: TraverseType ;
27
27
use crate :: util:: {
28
- camel_case_ident, is_structural, read_dir , shouty_snake_case_ident , snake_case_ident , throws ,
29
- webidl_const_v_to_backend_const_v, TypePosition ,
28
+ camel_case_ident, is_structural, is_type_unstable , read_dir , shouty_snake_case_ident ,
29
+ snake_case_ident , throws , webidl_const_v_to_backend_const_v, TypePosition ,
30
30
} ;
31
31
use anyhow:: Context ;
32
32
use anyhow:: Result ;
33
33
use proc_macro2:: { Ident , TokenStream } ;
34
34
use quote:: ToTokens ;
35
35
use sourcefile:: SourceFile ;
36
- use std:: collections:: { BTreeMap , BTreeSet } ;
36
+ use std:: collections:: { BTreeMap , BTreeSet , HashSet } ;
37
37
use std:: ffi:: OsStr ;
38
38
use std:: fmt;
39
39
use std:: fs;
40
40
use std:: path:: { Path , PathBuf } ;
41
41
use std:: process:: Command ;
42
42
use wasm_bindgen_backend:: util:: rust_ident;
43
43
use weedle:: attribute:: ExtendedAttributeList ;
44
+ use weedle:: common:: Identifier ;
44
45
use weedle:: dictionary:: DictionaryMember ;
45
46
use weedle:: interface:: InterfaceMember ;
46
47
use weedle:: Parse ;
@@ -126,6 +127,22 @@ fn parse(
126
127
definitions. first_pass ( & mut first_pass_record, ApiStability :: Stable ) ?;
127
128
128
129
let unstable_definitions = parse_source ( unstable_source) ?;
130
+
131
+ // Gather unstable type Identifiers so that stable APIs can be downgraded
132
+ // to unstable if they accept one of these types
133
+ let unstable_types: HashSet < Identifier > = unstable_definitions
134
+ . iter ( )
135
+ . flat_map ( |definition| {
136
+ use weedle:: Definition :: * ;
137
+ match definition {
138
+ Dictionary ( v) => Some ( v. identifier ) ,
139
+ Enum ( v) => Some ( v. identifier ) ,
140
+ Interface ( v) => Some ( v. identifier ) ,
141
+ _ => None ,
142
+ }
143
+ } )
144
+ . collect ( ) ;
145
+
129
146
unstable_definitions. first_pass ( & mut first_pass_record, ApiStability :: Unstable ) ?;
130
147
131
148
let mut types: BTreeMap < String , Program > = BTreeMap :: new ( ) ;
@@ -138,7 +155,14 @@ fn parse(
138
155
for ( js_name, d) in first_pass_record. dictionaries . iter ( ) {
139
156
let name = rust_ident ( & camel_case_ident ( js_name) ) ;
140
157
let program = types. entry ( name. to_string ( ) ) . or_default ( ) ;
141
- first_pass_record. append_dictionary ( & options, program, name, js_name. to_string ( ) , d) ;
158
+ first_pass_record. append_dictionary (
159
+ & options,
160
+ program,
161
+ name,
162
+ js_name. to_string ( ) ,
163
+ d,
164
+ & unstable_types,
165
+ ) ;
142
166
}
143
167
for ( js_name, n) in first_pass_record. namespaces . iter ( ) {
144
168
let name = rust_ident ( & snake_case_ident ( js_name) ) ;
@@ -148,7 +172,14 @@ fn parse(
148
172
for ( js_name, d) in first_pass_record. interfaces . iter ( ) {
149
173
let name = rust_ident ( & camel_case_ident ( js_name) ) ;
150
174
let program = types. entry ( name. to_string ( ) ) . or_default ( ) ;
151
- first_pass_record. append_interface ( & options, program, name, js_name. to_string ( ) , d) ;
175
+ first_pass_record. append_interface (
176
+ & options,
177
+ program,
178
+ name,
179
+ js_name. to_string ( ) ,
180
+ & unstable_types,
181
+ d,
182
+ ) ;
152
183
}
153
184
for ( js_name, d) in first_pass_record. callback_interfaces . iter ( ) {
154
185
let name = rust_ident ( & camel_case_ident ( js_name) ) ;
@@ -252,6 +283,7 @@ impl<'src> FirstPassRecord<'src> {
252
283
name : Ident ,
253
284
js_name : String ,
254
285
data : & first_pass:: DictionaryData < ' src > ,
286
+ unstable_types : & HashSet < Identifier > ,
255
287
) {
256
288
let def = match data. definition {
257
289
Some ( def) => def,
@@ -264,7 +296,7 @@ impl<'src> FirstPassRecord<'src> {
264
296
265
297
let mut fields = Vec :: new ( ) ;
266
298
267
- if !self . append_dictionary_members ( & js_name, & mut fields) {
299
+ if !self . append_dictionary_members ( & js_name, & mut fields, unstable , unstable_types ) {
268
300
return ;
269
301
}
270
302
@@ -278,15 +310,21 @@ impl<'src> FirstPassRecord<'src> {
278
310
. to_tokens ( & mut program. tokens ) ;
279
311
}
280
312
281
- fn append_dictionary_members ( & self , dict : & ' src str , dst : & mut Vec < DictionaryField > ) -> bool {
313
+ fn append_dictionary_members (
314
+ & self ,
315
+ dict : & ' src str ,
316
+ dst : & mut Vec < DictionaryField > ,
317
+ unstable : bool ,
318
+ unstable_types : & HashSet < Identifier > ,
319
+ ) -> bool {
282
320
let dict_data = & self . dictionaries [ & dict] ;
283
321
let definition = dict_data. definition . unwrap ( ) ;
284
322
285
323
// > The order of the dictionary members on a given dictionary is
286
324
// > such that inherited dictionary members are ordered before
287
325
// > non-inherited members ...
288
326
if let Some ( parent) = & definition. inheritance {
289
- if !self . append_dictionary_members ( parent. identifier . 0 , dst) {
327
+ if !self . append_dictionary_members ( parent. identifier . 0 , dst, unstable , unstable_types ) {
290
328
return false ;
291
329
}
292
330
}
@@ -299,7 +337,7 @@ impl<'src> FirstPassRecord<'src> {
299
337
let members = definition. members . body . iter ( ) ;
300
338
let partials = dict_data. partials . iter ( ) . flat_map ( |d| & d. members . body ) ;
301
339
for member in members. chain ( partials) {
302
- match self . dictionary_field ( member) {
340
+ match self . dictionary_field ( member, unstable , unstable_types ) {
303
341
Some ( f) => dst. push ( f) ,
304
342
None => {
305
343
log:: warn!(
@@ -321,7 +359,17 @@ impl<'src> FirstPassRecord<'src> {
321
359
return true ;
322
360
}
323
361
324
- fn dictionary_field ( & self , field : & ' src DictionaryMember < ' src > ) -> Option < DictionaryField > {
362
+ fn dictionary_field (
363
+ & self ,
364
+ field : & ' src DictionaryMember < ' src > ,
365
+ unstable : bool ,
366
+ unstable_types : & HashSet < Identifier > ,
367
+ ) -> Option < DictionaryField > {
368
+ let unstable_override = match unstable {
369
+ true => true ,
370
+ false => is_type_unstable ( & field. type_ , unstable_types) ,
371
+ } ;
372
+
325
373
// use argument position now as we're just binding setters
326
374
let ty = field
327
375
. type_
@@ -376,6 +424,7 @@ impl<'src> FirstPassRecord<'src> {
376
424
name : rust_ident ( & snake_case_ident ( field. identifier . 0 ) ) ,
377
425
js_name : field. identifier . 0 . to_string ( ) ,
378
426
ty,
427
+ unstable : unstable_override,
379
428
} )
380
429
}
381
430
@@ -424,7 +473,7 @@ impl<'src> FirstPassRecord<'src> {
424
473
}
425
474
}
426
475
427
- for x in self . create_imports ( None , id, data, false ) {
476
+ for x in self . create_imports ( None , id, data, false , & HashSet :: new ( ) ) {
428
477
functions. push ( Function {
429
478
name : x. name ,
430
479
js_name : x. js_name ,
@@ -465,6 +514,7 @@ impl<'src> FirstPassRecord<'src> {
465
514
program : & mut Program ,
466
515
name : Ident ,
467
516
js_name : String ,
517
+ unstable_types : & HashSet < Identifier > ,
468
518
data : & InterfaceData < ' src > ,
469
519
) {
470
520
let unstable = data. stability . is_unstable ( ) ;
@@ -505,7 +555,7 @@ impl<'src> FirstPassRecord<'src> {
505
555
}
506
556
507
557
for ( id, op_data) in data. operations . iter ( ) {
508
- self . member_operation ( & mut methods, data, id, op_data) ;
558
+ self . member_operation ( & mut methods, data, id, op_data, unstable_types ) ;
509
559
}
510
560
511
561
for mixin_data in self . all_mixins ( & js_name) {
@@ -533,7 +583,7 @@ impl<'src> FirstPassRecord<'src> {
533
583
}
534
584
535
585
for ( id, op_data) in mixin_data. operations . iter ( ) {
536
- self . member_operation ( & mut methods, data, id, op_data) ;
586
+ self . member_operation ( & mut methods, data, id, op_data, unstable_types ) ;
537
587
}
538
588
}
539
589
@@ -625,11 +675,12 @@ impl<'src> FirstPassRecord<'src> {
625
675
data : & InterfaceData < ' src > ,
626
676
id : & OperationId < ' src > ,
627
677
op_data : & OperationData < ' src > ,
678
+ unstable_types : & HashSet < Identifier > ,
628
679
) {
629
680
let attrs = data. definition_attributes ;
630
681
let unstable = data. stability . is_unstable ( ) ;
631
682
632
- for method in self . create_imports ( attrs, id, op_data, unstable) {
683
+ for method in self . create_imports ( attrs, id, op_data, unstable, unstable_types ) {
633
684
methods. push ( method) ;
634
685
}
635
686
}
@@ -663,6 +714,7 @@ impl<'src> FirstPassRecord<'src> {
663
714
. to_syn_type ( pos)
664
715
. unwrap ( )
665
716
. unwrap ( ) ,
717
+ unstable : false ,
666
718
} )
667
719
}
668
720
_ => {
0 commit comments