@@ -77,7 +77,7 @@ fn compile_ast(mut ast: backend::ast::Program) -> String {
77
77
let mut defined = BTreeSet :: from_iter (
78
78
vec ! [
79
79
"str" , "char" , "bool" , "JsValue" , "u8" , "i8" , "u16" , "i16" , "u32" , "i32" , "u64" , "i64" ,
80
- "usize" , "isize" , "f32" , "f64" ,
80
+ "usize" , "isize" , "f32" , "f64" , "Result" ,
81
81
] . into_iter ( )
82
82
. map ( |id| proc_macro2:: Ident :: new ( id, proc_macro2:: Span :: call_site ( ) ) ) ,
83
83
) ;
@@ -210,19 +210,38 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
210
210
) -> Result < ( ) > {
211
211
let mut add_constructor = |arguments : & [ webidl:: ast:: Argument ] , class : & str | {
212
212
let self_ty = ident_ty ( rust_ident ( & interface. name ) ) ;
213
+
213
214
let kind = backend:: ast:: ImportFunctionKind :: Method {
214
215
class : class. to_string ( ) ,
215
216
ty : self_ty. clone ( ) ,
216
217
kind : backend:: ast:: MethodKind :: Constructor ,
217
218
} ;
219
+
220
+ let structural = false ;
221
+
222
+ // Constructors aren't annotated with `[Throws]` extended attributes
223
+ // (how could they be, since they themselves are extended
224
+ // attributes?) so we must conservatively assume that they can
225
+ // always throw.
226
+ //
227
+ // From https://heycam.github.io/webidl/#Constructor (emphasis
228
+ // mine):
229
+ //
230
+ // > The prose definition of a constructor must either return an IDL
231
+ // > value of a type corresponding to the interface the
232
+ // > `[Constructor]` extended attribute appears on, **or throw an
233
+ // > exception**.
234
+ let throws = true ;
235
+
218
236
create_function (
219
237
"new" ,
220
238
arguments
221
239
. iter ( )
222
240
. map ( |arg| ( & * arg. name , & * arg. type_ , arg. variadic ) ) ,
223
241
Some ( self_ty) ,
224
242
kind,
225
- false ,
243
+ structural,
244
+ throws,
226
245
) . map ( |function| {
227
246
program. imports . push ( backend:: ast:: Import {
228
247
module : None ,
@@ -236,7 +255,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
236
255
match self {
237
256
webidl:: ast:: ExtendedAttribute :: ArgumentList (
238
257
webidl:: ast:: ArgumentListExtendedAttribute { arguments, name } ,
239
- ) if name == "Constructor" =>
258
+ )
259
+ if name == "Constructor" =>
240
260
{
241
261
add_constructor ( arguments, & interface. name ) ;
242
262
}
@@ -251,7 +271,8 @@ impl<'a> WebidlParse<&'a webidl::ast::NonPartialInterface> for webidl::ast::Exte
251
271
rhs_arguments,
252
272
rhs_name,
253
273
} ,
254
- ) if lhs_name == "NamedConstructor" =>
274
+ )
275
+ if lhs_name == "NamedConstructor" =>
255
276
{
256
277
add_constructor ( rhs_arguments, rhs_name) ;
257
278
}
@@ -322,14 +343,27 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularAttribute {
322
343
}
323
344
324
345
let is_structural = util:: is_structural ( & self . extended_attributes ) ;
346
+ let throws = util:: throws ( & self . extended_attributes ) ;
325
347
326
- create_getter ( & self . name , & self . type_ , self_name, false , is_structural)
327
- . map ( wrap_import_function)
348
+ create_getter (
349
+ & self . name ,
350
+ & self . type_ ,
351
+ self_name,
352
+ false ,
353
+ is_structural,
354
+ throws,
355
+ ) . map ( wrap_import_function)
328
356
. map ( |import| program. imports . push ( import) ) ;
329
357
330
358
if !self . read_only {
331
- create_setter ( & self . name , & self . type_ , self_name, false , is_structural)
332
- . map ( wrap_import_function)
359
+ create_setter (
360
+ & self . name ,
361
+ & self . type_ ,
362
+ self_name,
363
+ false ,
364
+ is_structural,
365
+ throws,
366
+ ) . map ( wrap_import_function)
333
367
. map ( |import| program. imports . push ( import) ) ;
334
368
}
335
369
@@ -344,14 +378,27 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticAttribute {
344
378
}
345
379
346
380
let is_structural = util:: is_structural ( & self . extended_attributes ) ;
381
+ let throws = util:: throws ( & self . extended_attributes ) ;
347
382
348
- create_getter ( & self . name , & self . type_ , self_name, true , is_structural)
349
- . map ( wrap_import_function)
383
+ create_getter (
384
+ & self . name ,
385
+ & self . type_ ,
386
+ self_name,
387
+ true ,
388
+ is_structural,
389
+ throws,
390
+ ) . map ( wrap_import_function)
350
391
. map ( |import| program. imports . push ( import) ) ;
351
392
352
393
if !self . read_only {
353
- create_setter ( & self . name , & self . type_ , self_name, true , is_structural)
354
- . map ( wrap_import_function)
394
+ create_setter (
395
+ & self . name ,
396
+ & self . type_ ,
397
+ self_name,
398
+ true ,
399
+ is_structural,
400
+ throws,
401
+ ) . map ( wrap_import_function)
355
402
. map ( |import| program. imports . push ( import) ) ;
356
403
}
357
404
@@ -365,12 +412,15 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::RegularOperation {
365
412
return Ok ( ( ) ) ;
366
413
}
367
414
415
+ let throws = util:: throws ( & self . extended_attributes ) ;
416
+
368
417
create_basic_method (
369
418
& self . arguments ,
370
419
self . name . as_ref ( ) ,
371
420
& self . return_type ,
372
421
self_name,
373
422
false ,
423
+ throws,
374
424
) . map ( wrap_import_function)
375
425
. map ( |import| program. imports . push ( import) ) ;
376
426
@@ -384,12 +434,15 @@ impl<'a> WebidlParse<&'a str> for webidl::ast::StaticOperation {
384
434
return Ok ( ( ) ) ;
385
435
}
386
436
437
+ let throws = util:: throws ( & self . extended_attributes ) ;
438
+
387
439
create_basic_method (
388
440
& self . arguments ,
389
441
self . name . as_ref ( ) ,
390
442
& self . return_type ,
391
443
self_name,
392
444
true ,
445
+ throws,
393
446
) . map ( wrap_import_function)
394
447
. map ( |import| program. imports . push ( import) ) ;
395
448
0 commit comments