Skip to content

Commit

Permalink
config
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr committed Jan 8, 2025
1 parent 6e75816 commit 0aa6ece
Show file tree
Hide file tree
Showing 21 changed files with 142 additions and 124 deletions.
38 changes: 38 additions & 0 deletions crates/libs/bindgen/src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use super::*;

use std::sync::atomic::{AtomicPtr, Ordering};

static CONFIG: AtomicPtr<Config> = AtomicPtr::new(std::ptr::null_mut());

pub fn config() -> &'static Config {
let ptr = CONFIG.load(Ordering::Relaxed);

if ptr.is_null() {
panic!();
} else {
unsafe { &*ptr }
}
}

pub struct Config {
pub types: TypeMap,
pub references: References,
pub output: String,
pub flat: bool,
pub no_allow: bool,
pub no_comment: bool,
pub no_core: bool,
pub no_toml: bool,
pub package: bool,
pub rustfmt: String,
pub sys: bool,
pub implement: bool,
pub derive: Derive,
}

impl Config {
pub fn init(value: Self) {
let config = Box::leak(Box::new(value));
CONFIG.store(config, Ordering::Relaxed);
}
}
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/derive_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use super::*;
pub struct DeriveWriter(BTreeSet<String>);

impl DeriveWriter {
pub fn new(writer: &Writer, type_name: TypeName) -> Self {
pub fn new(type_name: TypeName) -> Self {
let mut derive = BTreeSet::new();
derive.extend(writer.config.derive.get(type_name));
derive.extend(config().derive.get(type_name));
Self(derive)
}

Expand Down
31 changes: 6 additions & 25 deletions crates/libs/bindgen/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
clippy::needless_doctest_main
)]

mod config;
mod derive;
mod derive_writer;
mod filter;
Expand All @@ -24,6 +25,7 @@ mod value;
mod winmd;
mod writer;

use config::*;
use derive::*;
use derive_writer::*;
use filter::*;
Expand All @@ -47,22 +49,6 @@ use writer::*;
mod method_names;
use method_names::*;

struct Config {
pub types: TypeMap,
pub references: References,
pub output: String,
pub flat: bool,
pub no_allow: bool,
pub no_comment: bool,
pub no_core: bool,
pub no_toml: bool,
pub package: bool,
pub rustfmt: String,
pub sys: bool,
pub implement: bool,
pub derive: Derive,
}

/// The Windows code generator.
#[track_caller]
pub fn bindgen<I, S>(args: I)
Expand Down Expand Up @@ -165,7 +151,7 @@ where
let types = TypeMap::filter(&filter, &references);
let derive = Derive::new(&types, &derive);

let config = Box::leak(Box::new(Config {
Config::init(Config {
types,
flat,
references,
Expand All @@ -179,16 +165,11 @@ where
output,
sys,
implement,
}));
});

let tree = TypeTree::new(&config.types);

let writer = Writer {
config,
namespace: "",
};
let writer = Writer { namespace: "" };

writer.write(tree)
writer.write(TypeTree::new())
}

enum ArgKind {
Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/type_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,19 @@ impl TypeMap {
)
}

pub fn included(&self, config: &Config) -> bool {
pub fn included(&self) -> bool {
self.0.iter().all(|(tn, _)| {
// An empty namespace covers core types like `HRESULT`. This way we don't exclude methods
// that depend on core types that aren't explicitly included in the filter.
if tn.namespace().is_empty() {
return true;
}

if config.types.contains_key(tn) {
if config().types.contains_key(tn) {
return true;
}

if config.references.contains(*tn).is_some() {
if config().references.contains(*tn).is_some() {
return true;
}

Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/type_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ pub struct TypeTree {
}

impl TypeTree {
pub fn new(dependencies: &TypeMap) -> Self {
pub fn new() -> Self {
let mut tree = Self::with_namespace("");

for (tn, types) in dependencies.iter() {
for (tn, types) in config().types.iter() {
let tree = tree.insert_namespace(tn.namespace());
types.iter().for_each(|ty| {
tree.types.insert(ty.clone());
Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/types/class.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ impl Class {
let name = to_ident(type_name.name());
let mut dependencies = TypeMap::new();

if writer.config.package {
if config().package {
self.dependencies(&mut dependencies);
}

Expand All @@ -38,7 +38,7 @@ impl Class {
let mut virtual_names = MethodNames::new();

for method in interface
.get_methods(writer)
.get_methods()
.iter()
.filter_map(|method| match &method {
MethodOrName::Method(method) => Some(method),
Expand All @@ -47,7 +47,7 @@ impl Class {
{
let mut difference = TypeMap::new();

if writer.config.package {
if config().package {
difference = method.dependencies.difference(&dependencies);
}

Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/types/cpp_const.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ impl CppConst {

let mut dependencies = TypeMap::new();

if writer.config.package {
if config().package {
self.dependencies(&mut dependencies);
}

Expand All @@ -52,7 +52,7 @@ impl CppConst {
let crate_name = writer.write_core();
let value = constant.value().write();

// TODO: if writer.config.no_core then write these literals out as byte strings?
// TODO: if config().no_core then write these literals out as byte strings?
if is_ansi_encoding(self.field) {
quote! {
#cfg
Expand Down Expand Up @@ -94,7 +94,7 @@ impl CppConst {
value = quote! { #value as _ };
}

if writer.config.sys || field_ty == Type::Bool {
if config().sys || field_ty == Type::Bool {
quote! {
#cfg
pub const #name: #ty = #value;
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/types/cpp_delegate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ impl CppDelegate {

let mut dependencies = TypeMap::new();

if writer.config.package {
if config().package {
self.dependencies(&mut dependencies);
}

Expand Down
8 changes: 4 additions & 4 deletions crates/libs/bindgen/src/types/cpp_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ impl CppEnum {
let tn = self.def.type_name();
let is_scoped = self.def.has_attribute("ScopedEnumAttribute");

if !is_scoped && writer.config.sys {
if !is_scoped && config().sys {
return writer.write_cpp_handle(self.def);
}

let name = to_ident(tn.name());
let underlying_type = self.def.underlying_type().write_name(writer);

let mut derive = DeriveWriter::new(writer, tn);
let mut derive = DeriveWriter::new(tn);
derive.extend(["Copy", "Clone"]);

if !writer.config.sys {
if !config().sys {
derive.extend(["Default", "Debug", "PartialEq", "Eq"]);
}

Expand All @@ -67,7 +67,7 @@ impl CppEnum {
quote! {}
};

let flags = if writer.config.sys || !self.def.has_attribute("FlagsAttribute") {
let flags = if config().sys || !self.def.has_attribute("FlagsAttribute") {
quote! {}
} else {
quote! {
Expand Down
16 changes: 8 additions & 8 deletions crates/libs/bindgen/src/types/cpp_fn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ impl CppFn {

let return_sig = writer.write_return_sig(self.method, &signature, underlying_types);

let vararg =
if writer.config.sys && signature.call_flags.contains(MethodCallAttributes::VARARG) {
quote! { , ... }
} else {
quote! {}
};
let vararg = if config().sys && signature.call_flags.contains(MethodCallAttributes::VARARG)
{
quote! { , ... }
} else {
quote! {}
};

link_fmt(quote! {
windows_targets::link!(#library #abi #symbol fn #name(#(#params),* #vararg) #return_sig);
Expand All @@ -79,14 +79,14 @@ impl CppFn {
let signature = self.method.signature(self.namespace, &[]);
let mut dependencies = TypeMap::new();

if writer.config.package {
if config().package {
self.dependencies(&mut dependencies);
}

let link = self.write_link(writer, false);
let cfg = writer.write_cfg(self.method, self.namespace, &dependencies, false);
let window_long = self.write_window_long();
if writer.config.sys {
if config().sys {
return quote! {
#cfg
#link
Expand Down
28 changes: 14 additions & 14 deletions crates/libs/bindgen/src/types/cpp_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ impl CppInterface {
self.def.type_name()
}

pub fn get_methods(&self, writer: &Writer) -> Vec<CppMethodOrName> {
pub fn get_methods(&self) -> Vec<CppMethodOrName> {
let namespace = self.def.namespace();

self.def
.methods()
.map(|def| {
let method = CppMethod::new(def, namespace);
if method.dependencies.included(writer.config) {
if method.dependencies.included() {
CppMethodOrName::Method(method)
} else {
CppMethodOrName::Name(method.def.name())
Expand All @@ -45,14 +45,14 @@ impl CppInterface {
}

pub fn write(&self, writer: &Writer) -> TokenStream {
let methods = self.get_methods(writer);
let methods = self.get_methods();

let base_interfaces = self.base_interfaces();
let has_unknown_base = matches!(base_interfaces.first(), Some(Type::IUnknown));

let mut dependencies = TypeMap::new();

if writer.config.package {
if config().package {
self.dependencies(&mut dependencies);
}

Expand Down Expand Up @@ -82,7 +82,7 @@ impl CppInterface {
CppMethodOrName::Method(method) => {
let mut difference = TypeMap::new();

if writer.config.package {
if config().package {
difference = method.dependencies.difference(&dependencies);
}

Expand Down Expand Up @@ -122,10 +122,10 @@ impl CppInterface {
}
};

if writer.config.sys {
if config().sys {
let mut result = quote! {};

if !writer.config.package {
if !config().package {
if has_unknown_base {
if let Some(guid) = self.def.guid_attribute() {
let name: TokenStream = format!("IID_{}", self.def.name()).into();
Expand Down Expand Up @@ -193,7 +193,7 @@ impl CppInterface {
}) {
let mut difference = TypeMap::new();

if writer.config.package {
if config().package {
difference = method.dependencies.difference(&dependencies);
}

Expand All @@ -220,19 +220,19 @@ impl CppInterface {

let impl_name: TokenStream = format!("{}_Impl", self.def.name()).into();

if writer.config.package {
fn collect(interface: &CppInterface, dependencies: &mut TypeMap, writer: &Writer) {
for method in interface.get_methods(writer).iter() {
if config().package {
fn collect(interface: &CppInterface, dependencies: &mut TypeMap) {
for method in interface.get_methods().iter() {
if let CppMethodOrName::Method(method) = method {
dependencies.combine(&method.dependencies);
}
}
}

collect(self, &mut dependencies, writer);
collect(self, &mut dependencies);
base_interfaces.iter().for_each(|interface| {
if let Type::CppInterface(ty) = interface {
collect(ty, &mut dependencies, writer);
collect(ty, &mut dependencies);
}
});
}
Expand Down Expand Up @@ -404,7 +404,7 @@ impl CppInterface {
}

pub fn write_name(&self, writer: &Writer) -> TokenStream {
if writer.config.sys {
if config().sys {
quote! { *mut core::ffi::c_void }
} else {
self.type_name().write(writer, &[])
Expand Down
Loading

0 comments on commit 0aa6ece

Please sign in to comment.