diff --git a/src/analysis/imports.rs b/src/analysis/imports.rs index f9b718735..2a298c566 100644 --- a/src/analysis/imports.rs +++ b/src/analysis/imports.rs @@ -7,6 +7,7 @@ use std::{ }; use super::namespaces; +use crate::nameutil::mangle_crate; use crate::{library::Library, nameutil::crate_name, version::Version}; fn is_first_char_up(s: &str) -> bool { @@ -149,6 +150,7 @@ impl Imports { /// For example, if name is `X::Y::Z` then it will be available as `Z`. /// Uses defaults. pub fn add(&mut self, name: &str) { + let name = &mangle_crate(name); if !self.common_checks(name) { return; } diff --git a/src/analysis/rust_type.rs b/src/analysis/rust_type.rs index 142076845..a01fd60f8 100644 --- a/src/analysis/rust_type.rs +++ b/src/analysis/rust_type.rs @@ -1,6 +1,7 @@ use std::{borrow::Borrow, result}; use super::conversion_type::ConversionType; +use crate::nameutil::escape_digit; use crate::{ analysis::{record_type::RecordType, ref_mode::RefMode, try_from_glib::TryFromGlib}, config::functions::{CallbackParameter, CallbackParameters}, @@ -161,7 +162,7 @@ impl IntoString for Result { fn into_string(self) -> String { use self::TypeError::*; match self { - Ok(s) => s.into_string(), + Ok(s) => escape_digit(&s.into_string()), Err(Ignored(s)) => format!("/*Ignored*/{s}"), Err(Mismatch(s)) => format!("/*Metadata mismatch*/{s}"), Err(Unimplemented(s)) => format!("/*Unimplemented*/{s}"), diff --git a/src/codegen/bound.rs b/src/codegen/bound.rs index 7a5d998aa..915df17e6 100644 --- a/src/codegen/bound.rs +++ b/src/codegen/bound.rs @@ -1,3 +1,4 @@ +use crate::nameutil::escape_digit; use crate::{ analysis::{ bounds::{Bound, BoundType}, @@ -47,6 +48,8 @@ impl Bound { } }; + let trait_bound = escape_digit(&trait_bound); + match self.bound_type { BoundType::IsA(_) if *nullable => { format!("Option<{ref_str}{trait_bound}>") diff --git a/src/codegen/doc/format.rs b/src/codegen/doc/format.rs index 54f20d66d..a571f1243 100644 --- a/src/codegen/doc/format.rs +++ b/src/codegen/doc/format.rs @@ -340,7 +340,7 @@ fn find_constant_or_variant( }) { Some(gen_member_doc_link( enum_info.type_id, - &nameutil::enum_member_name(&member_info.name), + &nameutil::enum_name(&member_info.name), env, in_type, )) diff --git a/src/codegen/doc/mod.rs b/src/codegen/doc/mod.rs index e30153358..35e18cf8f 100644 --- a/src/codegen/doc/mod.rs +++ b/src/codegen/doc/mod.rs @@ -748,7 +748,7 @@ fn create_enum_doc(w: &mut dyn Write, env: &Env, enum_: &Enumeration, tid: TypeI if generate_doc && member.doc.is_some() { let sub_ty = TypeStruct { - name: nameutil::enum_member_name(&member.name), + name: nameutil::enum_name(&member.name), parent: Some(Box::new(ty.clone())), ty: SType::Variant, args: Vec::new(), diff --git a/src/codegen/enums.rs b/src/codegen/enums.rs index 63bf8bb8c..4de1d3b17 100644 --- a/src/codegen/enums.rs +++ b/src/codegen/enums.rs @@ -5,6 +5,7 @@ use std::{ }; use super::{function, trait_impls}; +use crate::nameutil::enum_member_name; use crate::{ analysis::enums::Info, codegen::{ @@ -19,7 +20,7 @@ use crate::{ env::Env, file_saver, library::*, - nameutil::{enum_member_name, use_glib_if_needed, use_glib_type}, + nameutil::{enum_name, use_glib_if_needed, use_glib_type}, traits::*, version::Version, }; @@ -62,7 +63,7 @@ pub fn generate(env: &Env, root_path: &Path, mod_rs: &mut Vec) { .map(|_| "#[allow(deprecated)]\n") .unwrap_or(""), enum_analysis.visibility.export_visibility(), - enum_.name + enum_name(&enum_.name) )); generate_enum(env, w, enum_, config, enum_analysis)?; @@ -114,6 +115,10 @@ fn generate_enum( cfg_condition, }); } + let _enum_name = enum_name(&enum_.name); + let analysis_name = enum_name(&analysis.name); + + println!("-- {_enum_name} - {analysis_name}"); cfg_deprecated( w, @@ -142,7 +147,7 @@ fn generate_enum( } doc_alias(w, &enum_.c_type, "", 0)?; - writeln!(w, "{} enum {} {{", analysis.visibility, enum_.name)?; + writeln!(w, "{} enum {} {{", analysis.visibility, &_enum_name)?; for member in &members { cfg_deprecated( w, @@ -195,7 +200,7 @@ fn generate_enum( version_condition(w, env, None, enum_.version, false, 0)?; cfg_condition_no_doc(w, config.cfg_condition.as_ref(), false, 0)?; allow_deprecated(w, enum_.deprecated_version, false, 0)?; - write!(w, "impl {} {{", analysis.name)?; + write!(w, "impl {} {{", &_enum_name)?; for func_analysis in functions { function::generate( w, @@ -215,7 +220,7 @@ fn generate_enum( trait_impls::generate( w, env, - &analysis.name, + &_enum_name, &analysis.functions, &analysis.specials, None, @@ -244,7 +249,7 @@ impl IntoGlib for {name} {{ {maybe_inline}fn into_glib(self) -> {sys_crate_name}::{ffi_name} {{", sys_crate_name = sys_crate_name, - name = enum_.name, + name = _enum_name, ffi_name = enum_.c_type, maybe_inline = maybe_inline )?; @@ -296,11 +301,10 @@ impl IntoGlib for {name} {{ writeln!( w, "#[doc(hidden)] -impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ +impl FromGlib<{sys_crate_name}::{ffi_name}> for {_enum_name} {{ {maybe_inline}unsafe fn from_glib(value: {sys_crate_name}::{ffi_name}) -> Self {{ {assert}", sys_crate_name = sys_crate_name, - name = enum_.name, ffi_name = enum_.c_type, assert = assert, maybe_inline = maybe_inline @@ -349,11 +353,10 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, any_deprecated_version, false, 0)?; writeln!( w, - "impl {glib_error_domain} for {name} {{ + "impl {glib_error_domain} for {_enum_name} {{ #[inline] fn domain() -> {glib_quark} {{ {assert}", - name = enum_.name, glib_error_domain = use_glib_type(env, "error::ErrorDomain"), glib_quark = use_glib_type(env, "Quark"), assert = assert @@ -420,9 +423,8 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "impl StaticType for {name} {{ + "impl StaticType for {_enum_name} {{ #[inline]", - name = enum_.name, )?; doc_alias(w, get_type, "", 1)?; writeln!( @@ -442,7 +444,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "impl {has_param_spec} for {name} {{ + "impl {has_param_spec} for {_enum_name} {{ type ParamSpec = {param_spec_enum}; type SetValue = Self; type BuilderFn = fn(&str, Self) -> {param_spec_builder}; @@ -451,7 +453,6 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ Self::ParamSpec::builder_with_default }} }}", - name = enum_.name, has_param_spec = use_glib_type(env, "HasParamSpec"), param_spec_enum = use_glib_type(env, "ParamSpecEnum"), param_spec_builder = use_glib_type(env, "ParamSpecEnumBuilder"), @@ -463,10 +464,9 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "impl {valuetype} for {name} {{ + "impl {valuetype} for {_enum_name} {{ type Type = Self; }}", - name = enum_.name, valuetype = use_glib_type(env, "value::ValueType"), )?; writeln!(w)?; @@ -476,7 +476,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "unsafe impl<'a> {from_value_type}<'a> for {name} {{ + "unsafe impl<'a> {from_value_type}<'a> for {_enum_name} {{ type Checker = {genericwrongvaluetypechecker}; #[inline] @@ -484,7 +484,6 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ {assert}from_glib({glib}(value.to_glib_none().0)) }} }}", - name = enum_.name, glib = use_glib_type(env, "gobject_ffi::g_value_get_enum"), gvalue = use_glib_type(env, "Value"), genericwrongvaluetypechecker = use_glib_type(env, "value::GenericValueTypeChecker"), @@ -498,7 +497,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "impl ToValue for {name} {{ + "impl ToValue for {_enum_name} {{ #[inline] fn to_value(&self) -> {gvalue} {{ let mut value = {gvalue}::for_value_type::(); @@ -513,7 +512,6 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ Self::static_type() }} }}", - name = enum_.name, glib = use_glib_type(env, "gobject_ffi::g_value_set_enum"), gvalue = use_glib_type(env, "Value"), gtype = use_glib_type(env, "Type"), @@ -525,13 +523,12 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ allow_deprecated(w, enum_.deprecated_version, false, 0)?; writeln!( w, - "impl From<{name}> for {gvalue} {{ + "impl From<{_enum_name}> for {gvalue} {{ #[inline] - fn from(v: {name}) -> Self {{ + fn from(v: {_enum_name}) -> Self {{ {assert}ToValue::to_value(&v) }} }}", - name = enum_.name, gvalue = use_glib_type(env, "Value"), assert = assert, )?; @@ -542,7 +539,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ w, env, config, - &enum_.name, + &_enum_name, enum_.version, enum_.members.iter(), |member| { diff --git a/src/codegen/flags.rs b/src/codegen/flags.rs index d7502bc51..856955482 100644 --- a/src/codegen/flags.rs +++ b/src/codegen/flags.rs @@ -4,6 +4,7 @@ use std::{ }; use super::{function, general::allow_deprecated, trait_impls}; +use crate::nameutil::flag_name; use crate::{ analysis::flags::Info, codegen::{ @@ -59,7 +60,7 @@ pub fn generate(env: &Env, root_path: &Path, mod_rs: &mut Vec) { .map(|_| "#[allow(deprecated)]\n") .unwrap_or(""), flags_analysis.visibility.export_visibility(), - flags.name + flag_name(&flags.name) )); generate_flags(env, w, flags, config, flags_analysis)?; } @@ -102,7 +103,8 @@ fn generate_flags( writeln!( w, " {} struct {}: u32 {{", - analysis.visibility, flags.name + analysis.visibility, + flag_name(&flags.name) )?; for member in &flags.members { let member_config = config.members.matched(&member.name); @@ -150,7 +152,7 @@ fn generate_flags( version_condition(w, env, None, flags.version, false, 0)?; cfg_condition_no_doc(w, config.cfg_condition.as_ref(), false, 0)?; allow_deprecated(w, flags.deprecated_version, false, 0)?; - write!(w, "impl {} {{", analysis.name)?; + write!(w, "impl {} {{", flag_name(&analysis.name))?; for func_analysis in functions { function::generate( w, @@ -170,7 +172,7 @@ fn generate_flags( trait_impls::generate( w, env, - &analysis.name, + &flag_name(&analysis.name), &analysis.functions, &analysis.specials, None, @@ -184,7 +186,7 @@ fn generate_flags( w, env, config, - &flags.name, + &flag_name(&flags.name), flags.version, flags.members.iter(), |member| { @@ -217,7 +219,7 @@ impl IntoGlib for {name} {{ }} ", sys_crate_name = sys_crate_name, - name = flags.name, + name = flag_name(&flags.name), ffi_name = flags.c_type )?; @@ -241,7 +243,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ }} ", sys_crate_name = sys_crate_name, - name = flags.name, + name = flag_name(&flags.name), ffi_name = flags.c_type, assert = assert )?; @@ -260,7 +262,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ w, "impl StaticType for {name} {{ #[inline]", - name = flags.name, + name = flag_name(&flags.name), )?; doc_alias(w, get_type, "", 1)?; writeln!( @@ -289,7 +291,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ Self::ParamSpec::builder }} }}", - name = flags.name, + name = flag_name(&flags.name), has_param_spec = use_glib_type(env, "HasParamSpec"), param_spec_flags = use_glib_type(env, "ParamSpecFlags"), param_spec_builder = use_glib_type(env, "ParamSpecFlagsBuilder"), @@ -304,7 +306,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ "impl {valuetype} for {name} {{ type Type = Self; }}", - name = flags.name, + name = flag_name(&flags.name), valuetype = use_glib_type(env, "value::ValueType"), )?; writeln!(w)?; @@ -322,7 +324,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ {assert}from_glib({glib}(value.to_glib_none().0)) }} }}", - name = flags.name, + name = flag_name(&flags.name), glib = use_glib_type(env, "gobject_ffi::g_value_get_flags"), gvalue = use_glib_type(env, "Value"), genericwrongvaluetypechecker = use_glib_type(env, "value::GenericValueTypeChecker"), @@ -351,7 +353,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ Self::static_type() }} }}", - name = flags.name, + name = flag_name(&flags.name), glib = use_glib_type(env, "gobject_ffi::g_value_set_flags"), gvalue = use_glib_type(env, "Value"), gtype = use_glib_type(env, "Type"), @@ -369,7 +371,7 @@ impl FromGlib<{sys_crate_name}::{ffi_name}> for {name} {{ {assert}ToValue::to_value(&v) }} }}", - name = flags.name, + name = flag_name(&flags.name), gvalue = use_glib_type(env, "Value"), assert = assert, )?; diff --git a/src/nameutil.rs b/src/nameutil.rs index 09b2c85ef..1f81c348c 100644 --- a/src/nameutil.rs +++ b/src/nameutil.rs @@ -74,14 +74,53 @@ pub fn module_name(name: &str) -> String { mangle_keywords(name.to_snake()).into_owned() } +pub fn mangle_crate(name: &str) -> String { + let parts: Vec<_> = name.split("::").collect(); + let name = if let Some(name) = parts.iter().last() { + let new_name = if name.starts_with(char::is_numeric) { + format!("_{name}") + } else { + name.to_string() + }; + + let reduced_count = parts.len() - 1; + let mut parts = parts.into_iter().take(reduced_count).collect::>(); + parts.push(&new_name); + parts.join("::") + } else { + name.into() + }; + name +} + +pub fn escape_digit(name: &str) -> String { + if name.starts_with(char::is_numeric) { + format!("_{name}") + } else { + mangle_keywords(name).into() + } +} + pub fn enum_member_name(name: &str) -> String { if name.starts_with(char::is_alphabetic) { name.to_camel() } else { - format!("_{}", name.to_camel()) + escape_digit(&name.to_camel()) } } +pub fn enum_name(name: &str) -> String { + if name.starts_with(char::is_alphabetic) { + name.to_camel() + } else { + escape_digit(&name.to_camel()) + } +} + +pub fn flag_name(name: &str) -> String { + escape_digit(name) +} + pub fn bitfield_member_name(name: &str) -> String { if name.starts_with(char::is_alphabetic) { name.to_uppercase()