diff options
author | Christian Poveda <christian.poveda@ferrous-systems.com> | 2022-09-27 13:43:33 -0500 |
---|---|---|
committer | Christian Poveda <christian.poveda@ferrous-systems.com> | 2022-09-27 13:43:33 -0500 |
commit | ddb319ce3579b687cdd06d934ac40c253e96221f (patch) | |
tree | e3a77f2d59ded3492055afb10ad6699fd25e3667 /src/codegen/postprocessing/merge_extern_blocks.rs | |
parent | 06a6479e9e6fe9b556a54b3d7f28c23b1268b048 (diff) |
split `processing` module
Diffstat (limited to 'src/codegen/postprocessing/merge_extern_blocks.rs')
-rw-r--r-- | src/codegen/postprocessing/merge_extern_blocks.rs | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/src/codegen/postprocessing/merge_extern_blocks.rs b/src/codegen/postprocessing/merge_extern_blocks.rs new file mode 100644 index 00000000..2b761494 --- /dev/null +++ b/src/codegen/postprocessing/merge_extern_blocks.rs @@ -0,0 +1,46 @@ +use syn::{Item, ItemForeignMod}; + +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(); + + 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; + } + } + // 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 foreign_mod in foreign_mods { + items.push(Item::ForeignMod(foreign_mod)); + } +} |