use crate::ns::*; use serde::{Serialize, Deserialize}; #[derive(Clone, Serialize, Deserialize)] pub enum Attribute { Metadata(Rc), Expression(Rc), Public(Location), Private(Location), Protected(Location), Internal(Location), Final(Location), Native(Location), Static(Location), Abstract(Location), Override(Location), Dynamic(Location), } #[derive(Clone, Serialize, Deserialize)] pub struct Metadata { pub location: Location, pub asdoc: Option>, pub name: (String, Location), pub entries: Option>>, } #[derive(Clone, Serialize, Deserialize)] pub struct MetadataEntry { pub location: Location, pub key: Option<(String, Location)>, pub value: Rc, } #[derive(Clone, Serialize, Deserialize)] pub enum MetadataValue { IdentifierString((String, Location)), String((String, Location)), } impl MetadataValue { pub fn location(&self) -> Location { match self { Self::IdentifierString((_, l)) => l.clone(), Self::String((_, l)) => l.clone(), } } } impl Attribute { pub fn location(&self) -> Location { match self { Self::Expression(m) => m.location(), Self::Metadata(m) => m.location.clone(), Self::Public(a) => a.clone(), Self::Private(a) => a.clone(), Self::Protected(a) => a.clone(), Self::Internal(a) => a.clone(), Self::Final(a) => a.clone(), Self::Native(a) => a.clone(), Self::Static(a) => a.clone(), Self::Abstract(a) => a.clone(), Self::Override(a) => a.clone(), Self::Dynamic(a) => a.clone(), } } pub fn has_access_modifier(list: &[Attribute]) -> bool { for a in list { match a { Self::Expression(_) | Self::Public(_) | Self::Private(_) | Self::Protected(_) | Self::Internal(_) => return true, _ => {} } } false } pub fn remove_metadata(list: &mut Vec, metadata: &Rc) { for i in 0..list.len() { if let Attribute::Metadata(metadata_1) = &list[i] { if Rc::ptr_eq(&metadata_1, metadata) { list.remove(i); break; } } } } pub fn find_metadata(list: &[Attribute]) -> Vec> { let mut r = vec![]; for a in list { match &a { Self::Metadata(e) => { r.push(e.clone()); }, _ => {}, } } r } pub fn find_expression(list: &[Attribute]) -> Option> { for a in list { match &a { Self::Expression(e) => return Some(e.clone()), _ => {} } }; None } pub fn find_public(list: &[Attribute]) -> Option { for a in list { match &a { Self::Public(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_private(list: &[Attribute]) -> Option { for a in list { match &a { Self::Private(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_protected(list: &[Attribute]) -> Option { for a in list { match &a { Self::Protected(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_internal(list: &[Attribute]) -> Option { for a in list { match &a { Self::Internal(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_final(list: &[Attribute]) -> Option { for a in list { match &a { Self::Final(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_native(list: &[Attribute]) -> Option { for a in list { match &a { Self::Native(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_static(list: &[Attribute]) -> Option { for a in list { match &a { Self::Static(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_abstract(list: &[Attribute]) -> Option { for a in list { match &a { Self::Abstract(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_override(list: &[Attribute]) -> Option { for a in list { match &a { Self::Override(l) => return Some(l.clone()), _ => {} } }; None } pub fn find_dynamic(list: &[Attribute]) -> Option { for a in list { match &a { Self::Dynamic(l) => return Some(l.clone()), _ => {} } }; None } pub fn has(list: &[Attribute], attribute: &Attribute) -> bool { match attribute { Self::Public(_) => Self::find_public(list).is_some(), Self::Private(_) => Self::find_private(list).is_some(), Self::Protected(_) => Self::find_protected(list).is_some(), Self::Internal(_) => Self::find_internal(list).is_some(), Self::Final(_) => Self::find_final(list).is_some(), Self::Native(_) => Self::find_native(list).is_some(), Self::Static(_) => Self::find_static(list).is_some(), Self::Abstract(_) => Self::find_abstract(list).is_some(), Self::Override(_) => Self::find_override(list).is_some(), Self::Dynamic(_) => Self::find_dynamic(list).is_some(), _ => false, } } pub fn is_duplicate_access_modifier(list: &[Attribute], attribute: &Attribute) -> bool { match attribute { Self::Expression(_) | Self::Public(_) | Self::Private(_) | Self::Protected(_) | Self::Internal(_) => Self::find_expression(list).is_some() || Self::find_public(list).is_some() || Self::find_private(list).is_some() || Self::find_protected(list).is_some() || Self::find_internal(list).is_some(), _ => false, } } pub fn is_metadata(&self) -> bool { matches!(self, Self::Metadata(_)) } pub fn is_public(&self) -> bool { matches!(self, Self::Public(_)) } pub fn is_private(&self) -> bool { matches!(self, Self::Private(_)) } pub fn is_protected(&self) -> bool { matches!(self, Self::Protected(_)) } pub fn is_internal(&self) -> bool { matches!(self, Self::Internal(_)) } pub fn is_final(&self) -> bool { matches!(self, Self::Final(_)) } pub fn is_native(&self) -> bool { matches!(self, Self::Native(_)) } pub fn is_static(&self) -> bool { matches!(self, Self::Static(_)) } pub fn is_abstract(&self) -> bool { matches!(self, Self::Abstract(_)) } pub fn is_override(&self) -> bool { matches!(self, Self::Override(_)) } pub fn is_dynamic(&self) -> bool { matches!(self, Self::Dynamic(_)) } pub fn from_identifier_name(name: &str, location: &Location) -> Option { if location.character_count() != name.chars().count() { return None; } match name.as_ref() { "final" => Some(Attribute::Final(location.clone())), "native" => Some(Attribute::Native(location.clone())), "static" => Some(Attribute::Static(location.clone())), "abstract" => Some(Attribute::Abstract(location.clone())), "override" => Some(Attribute::Override(location.clone())), "dynamic" => Some(Attribute::Dynamic(location.clone())), _ => None, } } }