mxmlextrema_as3parser/tree/
attributes.rs1use crate::ns::*;
2use serde::{Serialize, Deserialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub enum Attribute {
6 Metadata(Rc<Metadata>),
7 Expression(Rc<Expression>),
8 Public(Location),
9 Private(Location),
10 Protected(Location),
11 Internal(Location),
12 Final(Location),
13 Native(Location),
14 Static(Location),
15 Abstract(Location),
16 Override(Location),
17 Dynamic(Location),
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21pub struct Metadata {
22 pub location: Location,
23 pub asdoc: Option<Rc<Asdoc>>,
24 pub name: (String, Location),
25 pub entries: Option<Vec<Rc<MetadataEntry>>>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct MetadataEntry {
30 pub location: Location,
31 pub key: Option<(String, Location)>,
32 pub value: Rc<MetadataValue>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36pub enum MetadataValue {
37 IdentifierString((String, Location)),
38 String((String, Location)),
39}
40
41impl MetadataValue {
42 pub fn location(&self) -> Location {
43 match self {
44 Self::IdentifierString((_, l)) => l.clone(),
45 Self::String((_, l)) => l.clone(),
46 }
47 }
48}
49
50impl Attribute {
51 pub fn location(&self) -> Location {
52 match self {
53 Self::Expression(m) => m.location(),
54 Self::Metadata(m) => m.location.clone(),
55 Self::Public(a) => a.clone(),
56 Self::Private(a) => a.clone(),
57 Self::Protected(a) => a.clone(),
58 Self::Internal(a) => a.clone(),
59 Self::Final(a) => a.clone(),
60 Self::Native(a) => a.clone(),
61 Self::Static(a) => a.clone(),
62 Self::Abstract(a) => a.clone(),
63 Self::Override(a) => a.clone(),
64 Self::Dynamic(a) => a.clone(),
65 }
66 }
67
68 pub fn has_access_modifier(list: &[Attribute]) -> bool {
69 for a in list {
70 match a {
71 Self::Expression(_) |
72 Self::Public(_) |
73 Self::Private(_) |
74 Self::Protected(_) |
75 Self::Internal(_) => return true,
76 _ => {}
77 }
78 }
79 false
80 }
81
82 pub fn remove_metadata(list: &mut Vec<Attribute>, metadata: &Rc<Metadata>) {
83 for i in 0..list.len() {
84 if let Attribute::Metadata(metadata_1) = &list[i] {
85 if Rc::ptr_eq(&metadata_1, metadata) {
86 list.remove(i);
87 break;
88 }
89 }
90 }
91 }
92
93 pub fn find_metadata(list: &[Attribute]) -> Vec<Rc<Metadata>> {
94 let mut r = vec![];
95 for a in list {
96 match &a {
97 Self::Metadata(e) => {
98 r.push(e.clone());
99 },
100 _ => {},
101 }
102 }
103 r
104 }
105 pub fn find_expression(list: &[Attribute]) -> Option<Rc<Expression>> { for a in list { match &a { Self::Expression(e) => return Some(e.clone()), _ => {} } }; None }
106 pub fn find_public(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Public(l) => return Some(l.clone()), _ => {} } }; None }
107 pub fn find_private(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Private(l) => return Some(l.clone()), _ => {} } }; None }
108 pub fn find_protected(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Protected(l) => return Some(l.clone()), _ => {} } }; None }
109 pub fn find_internal(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Internal(l) => return Some(l.clone()), _ => {} } }; None }
110 pub fn find_final(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Final(l) => return Some(l.clone()), _ => {} } }; None }
111 pub fn find_native(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Native(l) => return Some(l.clone()), _ => {} } }; None }
112 pub fn find_static(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Static(l) => return Some(l.clone()), _ => {} } }; None }
113 pub fn find_abstract(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Abstract(l) => return Some(l.clone()), _ => {} } }; None }
114 pub fn find_override(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Override(l) => return Some(l.clone()), _ => {} } }; None }
115 pub fn find_dynamic(list: &[Attribute]) -> Option<Location> { for a in list { match &a { Self::Dynamic(l) => return Some(l.clone()), _ => {} } }; None }
116
117 pub fn has(list: &[Attribute], attribute: &Attribute) -> bool {
118 match attribute {
119 Self::Public(_) => Self::find_public(list).is_some(),
120 Self::Private(_) => Self::find_private(list).is_some(),
121 Self::Protected(_) => Self::find_protected(list).is_some(),
122 Self::Internal(_) => Self::find_internal(list).is_some(),
123 Self::Final(_) => Self::find_final(list).is_some(),
124 Self::Native(_) => Self::find_native(list).is_some(),
125 Self::Static(_) => Self::find_static(list).is_some(),
126 Self::Abstract(_) => Self::find_abstract(list).is_some(),
127 Self::Override(_) => Self::find_override(list).is_some(),
128 Self::Dynamic(_) => Self::find_dynamic(list).is_some(),
129 _ => false,
130 }
131 }
132
133 pub fn is_duplicate_access_modifier(list: &[Attribute], attribute: &Attribute) -> bool {
134 match attribute {
135 Self::Expression(_) |
136 Self::Public(_) |
137 Self::Private(_) |
138 Self::Protected(_) |
139 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(),
140 _ => false,
141 }
142 }
143
144 pub fn is_metadata(&self) -> bool { matches!(self, Self::Metadata(_)) }
145 pub fn is_public(&self) -> bool { matches!(self, Self::Public(_)) }
146 pub fn is_private(&self) -> bool { matches!(self, Self::Private(_)) }
147 pub fn is_protected(&self) -> bool { matches!(self, Self::Protected(_)) }
148 pub fn is_internal(&self) -> bool { matches!(self, Self::Internal(_)) }
149 pub fn is_final(&self) -> bool { matches!(self, Self::Final(_)) }
150 pub fn is_native(&self) -> bool { matches!(self, Self::Native(_)) }
151 pub fn is_static(&self) -> bool { matches!(self, Self::Static(_)) }
152 pub fn is_abstract(&self) -> bool { matches!(self, Self::Abstract(_)) }
153 pub fn is_override(&self) -> bool { matches!(self, Self::Override(_)) }
154 pub fn is_dynamic(&self) -> bool { matches!(self, Self::Dynamic(_)) }
155
156 pub fn from_identifier_name(name: &str, location: &Location) -> Option<Attribute> {
157 if location.character_count() != name.chars().count() {
158 return None;
159 }
160 match name.as_ref() {
161 "final" => Some(Attribute::Final(location.clone())),
162 "native" => Some(Attribute::Native(location.clone())),
163 "static" => Some(Attribute::Static(location.clone())),
164 "abstract" => Some(Attribute::Abstract(location.clone())),
165 "override" => Some(Attribute::Override(location.clone())),
166 "dynamic" => Some(Attribute::Dynamic(location.clone())),
167 _ => None,
168 }
169 }
170}