Merge pull request #2282 from ferrous-systems/sovereign-module-of-syn · rust-lang/rust-bindgen@b5ec18e (original) (raw)

`@@ -88,7 +88,6 @@ use std::{env, iter};

`

88

88

`// Some convenient typedefs for a fast hash map and hash set.

`

89

89

`type HashMap<K, V> = ::rustc_hash::FxHashMap<K, V>;

`

90

90

`type HashSet = ::rustc_hash::FxHashSet;

`

91

``

`-

use quote::ToTokens;

`

92

91

`pub(crate) use std::collections::hash_map::Entry;

`

93

92

``

94

93

`/// Default prefix for the anon fields.

`

`@@ -2118,11 +2117,6 @@ struct BindgenOptions {

`

2118

2117

`impl ::std::panic::UnwindSafe for BindgenOptions {}

`

2119

2118

``

2120

2119

`impl BindgenOptions {

`

2121

``

`` -

/// Whether any of the enabled options requires syn.

``

2122

``

`-

fn require_syn(&self) -> bool {

`

2123

``

`-

self.sort_semantically || self.merge_extern_blocks

`

2124

``

`-

}

`

2125

``

-

2126

2120

`fn build(&mut self) {

`

2127

2121

`let mut regex_sets = [

`

2128

2122

`&mut self.allowlisted_vars,

`

`@@ -2555,112 +2549,7 @@ impl Bindings {

`

2555

2549

`parse(&mut context)?;

`

2556

2550

`}

`

2557

2551

``

2558

``

`-

let (items, options, warnings) = codegen::codegen(context);

`

2559

``

-

2560

``

`-

let module = if options.require_syn() {

`

2561

``

`-

let module_wrapped_tokens =

`

2562

``

`-

quote!(mod wrapper_for_sorting_hack { #( #items )* });

`

2563

``

-

2564

``

`-

// This syn business is a hack, for now. This means that we are re-parsing already

`

2565

``

`` -

// generated code using syn (as opposed to quote) because syn provides us more

``

2566

``

`-

// control over the elements.

`

2567

``

`` -

// One caveat is that some of the items coming from quoted output might have

``

2568

``

`` -

// multiple items within them. Hence, we have to wrap the incoming in a mod.

``

2569

``

`` -

// The two unwraps here are deliberate because

``

2570

``

`` -

// The first one won't panic because we build the mod and know it is there

``

2571

``

`-

// The second one won't panic because we know original output has something in

`

2572

``

`-

// it already.

`

2573

``

`-

let mut syn_parsed_items =

`

2574

``

`-

syn::parse2::syn::ItemMod(module_wrapped_tokens)

`

2575

``

`-

.unwrap()

`

2576

``

`-

.content

`

2577

``

`-

.unwrap()

`

2578

``

`-

.1;

`

2579

``

-

2580

``

`-

if options.merge_extern_blocks {

`

2581

``

`-

// Here we will store all the items after deduplication.

`

2582

``

`-

let mut items = Vec::new();

`

2583

``

-

2584

``

`` -

// Keep all the extern blocks in a different Vec for faster search.

``

2585

``

`-

let mut foreign_mods = Vec::syn::ItemForeignMod::new();

`

2586

``

`-

for item in syn_parsed_items {

`

2587

``

`-

match item {

`

2588

``

`-

syn::Item::ForeignMod(syn::ItemForeignMod {

`

2589

``

`-

attrs,

`

2590

``

`-

abi,

`

2591

``

`-

brace_token,

`

2592

``

`-

items: foreign_items,

`

2593

``

`-

}) => {

`

2594

``

`-

let mut exists = false;

`

2595

``

`-

for foreign_mod in &mut foreign_mods {

`

2596

``

`-

// Check if there is a extern block with the same ABI and

`

2597

``

`-

// attributes.

`

2598

``

`-

if foreign_mod.attrs == attrs &&

`

2599

``

`-

foreign_mod.abi == abi

`

2600

``

`-

{

`

2601

``

`-

// Merge the items of the two blocks.

`

2602

``

`-

foreign_mod

`

2603

``

`-

.items

`

2604

``

`-

.extend_from_slice(&foreign_items);

`

2605

``

`-

exists = true;

`

2606

``

`-

break;

`

2607

``

`-

}

`

2608

``

`-

}

`

2609

``

`-

// If no existing extern block had the same ABI and attributes, store

`

2610

``

`-

// it.

`

2611

``

`-

if !exists {

`

2612

``

`-

foreign_mods.push(syn::ItemForeignMod {

`

2613

``

`-

attrs,

`

2614

``

`-

abi,

`

2615

``

`-

brace_token,

`

2616

``

`-

items: foreign_items,

`

2617

``

`-

});

`

2618

``

`-

}

`

2619

``

`-

}

`

2620

``

`-

// If the item is not an extern block, we don't have to do anything.

`

2621

``

`-

_ => items.push(item),

`

2622

``

`-

}

`

2623

``

`-

}

`

2624

``

-

2625

``

`-

// Move all the extern blocks alongiside the rest of the items.

`

2626

``

`-

for foreign_mod in foreign_mods {

`

2627

``

`-

items.push(syn::Item::ForeignMod(foreign_mod));

`

2628

``

`-

}

`

2629

``

-

2630

``

`-

syn_parsed_items = items;

`

2631

``

`-

}

`

2632

``

-

2633

``

`-

if options.sort_semantically {

`

2634

``

`-

syn_parsed_items.sort_by_key(|item| match item {

`

2635

``

`-

syn::Item::Type(_) => 0,

`

2636

``

`-

syn::Item::Struct(_) => 1,

`

2637

``

`-

syn::Item::Const(_) => 2,

`

2638

``

`-

syn::Item::Fn(_) => 3,

`

2639

``

`-

syn::Item::Enum(_) => 4,

`

2640

``

`-

syn::Item::Union(_) => 5,

`

2641

``

`-

syn::Item::Static(_) => 6,

`

2642

``

`-

syn::Item::Trait(_) => 7,

`

2643

``

`-

syn::Item::TraitAlias(_) => 8,

`

2644

``

`-

syn::Item::Impl(_) => 9,

`

2645

``

`-

syn::Item::Mod(_) => 10,

`

2646

``

`-

syn::Item::Use(_) => 11,

`

2647

``

`-

syn::Item::Verbatim(_) => 12,

`

2648

``

`-

syn::Item::ExternCrate(_) => 13,

`

2649

``

`-

syn::Item::ForeignMod(_) => 14,

`

2650

``

`-

syn::Item::Macro(_) => 15,

`

2651

``

`-

syn::Item::Macro2(_) => 16,

`

2652

``

`-

_ => 18,

`

2653

``

`-

});

`

2654

``

`-

}

`

2655

``

-

2656

``

`-

let synful_items = syn_parsed_items

`

2657

``

`-

.into_iter()

`

2658

``

`-

.map(|item| item.into_token_stream());

`

2659

``

-

2660

``

`-

quote! { #( #synful_items )* }

`

2661

``

`-

} else {

`

2662

``

`-

quote! { #( #items )* }

`

2663

``

`-

};

`

``

2552

`+

let (module, options, warnings) = codegen::codegen(context);

`

2664

2553

``

2665

2554

`Ok(Bindings {

`

2666

2555

` options,

`