diff options
author | Christian Poveda <31802960+pvdrz@users.noreply.github.com> | 2022-09-27 14:11:39 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-09-27 14:11:39 -0500 |
commit | b5ec18e37447467e158180bc189e8caa8a861156 (patch) | |
tree | e3a77f2d59ded3492055afb10ad6699fd25e3667 /src/codegen/postprocessing/merge_extern_blocks.rs | |
parent | 2963d057ee3df5dc576ee41c597919ed8a28bd68 (diff) | |
parent | ddb319ce3579b687cdd06d934ac40c253e96221f (diff) |
Merge pull request #2282 from ferrous-systems/sovereign-module-of-syn
Move codegen postprocessing to its own 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)); + } +} |