Skip to content

Commit

Permalink
Merge pull request #1540 from GuillaumeGomez/gen-cfg-automatically
Browse files Browse the repository at this point in the history
Automatically assume that `win32_` and `unix_` should use the related cfg
  • Loading branch information
GuillaumeGomez authored Feb 5, 2024
2 parents 4f82a49 + 45a6bd2 commit 5975266
Show file tree
Hide file tree
Showing 15 changed files with 279 additions and 48 deletions.
3 changes: 2 additions & 1 deletion src/analysis/constants.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::borrow::Borrow;

use crate::{config, env::Env, library, nameutil, traits::*, version::Version};
use crate::{config, env::Env, library, nameutil, traits::*, update_cfgs, version::Version};

#[derive(Debug)]
pub struct Info {
Expand Down Expand Up @@ -49,6 +49,7 @@ pub fn analyze<F: Borrow<library::Constant>>(
let cfg_condition = configured_constants
.iter()
.find_map(|c| c.cfg_condition.clone());
let cfg_condition = update_cfgs::get_constant_cfg_condition(&constant.name, &cfg_condition);

let name = nameutil::mangle_keywords(&*constant.name).into_owned();

Expand Down
4 changes: 4 additions & 0 deletions src/analysis/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use crate::{
},
nameutil,
traits::*,
update_cfgs,
version::Version,
};

Expand Down Expand Up @@ -651,6 +652,9 @@ fn analyze_function(
let cfg_condition = configured_functions
.iter()
.find_map(|f| f.cfg_condition.clone());
let ns = env.library.namespace(ns_id);
let cfg_condition =
update_cfgs::get_cfg_condition(&func.name, &cfg_condition, &ns.symbol_prefixes);
let doc_hidden = configured_functions.iter().any(|f| f.doc_hidden);
let doc_trait_name = configured_functions
.iter()
Expand Down
2 changes: 2 additions & 0 deletions src/analysis/namespaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub struct Namespace {
pub higher_crate_name: String,
pub package_names: Vec<String>,
pub symbol_prefixes: Vec<String>,
pub identifier_prefixes: Vec<String>,
pub shared_libs: Vec<String>,
pub versions: Vec<Version>,
}
Expand Down Expand Up @@ -58,6 +59,7 @@ pub fn run(gir: &library::Library) -> Info {
higher_crate_name,
package_names: ns.package_names.clone(),
symbol_prefixes: ns.symbol_prefixes.clone(),
identifier_prefixes: ns.identifier_prefixes.clone(),
shared_libs: ns.shared_library.clone(),
versions: ns.versions.iter().copied().collect(),
});
Expand Down
11 changes: 9 additions & 2 deletions src/analysis/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
library::{self, FunctionKind},
nameutil::*,
traits::*,
update_cfgs,
};

/// The location of an item within the object
Expand Down Expand Up @@ -303,6 +304,9 @@ pub fn class(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info>
imports.add("glib::prelude::*");
}

let ns = env.library.namespace(class_tid.ns_id);
let cfg_condition =
update_cfgs::get_object_cfg_condition(&name, &obj.cfg_condition, &ns.identifier_prefixes);
let base = InfoBase {
full_name,
type_id: class_tid,
Expand All @@ -312,7 +316,7 @@ pub fn class(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<Info>
imports,
version,
deprecated_version,
cfg_condition: obj.cfg_condition.clone(),
cfg_condition,
concurrency: obj.concurrency,
visibility: obj.visibility,
};
Expand Down Expand Up @@ -429,6 +433,9 @@ pub fn interface(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<I
deps,
);

let ns = env.library.namespace(iface_tid.ns_id);
let cfg_condition =
update_cfgs::get_object_cfg_condition(&name, &obj.cfg_condition, &ns.identifier_prefixes);
let base = InfoBase {
full_name,
type_id: iface_tid,
Expand All @@ -438,7 +445,7 @@ pub fn interface(env: &Env, obj: &GObject, deps: &[library::TypeId]) -> Option<I
imports,
version,
deprecated_version,
cfg_condition: obj.cfg_condition.clone(),
cfg_condition,
concurrency: obj.concurrency,
visibility: obj.visibility,
};
Expand Down
7 changes: 6 additions & 1 deletion src/analysis/record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::{
library,
nameutil::*,
traits::*,
update_cfgs,
version::Version,
};

Expand Down Expand Up @@ -195,6 +196,10 @@ pub fn new(env: &Env, obj: &GObject) -> Option<Info> {
}
}

let ns = env.library.namespace(record_tid.ns_id);
let cfg_condition =
update_cfgs::get_object_cfg_condition(&name, &obj.cfg_condition, &ns.identifier_prefixes);

let base = InfoBase {
full_name,
type_id: record_tid,
Expand All @@ -204,7 +209,7 @@ pub fn new(env: &Env, obj: &GObject) -> Option<Info> {
imports,
version,
deprecated_version,
cfg_condition: obj.cfg_condition.clone(),
cfg_condition,
concurrency: obj.concurrency,
visibility: obj.visibility,
};
Expand Down
16 changes: 10 additions & 6 deletions src/codegen/sys/fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
env::Env,
library::*,
traits::{IntoString, MaybeRefAs},
update_cfgs,
};

pub struct Fields {
Expand Down Expand Up @@ -164,10 +165,13 @@ fn field_ffi_type(env: &Env, field: &Field) -> Result {
}

fn get_gobject_cfg_condition(env: &Env, name: &str) -> Option<String> {
let full_name = format!("{}.{}", env.namespaces.main().name, name);
if let Some(obj) = env.config.objects.get(&full_name) {
obj.cfg_condition.clone()
} else {
None
}
let ns = env.namespaces.main();
let full_name = format!("{}.{}", ns.name, name);
env.config
.objects
.get(&full_name)
.and_then(|obj| {
update_cfgs::get_object_cfg_condition(name, &obj.cfg_condition, &ns.identifier_prefixes)
})
.or_else(|| update_cfgs::get_object_cfg_condition(name, &None, &ns.identifier_prefixes))
}
15 changes: 11 additions & 4 deletions src/codegen/sys/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use crate::{
env::Env,
library, nameutil,
traits::*,
update_cfgs,
};

// used as glib:get-type in GLib-2.0.gir
Expand Down Expand Up @@ -180,13 +181,19 @@ pub fn generate_other_funcs(

fn generate_cfg_configure(
w: &mut dyn Write,
env: &Env,
function_name: &str,
configured_functions: &[&Function],
commented: bool,
) -> Result<()> {
let ns = env.namespaces.main();
let cfg_condition_ = configured_functions
.iter()
.find_map(|f| f.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, commented, 1)?;
.find_map(|f| {
update_cfgs::get_cfg_condition(function_name, &f.cfg_condition, &ns.symbol_prefixes)
})
.or_else(|| update_cfgs::get_cfg_condition(function_name, &None, &ns.symbol_prefixes));
cfg_condition(w, cfg_condition_.as_ref(), commented, 1)?;
Ok(())
}

Expand Down Expand Up @@ -224,7 +231,7 @@ fn generate_object_funcs(
.max()
.flatten();
version_condition(w, env, None, version, false, 1)?;
generate_cfg_configure(w, &configured_functions, false)?;
generate_cfg_configure(w, env, glib_get_type, &configured_functions, false)?;
writeln!(w, " pub fn {glib_get_type}() -> GType;")?;
}
}
Expand Down Expand Up @@ -254,7 +261,7 @@ fn generate_object_funcs(

version_condition(w, env, None, version, commented, 1)?;
let name = func.c_identifier.as_ref().unwrap();
generate_cfg_configure(w, &configured_functions, commented)?;
generate_cfg_configure(w, env, name, &configured_functions, commented)?;
writeln!(w, " {comment}pub fn {name}{sig};")?;
}

Expand Down
88 changes: 70 additions & 18 deletions src/codegen/sys/lib_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use crate::{
library::*,
nameutil::*,
traits::*,
update_cfgs,
};

pub fn generate(env: &Env) {
Expand Down Expand Up @@ -180,7 +181,8 @@ fn generate_aliases(w: &mut dyn Write, env: &Env, items: &[&Alias]) -> Result<()
writeln!(w, "// Aliases")?;
}
for item in items {
let full_name = format!("{}.{}", env.namespaces.main().name, item.name);
let ns = env.namespaces.main();
let full_name = format!("{}.{}", ns.name, item.name);
if !env.type_status_sys(&full_name).need_generate() {
continue;
}
Expand All @@ -192,8 +194,17 @@ fn generate_aliases(w: &mut dyn Write, env: &Env, items: &[&Alias]) -> Result<()
.config
.objects
.get(&full_name)
.and_then(|obj| obj.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, false, 0)?;
.and_then(|obj| {
update_cfgs::get_object_cfg_condition(
&item.name,
&obj.cfg_condition,
&ns.identifier_prefixes,
)
})
.or_else(|| {
update_cfgs::get_object_cfg_condition(&item.name, &None, &ns.identifier_prefixes)
});
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
writeln!(w, "{}pub type {} = {};", comment, item.c_identifier, c_type)?;
}
if !items.is_empty() {
Expand Down Expand Up @@ -240,13 +251,15 @@ fn generate_bitfields(w: &mut dyn Write, env: &Env, items: &[&Bitfield]) -> Resu

fn generate_constant_cfg_configure(
w: &mut dyn Write,
constant: &Constant,
configured_constants: &[&constants::Constant],
commented: bool,
) -> Result<()> {
let cfg_condition_ = configured_constants
.iter()
.find_map(|f| f.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, commented, 1)?;
.find_map(|f| update_cfgs::get_constant_cfg_condition(&constant.name, &f.cfg_condition))
.or_else(|| update_cfgs::get_constant_cfg_condition(&constant.name, &None));
cfg_condition(w, cfg_condition_.as_ref(), commented, 1)?;
Ok(())
}

Expand Down Expand Up @@ -286,7 +299,12 @@ fn generate_constants(w: &mut dyn Write, env: &Env, constants: &[Constant]) -> R

if let Some(obj) = config {
let configured_constants = obj.constants.matched(&full_name);
generate_constant_cfg_configure(w, &configured_constants, !comment.is_empty())?;
generate_constant_cfg_configure(
w,
constant,
&configured_constants,
!comment.is_empty(),
)?;
}

writeln!(
Expand All @@ -307,7 +325,8 @@ fn generate_enums(w: &mut dyn Write, env: &Env, items: &[&Enumeration]) -> Resul
writeln!(w, "// Enums")?;
}
for item in items {
let full_name = format!("{}.{}", env.namespaces.main().name, item.name);
let ns = env.namespaces.main();
let full_name = format!("{}.{}", ns.name, item.name);
let config = env.config.objects.get(&full_name);
if let Some(false) = config.map(|c| c.status.need_generate()) {
continue;
Expand All @@ -316,8 +335,17 @@ fn generate_enums(w: &mut dyn Write, env: &Env, items: &[&Enumeration]) -> Resul
.config
.objects
.get(&full_name)
.and_then(|obj| obj.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, false, 0)?;
.and_then(|obj| {
update_cfgs::get_object_cfg_condition(
&item.name,
&obj.cfg_condition,
&ns.identifier_prefixes,
)
})
.or_else(|| {
update_cfgs::get_object_cfg_condition(&item.name, &None, &ns.identifier_prefixes)
});
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
writeln!(w, "pub type {} = c_int;", item.c_type)?;
for member in &item.members {
let member_config = config
Expand All @@ -333,7 +361,7 @@ fn generate_enums(w: &mut dyn Write, env: &Env, items: &[&Enumeration]) -> Resul
continue;
}

cfg_condition(w, cfg_condition_, false, 0)?;
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
version_condition(w, env, None, version, false, 0)?;
writeln!(
w,
Expand Down Expand Up @@ -420,18 +448,32 @@ fn generate_interfaces_structs(
writeln!(w, "// Interfaces")?;
}
for interface in interfaces {
let full_name = format!("{}.{}", env.namespaces.main().name, interface.name);
let ns = env.namespaces.main();
let full_name = format!("{}.{}", ns.name, interface.name);
if !env.type_status_sys(&full_name).need_generate() {
continue;
}
let cfg_condition_ = env
.config
.objects
.get(&full_name)
.and_then(|obj| obj.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, false, 0)?;
.and_then(|obj| {
update_cfgs::get_object_cfg_condition(
&interface.name,
&obj.cfg_condition,
&ns.identifier_prefixes,
)
})
.or_else(|| {
update_cfgs::get_object_cfg_condition(
&interface.name,
&None,
&ns.identifier_prefixes,
)
});
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
generate_opaque_type(w, &interface.c_type)?;
cfg_condition(w, cfg_condition_, false, 0)?;
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
generate_debug_impl(
w,
&interface.c_type,
Expand Down Expand Up @@ -506,15 +548,25 @@ impl ::std::fmt::Debug for GHookList {
}

fn generate_disguised(w: &mut dyn Write, env: &Env, record: &Record) -> Result<()> {
let full_name = format!("{}.{}", env.namespaces.main().name, record.name);
let ns = env.namespaces.main();
let full_name = format!("{}.{}", ns.name, record.name);
let cfg_condition_ = env
.config
.objects
.get(&full_name)
.and_then(|obj| obj.cfg_condition.as_ref());
cfg_condition(w, cfg_condition_, false, 0)?;
.and_then(|obj| {
update_cfgs::get_object_cfg_condition(
&record.name,
&obj.cfg_condition,
&ns.identifier_prefixes,
)
})
.or_else(|| {
update_cfgs::get_object_cfg_condition(&record.name, &None, &ns.identifier_prefixes)
});
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
generate_opaque_type(w, &format!("_{}", record.c_type))?;
cfg_condition(w, cfg_condition_, false, 0)?;
cfg_condition(w, cfg_condition_.as_ref(), false, 0)?;
if record.pointer {
writeln!(w, "pub type {name} = *mut _{name};", name = record.c_type)?;
} else {
Expand Down
5 changes: 1 addition & 4 deletions src/config/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,10 +344,7 @@ impl Parse for Function {
.lookup("version")
.and_then(Value::as_str)
.and_then(|s| s.parse().ok());
let cfg_condition = toml
.lookup("cfg_condition")
.and_then(Value::as_str)
.map(ToOwned::to_owned);
let cfg_condition = super::get_cfg_condition(toml, object_name);
let parameters = Parameters::parse(toml.lookup("parameter"), object_name);
let ret = Return::parse(toml.lookup("return"), object_name);
let doc_hidden = toml
Expand Down
5 changes: 1 addition & 4 deletions src/config/gobjects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,10 +330,7 @@ fn parse_object(
.lookup("version")
.and_then(Value::as_str)
.and_then(|s| s.parse().ok());
let cfg_condition = toml_object
.lookup("cfg_condition")
.and_then(Value::as_str)
.map(ToOwned::to_owned);
let cfg_condition = super::get_object_cfg_condition(toml_object, &name);
let generate_trait = toml_object.lookup("trait").and_then(Value::as_bool);
let final_type = toml_object
.lookup("final_type")
Expand Down
Loading

0 comments on commit 5975266

Please sign in to comment.