Skip to content

Commit 877c31c

Browse files
committed
web-sys: Don't remove dictionaries if required fields are removed
This commit updates the conditional binding generation for dictionaries to ensure that a dictionary is not entirely removed if any of its required fields are removed. If a required field is removed, however, it cannot be constructed, so the constructor is removed.
1 parent 618b5d3 commit 877c31c

File tree

4 files changed

+22
-17
lines changed

4 files changed

+22
-17
lines changed

crates/backend/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ pub enum ConstValue {
292292
pub struct Dictionary {
293293
pub name: Ident,
294294
pub fields: Vec<DictionaryField>,
295+
pub ctor: bool,
295296
}
296297

297298
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]

crates/backend/src/codegen.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,18 @@ impl ToTokens for ast::Dictionary {
12821282
let required_names2 = required_names;
12831283
let required_names3 = required_names;
12841284

1285+
let ctor = if self.ctor {
1286+
quote! {
1287+
pub fn new(#(#required_names: #required_types),*) -> #name {
1288+
let mut _ret = #name { obj: ::js_sys::Object::new() };
1289+
#(_ret.#required_names2(#required_names3);)*
1290+
return _ret
1291+
}
1292+
}
1293+
} else {
1294+
quote! {}
1295+
};
1296+
12851297
let const_name = Ident::new(&format!("_CONST_{}", name), Span::call_site());
12861298
(quote! {
12871299
#[derive(Clone, Debug)]
@@ -1293,12 +1305,7 @@ impl ToTokens for ast::Dictionary {
12931305

12941306
#[allow(clippy::all)]
12951307
impl #name {
1296-
pub fn new(#(#required_names: #required_types),*) -> #name {
1297-
let mut _ret = #name { obj: ::js_sys::Object::new() };
1298-
#(_ret.#required_names2(#required_names3);)*
1299-
return _ret
1300-
}
1301-
1308+
#ctor
13021309
#methods
13031310
}
13041311

crates/backend/src/defined.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -348,25 +348,20 @@ impl RemoveUndefinedImports for ast::Program {
348348
let mut changed = self.imports.remove_undefined_imports(is_defined);
349349
changed = self.consts.remove_undefined_imports(is_defined) || changed;
350350

351-
let mut dictionaries_to_remove = Vec::new();
352-
for (i, dictionary) in self.dictionaries.iter_mut().enumerate() {
351+
for dictionary in self.dictionaries.iter_mut() {
353352
let num_required =
354353
|dict: &ast::Dictionary| dict.fields.iter().filter(|f| f.required).count();
355354
let before = num_required(dictionary);
356355
changed = dictionary.fields.remove_undefined_imports(is_defined) || changed;
356+
357+
// If a required field was removed we can no longer construct this
358+
// dictionary so disable the constructor.
357359
if before != num_required(dictionary) {
358-
log::warn!(
359-
"removing {} due to a required field being removed",
360-
dictionary.name
361-
);
362-
dictionaries_to_remove.push(i);
360+
dictionary.ctor = false;
363361
}
364362
}
365-
for i in dictionaries_to_remove.iter().rev() {
366-
self.dictionaries.swap_remove(*i);
367-
}
368363

369-
changed || dictionaries_to_remove.len() > 0
364+
changed
370365
}
371366
}
372367

crates/webidl/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ impl<'src> FirstPassRecord<'src> {
317317
program.dictionaries.push(ast::Dictionary {
318318
name: rust_ident(&camel_case_ident(def.identifier.0)),
319319
fields,
320+
ctor: true,
320321
});
321322
}
322323

@@ -784,6 +785,7 @@ impl<'src> FirstPassRecord<'src> {
784785
program.dictionaries.push(ast::Dictionary {
785786
name: rust_ident(&camel_case_ident(item.definition.identifier.0)),
786787
fields,
788+
ctor: true,
787789
});
788790
}
789791
}

0 commit comments

Comments
 (0)