mxmlextrema_as3parser/tree/
expression.rs1use crate::ns::*;
2use serde::{Serialize, Deserialize};
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
6pub enum Expression {
7 QualifiedIdentifier(QualifiedIdentifier),
8 Paren(ParenExpression),
9 NullLiteral(NullLiteral),
10 BooleanLiteral(BooleanLiteral),
11 NumericLiteral(NumericLiteral),
12 StringLiteral(StringLiteral),
13 ThisLiteral(ThisLiteral),
14 RegExpLiteral(RegExpLiteral),
15 Xml(XmlExpression),
16 XmlMarkup(XmlMarkupExpression),
17 XmlList(XmlListExpression),
18 ArrayLiteral(ArrayLiteral),
19 VectorLiteral(VectorLiteral),
20 ObjectInitializer(ObjectInitializer),
21 Function(FunctionExpression),
22 ImportMeta(ImportMeta),
23 New(NewExpression),
24 Member(MemberExpression),
25 ComputedMember(ComputedMemberExpression),
26 Descendants(DescendantsExpression),
27 Filter(FilterExpression),
28 Super(SuperExpression),
29 Call(CallExpression),
30 WithTypeArguments(ApplyTypeExpression),
31 Unary(UnaryExpression),
32 OptionalChaining(OptionalChainingExpression),
33 OptionalChainingPlaceholder(OptionalChainingPlaceholder),
34 Binary(BinaryExpression),
35 Conditional(ConditionalExpression),
36 Assignment(AssignmentExpression),
37 Sequence(SequenceExpression),
38 AnyType(AnyTypeExpression),
39 VoidType(VoidTypeExpression),
40 ArrayType(ArrayTypeExpression),
41 TupleType(TupleTypeExpression),
42 FunctionType(FunctionTypeExpression),
43 Invalidated(InvalidatedNode),
44 ReservedNamespace(ReservedNamespaceExpression),
45}
46
47impl Expression {
48 pub fn location(&self) -> Location {
49 match self {
50 Self::QualifiedIdentifier(e) => e.location.clone(),
51 Self::Paren(e) => e.location.clone(),
52 Self::NullLiteral(e) => e.location.clone(),
53 Self::BooleanLiteral(e) => e.location.clone(),
54 Self::NumericLiteral(e) => e.location.clone(),
55 Self::StringLiteral(e) => e.location.clone(),
56 Self::ThisLiteral(e) => e.location.clone(),
57 Self::RegExpLiteral(e) => e.location.clone(),
58 Self::Xml(e) => e.location.clone(),
59 Self::XmlMarkup(e) => e.location.clone(),
60 Self::XmlList(e) => e.location.clone(),
61 Self::ArrayLiteral(e) => e.location.clone(),
62 Self::VectorLiteral(e) => e.location.clone(),
63 Self::ObjectInitializer(e) => e.location.clone(),
64 Self::Function(e) => e.location.clone(),
65 Self::ImportMeta(e) => e.location.clone(),
66 Self::New(e) => e.location.clone(),
67 Self::Member(e) => e.location.clone(),
68 Self::ComputedMember(e) => e.location.clone(),
69 Self::Descendants(e) => e.location.clone(),
70 Self::Filter(e) => e.location.clone(),
71 Self::Super(e) => e.location.clone(),
72 Self::Call(e) => e.location.clone(),
73 Self::WithTypeArguments(e) => e.location.clone(),
74 Self::Unary(e) => e.location.clone(),
75 Self::OptionalChaining(e) => e.location.clone(),
76 Self::OptionalChainingPlaceholder(e) => e.location.clone(),
77 Self::Binary(e) => e.location.clone(),
78 Self::Conditional(e) => e.location.clone(),
79 Self::Assignment(e) => e.location.clone(),
80 Self::Sequence(e) => e.location.clone(),
81 Self::AnyType(e) => e.location.clone(),
82 Self::VoidType(e) => e.location.clone(),
83 Self::ArrayType(e) => e.location.clone(),
84 Self::TupleType(e) => e.location.clone(),
85 Self::FunctionType(e) => e.location.clone(),
86 Self::Invalidated(e) => e.location.clone(),
87 Self::ReservedNamespace(e) => e.location(),
88 }
89 }
90
91 pub(crate) fn to_metadata(&self, parser: &Parser) -> Result<Option<Vec<Attribute>>, MetadataRefineError1> {
92 match self {
93 Self::ArrayLiteral(ArrayLiteral { elements, asdoc, .. }) => {
94 if elements.len() != 1 {
95 return Ok(None);
96 }
97 if let Element::Expression(ref exp) = elements[0] {
98 Ok(Some(vec![Attribute::Metadata(parser.refine_metadata(exp, asdoc.clone()).map_err(|e| MetadataRefineError1(e, exp.location()))?)]))
99 } else {
100 Ok(None)
101 }
102 },
103 Self::ComputedMember(ComputedMemberExpression { base, asdoc, key, .. }) => {
104 let a = base.to_metadata(parser)?;
105 if a.is_none() {
106 return Ok(None);
107 }
108 let mut a = a.unwrap();
109 if matches!(key.as_ref(), Self::Sequence(_)) {
110 return Ok(None);
111 }
112 a.push(Attribute::Metadata(parser.refine_metadata(key, asdoc.clone()).map_err(|e| MetadataRefineError1(e, key.location()))?));
113 Ok(Some(a))
114 },
115 _ => Ok(None),
116 }
117 }
118
119 pub fn to_identifier_name_or_asterisk(&self) -> Option<(String, Location)> {
120 match self {
121 Self::QualifiedIdentifier(id) => id.to_identifier_name_or_asterisk(),
122 _ => None,
123 }
124 }
125
126 pub fn to_identifier_name(&self) -> Option<(String, Location)> {
127 match self {
128 Self::QualifiedIdentifier(id) => id.to_identifier_name(),
129 _ => None,
130 }
131 }
132
133 pub fn valid_access_modifier(&self) -> bool {
134 match self {
135 Self::QualifiedIdentifier(id) => id.is_identifier_token(),
136 Self::Member(e) => e.base.valid_access_modifier(),
137 Self::ComputedMember(e) => e.base.valid_access_modifier(),
138 _ => false,
139 }
140 }
141
142 pub(crate) fn to_reserved_namespace_string(&self) -> Option<String> {
143 if let Self::ReservedNamespace(e) = self {
144 Some(e.to_string())
145 } else {
146 None
147 }
148 }
149
150 pub(crate) fn to_reserved_namespace_attribute(&self) -> Option<Attribute> {
151 if let Self::ReservedNamespace(e) = self {
152 Some(e.to_attribute())
153 } else {
154 None
155 }
156 }
157
158 pub fn is_invalidated(&self) -> bool {
159 matches!(self, Self::Invalidated(_))
160 }
161
162 pub fn is_non_null_operation(&self) -> bool {
163 match self {
164 Self::Unary(expr) => expr.operator == Operator::NonNull,
165 _ => false,
166 }
167 }
168
169 pub fn is_valid_assignment_left_hand_side(&self) -> bool {
170 match self {
171 Self::Invalidated(_) => true,
172 Self::Unary(e) => if e.operator == Operator::NonNull {
173 e.expression.is_valid_assignment_left_hand_side()
174 } else {
175 true
176 },
177 Self::ArrayLiteral(_) | Self::ObjectInitializer(_) => self.is_valid_destructuring(),
178 _ => true,
179 }
180 }
181
182 pub fn is_valid_destructuring(&self) -> bool {
183 match self {
184 Self::Invalidated(_) => true,
185 Self::QualifiedIdentifier(id) => !id.attribute && id.qualifier.is_none() && match &id.id {
186 QualifiedIdentifierIdentifier::Id(id) => id.0 != "*",
187 _ => false,
188 },
189 Self::ArrayLiteral(expr) => {
190 for el in &expr.elements {
191 match el {
192 Element::Elision => {},
193 Element::Expression(expr) => {
194 if !expr.is_valid_destructuring() {
195 return false;
196 }
197 },
198 Element::Rest((expr, _)) => {
199 if !expr.is_valid_destructuring() {
200 return false;
201 }
202 },
203 }
204 }
205 true
206 },
207 Self::ObjectInitializer(init) => {
208 for field in init.fields.iter() {
209 match field.as_ref() {
210 InitializerField::Field { value, .. } => {
211 if let Some(val) = value {
212 if !val.is_valid_destructuring() {
213 return false;
214 }
215 }
216 },
217 InitializerField::Rest((expr, _)) => {
218 if !expr.is_valid_destructuring() {
219 return false;
220 }
221 },
222 }
223 }
224 true
225 },
226 _ => false,
227 }
228 }
229
230 pub(crate) fn to_configuration_identifier(&self, parser: &Parser) -> Result<Option<((String, Location), (String, Location), Vec<Attribute>)>, MetadataRefineError1> {
232 if let Self::QualifiedIdentifier(id) = self {
233 if id.attribute {
234 return Ok(None);
235 }
236 if let Some(q) = &id.qualifier {
237 if let Some(q) = q.to_identifier_name() {
238 if let QualifiedIdentifierIdentifier::Id(id) = &id.id {
239 return Ok(Some((q, id.clone(), vec![])));
240 }
241 }
242 }
243 }
244 if let Self::ComputedMember(ComputedMemberExpression { base, asdoc, key, .. }) = self {
245 let a = base.to_configuration_identifier(parser)?;
246 if a.is_none() {
247 return Ok(None);
248 }
249 let (ns, name, mut a) = a.unwrap();
250 if matches!(key.as_ref(), Self::Sequence(_)) {
251 return Ok(None);
252 }
253 a.push(Attribute::Metadata(parser.refine_metadata(key, asdoc.clone()).map_err(|e| MetadataRefineError1(e, key.location()))?));
254 return Ok(Some((ns, name, a)));
255 }
256 Ok(None)
257 }
258
259 pub(crate) fn to_configuration_identifier_no_metadata(&self) -> Option<((String, Location), (String, Location))> {
261 if let Self::QualifiedIdentifier(id) = self {
262 if id.attribute {
263 return None;
264 }
265 if let Some(q) = &id.qualifier {
266 if let Some(q) = q.to_identifier_name() {
267 if let QualifiedIdentifierIdentifier::Id(id) = &id.id {
268 return Some((q, id.clone()));
269 }
270 }
271 }
272 }
273 None
274 }
275
276 pub fn search_optional_chaining_placeholder(self: &Rc<Self>) -> Option<Rc<Expression>> {
277 match self.as_ref() {
278 Self::OptionalChainingPlaceholder(_) => Some(self.clone()),
279 Self::Member(e) => e.base.search_optional_chaining_placeholder(),
280 Self::ComputedMember(e) => e.base.search_optional_chaining_placeholder(),
281 Self::Descendants(e) => e.base.search_optional_chaining_placeholder(),
282 Self::Filter(e) => e.base.search_optional_chaining_placeholder(),
283 Self::Unary(e) => e.expression.search_optional_chaining_placeholder(),
284 Self::Call(e) => e.base.search_optional_chaining_placeholder(),
285 Self::WithTypeArguments(e) => e.base.search_optional_chaining_placeholder(),
286 _ => None,
287 }
288 }
289}