diff options
author | Christian Poveda <31802960+pvdrz@users.noreply.github.com> | 2022-10-10 09:46:26 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-10 09:46:26 -0500 |
commit | d241e9554c393ba39e18aa3ef3fc3e14175a2b08 (patch) | |
tree | e00ac5a1c686a55ed9a9288ab796e274a9a63900 /bindgen/codegen/postprocessing/merge_extern_blocks.rs | |
parent | c8d569930e006a7e0975dfbaaf5e5d591749b30a (diff) | |
parent | 4dd91ff6d72fb5df122e5957f31d1368e84d80a2 (diff) |
Merge pull request #2299 from ferrous-systems/more-robust-postprocessing
Make postprocessing more robust
Diffstat (limited to 'bindgen/codegen/postprocessing/merge_extern_blocks.rs')
-rw-r--r-- | bindgen/codegen/postprocessing/merge_extern_blocks.rs | 94 |
1 files changed, 57 insertions, 37 deletions
diff --git a/bindgen/codegen/postprocessing/merge_extern_blocks.rs b/bindgen/codegen/postprocessing/merge_extern_blocks.rs index 2b761494..05e7e9ef 100644 --- a/bindgen/codegen/postprocessing/merge_extern_blocks.rs +++ b/bindgen/codegen/postprocessing/merge_extern_blocks.rs @@ -1,46 +1,66 @@ -use syn::{Item, ItemForeignMod}; +use syn::{ + visit_mut::{visit_item_mod_mut, VisitMut}, + Item, ItemForeignMod, ItemMod, +}; -pub(super) fn merge_extern_blocks(items: &mut Vec<Item>) { - // Keep all the extern blocks in a different `Vec` for faster search. - let mut foreign_mods = Vec::<ItemForeignMod>::new(); +pub(super) fn merge_extern_blocks(item_mod: &mut ItemMod) { + Visitor.visit_item_mod_mut(item_mod) +} + +struct Visitor; - for item in std::mem::take(items) { - match item { - Item::ForeignMod(ItemForeignMod { - attrs, - abi, - brace_token, - items: foreign_items, - }) => { - let mut exists = false; - for foreign_mod in &mut foreign_mods { - // Check if there is a extern block with the same ABI and - // attributes. - if foreign_mod.attrs == attrs && foreign_mod.abi == abi { - // Merge the items of the two blocks. - foreign_mod.items.extend_from_slice(&foreign_items); - exists = true; - break; +impl VisitMut for Visitor { + fn visit_item_mod_mut(&mut self, item_mod: &mut ItemMod) { + if let Some((_, ref mut items)) = item_mod.content { + // Keep all the extern blocks in a different `Vec` for faster search. + let mut extern_blocks = Vec::<ItemForeignMod>::new(); + + for item in std::mem::take(items) { + if let Item::ForeignMod(ItemForeignMod { + attrs, + abi, + brace_token, + items: extern_block_items, + }) = item + { + let mut exists = false; + for extern_block in &mut extern_blocks { + // Check if there is a extern block with the same ABI and + // attributes. + if extern_block.attrs == attrs && + extern_block.abi == abi + { + // Merge the items of the two blocks. + extern_block + .items + .extend_from_slice(&extern_block_items); + exists = true; + break; + } } + // If no existing extern block had the same ABI and attributes, store + // it. + if !exists { + extern_blocks.push(ItemForeignMod { + attrs, + abi, + brace_token, + items: extern_block_items, + }); + } + } else { + // If the item is not an extern block, we don't have to do anything and just + // push it back. + items.push(item); } - // If no existing extern block had the same ABI and attributes, store - // it. - if !exists { - foreign_mods.push(ItemForeignMod { - attrs, - abi, - brace_token, - items: foreign_items, - }); - } } - // If the item is not an extern block, we don't have to do anything. - _ => items.push(item), + + // Move all the extern blocks alongside the rest of the items. + for extern_block in extern_blocks { + items.push(Item::ForeignMod(extern_block)); + } } - } - // Move all the extern blocks alongside the rest of the items. - for foreign_mod in foreign_mods { - items.push(Item::ForeignMod(foreign_mod)); + visit_item_mod_mut(self, item_mod) } } |