boa_ast/expression/operator/update/
mod.rs1mod op;
11
12use crate::{
13 Expression, Span, Spanned,
14 expression::{Identifier, access::PropertyAccess},
15 visitor::{VisitWith, Visitor, VisitorMut},
16};
17use boa_interner::{Interner, ToInternedString};
18use core::ops::ControlFlow;
19
20pub use op::*;
21
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
31#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
32#[derive(Clone, Debug, PartialEq)]
33pub struct Update {
34 op: UpdateOp,
35 target: Box<UpdateTarget>,
36 span: Span,
37}
38
39impl Update {
40 #[inline]
42 #[must_use]
43 pub fn new(op: UpdateOp, target: UpdateTarget, span: Span) -> Self {
44 Self {
45 op,
46 target: Box::new(target),
47 span,
48 }
49 }
50
51 #[inline]
53 #[must_use]
54 pub const fn op(&self) -> UpdateOp {
55 self.op
56 }
57
58 #[inline]
60 #[must_use]
61 pub fn target(&self) -> &UpdateTarget {
62 self.target.as_ref()
63 }
64}
65
66impl Spanned for Update {
67 #[inline]
68 fn span(&self) -> Span {
69 self.span
70 }
71}
72
73impl ToInternedString for Update {
74 #[inline]
75 fn to_interned_string(&self, interner: &Interner) -> String {
76 match self.op {
77 UpdateOp::IncrementPost | UpdateOp::DecrementPost => {
78 format!("{}{}", self.target.to_interned_string(interner), self.op)
79 }
80 UpdateOp::IncrementPre | UpdateOp::DecrementPre => {
81 format!("{}{}", self.op, self.target.to_interned_string(interner))
82 }
83 }
84 }
85}
86
87impl From<Update> for Expression {
88 #[inline]
89 fn from(op: Update) -> Self {
90 Self::Update(op)
91 }
92}
93
94impl VisitWith for Update {
95 fn visit_with<'a, V>(&'a self, visitor: &mut V) -> ControlFlow<V::BreakTy>
96 where
97 V: Visitor<'a>,
98 {
99 match self.target.as_ref() {
100 UpdateTarget::Identifier(ident) => visitor.visit_identifier(ident),
101 UpdateTarget::PropertyAccess(access) => visitor.visit_property_access(access),
102 }
103 }
104
105 fn visit_with_mut<'a, V>(&'a mut self, visitor: &mut V) -> ControlFlow<V::BreakTy>
106 where
107 V: VisitorMut<'a>,
108 {
109 match &mut *self.target {
110 UpdateTarget::Identifier(ident) => visitor.visit_identifier_mut(ident),
111 UpdateTarget::PropertyAccess(access) => visitor.visit_property_access_mut(access),
112 }
113 }
114}
115
116#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
125#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
126#[derive(Clone, Debug, PartialEq)]
127pub enum UpdateTarget {
128 Identifier(Identifier),
130
131 PropertyAccess(PropertyAccess),
133}
134
135impl ToInternedString for UpdateTarget {
136 #[inline]
137 fn to_interned_string(&self, interner: &Interner) -> String {
138 match self {
139 Self::Identifier(identifier) => identifier.to_interned_string(interner),
140 Self::PropertyAccess(access) => access.to_interned_string(interner),
141 }
142 }
143}