1use owned_slice::OwnedSlice;
2use operator::OperatorKind;
3
4#[derive(Debug, PartialEq, Clone, Copy)]
5pub enum Value {
6 Undefined,
7 Null,
8 True,
9 False,
10 Number(OwnedSlice),
11 Binary(u64),
12 String(OwnedSlice),
13 RawQuasi(OwnedSlice),
14}
15
16#[derive(Debug, PartialEq, Clone)]
17pub struct Parameter {
18 pub name: OwnedSlice,
19 pub default: Option<Box<Expression>>
20}
21
22#[derive(Debug, PartialEq, Clone)]
23pub enum Expression {
24 Void,
25 This,
26 Identifier(OwnedSlice),
27 Literal(Value),
28 Template {
29 tag: Option<Box<Expression>>,
30 expressions: Vec<Expression>,
31 quasis: Vec<OwnedSlice>,
32 },
33 RegEx {
34 pattern: OwnedSlice,
35 flags: OwnedSlice
36 },
37 Array(Vec<Expression>),
38 Sequence(Vec<Expression>),
39 Object(Vec<ObjectMember>),
40 Member {
41 object: Box<Expression>,
42 property: OwnedSlice,
43 },
44 ComputedMember {
45 object: Box<Expression>,
46 property: Box<Expression>,
47 },
48 Call {
49 callee: Box<Expression>,
50 arguments: Vec<Expression>,
51 },
52 Binary {
53 parenthesized: bool,
54 operator: OperatorKind,
55 left: Box<Expression>,
56 right: Box<Expression>,
57 },
58 Prefix {
59 operator: OperatorKind,
60 operand: Box<Expression>,
61 },
62 Postfix {
63 operator: OperatorKind,
64 operand: Box<Expression>,
65 },
66 Conditional {
67 test: Box<Expression>,
68 consequent: Box<Expression>,
69 alternate: Box<Expression>,
70 },
71 ArrowFunction {
72 params: Vec<Parameter>,
73 body: Box<Statement>,
74 },
75 Function {
76 name: Option<OwnedSlice>,
77 params: Vec<Parameter>,
78 body: Vec<Statement>,
79 }
80}
81
82impl Expression {
83 pub fn binding_power(&self) -> u8 {
84 match *self {
85 Expression::Member {
86 ..
87 }
88 |
89 Expression::ArrowFunction {
90 ..
91 } => 18,
92
93 Expression::Call {
94 ..
95 } => 17,
96
97 Expression::Prefix {
98 ..
99 } => 15,
100
101 Expression::Binary {
102 ref operator,
103 ..
104 }
105 |
106 Expression::Postfix {
107 ref operator,
108 ..
109 } => operator.binding_power(),
110
111 Expression::Conditional {
112 ..
113 } => 4,
114
115 _ => 100,
116 }
117 }
118
119 #[inline]
120 pub fn binary<E: Into<Expression>>(left: E, operator: OperatorKind, right: E) -> Self {
121 Expression::Binary {
122 parenthesized: false,
123 operator: operator,
124 left: Box::new(left.into()),
125 right: Box::new(right.into()),
126 }
127 }
128
129 #[inline]
130 pub fn member<E: Into<Expression>, S: Into<OwnedSlice>>(object: E, property: S) -> Self {
131 Expression::Member {
132 object: Box::new(object.into()),
133 property: property.into(),
134 }
135 }
136
137 #[inline]
138 pub fn call<E: Into<Expression>>(callee: E, arguments: Vec<Expression>) -> Self {
139 Expression::Call {
140 callee: Box::new(callee.into()),
141 arguments: arguments,
142 }
143 }
144
145 #[inline]
146 pub fn parenthesize(mut self) -> Expression {
147 if let Expression::Binary {
148 ref mut parenthesized,
149 ..
150 } = self {
151 *parenthesized = true;
152 }
153
154 self
155 }
156
157 #[inline]
158 pub fn needs_parens(&self, bp: u8) -> bool {
159 match *self {
160 Expression::Binary {
161 ref parenthesized,
162 ref operator,
163 ..
164 } => *parenthesized && bp >= operator.binding_power(),
165 _ => false
166 }
167 }
168
169 #[inline]
170 pub fn is_allowed_as_bare_statement(&self) -> bool {
171 match *self {
172 Expression::Object(_) => false,
173 Expression::Function { .. } => false,
174
175 _ => true,
176 }
177 }
178}
179
180impl From<&'static str> for Expression {
181 #[inline]
182 fn from(ident: &'static str) -> Self {
183 Expression::Identifier(OwnedSlice::from_static(ident))
184 }
185}
186
187impl From<OwnedSlice> for Expression {
188 #[inline]
189 fn from(ident: OwnedSlice) -> Self {
190 Expression::Identifier(ident)
191 }
192}
193
194impl<'a> From<&'a OwnedSlice> for Expression {
195 #[inline]
196 fn from(ident: &'a OwnedSlice) -> Self {
197 Expression::Identifier(*ident)
198 }
199}
200
201#[derive(Debug, PartialEq, Clone)]
202pub enum ObjectMember {
203 Shorthand {
204 key: OwnedSlice,
205 },
206 Value {
207 key: ObjectKey,
208 value: Expression,
209 },
210 Method {
211 key: ObjectKey,
212 params: Vec<Parameter>,
213 body: Vec<Statement>,
214 },
215}
216
217#[derive(Debug, PartialEq, Clone)]
218pub enum ObjectKey {
219 Computed(Expression),
220 Literal(OwnedSlice),
221 Binary(u64),
222}
223
224#[derive(Debug, PartialEq, Clone)]
225pub enum ClassMember {
226 Constructor {
227 params: Vec<Parameter>,
228 body: Vec<Statement>,
229 },
230 Method {
231 is_static: bool,
232 key: ClassKey,
233 params: Vec<Parameter>,
234 body: Vec<Statement>,
235 },
236 Property {
237 is_static: bool,
238 key: ClassKey,
239 value: Expression,
240 }
241}
242
243#[derive(Debug, PartialEq, Clone)]
244pub enum ClassKey {
245 Computed(Expression),
246 Literal(OwnedSlice),
247 Number(OwnedSlice),
248 Binary(u64),
249}
250
251impl ClassKey {
252 #[inline]
253 pub fn is_constructor(&self) -> bool {
254 match *self {
255 ClassKey::Literal(ref name) => name.as_str() == "constructor",
256
257 _ => false
258 }
259 }
260}
261
262#[derive(Debug, PartialEq, Clone, Copy)]
263pub enum VariableDeclarationKind {
264 Var,
265 Let,
266 Const,
267}
268
269#[derive(Debug, PartialEq, Clone)]
270pub struct VariableDeclarator {
271 pub name: OwnedSlice,
272 pub value: Option<Expression>,
273}
274
275#[derive(Debug, PartialEq, Clone)]
276pub enum Statement {
277 Empty,
278 Block {
279 body: Vec<Statement>,
280 },
281 Transparent {
285 body: Vec<Statement>,
286 },
287 Labeled {
288 label: OwnedSlice,
289 body: Box<Statement>,
290 },
291 VariableDeclaration {
292 kind: VariableDeclarationKind,
293 declarators: Vec<VariableDeclarator>,
294 },
295 Expression {
296 value: Expression
297 },
298 Return {
299 value: Option<Expression>,
300 },
301 Break {
302 label: Option<OwnedSlice>,
303 },
304 Function {
305 name: OwnedSlice,
306 params: Vec<Parameter>,
307 body: Vec<Statement>,
308 },
309 Class {
310 name: OwnedSlice,
311 extends: Option<OwnedSlice>,
312 body: Vec<ClassMember>,
313 },
314 If {
315 test: Expression,
316 consequent: Box<Statement>,
317 alternate: Option<Box<Statement>>,
318 },
319 While {
320 test: Expression,
321 body: Box<Statement>,
322 },
323 For {
324 init: Option<Box<Statement>>,
325 test: Option<Expression>,
326 update: Option<Expression>,
327 body: Box<Statement>,
328 },
329 ForIn {
330 left: Box<Statement>,
331 right: Expression,
332 body: Box<Statement>,
333 },
334 ForOf {
335 left: Box<Statement>,
336 right: Expression,
337 body: Box<Statement>,
338 },
339 Throw {
340 value: Expression
341 },
342 Try {
343 body: Box<Statement>,
344 error: OwnedSlice,
345 handler: Box<Statement>,
346 }
347}
348
349impl From<Expression> for Statement {
350 #[inline]
351 fn from(expression: Expression) -> Self {
352 Statement::Expression {
353 value: expression
354 }
355 }
356}
357
358#[derive(Debug, PartialEq)]
359pub struct Program {
360 pub source: String,
361 pub body: Vec<Statement>,
362}