From 14730702306533c2805c9dd4a6846e762a4bbcca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Mon, 4 Sep 2023 19:53:31 +0200 Subject: [PATCH] utilities: annotation: Clean-up deprecated parsing and getter. --- src/bindgen/ir/annotation.rs | 40 ++++++++++++++++-------- src/bindgen/ir/enumeration.rs | 58 ++++++++++++++--------------------- src/bindgen/ir/function.rs | 31 ++++++++----------- src/bindgen/ir/mod.rs | 2 +- src/bindgen/ir/structure.rs | 19 +++++------- src/bindgen/utilities.rs | 41 +++++++++---------------- 6 files changed, 86 insertions(+), 105 deletions(-) diff --git a/src/bindgen/ir/annotation.rs b/src/bindgen/ir/annotation.rs index 7e555e4..48e3e4b 100644 --- a/src/bindgen/ir/annotation.rs +++ b/src/bindgen/ir/annotation.rs @@ -2,6 +2,7 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +use std::borrow::Cow; use std::collections::hash_map::Entry; use std::collections::HashMap; use std::str::FromStr; @@ -38,6 +39,12 @@ pub struct AnnotationSet { pub deprecated: Option, } +pub enum DeprecatedNoteKind { + Function, + Struct, + Enum, +} + impl AnnotationSet { pub fn new() -> AnnotationSet { AnnotationSet { @@ -55,25 +62,32 @@ impl AnnotationSet { self.must_use && config.language != Language::Cython } - pub(crate) fn deprecated_note(&self, config: &Config) -> Option<&str> { + pub(crate) fn deprecated_note<'c>( + &self, + config: &'c Config, + kind: DeprecatedNoteKind, + ) -> Option> { + let note = self.deprecated.as_deref()?; + if config.language == Language::Cython { return None; } - self.deprecated.as_deref() - } - - pub(crate) fn format_deprecated_note( - &self, - format_without_note: Option<&str>, - format_with_note: Option<&str>, - note: &str, - ) -> Option { if note.is_empty() { - return format_without_note.map(|x| x.to_string()); + return Some(Cow::Borrowed(match kind { + DeprecatedNoteKind::Enum => config.enumeration.deprecated.as_deref()?, + DeprecatedNoteKind::Function => config.function.deprecated.as_deref()?, + DeprecatedNoteKind::Struct => config.structure.deprecated.as_deref()?, + })); } - format_with_note - .map(|format_with_note| format_with_note.replace("{}", format!("{:?}", note).as_str())) + + let format = match kind { + DeprecatedNoteKind::Enum => &config.enumeration.deprecated_with_note, + DeprecatedNoteKind::Function => &config.function.deprecated_with_note, + DeprecatedNoteKind::Struct => &config.structure.deprecated_with_note, + } + .as_ref()?; + Some(Cow::Owned(format.replace("{}", &format!("{:?}", note)))) } pub fn load(attrs: &[syn::Attribute]) -> Result { diff --git a/src/bindgen/ir/enumeration.rs b/src/bindgen/ir/enumeration.rs index 7357b3b..a456b76 100644 --- a/src/bindgen/ir/enumeration.rs +++ b/src/bindgen/ir/enumeration.rs @@ -10,9 +10,9 @@ use crate::bindgen::config::{Config, Language}; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; use crate::bindgen::ir::{ - AnnotationSet, AnnotationValue, Cfg, ConditionWrite, Documentation, Field, GenericArgument, - GenericParams, GenericPath, Item, ItemContainer, Literal, Path, Repr, ReprStyle, Struct, - ToCondition, Type, + AnnotationSet, AnnotationValue, Cfg, ConditionWrite, DeprecatedNoteKind, Documentation, Field, + GenericArgument, GenericParams, GenericPath, Item, ItemContainer, Literal, Path, Repr, + ReprStyle, Struct, ToCondition, Type, }; use crate::bindgen::library::Library; use crate::bindgen::mangle; @@ -754,14 +754,11 @@ impl Enum { // If we need to specify size, then we have no choice but to create a typedef, // so `config.style` is not respected. write!(out, "enum"); - if let Some(note) = self.annotations.deprecated_note(config) { - if let Some(note) = self.annotations.format_deprecated_note( - config.enumeration.deprecated.as_deref(), - config.enumeration.deprecated_with_note.as_deref(), - note, - ) { - write!(out, " {}", note); - } + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Enum) + { + write!(out, " {}", note); } write!(out, " {}", tag_name); @@ -779,14 +776,11 @@ impl Enum { out.write("typedef "); } out.write("enum"); - if let Some(note) = self.annotations.deprecated_note(config) { - if let Some(note) = self.annotations.format_deprecated_note( - config.enumeration.deprecated.as_deref(), - config.enumeration.deprecated_with_note.as_deref(), - note, - ) { - write!(out, " {}", note); - } + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Enum) + { + write!(out, " {}", note); } if config.style.generate_tag() { write!(out, " {}", tag_name); @@ -806,14 +800,11 @@ impl Enum { } } - if let Some(note) = self.annotations.deprecated_note(config) { - if let Some(note) = self.annotations.format_deprecated_note( - config.structure.deprecated.as_deref(), - config.structure.deprecated_with_note.as_deref(), - note, - ) { - write!(out, " {}", note); - } + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Enum) + { + write!(out, " {}", note); } write!(out, " {}", tag_name); @@ -894,14 +885,11 @@ impl Enum { } } - if let Some(note) = self.annotations.deprecated_note(config) { - if let Some(note) = self.annotations.format_deprecated_note( - config.enumeration.deprecated.as_deref(), - config.enumeration.deprecated_with_note.as_deref(), - note, - ) { - write!(out, " {} ", note); - } + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Struct) + { + write!(out, " {} ", note); } if config.language != Language::C || config.style.generate_tag() { diff --git a/src/bindgen/ir/function.rs b/src/bindgen/ir/function.rs index 0d9857e..8c65f2f 100644 --- a/src/bindgen/ir/function.rs +++ b/src/bindgen/ir/function.rs @@ -12,7 +12,8 @@ use crate::bindgen::config::{Config, Language, Layout}; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; use crate::bindgen::ir::{ - AnnotationSet, Cfg, ConditionWrite, Documentation, GenericPath, Path, ToCondition, Type, + AnnotationSet, Cfg, ConditionWrite, DeprecatedNoteKind, Documentation, GenericPath, Path, + ToCondition, Type, }; use crate::bindgen::library::Library; use crate::bindgen::monomorph::Monomorphs; @@ -241,14 +242,11 @@ impl Source for Function { write!(out, "{} ", anno); } } - if let Some(note) = func.annotations.deprecated_note(config) { - if let Some(note) = func.annotations.format_deprecated_note( - config.function.deprecated.as_deref(), - config.function.deprecated_with_note.as_deref(), - note, - ) { - write!(out, "{} ", note); - } + if let Some(note) = func + .annotations + .deprecated_note(config, DeprecatedNoteKind::Function) + { + write!(out, "{} ", note); } } cdecl::write_func(out, func, Layout::Horizontal, config); @@ -293,15 +291,12 @@ impl Source for Function { out.new_line(); } } - if let Some(note) = func.annotations.deprecated_note(config) { - if let Some(note) = func.annotations.format_deprecated_note( - config.function.deprecated.as_deref(), - config.function.deprecated_with_note.as_deref(), - note, - ) { - write!(out, "{}", note); - out.new_line(); - } + if let Some(note) = func + .annotations + .deprecated_note(config, DeprecatedNoteKind::Function) + { + write!(out, "{}", note); + out.new_line(); } } cdecl::write_func(out, func, Layout::Vertical, config); diff --git a/src/bindgen/ir/mod.rs b/src/bindgen/ir/mod.rs index 7b0a922..3566f0d 100644 --- a/src/bindgen/ir/mod.rs +++ b/src/bindgen/ir/mod.rs @@ -20,7 +20,7 @@ pub mod ty; pub mod typedef; pub mod union; -pub use self::annotation::{AnnotationSet, AnnotationValue}; +pub use self::annotation::{AnnotationSet, AnnotationValue, DeprecatedNoteKind}; pub use self::cfg::*; pub use self::constant::*; pub use self::documentation::Documentation; diff --git a/src/bindgen/ir/structure.rs b/src/bindgen/ir/structure.rs index d0f8fd3..7c5c4a9 100644 --- a/src/bindgen/ir/structure.rs +++ b/src/bindgen/ir/structure.rs @@ -10,9 +10,9 @@ use crate::bindgen::config::{Config, Language, LayoutConfig}; use crate::bindgen::declarationtyperesolver::DeclarationTypeResolver; use crate::bindgen::dependencies::Dependencies; use crate::bindgen::ir::{ - AnnotationSet, Cfg, ConditionWrite, Constant, Documentation, Field, GenericArgument, - GenericParams, Item, ItemContainer, Path, Repr, ReprAlign, ReprStyle, ToCondition, Type, - Typedef, + AnnotationSet, Cfg, ConditionWrite, Constant, DeprecatedNoteKind, Documentation, Field, + GenericArgument, GenericParams, Item, ItemContainer, Path, Repr, ReprAlign, ReprStyle, + ToCondition, Type, Typedef, }; use crate::bindgen::library::Library; use crate::bindgen::mangle; @@ -455,14 +455,11 @@ impl Source for Struct { write!(out, " {}", anno); } } - if let Some(note) = self.annotations.deprecated_note(config) { - if let Some(note) = self.annotations.format_deprecated_note( - config.structure.deprecated.as_deref(), - config.structure.deprecated_with_note.as_deref(), - note, - ) { - write!(out, " {}", note); - } + if let Some(note) = self + .annotations + .deprecated_note(config, DeprecatedNoteKind::Struct) + { + write!(out, " {}", note); } if config.language != Language::C || config.style.generate_tag() { diff --git a/src/bindgen/utilities.rs b/src/bindgen/utilities.rs index 66f9415..0e314b9 100644 --- a/src/bindgen/utilities.rs +++ b/src/bindgen/utilities.rs @@ -139,47 +139,34 @@ pub trait SynAttributeHelpers { // #[deprecated] if attrs.has_attr_word("deprecated") { - return Some("".to_string()); + return Some(String::new()); } // #[deprecated(note = "")] - if let Some(attr) = attrs.iter().find(|attr| { + let attr = attrs.iter().find(|attr| { if let Ok(syn::Meta::List(list)) = attr.parse_meta() { list.path.is_ident("deprecated") } else { false } - }) { - let args: syn::punctuated::Punctuated = - match attr.parse_args_with(syn::punctuated::Punctuated::parse_terminated) { - Ok(args) => args, - Err(_) => { - warn!("couldn't parse deprecated attribute"); - return None; - } - }; + })?; - let lit = match args - .iter() - .find(|arg| arg.path.is_ident("note")) - .map(|arg| &arg.lit) - { - Some(lit) => lit, - None => { - warn!("couldn't parse deprecated attribute: no `note` field"); + let args: syn::punctuated::Punctuated = + match attr.parse_args_with(syn::punctuated::Punctuated::parse_terminated) { + Ok(args) => args, + Err(_) => { + warn!("couldn't parse deprecated attribute"); return None; } }; - return if let syn::Lit::Str(lit) = lit { - Some(lit.value()) - } else { - warn!("deprecated attribute must be a string"); - None - }; + let arg = args.iter().find(|arg| arg.path.is_ident("note"))?; + if let syn::Lit::Str(ref lit) = arg.lit { + Some(lit.value()) + } else { + warn!("deprecated attribute must be a string"); + None } - - None } fn is_no_mangle(&self) -> bool {