Skip to content

Commit

Permalink
macro_tools : attr::is_standard
Browse files Browse the repository at this point in the history
  • Loading branch information
Wandalen committed Apr 30, 2024
1 parent 1cb44dc commit f36d904
Show file tree
Hide file tree
Showing 5 changed files with 172 additions and 11 deletions.
42 changes: 37 additions & 5 deletions module/core/former/tests/inc/former_tests/attribute_feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,43 @@ use super::*;

// xxx : need to fix

#[ derive( former::Former ) ]
struct Foo
#[ derive( Debug, PartialEq ) ]
pub struct BaseCase
{
// #[ cfg( feature = "baz" ) ]
bar : i32,
#[ cfg( feature = "enabled" ) ]
enabled : i32,
#[ cfg( feature = "disabled" ) ]
disabled : i32,
}

// error => Unknown attribute #[cfg(feature = "baz")]
#[ derive( Debug, PartialEq, former::Former ) ]
// #[ debug ]
// #[ derive( Debug, PartialEq ) ]
pub struct Foo
{
// #[ cfg( feature = "enabled" ) ]
#[ allow( dead_code ) ]
enabled : i32,
#[ cfg( feature = "disabled" ) ]
disabled : i32,
}

// == begin of generated

// == end of generated

#[ test ]
fn basecase()
{
let got = BaseCase { enabled : 13 };
let exp = BaseCase { enabled : 13 };
a_id!( got, exp );
}

// #[ test ]
// fn basic()
// {
// let got = Foo::former().enabled( 13 ).form();
// let exp = Foo { enabled : 13 };
// a_id!( got, exp );
// }
3 changes: 0 additions & 3 deletions module/core/former/tests/inc/former_tests/visibility.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
#[ allow( unused_imports ) ]
use super::*;

// xxx : need to fix

#[ derive( Debug, PartialEq, former::Former ) ]
// #[ debug ]
// #[ derive( Debug, PartialEq ) ]
Expand All @@ -14,7 +12,6 @@ pub struct Foo
bar : i32,
}


// == begin of generated

// == end of generated
Expand Down
4 changes: 2 additions & 2 deletions module/core/former/tests/inc/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ mod former_tests
mod attribute_perform;
mod attribute_setter;
mod attribute_alias;
// mod attribute_feature; // xxx : write test
mod attribute_feature; // xxx : write test

mod string_slice_manual;
mod string_slice;
mod unsigned_primitive_types;
mod default_user_type;
mod user_type_no_default;
mod user_type_no_debug;
mod visibility; // xxx : write test
mod visibility;

mod name_collision_former_hashmap_without_parameter;
mod name_collision_former_vector_without_parameter;
Expand Down
103 changes: 103 additions & 0 deletions module/core/macro_tools/src/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,108 @@ pub( crate ) mod private
return Ok( false )
}

/// Checks if the given attribute name is a standard Rust attribute.
///
/// Standard Rust attributes are those which are recognized and processed
/// directly by the Rust compiler. They influence various aspects of compilation,
/// including but not limited to conditional compilation, optimization hints,
/// code visibility, and procedural macro behavior.
///
/// This function is useful when developing tools that need to interact with or
/// understand the significance of specific attributes in Rust source code, such
/// as linters, code analyzers, or procedural macros.
///
/// This function does not cover all possible attributes but includes many of the
/// common ones that are relevant to most Rust projects. Developers are encouraged
/// to update this function as needed to suit more specialized needs, especially
/// when dealing with nightly-only compiler attributes or deprecated ones.
///
/// # Parameters
/// - `attr_name`: A string slice that holds the name of the attribute to check.
///
/// # Returns
/// Returns `true` if `attr_name` is a recognized standard Rust attribute. Otherwise,
/// returns `false`.
///
/// # Examples
///
/// Standard attributes:
///
/// ```
/// assert_eq!( macro_tools::attr::is_standard( "cfg" ), true );
/// assert_eq!( macro_tools::attr::is_standard( "inline" ), true );
/// assert_eq!( macro_tools::attr::is_standard( "derive" ), true );
/// ```
///
/// Non-standard or custom attributes:
///
/// ```
/// assert_eq!( macro_tools::attr::is_standard( "custom_attr" ), false );
/// assert_eq!( macro_tools::attr::is_standard( "my_attribute" ), false );
/// ```
///

pub fn is_standard<'a>( attr_name : &'a str ) -> bool
{
match attr_name
{
// Conditional compilation
"cfg" | "cfg_attr" => true,

// Compiler instructions and optimizations
"inline" | "repr" | "derive" | "allow" | "warn" | "deny" | "forbid" => true,

// Testing attributes
"test" | "bench" => true,

// Documentation attributes
"doc" => true,

// Visibility and accessibility
"pub" => true, // This would typically need context to be accurate

// Safety and ABI
"unsafe" | "no_mangle" | "extern" => true,

// Module and Crate configuration
"path" | "macro_use" | "crate_type" | "crate_name" => true,

// Linking
"link" | "link_name" | "link_section" => true,

// Usage warnings
"must_use" => true,

// Other attributes
"cold" | "export_name" | "global_allocator" => true,

// Module handling
"used" | "unused" => true,

// Procedural macros and hygiene
"proc_macro" | "proc_macro_derive" | "proc_macro_attribute" => true,

// Stability attributes
"stable" | "unstable" | "rustc_const_unstable" | "rustc_const_stable" |
"rustc_diagnostic_item" | "rustc_deprecated" | "rustc_legacy_const_generics" => true,

// Special compiler attributes
"feature" | "non_exhaustive" => true,

// Future compatibility
"rustc_paren_sugar" | "rustc_insignificant_dtor" => true,

// Type system extensions
"opaque" => true,

// Miscellaneous
"track_caller" => true,

// Default case
_ => false,
}
}

///
/// Attribute which is inner.
///
Expand Down Expand Up @@ -316,6 +418,7 @@ pub mod exposed
{
equation,
has_debug,
is_standard,
AttributesInner,
AttributesOuter,
AttributedIdent,
Expand Down
31 changes: 30 additions & 1 deletion module/core/macro_tools/tests/inc/attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::*;
//

#[ test ]
fn basic()
fn parse()
{

let attr : syn::Attribute = syn::parse_quote!( #[ default( 31 ) ] );
Expand All @@ -22,3 +22,32 @@ fn basic()
a_id!( code_to_str!( got.right ), "31".to_string() );

}

#[ test ]
fn is_standard_standard()
{
// Test a selection of attributes known to be standard
assert!( is_standard( "cfg" ), "Expected 'cfg' to be a standard attribute." );
assert!( is_standard( "derive" ), "Expected 'derive' to be a standard attribute." );
assert!( is_standard( "inline" ), "Expected 'inline' to be a standard attribute." );
assert!( is_standard( "test" ), "Expected 'test' to be a standard attribute." );
assert!( is_standard( "doc" ), "Expected 'doc' to be a standard attribute." );
}

#[ test ]
fn is_standard_non_standard()
{
// Test some made-up attributes that should not be standard
assert!( !is_standard( "custom_attr" ), "Expected 'custom_attr' to not be a standard attribute." );
assert!( !is_standard( "my_attribute" ), "Expected 'my_attribute' to not be a standard attribute." );
assert!( !is_standard( "special_feature" ), "Expected 'special_feature' to not be a standard attribute." );
}

#[ test ]
fn is_standard_edge_cases()
{
// Test edge cases like empty strings or unusual input
assert!( !is_standard( "" ), "Expected empty string to not be a standard attribute." );
assert!( !is_standard( " " ), "Expected a single space to not be a standard attribute." );
assert!( !is_standard( "cfg_attr_extra" ), "Expected 'cfg_attr_extra' to not be a standard attribute." );
}

0 comments on commit f36d904

Please sign in to comment.