utilities: annotation: Clean-up deprecated parsing and getter.

This commit is contained in:
Emilio Cobos Álvarez
2023-09-04 19:53:31 +02:00
parent 0fb5d07ae4
commit 1473070230
6 changed files with 86 additions and 105 deletions
+27 -13
View File
@@ -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<String>,
}
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<Cow<'c, str>> {
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<String> {
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<AnnotationSet, String> {
+23 -35
View File
@@ -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() {
+13 -18
View File
@@ -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);
+1 -1
View File
@@ -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;
+8 -11
View File
@@ -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() {
+14 -27
View File
@@ -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<syn::MetaNameValue, Token![,]> =
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<syn::MetaNameValue, Token![,]> =
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 {